diff --git a/awx/provider.go b/awx/provider.go index e86f4a8..46060bd 100644 --- a/awx/provider.go +++ b/awx/provider.go @@ -61,6 +61,7 @@ func Provider() *schema.Provider { "awx_job_template_credential": resourceJobTemplateCredentials(), "awx_job_template": resourceJobTemplate(), "awx_job_template_launch": resourceJobTemplateLaunch(), + "awx_workflow_job_template_launch": resourceWorkflowJobTeamplateLaunch(), "awx_job_template_notification_template_error": resourceJobTemplateNotificationTemplateError(), "awx_job_template_notification_template_started": resourceJobTemplateNotificationTemplateStarted(), "awx_job_template_notification_template_success": resourceJobTemplateNotificationTemplateSuccess(), diff --git a/awx/resource_workflow_job_template_launch.go b/awx/resource_workflow_job_template_launch.go new file mode 100644 index 0000000..fecea71 --- /dev/null +++ b/awx/resource_workflow_job_template_launch.go @@ -0,0 +1,159 @@ +/* +*TBD* + +Example Usage + +```hcl +resource "awx_workflow_job_template_launch" "now" { + workflow_job_template_id = someid + wait_for_completion = true +} +``` + +*/ + +package awx + +import ( + "context" + "encoding/json" + "fmt" + "log" + "strconv" + "time" + + awx "github.com/denouche/goawx/client" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func resourceWorkflowJobTeamplateLaunch() *schema.Resource { + return &schema.Resource{ + CreateContext: resourceWorkflowJobTeamplateLaunchCreate, + ReadContext: resourceWorkflowJobRead, + DeleteContext: resourceWorkflowJobDelete, + + Schema: map[string]*schema.Schema{ + "workflow_job_template_id": { + Type: schema.TypeInt, + Required: true, + Description: "Workflow job template ID", + ForceNew: true, + }, + "extra_vars": { + Type: schema.TypeString, + Optional: true, + Description: "Override workflow job template variables. YAML or JSON values are supported.", + ForceNew: true, + StateFunc: normalizeJsonYaml, + }, + "wait_for_completion": { + Type: schema.TypeBool, + Required: false, + Optional: true, + Default: false, + Description: "Resource creation will wait for workflow job completion.", + ForceNew: true, + }, + }, + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(20 * time.Minute), + }, + } +} + +func statusInstanceWorkflowState(ctx context.Context, svc *awx.WorkflowJobService, id int) retry.StateRefreshFunc { + return func() (interface{}, string, error) { + + output, err := svc.GetWorkflowJob(id, map[string]string{}) + + return output, output.Status, err + } +} + +func workflowJobTemplateLaunchWait(ctx context.Context, svc *awx.WorkflowJobService, job *awx.JobLaunch, timeout time.Duration) error { + + stateConf := &retry.StateChangeConf{ + Pending: []string{"new", "pending", "waiting", "running"}, + Target: []string{"successful"}, + Refresh: statusInstanceWorkflowState(ctx, svc, job.ID), + Timeout: timeout, + Delay: 10 * time.Second, + MinTimeout: 3 * time.Second, + } + + _, err := stateConf.WaitForStateContext(ctx) + + return err +} + +// WorkflokJobTemplateLaunchData provides payload data used by the WorkflowJobTemplateLaunch method +type WorkflokJobTemplateLaunchData struct { + ExtraVars string `json:"extra_vars,omitempty"` +} + +func resourceWorkflowJobTeamplateLaunchCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + var diags diag.Diagnostics + client := m.(*awx.AWX) + awxService := client.WorkflowJobTemplateService + awxWorkflowJobService := client.WorkflowJobService + + workflowJobTemplateID := d.Get("workflow_job_template_id").(int) + _, err := awxService.GetWorkflowJobTemplateByID(workflowJobTemplateID, make(map[string]string)) + if err != nil { + return buildDiagNotFoundFail("Workflow job template", workflowJobTemplateID, err) + } + + data := WorkflokJobTemplateLaunchData{ + ExtraVars: d.Get("extra_vars").(string), + } + + var iData map[string]interface{} + idata, _ := json.Marshal(data) + json.Unmarshal(idata, &iData) + + res, err := awxService.Launch(workflowJobTemplateID, iData, map[string]string{}) + if err != nil { + log.Printf("Failed to create Workflow Template Launch %v", err) + diags = append(diags, diag.Diagnostic{ + Severity: diag.Error, + Summary: "Unable to create workflowJobTemplate", + Detail: fmt.Sprintf("WorkflowJobTemplateLaunch with template ID %d, failed to create %s", d.Get("workflow_job_template_id").(int), err.Error()), + }) + return diags + } + + // return resourceWorkflowJobRead(ctx, d, m) + d.SetId(strconv.Itoa(res.ID)) + if d.Get("wait_for_completion").(bool) { // Print the full structure of the result object + err = workflowJobTemplateLaunchWait(ctx, awxWorkflowJobService, res, d.Timeout(schema.TimeoutCreate)) + if err != nil { + diags = append(diags, diag.Diagnostic{ + Severity: diag.Error, + Summary: "WorkflowJobTemplate execution failure", + Detail: fmt.Sprintf("WorkflowJobTemplateLaunch with ID %d and Workflow template ID %d, failed to complete %s", res.ID, d.Get("workflow_job_template_id").(int), err.Error()), + }) + } + } + return diags +} + +func resourceWorkflowJobRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + var diags diag.Diagnostics + return diags +} + +func resourceWorkflowJobDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + var diags diag.Diagnostics + client := m.(*awx.AWX) + awxService := client.WorkflowJobService + jobID, diags := convertStateIDToNummeric("Delete Workflow Job", d) + _, err := awxService.GetWorkflowJob(jobID, map[string]string{}) + if err != nil { + return buildDiagNotFoundFail("Workflow job", jobID, err) + } + + d.SetId("") + return diags +} diff --git a/go.mod b/go.mod index ee432aa..e7dec0c 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/denouche/terraform-provider-awx go 1.20 require ( - github.com/denouche/goawx v0.21.1 + github.com/denouche/goawx v0.22.0 github.com/gruntwork-io/terratest v0.31.2 github.com/hashicorp/terraform-plugin-sdk/v2 v2.30.0 github.com/stretchr/testify v1.8.3 diff --git a/go.sum b/go.sum index bfc138e..f9fbfce 100644 --- a/go.sum +++ b/go.sum @@ -101,6 +101,8 @@ github.com/denouche/goawx v0.20.1 h1:Mnkk1QxGPBvo3U4FDhcdHFrSMwIT+IwAkLDVQ7dCAoc github.com/denouche/goawx v0.20.1/go.mod h1:MppzSteoj2xgfiqiRWW/Bf1a8z2FrRyvah1z0J2vJTY= github.com/denouche/goawx v0.21.1 h1:ImTBH6/L3u8QInlPHMWO02su4lQPHudj52ZvwKeL86A= github.com/denouche/goawx v0.21.1/go.mod h1:Bdo/LeUgeemE9Xt4bOVFVO6GJMxxUcduhQPDD5+yQ1A= +github.com/denouche/goawx v0.22.0 h1:P5ReudHwkBNrfiK2jbY10U0uFxCNyvEpw4x9u3wAcq0= +github.com/denouche/goawx v0.22.0/go.mod h1:Bdo/LeUgeemE9Xt4bOVFVO6GJMxxUcduhQPDD5+yQ1A= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=