Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

init os-login sshkey #6026

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/3221.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-resource
`google_os_login_ssh_public_key`
```
3 changes: 3 additions & 0 deletions google/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ type Config struct {
LoggingBasePath string
MLEngineBasePath string
MonitoringBasePath string
OSLoginBasePath string
PubsubBasePath string
RedisBasePath string
ResourceManagerBasePath string
Expand Down Expand Up @@ -236,6 +237,7 @@ var KMSDefaultBasePath = "https://cloudkms.googleapis.com/v1/"
var LoggingDefaultBasePath = "https://logging.googleapis.com/v2/"
var MLEngineDefaultBasePath = "https://ml.googleapis.com/v1/"
var MonitoringDefaultBasePath = "https://monitoring.googleapis.com/v3/"
var OSLoginDefaultBasePath = "https://oslogin.googleapis.com/v1/"
var PubsubDefaultBasePath = "https://pubsub.googleapis.com/v1/"
var RedisDefaultBasePath = "https://redis.googleapis.com/v1/"
var ResourceManagerDefaultBasePath = "https://cloudresourcemanager.googleapis.com/v1/"
Expand Down Expand Up @@ -735,6 +737,7 @@ func ConfigureBasePaths(c *Config) {
c.LoggingBasePath = LoggingDefaultBasePath
c.MLEngineBasePath = MLEngineDefaultBasePath
c.MonitoringBasePath = MonitoringDefaultBasePath
c.OSLoginBasePath = OSLoginDefaultBasePath
c.PubsubBasePath = PubsubDefaultBasePath
c.RedisBasePath = RedisDefaultBasePath
c.ResourceManagerBasePath = ResourceManagerDefaultBasePath
Expand Down
11 changes: 3 additions & 8 deletions google/data_source_google_client_openid_userinfo.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package google

import (
"fmt"
"time"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
Expand All @@ -22,15 +21,11 @@ func dataSourceGoogleClientOpenIDUserinfo() *schema.Resource {
func dataSourceGoogleClientOpenIDUserinfoRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)

// See https://github.com/golang/oauth2/issues/306 for a recommendation to do this from a Go maintainer
// URL retrieved from https://accounts.google.com/.well-known/openid-configuration
res, err := sendRequest(config, "GET", "", "https://openidconnect.googleapis.com/v1/userinfo", nil)
email, err := GetCurrentUserEmail(config)
if err != nil {
return fmt.Errorf("error retrieving userinfo for your provider credentials. have you enabled the 'https://www.googleapis.com/auth/userinfo.email' scope? error: %s", err)
return err
}

d.SetId(time.Now().UTC().String())
d.Set("email", res["email"])

d.Set("email", email)
return nil
}
14 changes: 12 additions & 2 deletions google/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,14 @@ func Provider() terraform.ResourceProvider {
"GOOGLE_MONITORING_CUSTOM_ENDPOINT",
}, MonitoringDefaultBasePath),
},
"os_login_custom_endpoint": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validateCustomEndpoint,
DefaultFunc: schema.MultiEnvDefaultFunc([]string{
"GOOGLE_OS_LOGIN_CUSTOM_ENDPOINT",
}, OSLoginDefaultBasePath),
},
"pubsub_custom_endpoint": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -521,9 +529,9 @@ func Provider() terraform.ResourceProvider {
return provider
}

// Generated resources: 110
// Generated resources: 111
// Generated IAM resources: 51
// Total generated resources: 161
// Total generated resources: 162
func ResourceMap() map[string]*schema.Resource {
resourceMap, _ := ResourceMapWithErrors()
return resourceMap
Expand Down Expand Up @@ -662,6 +670,7 @@ func ResourceMapWithErrors() (map[string]*schema.Resource, error) {
"google_monitoring_group": resourceMonitoringGroup(),
"google_monitoring_notification_channel": resourceMonitoringNotificationChannel(),
"google_monitoring_uptime_check_config": resourceMonitoringUptimeCheckConfig(),
"google_os_login_ssh_public_key": resourceOSLoginSSHPublicKey(),
"google_pubsub_topic": resourcePubsubTopic(),
"google_pubsub_topic_iam_binding": ResourceIamBinding(PubsubTopicIamSchema, PubsubTopicIamUpdaterProducer, PubsubTopicIdParseFunc),
"google_pubsub_topic_iam_member": ResourceIamMember(PubsubTopicIamSchema, PubsubTopicIamUpdaterProducer, PubsubTopicIdParseFunc),
Expand Down Expand Up @@ -868,6 +877,7 @@ func providerConfigure(d *schema.ResourceData, p *schema.Provider, terraformVers
config.LoggingBasePath = d.Get("logging_custom_endpoint").(string)
config.MLEngineBasePath = d.Get("ml_engine_custom_endpoint").(string)
config.MonitoringBasePath = d.Get("monitoring_custom_endpoint").(string)
config.OSLoginBasePath = d.Get("os_login_custom_endpoint").(string)
config.PubsubBasePath = d.Get("pubsub_custom_endpoint").(string)
config.RedisBasePath = d.Get("redis_custom_endpoint").(string)
config.ResourceManagerBasePath = d.Get("resource_manager_custom_endpoint").(string)
Expand Down
261 changes: 261 additions & 0 deletions google/resource_os_login_ssh_public_key.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,261 @@
// ----------------------------------------------------------------------------
//
// *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
//
// ----------------------------------------------------------------------------
//
// This file is automatically generated by Magic Modules and manual
// changes will be clobbered when the file is regenerated.
//
// Please read more about how to change this file in
// .github/CONTRIBUTING.md.
//
// ----------------------------------------------------------------------------

package google

import (
"fmt"
"log"
"reflect"
"strings"
"time"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)

func resourceOSLoginSSHPublicKey() *schema.Resource {
return &schema.Resource{
Create: resourceOSLoginSSHPublicKeyCreate,
Read: resourceOSLoginSSHPublicKeyRead,
Update: resourceOSLoginSSHPublicKeyUpdate,
Delete: resourceOSLoginSSHPublicKeyDelete,

Importer: &schema.ResourceImporter{
State: resourceOSLoginSSHPublicKeyImport,
},

Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(4 * time.Minute),
Update: schema.DefaultTimeout(4 * time.Minute),
Delete: schema.DefaultTimeout(4 * time.Minute),
},

Schema: map[string]*schema.Schema{
"key": {
Type: schema.TypeString,
Required: true,
Description: `Public key text in SSH format, defined by RFC4253 section 6.6.`,
},
"user": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: `The user email.`,
},
"expiration_time_usec": {
Type: schema.TypeString,
Optional: true,
Description: `An expiration time in microseconds since epoch.`,
},
"fingerprint": {
Type: schema.TypeString,
Computed: true,
Description: `The SHA-256 fingerprint of the SSH public key.`,
},
},
}
}

func resourceOSLoginSSHPublicKeyCreate(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)

obj := make(map[string]interface{})
keyProp, err := expandOSLoginSSHPublicKeyKey(d.Get("key"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("key"); !isEmptyValue(reflect.ValueOf(keyProp)) && (ok || !reflect.DeepEqual(v, keyProp)) {
obj["key"] = keyProp
}
expirationTimeUsecProp, err := expandOSLoginSSHPublicKeyExpirationTimeUsec(d.Get("expiration_time_usec"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("expiration_time_usec"); !isEmptyValue(reflect.ValueOf(expirationTimeUsecProp)) && (ok || !reflect.DeepEqual(v, expirationTimeUsecProp)) {
obj["expirationTimeUsec"] = expirationTimeUsecProp
}

url, err := replaceVars(d, config, "{{OSLoginBasePath}}users/{{user}}:importSshPublicKey")
if err != nil {
return err
}

log.Printf("[DEBUG] Creating new SSHPublicKey: %#v", obj)
res, err := sendRequestWithTimeout(config, "POST", "", url, obj, d.Timeout(schema.TimeoutCreate))
if err != nil {
return fmt.Errorf("Error creating SSHPublicKey: %s", err)
}

// Store the ID now
id, err := replaceVars(d, config, "users/{{user}}/sshPublicKeys/{{fingerprint}}")
if err != nil {
return fmt.Errorf("Error constructing id: %s", err)
}
d.SetId(id)

log.Printf("[DEBUG] Finished creating SSHPublicKey %q: %#v", d.Id(), res)

loginProfile, ok := res["loginProfile"]
if !ok {
return fmt.Errorf("Create response didn't contain critical fields. Create may not have succeeded.")
}

// `fingerprint` is autogenerated from the api so needs to be set post-create
sshPublicKeys := loginProfile.(map[string]interface{})["sshPublicKeys"]
for _, sshPublicKey := range sshPublicKeys.(map[string]interface{}) {
if sshPublicKey.(map[string]interface{})["key"].(string) == d.Get("key") {
d.Set("fingerprint", sshPublicKey.(map[string]interface{})["fingerprint"].(string))
break
}
}

// Store the ID now
id, err = replaceVars(d, config, "users/{{user}}/sshPublicKeys/{{fingerprint}}")
if err != nil {
return fmt.Errorf("Error constructing id: %s", err)
}
d.SetId(id)

return resourceOSLoginSSHPublicKeyRead(d, meta)
}

func resourceOSLoginSSHPublicKeyRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)

url, err := replaceVars(d, config, "{{OSLoginBasePath}}users/{{user}}/sshPublicKeys/{{fingerprint}}/{{name}}")
if err != nil {
return err
}

res, err := sendRequest(config, "GET", "", url, nil)
if err != nil {
return handleNotFoundError(err, d, fmt.Sprintf("OSLoginSSHPublicKey %q", d.Id()))
}

if err := d.Set("key", flattenOSLoginSSHPublicKeyKey(res["key"], d, config)); err != nil {
return fmt.Errorf("Error reading SSHPublicKey: %s", err)
}
if err := d.Set("expiration_time_usec", flattenOSLoginSSHPublicKeyExpirationTimeUsec(res["expirationTimeUsec"], d, config)); err != nil {
return fmt.Errorf("Error reading SSHPublicKey: %s", err)
}
if err := d.Set("fingerprint", flattenOSLoginSSHPublicKeyFingerprint(res["fingerprint"], d, config)); err != nil {
return fmt.Errorf("Error reading SSHPublicKey: %s", err)
}

return nil
}

func resourceOSLoginSSHPublicKeyUpdate(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)

obj := make(map[string]interface{})
keyProp, err := expandOSLoginSSHPublicKeyKey(d.Get("key"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("key"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, keyProp)) {
obj["key"] = keyProp
}
expirationTimeUsecProp, err := expandOSLoginSSHPublicKeyExpirationTimeUsec(d.Get("expiration_time_usec"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("expiration_time_usec"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, expirationTimeUsecProp)) {
obj["expirationTimeUsec"] = expirationTimeUsecProp
}

url, err := replaceVars(d, config, "{{OSLoginBasePath}}users/{{user}}/sshPublicKeys/{{fingerprint}}/{{name}}")
if err != nil {
return err
}

log.Printf("[DEBUG] Updating SSHPublicKey %q: %#v", d.Id(), obj)
updateMask := []string{}

if d.HasChange("key") {
updateMask = append(updateMask, "key")
}

if d.HasChange("expiration_time_usec") {
updateMask = append(updateMask, "expirationTimeUsec")
}
// updateMask is a URL parameter but not present in the schema, so replaceVars
// won't set it
url, err = addQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")})
if err != nil {
return err
}
_, err = sendRequestWithTimeout(config, "PATCH", "", url, obj, d.Timeout(schema.TimeoutUpdate))

if err != nil {
return fmt.Errorf("Error updating SSHPublicKey %q: %s", d.Id(), err)
}

return resourceOSLoginSSHPublicKeyRead(d, meta)
}

func resourceOSLoginSSHPublicKeyDelete(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)

url, err := replaceVars(d, config, "{{OSLoginBasePath}}users/{{user}}/sshPublicKeys/{{fingerprint}}/{{name}}")
if err != nil {
return err
}

var obj map[string]interface{}
log.Printf("[DEBUG] Deleting SSHPublicKey %q", d.Id())

res, err := sendRequestWithTimeout(config, "DELETE", "", url, obj, d.Timeout(schema.TimeoutDelete))
if err != nil {
return handleNotFoundError(err, d, "SSHPublicKey")
}

log.Printf("[DEBUG] Finished deleting SSHPublicKey %q: %#v", d.Id(), res)
return nil
}

func resourceOSLoginSSHPublicKeyImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
config := meta.(*Config)
if err := parseImportId([]string{
"users/(?P<user>[^/]+)/sshPublicKeys/(?P<fingerprint>[^/]+)",
"(?P<user>[^/]+)/(?P<fingerprint>[^/]+)",
}, d, config); err != nil {
return nil, err
}

// Replace import id for the resource id
id, err := replaceVars(d, config, "users/{{user}}/sshPublicKeys/{{fingerprint}}")
if err != nil {
return nil, fmt.Errorf("Error constructing id: %s", err)
}
d.SetId(id)

return []*schema.ResourceData{d}, nil
}

func flattenOSLoginSSHPublicKeyKey(v interface{}, d *schema.ResourceData, config *Config) interface{} {
return v
}

func flattenOSLoginSSHPublicKeyExpirationTimeUsec(v interface{}, d *schema.ResourceData, config *Config) interface{} {
return v
}

func flattenOSLoginSSHPublicKeyFingerprint(v interface{}, d *schema.ResourceData, config *Config) interface{} {
return v
}

func expandOSLoginSSHPublicKeyKey(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
return v, nil
}

func expandOSLoginSSHPublicKeyExpirationTimeUsec(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
return v, nil
}
Loading