-
Notifications
You must be signed in to change notification settings - Fork 263
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* Adds hmac key * Fixes up hmacKey resource properties in terraform * Update products/storage/terraform.yaml Co-Authored-By: Riley Karson <[email protected]> * Update products/storage/api.yaml Co-Authored-By: Riley Karson <[email protected]> * Adds an example, website links, and several fixes from review * Adds test and fixes hmac_key id * tweaking hmac_key example * Update third_party/terraform/tests/resource_storage_hmac_key_test.go Co-Authored-By: Riley Karson <[email protected]> * Update products/storage/api.yaml Co-Authored-By: Riley Karson <[email protected]> * Update third_party/terraform/tests/resource_storage_hmac_key_test.go Co-Authored-By: Riley Karson <[email protected]> * hmac_key: adds doc warning about secrets, fixes yaml formatting, and improves test * More fixes for review * Fixing gofmt * fix resource name * more iteration * More fixes * RM unused var in hmac_key_test * hmac_key: Pre-delete and more fixes * Fixing wrong assumptions * Edits to support read schema * Get tests passing, handle deleted items properly * Sidebar - to _ * Remove the update encoder because the docs are wrong on update format anyways Co-authored-by: Riley Karson <[email protected]> Signed-off-by: Modular Magician <[email protected]> Co-authored-by: Riley Karson <[email protected]>
- Loading branch information
1 parent
715443e
commit 7ba30db
Showing
7 changed files
with
639 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
```release-note:new-resource | ||
`google_storage_hmac_key` | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,361 @@ | ||
// ---------------------------------------------------------------------------- | ||
// | ||
// *** 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" | ||
"time" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" | ||
"github.com/hashicorp/terraform-plugin-sdk/helper/validation" | ||
) | ||
|
||
func resourceStorageHmacKey() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceStorageHmacKeyCreate, | ||
Read: resourceStorageHmacKeyRead, | ||
Update: resourceStorageHmacKeyUpdate, | ||
Delete: resourceStorageHmacKeyDelete, | ||
|
||
Importer: &schema.ResourceImporter{ | ||
State: resourceStorageHmacKeyImport, | ||
}, | ||
|
||
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{ | ||
"service_account_email": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
Description: `The email address of the key's associated service account.`, | ||
}, | ||
"state": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
ValidateFunc: validation.StringInSlice([]string{"ACTIVE", "INACTIVE", ""}, false), | ||
Description: `The state of the key. Can be set to one of ACTIVE, INACTIVE.`, | ||
Default: "ACTIVE", | ||
}, | ||
"access_id": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
Description: `The access ID of the HMAC Key.`, | ||
}, | ||
"secret": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
Description: `HMAC secret key material.`, | ||
Sensitive: true, | ||
}, | ||
"time_created": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
Description: `'The creation time of the HMAC key in RFC 3339 format. '`, | ||
}, | ||
"updated": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
Description: `'The last modification time of the HMAC key metadata in RFC 3339 format.'`, | ||
}, | ||
"project": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
Computed: true, | ||
ForceNew: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceStorageHmacKeyCreate(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(*Config) | ||
|
||
obj := make(map[string]interface{}) | ||
serviceAccountEmailProp, err := expandStorageHmacKeyServiceAccountEmail(d.Get("service_account_email"), d, config) | ||
if err != nil { | ||
return err | ||
} else if v, ok := d.GetOkExists("service_account_email"); !isEmptyValue(reflect.ValueOf(serviceAccountEmailProp)) && (ok || !reflect.DeepEqual(v, serviceAccountEmailProp)) { | ||
obj["serviceAccountEmail"] = serviceAccountEmailProp | ||
} | ||
stateProp, err := expandStorageHmacKeyState(d.Get("state"), d, config) | ||
if err != nil { | ||
return err | ||
} else if v, ok := d.GetOkExists("state"); !isEmptyValue(reflect.ValueOf(stateProp)) && (ok || !reflect.DeepEqual(v, stateProp)) { | ||
obj["state"] = stateProp | ||
} | ||
|
||
url, err := replaceVars(d, config, "{{StorageBasePath}}projects/{{project}}/hmacKeys?serviceAccountEmail={{service_account_email}}") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
log.Printf("[DEBUG] Creating new HmacKey: %#v", obj) | ||
project, err := getProject(d, config) | ||
if err != nil { | ||
return err | ||
} | ||
res, err := sendRequestWithTimeout(config, "POST", project, url, obj, d.Timeout(schema.TimeoutCreate)) | ||
if err != nil { | ||
return fmt.Errorf("Error creating HmacKey: %s", err) | ||
} | ||
|
||
// Store the ID now | ||
id, err := replaceVars(d, config, "projects/{{project}}/hmacKeys/{{access_id}}") | ||
if err != nil { | ||
return fmt.Errorf("Error constructing id: %s", err) | ||
} | ||
d.SetId(id) | ||
|
||
log.Printf("[DEBUG] Finished creating HmacKey %q: %#v", d.Id(), res) | ||
|
||
// `secret` and `access_id` are generated by the API upon successful CREATE. The following | ||
// ensures terraform has the correct values based on the Projects.hmacKeys response object. | ||
secret, ok := res["secret"].(string) | ||
if !ok { | ||
return fmt.Errorf("The response to CREATE was missing an expected field. Your create did not work.") | ||
} | ||
|
||
d.Set("secret", secret) | ||
|
||
metadata := res["metadata"].(map[string]interface{}) | ||
accessId, ok := metadata["accessId"].(string) | ||
if !ok { | ||
return fmt.Errorf("The response to CREATE was missing an expected field. Your create did not work.") | ||
} | ||
|
||
d.Set("access_id", accessId) | ||
|
||
id, err = replaceVars(d, config, "projects/{{project}}/hmacKeys/{{access_id}}") | ||
if err != nil { | ||
return fmt.Errorf("Error constructing id: %s", err) | ||
} | ||
|
||
d.SetId(id) | ||
|
||
return resourceStorageHmacKeyRead(d, meta) | ||
} | ||
|
||
func resourceStorageHmacKeyRead(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(*Config) | ||
|
||
url, err := replaceVars(d, config, "{{StorageBasePath}}projects/{{project}}/hmacKeys/{{access_id}}") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
project, err := getProject(d, config) | ||
if err != nil { | ||
return err | ||
} | ||
res, err := sendRequest(config, "GET", project, url, nil) | ||
if err != nil { | ||
return handleNotFoundError(err, d, fmt.Sprintf("StorageHmacKey %q", d.Id())) | ||
} | ||
|
||
res, err = resourceStorageHmacKeyDecoder(d, meta, res) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if res == nil { | ||
// Decoding the object has resulted in it being gone. It may be marked deleted | ||
log.Printf("[DEBUG] Removing StorageHmacKey because it no longer exists.") | ||
d.SetId("") | ||
return nil | ||
} | ||
|
||
if err := d.Set("project", project); err != nil { | ||
return fmt.Errorf("Error reading HmacKey: %s", err) | ||
} | ||
|
||
if err := d.Set("service_account_email", flattenStorageHmacKeyServiceAccountEmail(res["serviceAccountEmail"], d, config)); err != nil { | ||
return fmt.Errorf("Error reading HmacKey: %s", err) | ||
} | ||
if err := d.Set("state", flattenStorageHmacKeyState(res["state"], d, config)); err != nil { | ||
return fmt.Errorf("Error reading HmacKey: %s", err) | ||
} | ||
if err := d.Set("access_id", flattenStorageHmacKeyAccessId(res["accessId"], d, config)); err != nil { | ||
return fmt.Errorf("Error reading HmacKey: %s", err) | ||
} | ||
if err := d.Set("time_created", flattenStorageHmacKeyTimeCreated(res["timeCreated"], d, config)); err != nil { | ||
return fmt.Errorf("Error reading HmacKey: %s", err) | ||
} | ||
if err := d.Set("updated", flattenStorageHmacKeyUpdated(res["updated"], d, config)); err != nil { | ||
return fmt.Errorf("Error reading HmacKey: %s", err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func resourceStorageHmacKeyUpdate(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(*Config) | ||
|
||
project, err := getProject(d, config) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
d.Partial(true) | ||
|
||
if d.HasChange("state") { | ||
obj := make(map[string]interface{}) | ||
|
||
getUrl, err := replaceVars(d, config, "{{StorageBasePath}}projects/{{project}}/hmacKeys/{{access_id}}") | ||
if err != nil { | ||
return err | ||
} | ||
getRes, err := sendRequest(config, "GET", project, getUrl, nil) | ||
if err != nil { | ||
return handleNotFoundError(err, d, fmt.Sprintf("StorageHmacKey %q", d.Id())) | ||
} | ||
|
||
obj["etag"] = getRes["etag"] | ||
|
||
stateProp, err := expandStorageHmacKeyState(d.Get("state"), d, config) | ||
if err != nil { | ||
return err | ||
} else if v, ok := d.GetOkExists("state"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, stateProp)) { | ||
obj["state"] = stateProp | ||
} | ||
|
||
url, err := replaceVars(d, config, "{{StorageBasePath}}projects/{{project}}/hmacKeys/{{access_id}}") | ||
if err != nil { | ||
return err | ||
} | ||
_, err = sendRequestWithTimeout(config, "PUT", project, url, obj, d.Timeout(schema.TimeoutUpdate)) | ||
if err != nil { | ||
return fmt.Errorf("Error updating HmacKey %q: %s", d.Id(), err) | ||
} | ||
|
||
d.SetPartial("state") | ||
} | ||
|
||
d.Partial(false) | ||
|
||
return resourceStorageHmacKeyRead(d, meta) | ||
} | ||
|
||
func resourceStorageHmacKeyDelete(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(*Config) | ||
|
||
project, err := getProject(d, config) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
url, err := replaceVars(d, config, "{{StorageBasePath}}projects/{{project}}/hmacKeys/{{access_id}}") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
var obj map[string]interface{} | ||
getUrl, err := replaceVars(d, config, "{{StorageBasePath}}projects/{{project}}/hmacKeys/{{access_id}}") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
getRes, err := sendRequest(config, "GET", project, getUrl, nil) | ||
if err != nil { | ||
return handleNotFoundError(err, d, fmt.Sprintf("StorageHmacKey %q", d.Id())) | ||
} | ||
|
||
// HmacKeys need to be INACTIVE to be deleted and the API doesn't accept noop | ||
// updates | ||
if v := getRes["state"]; v == "ACTIVE" { | ||
getRes["state"] = "INACTIVE" | ||
updateUrl, err := replaceVars(d, config, "{{StorageBasePath}}projects/{{project}}/hmacKeys/{{access_id}}") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
log.Printf("[DEBUG] Deactivating HmacKey %q: %#v", d.Id(), getRes) | ||
_, err = sendRequestWithTimeout(config, "PUT", project, updateUrl, getRes, d.Timeout(schema.TimeoutUpdate)) | ||
if err != nil { | ||
return fmt.Errorf("Error deactivating HmacKey %q: %s", d.Id(), err) | ||
} | ||
} | ||
log.Printf("[DEBUG] Deleting HmacKey %q", d.Id()) | ||
|
||
res, err := sendRequestWithTimeout(config, "DELETE", project, url, obj, d.Timeout(schema.TimeoutDelete)) | ||
if err != nil { | ||
return handleNotFoundError(err, d, "HmacKey") | ||
} | ||
|
||
log.Printf("[DEBUG] Finished deleting HmacKey %q: %#v", d.Id(), res) | ||
return nil | ||
} | ||
|
||
func resourceStorageHmacKeyImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { | ||
config := meta.(*Config) | ||
if err := parseImportId([]string{ | ||
"projects/(?P<project>[^/]+)/hmacKeys/(?P<access_id>[^/]+)", | ||
"(?P<project>[^/]+)/(?P<access_id>[^/]+)", | ||
"(?P<access_id>[^/]+)", | ||
}, d, config); err != nil { | ||
return nil, err | ||
} | ||
|
||
// Replace import id for the resource id | ||
id, err := replaceVars(d, config, "projects/{{project}}/hmacKeys/{{access_id}}") | ||
if err != nil { | ||
return nil, fmt.Errorf("Error constructing id: %s", err) | ||
} | ||
d.SetId(id) | ||
|
||
return []*schema.ResourceData{d}, nil | ||
} | ||
|
||
func flattenStorageHmacKeyServiceAccountEmail(v interface{}, d *schema.ResourceData, config *Config) interface{} { | ||
return v | ||
} | ||
|
||
func flattenStorageHmacKeyState(v interface{}, d *schema.ResourceData, config *Config) interface{} { | ||
return v | ||
} | ||
|
||
func flattenStorageHmacKeyAccessId(v interface{}, d *schema.ResourceData, config *Config) interface{} { | ||
return v | ||
} | ||
|
||
func flattenStorageHmacKeyTimeCreated(v interface{}, d *schema.ResourceData, config *Config) interface{} { | ||
return v | ||
} | ||
|
||
func flattenStorageHmacKeyUpdated(v interface{}, d *schema.ResourceData, config *Config) interface{} { | ||
return v | ||
} | ||
|
||
func expandStorageHmacKeyServiceAccountEmail(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { | ||
return v, nil | ||
} | ||
|
||
func expandStorageHmacKeyState(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { | ||
return v, nil | ||
} | ||
|
||
func resourceStorageHmacKeyDecoder(d *schema.ResourceData, meta interface{}, res map[string]interface{}) (map[string]interface{}, error) { | ||
if v := res["state"]; v == "DELETED" { | ||
return nil, nil | ||
} | ||
|
||
return res, nil | ||
} |
Oops, something went wrong.