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

Handle scheduler job state #11141

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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
151 changes: 102 additions & 49 deletions google/resource_cloud_scheduler_job.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,11 @@ A duration in seconds with up to nine fractional digits, terminated by 's'. Exam
Description: `A human-readable description for the job.
This string must not contain more than 500 characters.`,
},
"state": {
Type: schema.TypeString,
Optional: true,
Description: `PAUSED | ENABLED`,
},
"http_target": {
Type: schema.TypeList,
Optional: true,
Expand Down Expand Up @@ -431,10 +436,6 @@ The value of this field must be a time zone name from the tz database.`,

func resourceCloudSchedulerJobCreate(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
userAgent, err := generateUserAgentString(d, config.userAgent)
if err != nil {
return err
}

obj := make(map[string]interface{})
nameProp, err := expandCloudSchedulerJobName(d.Get("name"), d, config)
Expand Down Expand Up @@ -492,40 +493,85 @@ func resourceCloudSchedulerJobCreate(d *schema.ResourceData, meta interface{}) e
obj["httpTarget"] = httpTargetProp
}

url, err := replaceVars(d, config, "{{CloudSchedulerBasePath}}projects/{{project}}/locations/{{region}}/jobs")
log.Printf("[DEBUG] Creating new Job: %#v", obj)

res, err := jobSendRequestWithTimeout(d, meta, "POST", "", obj, d.Timeout(schema.TimeoutCreate))
if err != nil {
return fmt.Errorf("Error creating Job: %s", err)
}

// Store the ID now
id, err := replaceVars(d, config, "projects/{{project}}/locations/{{region}}/jobs/{{name}}")
if err != nil {
return fmt.Errorf("Error constructing id: %s", err)
}
d.SetId(id)

state, ok := d.GetOk("state")
if ok && state != res["state"] {
resourceCloudSchedulerJobSetState(state.(string), d, meta)
}

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

return resourceCloudSchedulerJobRead(d, meta)
}

func resourceCloudSchedulerJobEnable(d *schema.ResourceData, meta interface{}) error {
return resourceCloudSchedulerJobSetState("ENABLED", d, meta)
}

func resourceCloudSchedulerJobSetState(state string, d *schema.ResourceData, meta interface{}) error {
log.Printf("[INFO] State -> %v", state)
config := meta.(*Config)
userAgent, err := generateUserAgentString(d, config.userAgent)
if err != nil {
return err
}

action := ""
switch state {
case "PAUSED":
action = "pause"
case "ENABLED":
action = "resume"
default:
return fmt.Errorf("Invalid job state: %s", state)

}
url, err := replaceVars(d, config, "{{CloudSchedulerBasePath}}projects/{{project}}/locations/{{region}}/jobs/{{name}}:"+action)
if err != nil {
return err
}

log.Printf("[DEBUG] Creating new Job: %#v", obj)
billingProject := ""

project, err := 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 := getBillingProject(d, config); err == nil {
billingProject = bp
}

res, err := sendRequestWithTimeout(config, "POST", billingProject, url, userAgent, obj, d.Timeout(schema.TimeoutCreate))
res, err := sendRequestWithTimeout(config, "POST", billingProject, url, userAgent, make(map[string]interface{}), d.Timeout(schema.TimeoutCreate))
if err != nil {
return fmt.Errorf("Error creating Job: %s", err)
return fmt.Errorf("Error pausing job: %s", err)
}

// Store the ID now
id, err := replaceVars(d, config, "projects/{{project}}/locations/{{region}}/jobs/{{name}}")
d.Set("state", state)
log.Printf("[DEBUG] Finished %v Job %q: %#v", action, d.Id(), res)
return nil
}

func resourceCloudSchedulerJobGetState(d *schema.ResourceData, meta interface{}) (string, error) {
res, err := jobSendRequest(d, meta, "GET", "/{{name}}", nil)
if err != nil {
return fmt.Errorf("Error constructing id: %s", err)
return "", err
}
d.SetId(id)

log.Printf("[DEBUG] Finished creating Job %q: %#v", d.Id(), res)
return res["state"].(string), nil
}

return resourceCloudSchedulerJobRead(d, meta)
func jobSendRequest(d *schema.ResourceData, meta interface{}, method string, path string, body map[string]interface{}) (map[string]interface{}, error) {
return jobSendRequestWithTimeout(d, meta, method, path, body, DefaultRequestTimeout)
}

func resourceCloudSchedulerJobRead(d *schema.ResourceData, meta interface{}) error {
Expand Down Expand Up @@ -597,24 +643,30 @@ func resourceCloudSchedulerJobRead(d *schema.ResourceData, meta interface{}) err
if err := d.Set("http_target", flattenCloudSchedulerJobHttpTarget(res["httpTarget"], 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)
}

log.Printf("[INFO] Job state: %v", d.Get("state"))

return nil
}

func resourceCloudSchedulerJobUpdate(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
userAgent, err := generateUserAgentString(d, config.userAgent)
currentState, err := resourceCloudSchedulerJobGetState(d, meta)
if err != nil {
return err
}

billingProject := ""

project, err := getProject(d, config)
if err != nil {
return fmt.Errorf("Error fetching project for Job: %s", err)
// Job cannot be updated while PAUSED
if currentState == "PAUSED" {
err = resourceCloudSchedulerJobEnable(d, meta)
if err != nil {
return err
}
}
billingProject = project

config := meta.(*Config)

obj := make(map[string]interface{})
descriptionProp, err := expandCloudSchedulerJobDescription(d.Get("description"), d, config)
Expand Down Expand Up @@ -666,19 +718,14 @@ func resourceCloudSchedulerJobUpdate(d *schema.ResourceData, meta interface{}) e
obj["httpTarget"] = httpTargetProp
}

url, err := 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 := getBillingProject(d, config); err == nil {
billingProject = bp
}
res, err := jobSendRequestWithTimeout(d, meta, "PATCH", "/{{name}}", obj, d.Timeout(schema.TimeoutUpdate))

res, err := sendRequestWithTimeout(config, "PATCH", billingProject, url, userAgent, obj, d.Timeout(schema.TimeoutUpdate))
state, ok := d.GetOk("state")
if ok && state != res["state"] {
resourceCloudSchedulerJobSetState(state.(string), d, meta)
}

if err != nil {
return fmt.Errorf("Error updating Job %q: %s", d.Id(), err)
Expand All @@ -689,35 +736,37 @@ func resourceCloudSchedulerJobUpdate(d *schema.ResourceData, meta interface{}) e
return resourceCloudSchedulerJobRead(d, meta)
}

func resourceCloudSchedulerJobDelete(d *schema.ResourceData, meta interface{}) error {
func jobSendRequestWithTimeout(d *schema.ResourceData, meta interface{}, method string, path string, body map[string]interface{}, timeout time.Duration) (map[string]interface{}, error) {
config := meta.(*Config)
userAgent, err := generateUserAgentString(d, config.userAgent)
if err != nil {
return err
return nil, err
}

billingProject := ""

project, err := getProject(d, config)
if err != nil {
return fmt.Errorf("Error fetching project for Job: %s", err)
return nil, fmt.Errorf("Error fetching project for Job: %s", err)
}
billingProject = project
if bp, err := getBillingProject(d, config); err == nil {
billingProject = bp
}

url, err := replaceVars(d, config, "{{CloudSchedulerBasePath}}projects/{{project}}/locations/{{region}}/jobs/{{name}}")
url, err := replaceVars(d, config, "{{CloudSchedulerBasePath}}projects/{{project}}/locations/{{region}}/jobs"+path)
if err != nil {
return err
return nil, err
}

return sendRequestWithTimeout(config, method, billingProject, url, userAgent, body, timeout)
}

func resourceCloudSchedulerJobDelete(d *schema.ResourceData, meta interface{}) error {
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 := getBillingProject(d, config); err == nil {
billingProject = bp
}

res, err := sendRequestWithTimeout(config, "DELETE", billingProject, url, userAgent, obj, d.Timeout(schema.TimeoutDelete))
res, err := jobSendRequestWithTimeout(d, meta, "DELETE", "/{{name}}", obj, d.Timeout(schema.TimeoutDelete))
if err != nil {
return handleNotFoundError(err, d, "Job")
}
Expand Down Expand Up @@ -754,6 +803,10 @@ func flattenCloudSchedulerJobName(v interface{}, d *schema.ResourceData, config
return NameFromSelfLinkStateFunc(v)
}

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

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