Skip to content

Commit

Permalink
Merge pull request #141 from rundeck/job-ref-flags
Browse files Browse the repository at this point in the history
Job ref flags
  • Loading branch information
fdevans authored Sep 26, 2024
2 parents 27a6ca2 + 22450a6 commit 79698ba
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 22 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
20 changes: 12 additions & 8 deletions rundeck/job.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
42 changes: 33 additions & 9 deletions rundeck/resource_job.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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{}{
Expand Down
103 changes: 98 additions & 5 deletions rundeck/resource_job_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
},
Expand Down Expand Up @@ -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"
Expand Down
8 changes: 8 additions & 0 deletions website/docs/r/job.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down

0 comments on commit 79698ba

Please sign in to comment.