From a9a243e9ca4cccd1fbdfc8986f6eff20e8005d7d Mon Sep 17 00:00:00 2001 From: megan07 Date: Thu, 8 Aug 2019 22:00:01 +0000 Subject: [PATCH] Add support for oauth and oidc tokens to cloud_scheduler_job Signed-off-by: Modular Magician --- google/cloudscheduler_job.go | 133 +++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) diff --git a/google/cloudscheduler_job.go b/google/cloudscheduler_job.go index 9862d2c36..a5cb81497 100644 --- a/google/cloudscheduler_job.go +++ b/google/cloudscheduler_job.go @@ -17,8 +17,59 @@ package google import ( "fmt" "reflect" + "strings" + + "github.com/hashicorp/terraform/helper/schema" ) +// Both oidc and oauth headers cannot be set +func validateAuthHeaders(diff *schema.ResourceDiff, v interface{}) error { + httpBlock := diff.Get("http_target.0").(map[string]interface{}) + + if httpBlock != nil { + oauth := httpBlock["oauth_token"] + oidc := httpBlock["oidc_token"] + + if oauth != nil && oidc != nil { + if len(oidc.([]interface{})) > 0 && len(oauth.([]interface{})) > 0 { + return fmt.Errorf("Error in http_target: only one of oauth_token or oidc_token can be specified, but not both.") + } + } + } + + return nil +} + +func authHeaderDiffSuppress(k, old, new string, d *schema.ResourceData) bool { + b := strings.Split(k, ".") + if b[0] == "http_target" && len(b) > 4 { + block := b[2] + attr := b[4] + + // If generating an oauth_token and scope is not provided in the configuration, + // the default "https://www.googleapis.com/auth/cloud-platform" scope will be used. + // Although not in the configuration, this is returned and will be stored in state. + if block == "oauth_token" && attr == "scope" { + if old == canonicalizeServiceScope("cloud-platform") && new == "" { + return true + } + } + + // If generating an oidc_token and audience is not provided in the configuration, + // the URI specified in target will be used. Although not in the configuration, + // this is returned and will be stored in state. + if block == "oidc_token" && attr == "audience" { + uri := d.Get(strings.Join(b[0:2], ".") + ".uri") + if old == uri && new == "" { + return true + } + } + + } + + return false +} + func GetCloudSchedulerJobCaiObject(d TerraformResourceData, config *Config) (Asset, error) { name, err := assetName(d, config, "//cloudscheduler.googleapis.com/projects/{{project}}/locations/{{region}}/jobs/{{name}}") if err != nil { @@ -399,6 +450,20 @@ func expandCloudSchedulerJobHttpTarget(v interface{}, d TerraformResourceData, c transformed["headers"] = transformedHeaders } + transformedOauthToken, err := expandCloudSchedulerJobHttpTargetOauthToken(original["oauth_token"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedOauthToken); val.IsValid() && !isEmptyValue(val) { + transformed["oauthToken"] = transformedOauthToken + } + + transformedOidcToken, err := expandCloudSchedulerJobHttpTargetOidcToken(original["oidc_token"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedOidcToken); val.IsValid() && !isEmptyValue(val) { + transformed["oidcToken"] = transformedOidcToken + } + return transformed, nil } @@ -424,3 +489,71 @@ func expandCloudSchedulerJobHttpTargetHeaders(v interface{}, d TerraformResource } return m, nil } + +func expandCloudSchedulerJobHttpTargetOauthToken(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{}) + + transformedServiceAccountEmail, err := expandCloudSchedulerJobHttpTargetOauthTokenServiceAccountEmail(original["service_account_email"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedServiceAccountEmail); val.IsValid() && !isEmptyValue(val) { + transformed["serviceAccountEmail"] = transformedServiceAccountEmail + } + + transformedScope, err := expandCloudSchedulerJobHttpTargetOauthTokenScope(original["scope"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedScope); val.IsValid() && !isEmptyValue(val) { + transformed["scope"] = transformedScope + } + + return transformed, nil +} + +func expandCloudSchedulerJobHttpTargetOauthTokenServiceAccountEmail(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandCloudSchedulerJobHttpTargetOauthTokenScope(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandCloudSchedulerJobHttpTargetOidcToken(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{}) + + transformedServiceAccountEmail, err := expandCloudSchedulerJobHttpTargetOidcTokenServiceAccountEmail(original["service_account_email"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedServiceAccountEmail); val.IsValid() && !isEmptyValue(val) { + transformed["serviceAccountEmail"] = transformedServiceAccountEmail + } + + transformedAudience, err := expandCloudSchedulerJobHttpTargetOidcTokenAudience(original["audience"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAudience); val.IsValid() && !isEmptyValue(val) { + transformed["audience"] = transformedAudience + } + + return transformed, nil +} + +func expandCloudSchedulerJobHttpTargetOidcTokenServiceAccountEmail(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandCloudSchedulerJobHttpTargetOidcTokenAudience(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +}