diff --git a/CHANGELOG.md b/CHANGELOG.md index cf5bbeeb6..4b601bb65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 0.4.9 +- Added flags for using Job Reference steps. + ## 0.4.8 - Added Job step option for `script_url` - Added ability to reference jobs in other projects through the use of `project_name` in `job` command type. diff --git a/rundeck/job.go b/rundeck/job.go index bf7e50436..202376ee2 100644 --- a/rundeck/job.go +++ b/rundeck/job.go @@ -297,14 +297,18 @@ type JobCommandScriptInterpreter struct { // JobCommandJobRef is a reference to another job that will run as one of the commands of a job. type JobCommandJobRef struct { - XMLName xml.Name `xml:"jobref"` - Name string `xml:"name,attr"` - GroupName string `xml:"group,attr"` - Project string `xml:"project,attr"` - RunForEachNode bool `xml:"nodeStep,attr"` - Dispatch *JobDispatch `xml:"dispatch,omitempty"` - NodeFilter *JobNodeFilter `xml:"nodefilters,omitempty"` - Arguments JobCommandJobRefArguments `xml:"arg"` + XMLName xml.Name `xml:"jobref"` + Name string `xml:"name,attr"` + GroupName string `xml:"group,attr"` + Project string `xml:"project,attr"` + RunForEachNode bool `xml:"nodeStep,attr"` + Dispatch *JobDispatch `xml:"dispatch,omitempty"` + NodeFilter *JobNodeFilter `xml:"nodefilters,omitempty"` + Arguments JobCommandJobRefArguments `xml:"arg"` + ChildNodes bool `xml:"childNodes,attr"` + FailOnDisable bool `xml:"failOnDisable,attr"` + IgnoreNotifications bool `xml:"ignoreNotifications,attr"` + ImportOptions bool `xml:"importOptions,attr"` } // JobCommandJobRefArguments is a string representing the arguments in a JobCommandJobRef. diff --git a/rundeck/resource_job.go b/rundeck/resource_job.go index 04d8147f5..2716b7cc3 100644 --- a/rundeck/resource_job.go +++ b/rundeck/resource_job.go @@ -521,6 +521,22 @@ func resourceRundeckJobCommandJob() *schema.Resource { Type: schema.TypeString, Optional: true, }, + "child_nodes": { + Type: schema.TypeBool, + Optional: true, + }, + "fail_on_disable": { + Type: schema.TypeBool, + Optional: true, + }, + "ignore_notifications": { + Type: schema.TypeBool, + Optional: true, + }, + "import_options": { + Type: schema.TypeBool, + Optional: true, + }, "node_filters": { Type: schema.TypeList, Optional: true, @@ -1255,11 +1271,15 @@ func jobCommandJobRefFromResourceData(key string, commandMap map[string]interfac } jobRefMap := jobRefsI[0].(map[string]interface{}) jobRef := &JobCommandJobRef{ - Name: jobRefMap["name"].(string), - GroupName: jobRefMap["group_name"].(string), - Project: jobRefMap["project_name"].(string), - RunForEachNode: jobRefMap["run_for_each_node"].(bool), - Arguments: JobCommandJobRefArguments(jobRefMap["args"].(string)), + Name: jobRefMap["name"].(string), + GroupName: jobRefMap["group_name"].(string), + Project: jobRefMap["project_name"].(string), + RunForEachNode: jobRefMap["run_for_each_node"].(bool), + Arguments: JobCommandJobRefArguments(jobRefMap["args"].(string)), + ChildNodes: jobRefMap["child_nodes"].(bool), + FailOnDisable: jobRefMap["fail_on_disable"].(bool), + ImportOptions: jobRefMap["import_options"].(bool), + IgnoreNotifications: jobRefMap["ignore_notifications"].(bool), } nodeFiltersI := jobRefMap["node_filters"].([]interface{}) if len(nodeFiltersI) > 1 { @@ -1355,10 +1375,14 @@ func commandToResourceData(command *JobCommand) (map[string]interface{}, error) if command.Job != nil { jobRefConfigI := map[string]interface{}{ - "name": command.Job.Name, - "group_name": command.Job.GroupName, - "run_for_each_node": command.Job.RunForEachNode, - "args": command.Job.Arguments, + "name": command.Job.Name, + "group_name": command.Job.GroupName, + "run_for_each_node": command.Job.RunForEachNode, + "args": command.Job.Arguments, + "child_nodes": command.Job.ChildNodes, + "fail_on_disable": command.Job.FailOnDisable, + "import_options": command.Job.ImportOptions, + "ignore_notifications": command.Job.IgnoreNotifications, } if command.Job.NodeFilter != nil { nodeFilterConfigI := map[string]interface{}{ diff --git a/rundeck/resource_job_test.go b/rundeck/resource_job_test.go index 7437741e1..8fbd93606 100644 --- a/rundeck/resource_job_test.go +++ b/rundeck/resource_job_test.go @@ -54,13 +54,49 @@ func TestAccJob_cmd_nodefilter(t *testing.T) { { Config: testAccJobConfig_cmd_nodefilter, Check: resource.ComposeTestCheckFunc( - testAccJobCheckExists("rundeck_job.test", &job), + testAccJobCheckExists("rundeck_job.source_test_job", &job), func(s *terraform.State) error { - if expected := "basic-job-with-node-filter"; job.Name != expected { - return fmt.Errorf("wrong name; expected %v, got %v", expected, job.Name) + if job.CommandSequence.Commands[0].Job.FailOnDisable != true { + return fmt.Errorf("FailOnDisable should be enabled") } - if expected := "name: tacobell"; job.CommandSequence.Commands[0].Job.NodeFilter.Query != expected { - return fmt.Errorf("failed to set job node filter; expected %v, got %v", expected, job.CommandSequence.Commands[0].Job.NodeFilter.Query) + if job.CommandSequence.Commands[0].Job.ChildNodes != true { + return fmt.Errorf("ChildNodes should be enabled") + } + if job.CommandSequence.Commands[0].Job.IgnoreNotifications != true { + return fmt.Errorf("IgnoreNotifications should be enabled") + } + if job.CommandSequence.Commands[0].Job.ImportOptions != true { + return fmt.Errorf("ImportOptions should be enabled") + } + if expected := "source_test_job"; job.CommandSequence.Commands[0].Job.Name != expected { + return fmt.Errorf("wrong referenced job name; expected %v, got %v", expected, job.CommandSequence.Commands[0].Job.Name) + } + if expected := "source_project"; job.CommandSequence.Commands[0].Job.Project != expected { + return fmt.Errorf("wrong referenced project name; expected %v, got %v", expected, job.CommandSequence.Commands[0].Job.Project) + } + return nil + }, + ), + }, + }, + }) +} + +func TestAccJob_cmd_referred_job(t *testing.T) { + var job JobDetail + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccJobCheckDestroy(&job), + Steps: []resource.TestStep{ + { + Config: testAccJobConfig_cmd_referred_job, + Check: resource.ComposeTestCheckFunc( + testAccJobCheckExists("rundeck_job.target_test_job", &job), + func(s *terraform.State) error { + if expected := "target_references_job"; job.Name != expected { + return fmt.Errorf("wrong name; expected %v, got %v", expected, job.Name) } return nil }, @@ -420,6 +456,63 @@ resource "rundeck_job" "test" { } ` +const testAccJobConfig_cmd_referred_job = ` +resource "rundeck_project" "source_test" { + name = "source_project" + description = "Source project for referred job acceptance tests" + + resource_model_source { + type = "file" + config = { + format = "resourcexml" + file = "/tmp/terraform-acc-tests.xml" + } + } +} +resource "rundeck_project" "target_test" { + name = "target_project" + description = "Target project for job acceptance tests" + + resource_model_source { + type = "file" + config = { + format = "resourcexml" + file = "/tmp/terraform-acc-tests.xml" + } + } +} +resource "rundeck_job" "source_test_job" { + project_name = "${rundeck_project.source_test.name}" + name = "source_test_job" + description = "A basic job" + execution_enabled = true + option { + name = "foo" + default_value = "bar" + } +} +resource "rundeck_job" "target_test_job" { + project_name = "${rundeck_project.target_test.name}" + name = "target_references_job" + description = "A job referencing another job" + execution_enabled = true + option { + name = "foo" + default_value = "bar" + command { + job { + name = "${rundeck_job.source_test_job.name}" + project_name = "${rundeck_project.target_test.name}" + run_for_each_node = true + child_nodes = true + fail_on_disable = true + ignore_notifications = true + import_options = true + } + } +} +` + const testAccJobConfig_noNodeFilterQuery = ` resource "rundeck_project" "test" { name = "terraform-acc-test-job-node-filter" diff --git a/website/docs/r/job.html.md b/website/docs/r/job.html.md index 1d4a90bf0..7934fd9c2 100644 --- a/website/docs/r/job.html.md +++ b/website/docs/r/job.html.md @@ -275,6 +275,14 @@ A command's `job` block has the following structure: * `args`: (Optional) A string giving the arguments to pass to the target job, using [Rundeck's job arguments syntax](http://rundeck.org/docs/manual/jobs.html#job-reference-step). +* `import_options`: (Optional) Pass as argument any options that match the referenced job's options. + +* `skip_notifications` (Optional) If the referenced job has notifications, they will be skipped. + +* `fail_on_disable` (Optional) If the referenced job has disabled execution, it will be considered a failure + +* `child_nodes`: (Optional) If the referenced job is from another project, you can use referenced job node list instead of the parent's nodes. + * `node_filters`: (Optional) A map for overriding the referenced job's node filters. A command's `node_filters` block has the following structure: