| // Copyright (c) HashiCorp, Inc. |
| // SPDX-License-Identifier: MPL-2.0 |
| |
| // ---------------------------------------------------------------------------- |
| // |
| // *** AUTO GENERATED CODE *** Type: MMv1 *** |
| // |
| // ---------------------------------------------------------------------------- |
| // |
| // 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 cloudscheduler |
| |
| import ( |
| "context" |
| "fmt" |
| "log" |
| "reflect" |
| "regexp" |
| "strings" |
| "time" |
| |
| "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" |
| "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" |
| |
| "github.com/hashicorp/terraform-provider-google-beta/google-beta/tpgresource" |
| transport_tpg "github.com/hashicorp/terraform-provider-google-beta/google-beta/transport" |
| "github.com/hashicorp/terraform-provider-google-beta/google-beta/verify" |
| ) |
| |
| // Both oidc and oauth headers cannot be set |
| func validateAuthHeaders(_ context.Context, 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 { |
| // 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. |
| // Similarly, 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, in both cases the default is returned in the object, but is not in. |
| // state. We suppress the diff if the values are these defaults but are not stored in state. |
| |
| b := strings.Split(k, ".") |
| if b[0] == "http_target" && len(b) > 4 { |
| block := b[2] |
| attr := b[4] |
| |
| if block == "oauth_token" && attr == "scope" { |
| if old == tpgresource.CanonicalizeServiceScope("cloud-platform") && new == "" { |
| return true |
| } |
| } |
| |
| if block == "oidc_token" && attr == "audience" { |
| uri := d.Get(strings.Join(b[0:2], ".") + ".uri") |
| if old == uri && new == "" { |
| return true |
| } |
| } |
| |
| } |
| |
| return false |
| } |
| |
| func validateHttpHeaders() schema.SchemaValidateFunc { |
| return func(i interface{}, k string) (s []string, es []error) { |
| headers := i.(map[string]interface{}) |
| if _, ok := headers["Content-Length"]; ok { |
| es = append(es, fmt.Errorf("Cannot set the Content-Length header on %s", k)) |
| return |
| } |
| r := regexp.MustCompile(`(X-Google-|X-AppEngine-).*`) |
| for key := range headers { |
| if r.MatchString(key) { |
| es = append(es, fmt.Errorf("Cannot set the %s header on %s", key, k)) |
| return |
| } |
| } |
| |
| return |
| } |
| } |
| |
| func ResourceCloudSchedulerJob() *schema.Resource { |
| return &schema.Resource{ |
| Create: resourceCloudSchedulerJobCreate, |
| Read: resourceCloudSchedulerJobRead, |
| Update: resourceCloudSchedulerJobUpdate, |
| Delete: resourceCloudSchedulerJobDelete, |
| |
| Importer: &schema.ResourceImporter{ |
| State: resourceCloudSchedulerJobImport, |
| }, |
| |
| Timeouts: &schema.ResourceTimeout{ |
| Create: schema.DefaultTimeout(20 * time.Minute), |
| Update: schema.DefaultTimeout(20 * time.Minute), |
| Delete: schema.DefaultTimeout(20 * time.Minute), |
| }, |
| |
| CustomizeDiff: customdiff.All( |
| validateAuthHeaders, |
| tpgresource.DefaultProviderProject, |
| tpgresource.DefaultProviderRegion, |
| ), |
| |
| Schema: map[string]*schema.Schema{ |
| "name": { |
| Type: schema.TypeString, |
| Required: true, |
| ForceNew: true, |
| Description: `The name of the job.`, |
| }, |
| "app_engine_http_target": { |
| Type: schema.TypeList, |
| Optional: true, |
| Description: `App Engine HTTP target. |
| If the job providers a App Engine HTTP target the cron will |
| send a request to the service instance`, |
| MaxItems: 1, |
| Elem: &schema.Resource{ |
| Schema: map[string]*schema.Schema{ |
| "relative_uri": { |
| Type: schema.TypeString, |
| Required: true, |
| Description: `The relative URI. |
| The relative URL must begin with "/" and must be a valid HTTP relative URL. |
| It can contain a path, query string arguments, and \# fragments. |
| If the relative URL is empty, then the root path "/" will be used. |
| No spaces are allowed, and the maximum length allowed is 2083 characters`, |
| }, |
| "app_engine_routing": { |
| Type: schema.TypeList, |
| Optional: true, |
| Description: `App Engine Routing setting for the job.`, |
| MaxItems: 1, |
| Elem: &schema.Resource{ |
| Schema: map[string]*schema.Schema{ |
| "instance": { |
| Type: schema.TypeString, |
| Optional: true, |
| Description: `App instance. |
| By default, the job is sent to an instance which is available when the job is attempted.`, |
| AtLeastOneOf: []string{"app_engine_http_target.0.app_engine_routing.0.service", "app_engine_http_target.0.app_engine_routing.0.version", "app_engine_http_target.0.app_engine_routing.0.instance"}, |
| }, |
| "service": { |
| Type: schema.TypeString, |
| Optional: true, |
| Description: `App service. |
| By default, the job is sent to the service which is the default service when the job is attempted.`, |
| AtLeastOneOf: []string{"app_engine_http_target.0.app_engine_routing.0.service", "app_engine_http_target.0.app_engine_routing.0.version", "app_engine_http_target.0.app_engine_routing.0.instance"}, |
| }, |
| "version": { |
| Type: schema.TypeString, |
| Optional: true, |
| Description: `App version. |
| By default, the job is sent to the version which is the default version when the job is attempted.`, |
| AtLeastOneOf: []string{"app_engine_http_target.0.app_engine_routing.0.service", "app_engine_http_target.0.app_engine_routing.0.version", "app_engine_http_target.0.app_engine_routing.0.instance"}, |
| }, |
| }, |
| }, |
| }, |
| "body": { |
| Type: schema.TypeString, |
| Optional: true, |
| ValidateFunc: verify.ValidateBase64String, |
| Description: `HTTP request body. |
| A request body is allowed only if the HTTP method is POST or PUT. |
| It will result in invalid argument error to set a body on a job with an incompatible HttpMethod. |
| |
| A base64-encoded string.`, |
| }, |
| "headers": { |
| Type: schema.TypeMap, |
| Optional: true, |
| ValidateFunc: validateHttpHeaders(), |
| Description: `HTTP request headers. |
| This map contains the header field names and values. |
| Headers can be set when the job is created.`, |
| Elem: &schema.Schema{Type: schema.TypeString}, |
| }, |
| "http_method": { |
| Type: schema.TypeString, |
| Optional: true, |
| Description: `Which HTTP method to use for the request.`, |
| }, |
| }, |
| }, |
| ExactlyOneOf: []string{"pubsub_target", "http_target", "app_engine_http_target"}, |
| }, |
| "attempt_deadline": { |
| Type: schema.TypeString, |
| Optional: true, |
| DiffSuppressFunc: tpgresource.EmptyOrDefaultStringSuppress("180s"), |
| Description: `The deadline for job attempts. If the request handler does not respond by this deadline then the request is |
| cancelled and the attempt is marked as a DEADLINE_EXCEEDED failure. The failed attempt can be viewed in |
| execution logs. Cloud Scheduler will retry the job according to the RetryConfig. |
| The allowed duration for this deadline is: |
| * For HTTP targets, between 15 seconds and 30 minutes. |
| * For App Engine HTTP targets, between 15 seconds and 24 hours. |
| * **Note**: For PubSub targets, this field is ignored - setting it will introduce an unresolvable diff. |
| A duration in seconds with up to nine fractional digits, terminated by 's'. Example: "3.5s"`, |
| Default: "180s", |
| }, |
| "description": { |
| Type: schema.TypeString, |
| Optional: true, |
| Description: `A human-readable description for the job. |
| This string must not contain more than 500 characters.`, |
| }, |
| "http_target": { |
| Type: schema.TypeList, |
| Optional: true, |
| Description: `HTTP target. |
| If the job providers a http_target the cron will |
| send a request to the targeted url`, |
| MaxItems: 1, |
| Elem: &schema.Resource{ |
| Schema: map[string]*schema.Schema{ |
| "uri": { |
| Type: schema.TypeString, |
| Required: true, |
| DiffSuppressFunc: tpgresource.LastSlashDiffSuppress, |
| Description: `The full URI path that the request will be sent to.`, |
| }, |
| "body": { |
| Type: schema.TypeString, |
| Optional: true, |
| ValidateFunc: verify.ValidateBase64String, |
| Description: `HTTP request body. |
| A request body is allowed only if the HTTP method is POST, PUT, or PATCH. |
| It is an error to set body on a job with an incompatible HttpMethod. |
| |
| A base64-encoded string.`, |
| }, |
| "headers": { |
| Type: schema.TypeMap, |
| Optional: true, |
| ValidateFunc: validateHttpHeaders(), |
| Description: `This map contains the header field names and values. |
| Repeated headers are not supported, but a header value can contain commas.`, |
| Elem: &schema.Schema{Type: schema.TypeString}, |
| }, |
| "http_method": { |
| Type: schema.TypeString, |
| Optional: true, |
| Description: `Which HTTP method to use for the request.`, |
| }, |
| "oauth_token": { |
| Type: schema.TypeList, |
| Optional: true, |
| DiffSuppressFunc: authHeaderDiffSuppress, |
| Description: `Contains information needed for generating an OAuth token. |
| This type of authorization should be used when sending requests to a GCP endpoint.`, |
| MaxItems: 1, |
| Elem: &schema.Resource{ |
| Schema: map[string]*schema.Schema{ |
| "service_account_email": { |
| Type: schema.TypeString, |
| Required: true, |
| Description: `Service account email to be used for generating OAuth token. |
| The service account must be within the same project as the job.`, |
| }, |
| "scope": { |
| Type: schema.TypeString, |
| Optional: true, |
| Description: `OAuth scope to be used for generating OAuth access token. If not specified, |
| "https://www.googleapis.com/auth/cloud-platform" will be used.`, |
| }, |
| }, |
| }, |
| }, |
| "oidc_token": { |
| Type: schema.TypeList, |
| Optional: true, |
| DiffSuppressFunc: authHeaderDiffSuppress, |
| Description: `Contains information needed for generating an OpenID Connect token. |
| This type of authorization should be used when sending requests to third party endpoints or Cloud Run.`, |
| MaxItems: 1, |
| Elem: &schema.Resource{ |
| Schema: map[string]*schema.Schema{ |
| "service_account_email": { |
| Type: schema.TypeString, |
| Required: true, |
| Description: `Service account email to be used for generating OAuth token. |
| The service account must be within the same project as the job.`, |
| }, |
| "audience": { |
| Type: schema.TypeString, |
| Optional: true, |
| Description: `Audience to be used when generating OIDC token. If not specified, |
| the URI specified in target will be used.`, |
| }, |
| }, |
| }, |
| }, |
| }, |
| }, |
| ExactlyOneOf: []string{"pubsub_target", "http_target", "app_engine_http_target"}, |
| }, |
| "paused": { |
| Type: schema.TypeBool, |
| Computed: true, |
| Optional: true, |
| Description: `Sets the job to a paused state. Jobs default to being enabled when this property is not set.`, |
| }, |
| "pubsub_target": { |
| Type: schema.TypeList, |
| Optional: true, |
| Description: `Pub/Sub target |
| If the job providers a Pub/Sub target the cron will publish |
| a message to the provided topic`, |
| MaxItems: 1, |
| Elem: &schema.Resource{ |
| Schema: map[string]*schema.Schema{ |
| "topic_name": { |
| Type: schema.TypeString, |
| Required: true, |
| Description: `The full resource name for the Cloud Pub/Sub topic to which |
| messages will be published when a job is delivered. ~>**NOTE:** |
| The topic name must be in the same format as required by PubSub's |
| PublishRequest.name, e.g. 'projects/my-project/topics/my-topic'.`, |
| }, |
| "attributes": { |
| Type: schema.TypeMap, |
| Optional: true, |
| Description: `Attributes for PubsubMessage. |
| Pubsub message must contain either non-empty data, or at least one attribute.`, |
| Elem: &schema.Schema{Type: schema.TypeString}, |
| }, |
| "data": { |
| Type: schema.TypeString, |
| Optional: true, |
| ValidateFunc: verify.ValidateBase64String, |
| Description: `The message payload for PubsubMessage. |
| Pubsub message must contain either non-empty data, or at least one attribute. |
| |
| A base64-encoded string.`, |
| }, |
| }, |
| }, |
| ExactlyOneOf: []string{"pubsub_target", "http_target", "app_engine_http_target"}, |
| }, |
| "region": { |
| Type: schema.TypeString, |
| Computed: true, |
| Optional: true, |
| ForceNew: true, |
| Description: `Region where the scheduler job resides. If it is not provided, Terraform will use the provider default.`, |
| }, |
| "retry_config": { |
| Type: schema.TypeList, |
| Optional: true, |
| Description: `By default, if a job does not complete successfully, |
| meaning that an acknowledgement is not received from the handler, |
| then it will be retried with exponential backoff according to the settings`, |
| MaxItems: 1, |
| Elem: &schema.Resource{ |
| Schema: map[string]*schema.Schema{ |
| "max_backoff_duration": { |
| Type: schema.TypeString, |
| Computed: true, |
| Optional: true, |
| Description: `The maximum amount of time to wait before retrying a job after it fails. |
| A duration in seconds with up to nine fractional digits, terminated by 's'.`, |
| AtLeastOneOf: []string{"retry_config.0.retry_count", "retry_config.0.max_retry_duration", "retry_config.0.min_backoff_duration", "retry_config.0.max_backoff_duration", "retry_config.0.max_doublings"}, |
| }, |
| "max_doublings": { |
| Type: schema.TypeInt, |
| Computed: true, |
| Optional: true, |
| Description: `The time between retries will double maxDoublings times. |
| A job's retry interval starts at minBackoffDuration, |
| then doubles maxDoublings times, then increases linearly, |
| and finally retries retries at intervals of maxBackoffDuration up to retryCount times.`, |
| AtLeastOneOf: []string{"retry_config.0.retry_count", "retry_config.0.max_retry_duration", "retry_config.0.min_backoff_duration", "retry_config.0.max_backoff_duration", "retry_config.0.max_doublings"}, |
| }, |
| "max_retry_duration": { |
| Type: schema.TypeString, |
| Computed: true, |
| Optional: true, |
| Description: `The time limit for retrying a failed job, measured from time when an execution was first attempted. |
| If specified with retryCount, the job will be retried until both limits are reached. |
| A duration in seconds with up to nine fractional digits, terminated by 's'.`, |
| AtLeastOneOf: []string{"retry_config.0.retry_count", "retry_config.0.max_retry_duration", "retry_config.0.min_backoff_duration", "retry_config.0.max_backoff_duration", "retry_config.0.max_doublings"}, |
| }, |
| "min_backoff_duration": { |
| Type: schema.TypeString, |
| Computed: true, |
| Optional: true, |
| Description: `The minimum amount of time to wait before retrying a job after it fails. |
| A duration in seconds with up to nine fractional digits, terminated by 's'.`, |
| AtLeastOneOf: []string{"retry_config.0.retry_count", "retry_config.0.max_retry_duration", "retry_config.0.min_backoff_duration", "retry_config.0.max_backoff_duration", "retry_config.0.max_doublings"}, |
| }, |
| "retry_count": { |
| Type: schema.TypeInt, |
| Computed: true, |
| Optional: true, |
| Description: `The number of attempts that the system will make to run a |
| job using the exponential backoff procedure described by maxDoublings. |
| Values greater than 5 and negative values are not allowed.`, |
| AtLeastOneOf: []string{"retry_config.0.retry_count", "retry_config.0.max_retry_duration", "retry_config.0.min_backoff_duration", "retry_config.0.max_backoff_duration", "retry_config.0.max_doublings"}, |
| }, |
| }, |
| }, |
| }, |
| "schedule": { |
| Type: schema.TypeString, |
| Optional: true, |
| Description: `Describes the schedule on which the job will be executed.`, |
| }, |
| "time_zone": { |
| Type: schema.TypeString, |
| Optional: true, |
| Description: `Specifies the time zone to be used in interpreting schedule. |
| The value of this field must be a time zone name from the tz database.`, |
| Default: "Etc/UTC", |
| }, |
| "state": { |
| Type: schema.TypeString, |
| Computed: true, |
| Description: `State of the job.`, |
| }, |
| "project": { |
| Type: schema.TypeString, |
| Optional: true, |
| Computed: true, |
| ForceNew: true, |
| }, |
| }, |
| UseJSONNumber: true, |
| } |
| } |
| |
| func resourceCloudSchedulerJobCreate(d *schema.ResourceData, meta interface{}) error { |
| config := meta.(*transport_tpg.Config) |
| userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) |
| if err != nil { |
| return err |
| } |
| |
| obj := make(map[string]interface{}) |
| nameProp, err := expandCloudSchedulerJobName(d.Get("name"), d, config) |
| if err != nil { |
| return err |
| } else if v, ok := d.GetOkExists("name"); !tpgresource.IsEmptyValue(reflect.ValueOf(nameProp)) && (ok || !reflect.DeepEqual(v, nameProp)) { |
| obj["name"] = nameProp |
| } |
| descriptionProp, err := expandCloudSchedulerJobDescription(d.Get("description"), d, config) |
| if err != nil { |
| return err |
| } else if v, ok := d.GetOkExists("description"); !tpgresource.IsEmptyValue(reflect.ValueOf(descriptionProp)) && (ok || !reflect.DeepEqual(v, descriptionProp)) { |
| obj["description"] = descriptionProp |
| } |
| scheduleProp, err := expandCloudSchedulerJobSchedule(d.Get("schedule"), d, config) |
| if err != nil { |
| return err |
| } else if v, ok := d.GetOkExists("schedule"); !tpgresource.IsEmptyValue(reflect.ValueOf(scheduleProp)) && (ok || !reflect.DeepEqual(v, scheduleProp)) { |
| obj["schedule"] = scheduleProp |
| } |
| timeZoneProp, err := expandCloudSchedulerJobTimeZone(d.Get("time_zone"), d, config) |
| if err != nil { |
| return err |
| } else if v, ok := d.GetOkExists("time_zone"); !tpgresource.IsEmptyValue(reflect.ValueOf(timeZoneProp)) && (ok || !reflect.DeepEqual(v, timeZoneProp)) { |
| obj["timeZone"] = timeZoneProp |
| } |
| pausedProp, err := expandCloudSchedulerJobPaused(d.Get("paused"), d, config) |
| if err != nil { |
| return err |
| } else if v, ok := d.GetOkExists("paused"); !tpgresource.IsEmptyValue(reflect.ValueOf(pausedProp)) && (ok || !reflect.DeepEqual(v, pausedProp)) { |
| obj["paused"] = pausedProp |
| } |
| attemptDeadlineProp, err := expandCloudSchedulerJobAttemptDeadline(d.Get("attempt_deadline"), d, config) |
| if err != nil { |
| return err |
| } else if v, ok := d.GetOkExists("attempt_deadline"); !tpgresource.IsEmptyValue(reflect.ValueOf(attemptDeadlineProp)) && (ok || !reflect.DeepEqual(v, attemptDeadlineProp)) { |
| obj["attemptDeadline"] = attemptDeadlineProp |
| } |
| retryConfigProp, err := expandCloudSchedulerJobRetryConfig(d.Get("retry_config"), d, config) |
| if err != nil { |
| return err |
| } else if v, ok := d.GetOkExists("retry_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(retryConfigProp)) && (ok || !reflect.DeepEqual(v, retryConfigProp)) { |
| obj["retryConfig"] = retryConfigProp |
| } |
| pubsubTargetProp, err := expandCloudSchedulerJobPubsubTarget(d.Get("pubsub_target"), d, config) |
| if err != nil { |
| return err |
| } else if v, ok := d.GetOkExists("pubsub_target"); !tpgresource.IsEmptyValue(reflect.ValueOf(pubsubTargetProp)) && (ok || !reflect.DeepEqual(v, pubsubTargetProp)) { |
| obj["pubsubTarget"] = pubsubTargetProp |
| } |
| appEngineHttpTargetProp, err := expandCloudSchedulerJobAppEngineHttpTarget(d.Get("app_engine_http_target"), d, config) |
| if err != nil { |
| return err |
| } else if v, ok := d.GetOkExists("app_engine_http_target"); !tpgresource.IsEmptyValue(reflect.ValueOf(appEngineHttpTargetProp)) && (ok || !reflect.DeepEqual(v, appEngineHttpTargetProp)) { |
| obj["appEngineHttpTarget"] = appEngineHttpTargetProp |
| } |
| httpTargetProp, err := expandCloudSchedulerJobHttpTarget(d.Get("http_target"), d, config) |
| if err != nil { |
| return err |
| } else if v, ok := d.GetOkExists("http_target"); !tpgresource.IsEmptyValue(reflect.ValueOf(httpTargetProp)) && (ok || !reflect.DeepEqual(v, httpTargetProp)) { |
| obj["httpTarget"] = httpTargetProp |
| } |
| |
| obj, err = resourceCloudSchedulerJobEncoder(d, meta, obj) |
| if err != nil { |
| return err |
| } |
| |
| url, err := tpgresource.ReplaceVars(d, config, "{{CloudSchedulerBasePath}}projects/{{project}}/locations/{{region}}/jobs") |
| if err != nil { |
| return err |
| } |
| |
| log.Printf("[DEBUG] Creating new Job: %#v", obj) |
| billingProject := "" |
| |
| project, err := tpgresource.GetProject(d, config) |
| if err != nil { |
| return fmt.Errorf("Error fetching project for Job: %s", err) |
| } |
| billingProject = project |
| |
| // err == nil indicates that the billing_project value was found |
| if bp, err := tpgresource.GetBillingProject(d, config); err == nil { |
| billingProject = bp |
| } |
| |
| res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ |
| Config: config, |
| Method: "POST", |
| Project: billingProject, |
| RawURL: url, |
| UserAgent: userAgent, |
| Body: obj, |
| Timeout: d.Timeout(schema.TimeoutCreate), |
| }) |
| if err != nil { |
| return fmt.Errorf("Error creating Job: %s", err) |
| } |
| |
| // Store the ID now |
| id, err := tpgresource.ReplaceVars(d, config, "projects/{{project}}/locations/{{region}}/jobs/{{name}}") |
| if err != nil { |
| return fmt.Errorf("Error constructing id: %s", err) |
| } |
| d.SetId(id) |
| |
| endpoint := "resume" // Default to enabled |
| logSuccessMsg := "Job state has been set to ENABLED" |
| if paused, pausedOk := d.GetOk("paused"); pausedOk && paused.(bool) { |
| endpoint = "pause" |
| logSuccessMsg = "Job state has been set to PAUSED" |
| } |
| |
| linkTmpl := fmt.Sprintf("{{CloudSchedulerBasePath}}projects/{{project}}/locations/{{region}}/jobs/{{name}}:%s", endpoint) |
| url, err = tpgresource.ReplaceVars(d, config, linkTmpl) |
| if err != nil { |
| return err |
| } |
| |
| emptyReqBody := make(map[string]interface{}) |
| |
| _, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ |
| Config: config, |
| Method: "POST", |
| Project: billingProject, |
| RawURL: url, |
| UserAgent: userAgent, |
| Body: emptyReqBody, |
| Timeout: d.Timeout(schema.TimeoutUpdate), |
| }) |
| if err != nil { |
| return fmt.Errorf("Error setting Cloud Scheduler Job status: %s", err) |
| } |
| |
| log.Printf("[DEBUG] Finished updating Job %q status: %s", d.Id(), logSuccessMsg) |
| |
| log.Printf("[DEBUG] Finished creating Job %q: %#v", d.Id(), res) |
| |
| return resourceCloudSchedulerJobRead(d, meta) |
| } |
| |
| func resourceCloudSchedulerJobRead(d *schema.ResourceData, meta interface{}) error { |
| config := meta.(*transport_tpg.Config) |
| userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) |
| if err != nil { |
| return err |
| } |
| |
| url, err := tpgresource.ReplaceVars(d, config, "{{CloudSchedulerBasePath}}projects/{{project}}/locations/{{region}}/jobs/{{name}}") |
| if err != nil { |
| return err |
| } |
| |
| billingProject := "" |
| |
| project, err := tpgresource.GetProject(d, config) |
| if err != nil { |
| return fmt.Errorf("Error fetching project for Job: %s", err) |
| } |
| billingProject = project |
| |
| // err == nil indicates that the billing_project value was found |
| if bp, err := tpgresource.GetBillingProject(d, config); err == nil { |
| billingProject = bp |
| } |
| |
| res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ |
| Config: config, |
| Method: "GET", |
| Project: billingProject, |
| RawURL: url, |
| UserAgent: userAgent, |
| }) |
| if err != nil { |
| return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("CloudSchedulerJob %q", d.Id())) |
| } |
| |
| if err := d.Set("project", project); err != nil { |
| return fmt.Errorf("Error reading Job: %s", err) |
| } |
| |
| region, err := tpgresource.GetRegion(d, config) |
| if err != nil { |
| return err |
| } |
| if err := d.Set("region", region); err != nil { |
| return fmt.Errorf("Error reading Job: %s", err) |
| } |
| |
| if err := d.Set("name", flattenCloudSchedulerJobName(res["name"], d, config)); err != nil { |
| return fmt.Errorf("Error reading Job: %s", err) |
| } |
| if err := d.Set("description", flattenCloudSchedulerJobDescription(res["description"], d, config)); err != nil { |
| return fmt.Errorf("Error reading Job: %s", err) |
| } |
| if err := d.Set("schedule", flattenCloudSchedulerJobSchedule(res["schedule"], d, config)); err != nil { |
| return fmt.Errorf("Error reading Job: %s", err) |
| } |
| if err := d.Set("time_zone", flattenCloudSchedulerJobTimeZone(res["timeZone"], d, config)); err != nil { |
| return fmt.Errorf("Error reading Job: %s", err) |
| } |
| if err := d.Set("state", flattenCloudSchedulerJobState(res["state"], d, config)); err != nil { |
| return fmt.Errorf("Error reading Job: %s", err) |
| } |
| if err := d.Set("paused", flattenCloudSchedulerJobPaused(res["paused"], d, config)); err != nil { |
| return fmt.Errorf("Error reading Job: %s", err) |
| } |
| if err := d.Set("attempt_deadline", flattenCloudSchedulerJobAttemptDeadline(res["attemptDeadline"], d, config)); err != nil { |
| return fmt.Errorf("Error reading Job: %s", err) |
| } |
| if err := d.Set("retry_config", flattenCloudSchedulerJobRetryConfig(res["retryConfig"], d, config)); err != nil { |
| return fmt.Errorf("Error reading Job: %s", err) |
| } |
| if err := d.Set("pubsub_target", flattenCloudSchedulerJobPubsubTarget(res["pubsubTarget"], d, config)); err != nil { |
| return fmt.Errorf("Error reading Job: %s", err) |
| } |
| if err := d.Set("app_engine_http_target", flattenCloudSchedulerJobAppEngineHttpTarget(res["appEngineHttpTarget"], d, config)); err != nil { |
| return fmt.Errorf("Error reading Job: %s", err) |
| } |
| if err := d.Set("http_target", flattenCloudSchedulerJobHttpTarget(res["httpTarget"], d, config)); err != nil { |
| return fmt.Errorf("Error reading Job: %s", err) |
| } |
| |
| return nil |
| } |
| |
| func resourceCloudSchedulerJobUpdate(d *schema.ResourceData, meta interface{}) error { |
| config := meta.(*transport_tpg.Config) |
| userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) |
| if err != nil { |
| return err |
| } |
| |
| billingProject := "" |
| |
| project, err := tpgresource.GetProject(d, config) |
| if err != nil { |
| return fmt.Errorf("Error fetching project for Job: %s", err) |
| } |
| billingProject = project |
| |
| obj := make(map[string]interface{}) |
| descriptionProp, err := expandCloudSchedulerJobDescription(d.Get("description"), d, config) |
| if err != nil { |
| return err |
| } else if v, ok := d.GetOkExists("description"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, descriptionProp)) { |
| obj["description"] = descriptionProp |
| } |
| scheduleProp, err := expandCloudSchedulerJobSchedule(d.Get("schedule"), d, config) |
| if err != nil { |
| return err |
| } else if v, ok := d.GetOkExists("schedule"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, scheduleProp)) { |
| obj["schedule"] = scheduleProp |
| } |
| timeZoneProp, err := expandCloudSchedulerJobTimeZone(d.Get("time_zone"), d, config) |
| if err != nil { |
| return err |
| } else if v, ok := d.GetOkExists("time_zone"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, timeZoneProp)) { |
| obj["timeZone"] = timeZoneProp |
| } |
| pausedProp, err := expandCloudSchedulerJobPaused(d.Get("paused"), d, config) |
| if err != nil { |
| return err |
| } else if v, ok := d.GetOkExists("paused"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, pausedProp)) { |
| obj["paused"] = pausedProp |
| } |
| attemptDeadlineProp, err := expandCloudSchedulerJobAttemptDeadline(d.Get("attempt_deadline"), d, config) |
| if err != nil { |
| return err |
| } else if v, ok := d.GetOkExists("attempt_deadline"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, attemptDeadlineProp)) { |
| obj["attemptDeadline"] = attemptDeadlineProp |
| } |
| retryConfigProp, err := expandCloudSchedulerJobRetryConfig(d.Get("retry_config"), d, config) |
| if err != nil { |
| return err |
| } else if v, ok := d.GetOkExists("retry_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, retryConfigProp)) { |
| obj["retryConfig"] = retryConfigProp |
| } |
| pubsubTargetProp, err := expandCloudSchedulerJobPubsubTarget(d.Get("pubsub_target"), d, config) |
| if err != nil { |
| return err |
| } else if v, ok := d.GetOkExists("pubsub_target"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, pubsubTargetProp)) { |
| obj["pubsubTarget"] = pubsubTargetProp |
| } |
| appEngineHttpTargetProp, err := expandCloudSchedulerJobAppEngineHttpTarget(d.Get("app_engine_http_target"), d, config) |
| if err != nil { |
| return err |
| } else if v, ok := d.GetOkExists("app_engine_http_target"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, appEngineHttpTargetProp)) { |
| obj["appEngineHttpTarget"] = appEngineHttpTargetProp |
| } |
| httpTargetProp, err := expandCloudSchedulerJobHttpTarget(d.Get("http_target"), d, config) |
| if err != nil { |
| return err |
| } else if v, ok := d.GetOkExists("http_target"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, httpTargetProp)) { |
| obj["httpTarget"] = httpTargetProp |
| } |
| |
| obj, err = resourceCloudSchedulerJobUpdateEncoder(d, meta, obj) |
| if err != nil { |
| return err |
| } |
| |
| url, err := tpgresource.ReplaceVars(d, config, "{{CloudSchedulerBasePath}}projects/{{project}}/locations/{{region}}/jobs/{{name}}") |
| if err != nil { |
| return err |
| } |
| |
| log.Printf("[DEBUG] Updating Job %q: %#v", d.Id(), obj) |
| |
| // err == nil indicates that the billing_project value was found |
| if bp, err := tpgresource.GetBillingProject(d, config); err == nil { |
| billingProject = bp |
| } |
| |
| res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ |
| Config: config, |
| Method: "PATCH", |
| Project: billingProject, |
| RawURL: url, |
| UserAgent: userAgent, |
| Body: obj, |
| Timeout: d.Timeout(schema.TimeoutUpdate), |
| }) |
| |
| if err != nil { |
| return fmt.Errorf("Error updating Job %q: %s", d.Id(), err) |
| } else { |
| log.Printf("[DEBUG] Finished updating Job %q: %#v", d.Id(), res) |
| } |
| |
| if d.HasChange("paused") { |
| endpoint := "resume" // Default to enabled |
| logSuccessMsg := "Job state has been set to ENABLED" |
| if paused, pausedOk := d.GetOk("paused"); pausedOk { |
| if paused.(bool) { |
| endpoint = "pause" |
| logSuccessMsg = "Job state has been set to PAUSED" |
| } |
| } |
| |
| linkTmpl := fmt.Sprintf("{{CloudSchedulerBasePath}}projects/{{project}}/locations/{{region}}/jobs/{{name}}:%s", endpoint) |
| url, err = tpgresource.ReplaceVars(d, config, linkTmpl) |
| if err != nil { |
| return err |
| } |
| |
| emptyReqBody := make(map[string]interface{}) |
| |
| _, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ |
| Config: config, |
| Method: "POST", |
| Project: billingProject, |
| RawURL: url, |
| UserAgent: userAgent, |
| Body: emptyReqBody, |
| Timeout: d.Timeout(schema.TimeoutUpdate), |
| }) |
| if err != nil { |
| return fmt.Errorf("Error setting Cloud Scheduler Job status: %s", err) |
| } |
| |
| log.Printf("[DEBUG] Finished updating Job %q status: %s", d.Id(), logSuccessMsg) |
| } |
| return resourceCloudSchedulerJobRead(d, meta) |
| } |
| |
| func resourceCloudSchedulerJobDelete(d *schema.ResourceData, meta interface{}) error { |
| config := meta.(*transport_tpg.Config) |
| userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) |
| if err != nil { |
| return err |
| } |
| |
| billingProject := "" |
| |
| project, err := tpgresource.GetProject(d, config) |
| if err != nil { |
| return fmt.Errorf("Error fetching project for Job: %s", err) |
| } |
| billingProject = project |
| |
| url, err := tpgresource.ReplaceVars(d, config, "{{CloudSchedulerBasePath}}projects/{{project}}/locations/{{region}}/jobs/{{name}}") |
| if err != nil { |
| return err |
| } |
| |
| var obj map[string]interface{} |
| log.Printf("[DEBUG] Deleting Job %q", d.Id()) |
| |
| // err == nil indicates that the billing_project value was found |
| if bp, err := tpgresource.GetBillingProject(d, config); err == nil { |
| billingProject = bp |
| } |
| |
| res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ |
| Config: config, |
| Method: "DELETE", |
| Project: billingProject, |
| RawURL: url, |
| UserAgent: userAgent, |
| Body: obj, |
| Timeout: d.Timeout(schema.TimeoutDelete), |
| }) |
| if err != nil { |
| return transport_tpg.HandleNotFoundError(err, d, "Job") |
| } |
| |
| log.Printf("[DEBUG] Finished deleting Job %q: %#v", d.Id(), res) |
| return nil |
| } |
| |
| func resourceCloudSchedulerJobImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { |
| config := meta.(*transport_tpg.Config) |
| if err := tpgresource.ParseImportId([]string{ |
| "^projects/(?P<project>[^/]+)/locations/(?P<region>[^/]+)/jobs/(?P<name>[^/]+)$", |
| "^(?P<project>[^/]+)/(?P<region>[^/]+)/(?P<name>[^/]+)$", |
| "^(?P<region>[^/]+)/(?P<name>[^/]+)$", |
| "^(?P<name>[^/]+)$", |
| }, d, config); err != nil { |
| return nil, err |
| } |
| |
| // Replace import id for the resource id |
| id, err := tpgresource.ReplaceVars(d, config, "projects/{{project}}/locations/{{region}}/jobs/{{name}}") |
| if err != nil { |
| return nil, fmt.Errorf("Error constructing id: %s", err) |
| } |
| d.SetId(id) |
| |
| return []*schema.ResourceData{d}, nil |
| } |
| |
| func flattenCloudSchedulerJobName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| if v == nil { |
| return v |
| } |
| return tpgresource.NameFromSelfLinkStateFunc(v) |
| } |
| |
| func flattenCloudSchedulerJobDescription(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func flattenCloudSchedulerJobSchedule(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func flattenCloudSchedulerJobTimeZone(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func flattenCloudSchedulerJobState(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func flattenCloudSchedulerJobPaused(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| state := d.Get("state") |
| if state == "PAUSED" { |
| return true |
| } |
| if state == "ENABLED" { |
| return false |
| } |
| return false // Job has an error state that's not paused or enabled |
| } |
| |
| func flattenCloudSchedulerJobAttemptDeadline(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func flattenCloudSchedulerJobRetryConfig(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| if v == nil { |
| return nil |
| } |
| original := v.(map[string]interface{}) |
| if len(original) == 0 { |
| return nil |
| } |
| transformed := make(map[string]interface{}) |
| transformed["retry_count"] = |
| flattenCloudSchedulerJobRetryConfigRetryCount(original["retryCount"], d, config) |
| transformed["max_retry_duration"] = |
| flattenCloudSchedulerJobRetryConfigMaxRetryDuration(original["maxRetryDuration"], d, config) |
| transformed["min_backoff_duration"] = |
| flattenCloudSchedulerJobRetryConfigMinBackoffDuration(original["minBackoffDuration"], d, config) |
| transformed["max_backoff_duration"] = |
| flattenCloudSchedulerJobRetryConfigMaxBackoffDuration(original["maxBackoffDuration"], d, config) |
| transformed["max_doublings"] = |
| flattenCloudSchedulerJobRetryConfigMaxDoublings(original["maxDoublings"], d, config) |
| return []interface{}{transformed} |
| } |
| func flattenCloudSchedulerJobRetryConfigRetryCount(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| // Handles the string fixed64 format |
| if strVal, ok := v.(string); ok { |
| if intVal, err := tpgresource.StringToFixed64(strVal); err == nil { |
| return intVal |
| } |
| } |
| |
| // number values are represented as float64 |
| if floatVal, ok := v.(float64); ok { |
| intVal := int(floatVal) |
| return intVal |
| } |
| |
| return v // let terraform core handle it otherwise |
| } |
| |
| func flattenCloudSchedulerJobRetryConfigMaxRetryDuration(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func flattenCloudSchedulerJobRetryConfigMinBackoffDuration(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func flattenCloudSchedulerJobRetryConfigMaxBackoffDuration(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func flattenCloudSchedulerJobRetryConfigMaxDoublings(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| // Handles the string fixed64 format |
| if strVal, ok := v.(string); ok { |
| if intVal, err := tpgresource.StringToFixed64(strVal); err == nil { |
| return intVal |
| } |
| } |
| |
| // number values are represented as float64 |
| if floatVal, ok := v.(float64); ok { |
| intVal := int(floatVal) |
| return intVal |
| } |
| |
| return v // let terraform core handle it otherwise |
| } |
| |
| func flattenCloudSchedulerJobPubsubTarget(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| if v == nil { |
| return nil |
| } |
| original := v.(map[string]interface{}) |
| if len(original) == 0 { |
| return nil |
| } |
| transformed := make(map[string]interface{}) |
| transformed["topic_name"] = |
| flattenCloudSchedulerJobPubsubTargetTopicName(original["topicName"], d, config) |
| transformed["data"] = |
| flattenCloudSchedulerJobPubsubTargetData(original["data"], d, config) |
| transformed["attributes"] = |
| flattenCloudSchedulerJobPubsubTargetAttributes(original["attributes"], d, config) |
| return []interface{}{transformed} |
| } |
| func flattenCloudSchedulerJobPubsubTargetTopicName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func flattenCloudSchedulerJobPubsubTargetData(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func flattenCloudSchedulerJobPubsubTargetAttributes(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func flattenCloudSchedulerJobAppEngineHttpTarget(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| if v == nil { |
| return nil |
| } |
| original := v.(map[string]interface{}) |
| if len(original) == 0 { |
| return nil |
| } |
| transformed := make(map[string]interface{}) |
| transformed["http_method"] = |
| flattenCloudSchedulerJobAppEngineHttpTargetHttpMethod(original["httpMethod"], d, config) |
| transformed["app_engine_routing"] = |
| flattenCloudSchedulerJobAppEngineHttpTargetAppEngineRouting(original["appEngineRouting"], d, config) |
| transformed["relative_uri"] = |
| flattenCloudSchedulerJobAppEngineHttpTargetRelativeUri(original["relativeUri"], d, config) |
| transformed["body"] = |
| flattenCloudSchedulerJobAppEngineHttpTargetBody(original["body"], d, config) |
| transformed["headers"] = |
| flattenCloudSchedulerJobAppEngineHttpTargetHeaders(original["headers"], d, config) |
| return []interface{}{transformed} |
| } |
| func flattenCloudSchedulerJobAppEngineHttpTargetHttpMethod(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| // An `appEngineRouting` in API response is useless, so we set config values rather than api response to state. |
| func flattenCloudSchedulerJobAppEngineHttpTargetAppEngineRouting(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| if v == nil { |
| return nil |
| } |
| if stateV, ok := d.GetOk("app_engine_http_target"); ok && len(stateV.([]interface{})) > 0 { |
| return d.Get("app_engine_http_target.0.app_engine_routing") |
| } |
| original := v.(map[string]interface{}) |
| if len(original) == 0 { |
| return nil |
| } |
| transformed := make(map[string]interface{}) |
| transformed["service"] = original["service"] |
| transformed["version"] = original["version"] |
| transformed["instance"] = original["instance"] |
| return []interface{}{transformed} |
| } |
| |
| func flattenCloudSchedulerJobAppEngineHttpTargetRelativeUri(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func flattenCloudSchedulerJobAppEngineHttpTargetBody(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func flattenCloudSchedulerJobAppEngineHttpTargetHeaders(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| var headers = v.(map[string]interface{}) |
| if v, ok := headers["User-Agent"]; ok { |
| if v.(string) == "AppEngine-Google; (+http://code.google.com/appengine)" { |
| delete(headers, "User-Agent") |
| } else if v.(string) == "Google-Cloud-Scheduler" { |
| delete(headers, "User-Agent") |
| } else { |
| headers["User-Agent"] = strings.TrimSpace(strings.Replace(v.(string), "AppEngine-Google; (+http://code.google.com/appengine)", "", -1)) |
| } |
| } |
| if v, ok := headers["Content-Type"]; ok { |
| if v.(string) == "application/octet-stream" { |
| delete(headers, "Content-Type") |
| } |
| } |
| r := regexp.MustCompile(`(X-Google-|X-AppEngine-|Content-Length).*`) |
| for key := range headers { |
| if r.MatchString(key) { |
| delete(headers, key) |
| } |
| } |
| return headers |
| } |
| |
| func flattenCloudSchedulerJobHttpTarget(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| if v == nil { |
| return nil |
| } |
| original := v.(map[string]interface{}) |
| if len(original) == 0 { |
| return nil |
| } |
| transformed := make(map[string]interface{}) |
| transformed["uri"] = |
| flattenCloudSchedulerJobHttpTargetUri(original["uri"], d, config) |
| transformed["http_method"] = |
| flattenCloudSchedulerJobHttpTargetHttpMethod(original["httpMethod"], d, config) |
| transformed["body"] = |
| flattenCloudSchedulerJobHttpTargetBody(original["body"], d, config) |
| transformed["headers"] = |
| flattenCloudSchedulerJobHttpTargetHeaders(original["headers"], d, config) |
| transformed["oauth_token"] = |
| flattenCloudSchedulerJobHttpTargetOauthToken(original["oauthToken"], d, config) |
| transformed["oidc_token"] = |
| flattenCloudSchedulerJobHttpTargetOidcToken(original["oidcToken"], d, config) |
| return []interface{}{transformed} |
| } |
| func flattenCloudSchedulerJobHttpTargetUri(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func flattenCloudSchedulerJobHttpTargetHttpMethod(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func flattenCloudSchedulerJobHttpTargetBody(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func flattenCloudSchedulerJobHttpTargetHeaders(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| var headers = v.(map[string]interface{}) |
| if v, ok := headers["User-Agent"]; ok { |
| if v.(string) == "AppEngine-Google; (+http://code.google.com/appengine)" { |
| delete(headers, "User-Agent") |
| } else if v.(string) == "Google-Cloud-Scheduler" { |
| delete(headers, "User-Agent") |
| } else { |
| headers["User-Agent"] = strings.TrimSpace(strings.Replace(v.(string), "AppEngine-Google; (+http://code.google.com/appengine)", "", -1)) |
| } |
| } |
| if v, ok := headers["Content-Type"]; ok { |
| if v.(string) == "application/octet-stream" { |
| delete(headers, "Content-Type") |
| } |
| } |
| r := regexp.MustCompile(`(X-Google-|X-AppEngine-|Content-Length).*`) |
| for key := range headers { |
| if r.MatchString(key) { |
| delete(headers, key) |
| } |
| } |
| return headers |
| } |
| |
| func flattenCloudSchedulerJobHttpTargetOauthToken(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| if v == nil { |
| return nil |
| } |
| original := v.(map[string]interface{}) |
| if len(original) == 0 { |
| return nil |
| } |
| transformed := make(map[string]interface{}) |
| transformed["service_account_email"] = |
| flattenCloudSchedulerJobHttpTargetOauthTokenServiceAccountEmail(original["serviceAccountEmail"], d, config) |
| transformed["scope"] = |
| flattenCloudSchedulerJobHttpTargetOauthTokenScope(original["scope"], d, config) |
| return []interface{}{transformed} |
| } |
| func flattenCloudSchedulerJobHttpTargetOauthTokenServiceAccountEmail(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func flattenCloudSchedulerJobHttpTargetOauthTokenScope(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func flattenCloudSchedulerJobHttpTargetOidcToken(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| if v == nil { |
| return nil |
| } |
| original := v.(map[string]interface{}) |
| if len(original) == 0 { |
| return nil |
| } |
| transformed := make(map[string]interface{}) |
| transformed["service_account_email"] = |
| flattenCloudSchedulerJobHttpTargetOidcTokenServiceAccountEmail(original["serviceAccountEmail"], d, config) |
| transformed["audience"] = |
| flattenCloudSchedulerJobHttpTargetOidcTokenAudience(original["audience"], d, config) |
| return []interface{}{transformed} |
| } |
| func flattenCloudSchedulerJobHttpTargetOidcTokenServiceAccountEmail(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func flattenCloudSchedulerJobHttpTargetOidcTokenAudience(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func expandCloudSchedulerJobName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return tpgresource.ReplaceVars(d, config, "projects/{{project}}/locations/{{region}}/jobs/{{name}}") |
| } |
| |
| func expandCloudSchedulerJobDescription(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandCloudSchedulerJobSchedule(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandCloudSchedulerJobTimeZone(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandCloudSchedulerJobPaused(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandCloudSchedulerJobAttemptDeadline(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandCloudSchedulerJobRetryConfig(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.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{}) |
| |
| transformedRetryCount, err := expandCloudSchedulerJobRetryConfigRetryCount(original["retry_count"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedRetryCount); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| transformed["retryCount"] = transformedRetryCount |
| } |
| |
| transformedMaxRetryDuration, err := expandCloudSchedulerJobRetryConfigMaxRetryDuration(original["max_retry_duration"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedMaxRetryDuration); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| transformed["maxRetryDuration"] = transformedMaxRetryDuration |
| } |
| |
| transformedMinBackoffDuration, err := expandCloudSchedulerJobRetryConfigMinBackoffDuration(original["min_backoff_duration"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedMinBackoffDuration); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| transformed["minBackoffDuration"] = transformedMinBackoffDuration |
| } |
| |
| transformedMaxBackoffDuration, err := expandCloudSchedulerJobRetryConfigMaxBackoffDuration(original["max_backoff_duration"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedMaxBackoffDuration); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| transformed["maxBackoffDuration"] = transformedMaxBackoffDuration |
| } |
| |
| transformedMaxDoublings, err := expandCloudSchedulerJobRetryConfigMaxDoublings(original["max_doublings"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedMaxDoublings); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| transformed["maxDoublings"] = transformedMaxDoublings |
| } |
| |
| return transformed, nil |
| } |
| |
| func expandCloudSchedulerJobRetryConfigRetryCount(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandCloudSchedulerJobRetryConfigMaxRetryDuration(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandCloudSchedulerJobRetryConfigMinBackoffDuration(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandCloudSchedulerJobRetryConfigMaxBackoffDuration(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandCloudSchedulerJobRetryConfigMaxDoublings(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandCloudSchedulerJobPubsubTarget(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.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{}) |
| |
| transformedTopicName, err := expandCloudSchedulerJobPubsubTargetTopicName(original["topic_name"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedTopicName); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| transformed["topicName"] = transformedTopicName |
| } |
| |
| transformedData, err := expandCloudSchedulerJobPubsubTargetData(original["data"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedData); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| transformed["data"] = transformedData |
| } |
| |
| transformedAttributes, err := expandCloudSchedulerJobPubsubTargetAttributes(original["attributes"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedAttributes); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| transformed["attributes"] = transformedAttributes |
| } |
| |
| return transformed, nil |
| } |
| |
| func expandCloudSchedulerJobPubsubTargetTopicName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandCloudSchedulerJobPubsubTargetData(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandCloudSchedulerJobPubsubTargetAttributes(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { |
| if v == nil { |
| return map[string]string{}, nil |
| } |
| m := make(map[string]string) |
| for k, val := range v.(map[string]interface{}) { |
| m[k] = val.(string) |
| } |
| return m, nil |
| } |
| |
| func expandCloudSchedulerJobAppEngineHttpTarget(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.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{}) |
| |
| transformedHttpMethod, err := expandCloudSchedulerJobAppEngineHttpTargetHttpMethod(original["http_method"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedHttpMethod); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| transformed["httpMethod"] = transformedHttpMethod |
| } |
| |
| transformedAppEngineRouting, err := expandCloudSchedulerJobAppEngineHttpTargetAppEngineRouting(original["app_engine_routing"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedAppEngineRouting); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| transformed["appEngineRouting"] = transformedAppEngineRouting |
| } |
| |
| transformedRelativeUri, err := expandCloudSchedulerJobAppEngineHttpTargetRelativeUri(original["relative_uri"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedRelativeUri); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| transformed["relativeUri"] = transformedRelativeUri |
| } |
| |
| transformedBody, err := expandCloudSchedulerJobAppEngineHttpTargetBody(original["body"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedBody); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| transformed["body"] = transformedBody |
| } |
| |
| transformedHeaders, err := expandCloudSchedulerJobAppEngineHttpTargetHeaders(original["headers"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedHeaders); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| transformed["headers"] = transformedHeaders |
| } |
| |
| return transformed, nil |
| } |
| |
| func expandCloudSchedulerJobAppEngineHttpTargetHttpMethod(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandCloudSchedulerJobAppEngineHttpTargetAppEngineRouting(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.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{}) |
| |
| transformedService, err := expandCloudSchedulerJobAppEngineHttpTargetAppEngineRoutingService(original["service"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedService); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| transformed["service"] = transformedService |
| } |
| |
| transformedVersion, err := expandCloudSchedulerJobAppEngineHttpTargetAppEngineRoutingVersion(original["version"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedVersion); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| transformed["version"] = transformedVersion |
| } |
| |
| transformedInstance, err := expandCloudSchedulerJobAppEngineHttpTargetAppEngineRoutingInstance(original["instance"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedInstance); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| transformed["instance"] = transformedInstance |
| } |
| |
| return transformed, nil |
| } |
| |
| func expandCloudSchedulerJobAppEngineHttpTargetAppEngineRoutingService(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandCloudSchedulerJobAppEngineHttpTargetAppEngineRoutingVersion(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandCloudSchedulerJobAppEngineHttpTargetAppEngineRoutingInstance(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandCloudSchedulerJobAppEngineHttpTargetRelativeUri(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandCloudSchedulerJobAppEngineHttpTargetBody(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandCloudSchedulerJobAppEngineHttpTargetHeaders(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { |
| if v == nil { |
| return map[string]string{}, nil |
| } |
| m := make(map[string]string) |
| for k, val := range v.(map[string]interface{}) { |
| m[k] = val.(string) |
| } |
| return m, nil |
| } |
| |
| func expandCloudSchedulerJobHttpTarget(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.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{}) |
| |
| transformedUri, err := expandCloudSchedulerJobHttpTargetUri(original["uri"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedUri); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| transformed["uri"] = transformedUri |
| } |
| |
| transformedHttpMethod, err := expandCloudSchedulerJobHttpTargetHttpMethod(original["http_method"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedHttpMethod); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| transformed["httpMethod"] = transformedHttpMethod |
| } |
| |
| transformedBody, err := expandCloudSchedulerJobHttpTargetBody(original["body"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedBody); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| transformed["body"] = transformedBody |
| } |
| |
| transformedHeaders, err := expandCloudSchedulerJobHttpTargetHeaders(original["headers"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedHeaders); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| 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() && !tpgresource.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() && !tpgresource.IsEmptyValue(val) { |
| transformed["oidcToken"] = transformedOidcToken |
| } |
| |
| return transformed, nil |
| } |
| |
| func expandCloudSchedulerJobHttpTargetUri(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandCloudSchedulerJobHttpTargetHttpMethod(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandCloudSchedulerJobHttpTargetBody(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandCloudSchedulerJobHttpTargetHeaders(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { |
| if v == nil { |
| return map[string]string{}, nil |
| } |
| m := make(map[string]string) |
| for k, val := range v.(map[string]interface{}) { |
| m[k] = val.(string) |
| } |
| return m, nil |
| } |
| |
| func expandCloudSchedulerJobHttpTargetOauthToken(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.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() && !tpgresource.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() && !tpgresource.IsEmptyValue(val) { |
| transformed["scope"] = transformedScope |
| } |
| |
| return transformed, nil |
| } |
| |
| func expandCloudSchedulerJobHttpTargetOauthTokenServiceAccountEmail(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandCloudSchedulerJobHttpTargetOauthTokenScope(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandCloudSchedulerJobHttpTargetOidcToken(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.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() && !tpgresource.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() && !tpgresource.IsEmptyValue(val) { |
| transformed["audience"] = transformedAudience |
| } |
| |
| return transformed, nil |
| } |
| |
| func expandCloudSchedulerJobHttpTargetOidcTokenServiceAccountEmail(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandCloudSchedulerJobHttpTargetOidcTokenAudience(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func resourceCloudSchedulerJobEncoder(d *schema.ResourceData, meta interface{}, obj map[string]interface{}) (map[string]interface{}, error) { |
| delete(obj, "paused") // Field doesn't exist in API |
| return obj, nil |
| } |
| |
| func resourceCloudSchedulerJobUpdateEncoder(d *schema.ResourceData, meta interface{}, obj map[string]interface{}) (map[string]interface{}, error) { |
| delete(obj, "paused") // Field doesn't exist in API |
| return obj, nil |
| } |