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

network-services: Added aws_v4_authentication field to EdgeCacheOrigin #13020

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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/6736.txt
@@ -0,0 +1,3 @@
```release-note:enhancement
network_services: Added `aws_v4_authentication ` field to `google_network_services_edge_cache_origin ` to support S3-compatible Origins
```
120 changes: 120 additions & 0 deletions google/resource_network_services_edge_cache_origin.go
Expand Up @@ -61,6 +61,33 @@ This address will be used as the origin for cache requests - e.g. FQDN: media-ba
When providing an FQDN (hostname), it must be publicly resolvable (e.g. via Google public DNS) and IP addresses must be publicly routable. It must not contain a protocol (e.g., https://) and it must not contain any slashes.
If a Cloud Storage bucket is provided, it must be in the canonical "gs://bucketname" format. Other forms, such as "storage.googleapis.com", will be rejected.`,
},
"aws_v4_authentication": {
Type: schema.TypeList,
Optional: true,
Description: `Enable AWS Signature Version 4 origin authentication.`,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"access_key_id": {
Type: schema.TypeString,
Required: true,
Description: `The access key ID your origin uses to identify the key.`,
},
"origin_region": {
Type: schema.TypeString,
Required: true,
Description: `The name of the AWS region that your origin is in.`,
},
"secret_access_key_version": {
Type: schema.TypeString,
Required: true,
Description: `The Secret Manager secret version of the secret access key used by your origin.

This is the resource name of the secret version in the format 'projects/*/secrets/*/versions/*' where the '*' values are replaced by the project, secret, and version you require.`,
},
},
},
},
"description": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -271,6 +298,12 @@ func resourceNetworkServicesEdgeCacheOriginCreate(d *schema.ResourceData, meta i
} else if v, ok := d.GetOkExists("timeout"); !isEmptyValue(reflect.ValueOf(timeoutProp)) && (ok || !reflect.DeepEqual(v, timeoutProp)) {
obj["timeout"] = timeoutProp
}
awsV4AuthenticationProp, err := expandNetworkServicesEdgeCacheOriginAwsV4Authentication(d.Get("aws_v4_authentication"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("aws_v4_authentication"); !isEmptyValue(reflect.ValueOf(awsV4AuthenticationProp)) && (ok || !reflect.DeepEqual(v, awsV4AuthenticationProp)) {
obj["awsV4Authentication"] = awsV4AuthenticationProp
}

url, err := replaceVars(d, config, "{{NetworkServicesBasePath}}projects/{{project}}/locations/global/edgeCacheOrigins?edgeCacheOriginId={{name}}")
if err != nil {
Expand Down Expand Up @@ -379,6 +412,9 @@ func resourceNetworkServicesEdgeCacheOriginRead(d *schema.ResourceData, meta int
if err := d.Set("timeout", flattenNetworkServicesEdgeCacheOriginTimeout(res["timeout"], d, config)); err != nil {
return fmt.Errorf("Error reading EdgeCacheOrigin: %s", err)
}
if err := d.Set("aws_v4_authentication", flattenNetworkServicesEdgeCacheOriginAwsV4Authentication(res["awsV4Authentication"], d, config)); err != nil {
return fmt.Errorf("Error reading EdgeCacheOrigin: %s", err)
}

return nil
}
Expand Down Expand Up @@ -453,6 +489,12 @@ func resourceNetworkServicesEdgeCacheOriginUpdate(d *schema.ResourceData, meta i
} else if v, ok := d.GetOkExists("timeout"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, timeoutProp)) {
obj["timeout"] = timeoutProp
}
awsV4AuthenticationProp, err := expandNetworkServicesEdgeCacheOriginAwsV4Authentication(d.Get("aws_v4_authentication"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("aws_v4_authentication"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, awsV4AuthenticationProp)) {
obj["awsV4Authentication"] = awsV4AuthenticationProp
}

url, err := replaceVars(d, config, "{{NetworkServicesBasePath}}projects/{{project}}/locations/global/edgeCacheOrigins/{{name}}")
if err != nil {
Expand Down Expand Up @@ -497,6 +539,10 @@ func resourceNetworkServicesEdgeCacheOriginUpdate(d *schema.ResourceData, meta i
if d.HasChange("timeout") {
updateMask = append(updateMask, "timeout")
}

if d.HasChange("aws_v4_authentication") {
updateMask = append(updateMask, "awsV4Authentication")
}
// 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, ",")})
Expand Down Expand Up @@ -675,6 +721,35 @@ func flattenNetworkServicesEdgeCacheOriginTimeout(v interface{}, d *schema.Resou
return []interface{}{out}
}

func flattenNetworkServicesEdgeCacheOriginAwsV4Authentication(v interface{}, d *schema.ResourceData, config *Config) interface{} {
if v == nil {
return nil
}
original := v.(map[string]interface{})
if len(original) == 0 {
return nil
}
transformed := make(map[string]interface{})
transformed["access_key_id"] =
flattenNetworkServicesEdgeCacheOriginAwsV4AuthenticationAccessKeyId(original["accessKeyId"], d, config)
transformed["secret_access_key_version"] =
flattenNetworkServicesEdgeCacheOriginAwsV4AuthenticationSecretAccessKeyVersion(original["secretAccessKeyVersion"], d, config)
transformed["origin_region"] =
flattenNetworkServicesEdgeCacheOriginAwsV4AuthenticationOriginRegion(original["originRegion"], d, config)
return []interface{}{transformed}
}
func flattenNetworkServicesEdgeCacheOriginAwsV4AuthenticationAccessKeyId(v interface{}, d *schema.ResourceData, config *Config) interface{} {
return v
}

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

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

func expandNetworkServicesEdgeCacheOriginDescription(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
return v, nil
}
Expand Down Expand Up @@ -769,3 +844,48 @@ func expandNetworkServicesEdgeCacheOriginTimeoutResponseTimeout(v interface{}, d
func expandNetworkServicesEdgeCacheOriginTimeoutReadTimeout(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
return v, nil
}

func expandNetworkServicesEdgeCacheOriginAwsV4Authentication(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
l := v.([]interface{})
if len(l) == 0 || l[0] == nil {
return nil, nil
}
raw := l[0]
original := raw.(map[string]interface{})
transformed := make(map[string]interface{})

transformedAccessKeyId, err := expandNetworkServicesEdgeCacheOriginAwsV4AuthenticationAccessKeyId(original["access_key_id"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedAccessKeyId); val.IsValid() && !isEmptyValue(val) {
transformed["accessKeyId"] = transformedAccessKeyId
}

transformedSecretAccessKeyVersion, err := expandNetworkServicesEdgeCacheOriginAwsV4AuthenticationSecretAccessKeyVersion(original["secret_access_key_version"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedSecretAccessKeyVersion); val.IsValid() && !isEmptyValue(val) {
transformed["secretAccessKeyVersion"] = transformedSecretAccessKeyVersion
}

transformedOriginRegion, err := expandNetworkServicesEdgeCacheOriginAwsV4AuthenticationOriginRegion(original["origin_region"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedOriginRegion); val.IsValid() && !isEmptyValue(val) {
transformed["originRegion"] = transformedOriginRegion
}

return transformed, nil
}

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

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

func expandNetworkServicesEdgeCacheOriginAwsV4AuthenticationOriginRegion(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
return v, nil
}
Expand Up @@ -125,6 +125,60 @@ resource "google_network_services_edge_cache_origin" "default" {
`, context)
}

func TestAccNetworkServicesEdgeCacheOrigin_networkServicesEdgeCacheOriginV4authExample(t *testing.T) {
t.Parallel()

context := map[string]interface{}{
"random_suffix": randString(t, 10),
}

vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckNetworkServicesEdgeCacheOriginDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccNetworkServicesEdgeCacheOrigin_networkServicesEdgeCacheOriginV4authExample(context),
},
{
ResourceName: "google_network_services_edge_cache_origin.default",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"name", "timeout"},
},
},
})
}

func testAccNetworkServicesEdgeCacheOrigin_networkServicesEdgeCacheOriginV4authExample(context map[string]interface{}) string {
return Nprintf(`
resource "google_secret_manager_secret" "secret-basic" {
secret_id = "tf-test-secret-name%{random_suffix}"

replication {
automatic = true
}
}

resource "google_secret_manager_secret_version" "secret-version-basic" {
secret = google_secret_manager_secret.secret-basic.id

secret_data = "secret-data"
}

resource "google_network_services_edge_cache_origin" "default" {
name = "tf-test-my-origin%{random_suffix}"
origin_address = "gs://media-edge-default"
description = "The default bucket for V4 authentication"
aws_v4_authentication {
access_key_id = "ACCESSKEYID"
secret_access_key_version = google_secret_manager_secret_version.secret-version-basic.id
origin_region = "auto"
}
}
`, context)
}

func testAccCheckNetworkServicesEdgeCacheOriginDestroyProducer(t *testing.T) func(s *terraform.State) error {
return func(s *terraform.State) error {
for name, rs := range s.RootModule().Resources {
Expand Down
54 changes: 54 additions & 0 deletions website/docs/r/network_services_edge_cache_origin.html.markdown
Expand Up @@ -86,6 +86,40 @@ resource "google_network_services_edge_cache_origin" "default" {
}
}
```
<div class = "oics-button" style="float: right; margin: 0 0 -15px">
<a href="https://console.cloud.google.com/cloudshell/open?cloudshell_git_repo=https%3A%2F%2Fgithub.com%2Fterraform-google-modules%2Fdocs-examples.git&cloudshell_working_dir=network_services_edge_cache_origin_v4auth&cloudshell_image=gcr.io%2Fgraphite-cloud-shell-images%2Fterraform%3Alatest&open_in_editor=main.tf&cloudshell_print=.%2Fmotd&cloudshell_tutorial=.%2Ftutorial.md" target="_blank">
<img alt="Open in Cloud Shell" src="//gstatic.com/cloudssh/images/open-btn.svg" style="max-height: 44px; margin: 32px auto; max-width: 100%;">
</a>
</div>
## Example Usage - Network Services Edge Cache Origin V4auth


```hcl
resource "google_secret_manager_secret" "secret-basic" {
secret_id = "secret-name"

replication {
automatic = true
}
}

resource "google_secret_manager_secret_version" "secret-version-basic" {
secret = google_secret_manager_secret.secret-basic.id

secret_data = "secret-data"
}

resource "google_network_services_edge_cache_origin" "default" {
name = "my-origin"
origin_address = "gs://media-edge-default"
description = "The default bucket for V4 authentication"
aws_v4_authentication {
access_key_id = "ACCESSKEYID"
secret_access_key_version = google_secret_manager_secret_version.secret-version-basic.id
origin_region = "auto"
}
}
```

## Argument Reference

Expand Down Expand Up @@ -168,6 +202,11 @@ The following arguments are supported:
The connection and HTTP timeout configuration for this origin.
Structure is [documented below](#nested_timeout).

* `aws_v4_authentication` -
(Optional)
Enable AWS Signature Version 4 origin authentication.
Structure is [documented below](#nested_aws_v4_authentication).

* `project` - (Optional) The ID of the project in which the resource belongs.
If it is not provided, the provider project is used.

Expand Down Expand Up @@ -201,6 +240,21 @@ The following arguments are supported:
The readTimeout is capped by the responseTimeout. All reads of the HTTP connection/stream must be completed by the deadline set by the responseTimeout.
If the response headers have already been written to the connection, the response will be truncated and logged.

<a name="nested_aws_v4_authentication"></a>The `aws_v4_authentication` block supports:

* `access_key_id` -
(Required)
The access key ID your origin uses to identify the key.

* `secret_access_key_version` -
(Required)
The Secret Manager secret version of the secret access key used by your origin.
This is the resource name of the secret version in the format `projects/*/secrets/*/versions/*` where the `*` values are replaced by the project, secret, and version you require.

* `origin_region` -
(Required)
The name of the AWS region that your origin is in.

## Attributes Reference

In addition to the arguments listed above, the following computed attributes are exported:
Expand Down