diff --git a/rundeck/import_resource_job_test.go b/rundeck/import_resource_job_test.go new file mode 100644 index 000000000..acd626f19 --- /dev/null +++ b/rundeck/import_resource_job_test.go @@ -0,0 +1,32 @@ +package rundeck + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" +) + +func TestAccRundeckJob_Import(t *testing.T) { + name := "rundeck_job.test" + project_name := "terraform-acc-test-job" + var job JobDetail + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccJobCheckDestroy(&job), + Steps: []resource.TestStep{ + { + Config: testAccJobConfig_basic, + Check: testAccJobCheckExists(name, &job), + }, + { + ResourceName: name, + ImportStateIdPrefix: fmt.Sprintf("%s/", project_name), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} diff --git a/rundeck/resource_job.go b/rundeck/resource_job.go index 65b5d3be8..04d8147f5 100644 --- a/rundeck/resource_job.go +++ b/rundeck/resource_job.go @@ -16,6 +16,9 @@ func resourceRundeckJob() *schema.Resource { Delete: DeleteJob, Exists: JobExists, Read: ReadJob, + Importer: &schema.ResourceImporter{ + State: resourceJobImport, + }, Schema: map[string]*schema.Schema{ "name": { @@ -960,6 +963,9 @@ func jobToResourceData(job *JobDetail, d *schema.ResourceData) error { if err := d.Set("allow_concurrent_executions", job.AllowConcurrentExecutions); err != nil { return err } + if err := d.Set("timeout", job.Timeout); err != nil { + return err + } if job.Retry != nil { if err := d.Set("retry", job.Retry.Value); err != nil { return err @@ -981,6 +987,9 @@ func jobToResourceData(job *JobDetail, d *schema.ResourceData) error { if err := d.Set("rank_order", job.Dispatch.RankOrder); err != nil { return err } + if err := d.Set("success_on_empty_node_filter", job.Dispatch.SuccessOnEmptyNodeFilter); err != nil { + return err + } } else { if err := d.Set("max_thread_count", 1); err != nil { return err @@ -1422,3 +1431,29 @@ func readNotification(notification *Notification, notificationType string) map[s } return notificationConfigI } + +func resourceJobImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + idAttr := strings.SplitN(d.Id(), "/", 2) + var jobID string + var projectName string + + if len(idAttr) == 2 { + projectName = idAttr[0] + jobID = idAttr[1] + } else { + return nil, fmt.Errorf("invalid id %q specified, should be in format \"projectName/JobUUID\" for import", d.Id()) + } + d.SetId(jobID) + + err := ReadJob(d, meta) + if err != nil { + return nil, err + } + // Get the information out of the api if available. + // Otherwise use information supplied by user. + if d.Get("project_name") == "" { + d.Set("project_name", projectName) + } + + return []*schema.ResourceData{d}, nil +} diff --git a/rundeck/resource_job_test.go b/rundeck/resource_job_test.go index d4e008bf1..7437741e1 100644 --- a/rundeck/resource_job_test.go +++ b/rundeck/resource_job_test.go @@ -83,7 +83,7 @@ func TestOchestrator_high_low(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccJobCheckExists("rundeck_job.test", &job), func(s *terraform.State) error { - if expected := "basic-job-with-node-filter"; job.Name != expected { + if expected := "orchestrator-High-Low"; job.Name != expected { return fmt.Errorf("wrong name; expected %v, got %v", expected, job.Name) } if expected := "name: tacobell"; job.CommandSequence.Commands[0].Job.NodeFilter.Query != expected { @@ -110,7 +110,7 @@ func TestOchestrator_max_percent(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccJobCheckExists("rundeck_job.test", &job), func(s *terraform.State) error { - if expected := "basic-job-with-node-filter"; job.Name != expected { + if expected := "orchestrator-MaxPercent"; job.Name != expected { return fmt.Errorf("wrong name; expected %v, got %v", expected, job.Name) } if expected := "name: tacobell"; job.CommandSequence.Commands[0].Job.NodeFilter.Query != expected { @@ -261,8 +261,23 @@ func TestAccJobOptions_secure_choice(t *testing.T) { CheckDestroy: testAccJobCheckDestroy(&job), Steps: []resource.TestStep{ { - Config: testAccJobOptions_secure_options, - ExpectError: regexp.MustCompile("argument \"value_choices\" can not have empty values; try \"required\""), + Config: testAccJobOptions_secure_options, + Check: resource.ComposeTestCheckFunc( + testAccJobCheckExists("rundeck_job.test", &job), + func(s *terraform.State) error { + secureOption := job.OptionsConfig.Options[0] + if expected := "foo_secure"; secureOption.Name != expected { + return fmt.Errorf("wrong name; expected %v, got %v", expected, secureOption.Name) + } + if expected := "/keys/test/path/"; secureOption.StoragePath != expected { + return fmt.Errorf("wrong storage_path; expected %v, got %v", expected, secureOption.Name) + } + if expected := true; secureOption.ObscureInput != expected { + return fmt.Errorf("failed to set the input as obscure; expected %v, got %v", expected, secureOption.ObscureInput) + } + return nil + }, + ), }, }, }) diff --git a/website/docs/r/job.html.md b/website/docs/r/job.html.md index 2676ced44..797947271 100644 --- a/website/docs/r/job.html.md +++ b/website/docs/r/job.html.md @@ -325,3 +325,11 @@ A notification's `plugin` block has the following structure: The following attribute is exported: * `id` - A unique identifier for the job. + +## Import + +Rundeck job can be imported using the project and job uuid, e.g. + +``` +$ terraform import rundeck_job.my_job project_name/JOB-UUID +```