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

Job ref flags #141

Merged
merged 4 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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