From 5b54ec15438f348150c9739c22158e1fcac41c92 Mon Sep 17 00:00:00 2001 From: jgramoll Date: Wed, 31 Jul 2019 17:30:47 -0500 Subject: [PATCH] add job declarative actions to provider --- README.md | 8 + client/job.go | 39 ++++- client/job_action.go | 5 + .../{job_config_actions.go => job_actions.go} | 26 +-- client/job_config.go | 2 +- client/job_config_action.go | 3 - client/job_config_declarative_job_action.go | 16 -- client/job_config_test.go | 4 +- client/job_declarative_job_action.go | 16 ++ ...eclarative_job_property_tracker_action.go} | 8 +- provider/job_action.go | 12 ++ provider/job_action_resource.go | 163 ++++++++++++++++++ provider/job_action_test.go | 47 +++++ provider/job_declarative_job_action.go | 34 ++++ .../job_declarative_job_action_resource.go | 31 ++++ provider/job_declarative_job_action_test.go | 61 +++++++ ...declarative_job_property_tracker_action.go | 35 ++++ ...ve_job_property_tracker_action_resource.go | 31 ++++ ...rative_job_property_tracker_action_test.go | 61 +++++++ provider/provider.go | 4 +- 20 files changed, 564 insertions(+), 42 deletions(-) create mode 100644 client/job_action.go rename client/{job_config_actions.go => job_actions.go} (59%) delete mode 100644 client/job_config_action.go delete mode 100644 client/job_config_declarative_job_action.go create mode 100644 client/job_declarative_job_action.go rename client/{job_config_declarative_job_property_tracker_action.go => job_declarative_job_property_tracker_action.go} (56%) create mode 100644 provider/job_action.go create mode 100644 provider/job_action_resource.go create mode 100644 provider/job_action_test.go create mode 100644 provider/job_declarative_job_action.go create mode 100644 provider/job_declarative_job_action_resource.go create mode 100644 provider/job_declarative_job_action_test.go create mode 100644 provider/job_declarative_job_property_tracker_action.go create mode 100644 provider/job_declarative_job_property_tracker_action_resource.go create mode 100644 provider/job_declarative_job_property_tracker_action_test.go diff --git a/README.md b/README.md index 73803ad..4c0740f 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,14 @@ resource "jenkins_job" "premerge" { name = "Premerge checks" } +resource "jenkins_job_declarative_job_action" premerge { + job = "${jenkins_job.premerge.id}" +} + +resource "jenkins_job_declarative_job_property_tracker_action" premerge { + job = "${jenkins_job.premerge.id}" +} + resource "jenkins_job_git_scm" "premerge" { job = "${jenkins_job.premerge.id}" diff --git a/client/job.go b/client/job.go index 5ab9abd..879d6b8 100644 --- a/client/job.go +++ b/client/job.go @@ -8,12 +8,15 @@ import ( // ErrJobPropertyNotFound job property not found var ErrJobPropertyNotFound = errors.New("Could not find job property") +// ErrJobActionNotFound job action not found +var ErrJobActionNotFound = errors.New("Could not find job action") + // Job type Job struct { Id string Name string Disabled bool - Actions *JobConfigActions `xml:"actions"` + Actions *JobActions `xml:"actions"` Description string KeepDependencies bool Properties *JobProperties @@ -23,7 +26,7 @@ type Job struct { // NewJob return Job object with default values func NewJob() *Job { return &Job{ - Actions: NewJobConfigActions(), + Actions: NewJobActions(), KeepDependencies: false, Properties: NewJobProperties(), } @@ -80,3 +83,35 @@ func (job *Job) DeleteProperty(propertyId string) error { } return ErrJobPropertyNotFound } + +func (job *Job) GetAction(actionId string) (JobAction, error) { + for _, action := range *job.Actions.Items { + if action.GetId() == actionId { + return action, nil + } + } + return nil, ErrJobActionNotFound +} + +func (job *Job) UpdateAction(action JobAction) error { + actions := *job.Actions.Items + actionId := action.GetId() + for i, oldAction := range actions { + if oldAction.GetId() == actionId { + actions[i] = action + return nil + } + } + return ErrJobActionNotFound +} + +func (job *Job) DeleteAction(actionId string) error { + actions := *job.Actions.Items + for i, action := range actions { + if action.GetId() == actionId { + *job.Actions.Items = append(actions[:i], actions[i+1:]...) + return nil + } + } + return ErrJobActionNotFound +} diff --git a/client/job_action.go b/client/job_action.go new file mode 100644 index 0000000..07bc22a --- /dev/null +++ b/client/job_action.go @@ -0,0 +1,5 @@ +package client + +type JobAction interface { + GetId() string +} diff --git a/client/job_config_actions.go b/client/job_actions.go similarity index 59% rename from client/job_config_actions.go rename to client/job_actions.go index 7513dc7..9da9a9e 100644 --- a/client/job_config_actions.go +++ b/client/job_actions.go @@ -4,44 +4,44 @@ import ( "encoding/xml" ) -type JobConfigActions struct { - XMLName xml.Name `xml:"actions"` - Items *[]JobConfigAction `xml:",any"` +type JobActions struct { + XMLName xml.Name `xml:"actions"` + Items *[]JobAction `xml:",any"` } -func NewJobConfigActions() *JobConfigActions { - return &JobConfigActions{ - Items: &[]JobConfigAction{}, +func NewJobActions() *JobActions { + return &JobActions{ + Items: &[]JobAction{}, } } -func (actions *JobConfigActions) Append(action JobConfigAction) *JobConfigActions { - newActions := NewJobConfigActions() +func (actions *JobActions) Append(action JobAction) *JobActions { + newActions := NewJobActions() if actions.Items != nil { *newActions.Items = append(*actions.Items, action) } else { - *newActions.Items = []JobConfigAction{action} + *newActions.Items = []JobAction{action} } return newActions } -func (actions *JobConfigActions) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { +func (actions *JobActions) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { var tok xml.Token var err error - actions.Items = &[]JobConfigAction{} + actions.Items = &[]JobAction{} for tok, err = d.Token(); err == nil; tok, err = d.Token() { if elem, ok := tok.(xml.StartElement); ok { // TODO use map switch elem.Name.Local { case "org.jenkinsci.plugins.pipeline.modeldefinition.actions.DeclarativeJobAction": - action := NewJobConfigDeclarativeJobAction() + action := NewJobDeclarativeJobAction() err := d.DecodeElement(action, &elem) if err != nil { return err } *actions.Items = append(*actions.Items, action) case "org.jenkinsci.plugins.pipeline.modeldefinition.actions.DeclarativeJobPropertyTrackerAction": - action := NewJobConfigDeclarativeJobPropertyTrackerAction() + action := NewJobDeclarativeJobPropertyTrackerAction() err := d.DecodeElement(action, &elem) if err != nil { return err diff --git a/client/job_config.go b/client/job_config.go index be59f49..b175131 100644 --- a/client/job_config.go +++ b/client/job_config.go @@ -9,7 +9,7 @@ type jobConfig struct { Id string `xml:"id,attr,omitempty"` Plugin string `xml:"plugin,attr,omitempty"` - Actions *JobConfigActions `xml:"actions"` + Actions *JobActions `xml:"actions"` Description string `xml:"description"` KeepDependencies bool `xml:"keepDependencies"` Properties *JobProperties `xml:"properties"` diff --git a/client/job_config_action.go b/client/job_config_action.go deleted file mode 100644 index 0afcc29..0000000 --- a/client/job_config_action.go +++ /dev/null @@ -1,3 +0,0 @@ -package client - -type JobConfigAction interface{} diff --git a/client/job_config_declarative_job_action.go b/client/job_config_declarative_job_action.go deleted file mode 100644 index 731d2b9..0000000 --- a/client/job_config_declarative_job_action.go +++ /dev/null @@ -1,16 +0,0 @@ -package client - -import "encoding/xml" - -type JobConfigDeclarativeJobAction struct { - XMLName xml.Name `xml:"org.jenkinsci.plugins.pipeline.modeldefinition.actions.DeclarativeJobAction"` - Id string `xml:"id,attr,omitempty"` -} - -func NewJobConfigDeclarativeJobAction() *JobConfigDeclarativeJobAction { - return &JobConfigDeclarativeJobAction{} -} - -func (action *JobConfigDeclarativeJobAction) GetId() string { - return action.Id -} diff --git a/client/job_config_test.go b/client/job_config_test.go index 44b4883..3ad6dbc 100644 --- a/client/job_config_test.go +++ b/client/job_config_test.go @@ -10,8 +10,8 @@ import ( func TestJobConfigSerialize(t *testing.T) { job := NewJob() job.Description = "my-desc" - job.Actions = job.Actions.Append(NewJobConfigDeclarativeJobAction()) - job.Actions = job.Actions.Append(NewJobConfigDeclarativeJobPropertyTrackerAction()) + job.Actions = job.Actions.Append(NewJobDeclarativeJobAction()) + job.Actions = job.Actions.Append(NewJobDeclarativeJobPropertyTrackerAction()) definition := NewCpsScmFlowDefinition() definition.SCM = NewGitScm() diff --git a/client/job_declarative_job_action.go b/client/job_declarative_job_action.go new file mode 100644 index 0000000..c9ee628 --- /dev/null +++ b/client/job_declarative_job_action.go @@ -0,0 +1,16 @@ +package client + +import "encoding/xml" + +type JobDeclarativeJobAction struct { + XMLName xml.Name `xml:"org.jenkinsci.plugins.pipeline.modeldefinition.actions.DeclarativeJobAction"` + Id string `xml:"id,attr,omitempty"` +} + +func NewJobDeclarativeJobAction() *JobDeclarativeJobAction { + return &JobDeclarativeJobAction{} +} + +func (action *JobDeclarativeJobAction) GetId() string { + return action.Id +} diff --git a/client/job_config_declarative_job_property_tracker_action.go b/client/job_declarative_job_property_tracker_action.go similarity index 56% rename from client/job_config_declarative_job_property_tracker_action.go rename to client/job_declarative_job_property_tracker_action.go index c11809a..91af5c8 100644 --- a/client/job_config_declarative_job_property_tracker_action.go +++ b/client/job_declarative_job_property_tracker_action.go @@ -2,7 +2,7 @@ package client import "encoding/xml" -type JobConfigDeclarativeJobPropertyTrackerAction struct { +type JobDeclarativeJobPropertyTrackerAction struct { XMLName xml.Name `xml:"org.jenkinsci.plugins.pipeline.modeldefinition.actions.DeclarativeJobPropertyTrackerAction"` Id string `xml:"id,attr,omitempty"` @@ -12,10 +12,10 @@ type JobConfigDeclarativeJobPropertyTrackerAction struct { Options string `xml:"options"` } -func NewJobConfigDeclarativeJobPropertyTrackerAction() *JobConfigDeclarativeJobPropertyTrackerAction { - return &JobConfigDeclarativeJobPropertyTrackerAction{} +func NewJobDeclarativeJobPropertyTrackerAction() *JobDeclarativeJobPropertyTrackerAction { + return &JobDeclarativeJobPropertyTrackerAction{} } -func (action *JobConfigDeclarativeJobPropertyTrackerAction) GetId() string { +func (action *JobDeclarativeJobPropertyTrackerAction) GetId() string { return action.Id } diff --git a/provider/job_action.go b/provider/job_action.go new file mode 100644 index 0000000..72e670e --- /dev/null +++ b/provider/job_action.go @@ -0,0 +1,12 @@ +package provider + +import ( + "github.com/hashicorp/terraform/helper/schema" + "github.com/jgramoll/terraform-provider-jenkins/client" +) + +type jobAction interface { + fromClientAction(client.JobAction) (jobAction, error) + toClientAction(id string) (client.JobAction, error) + setResourceData(*schema.ResourceData) error +} diff --git a/provider/job_action_resource.go b/provider/job_action_resource.go new file mode 100644 index 0000000..9def1bc --- /dev/null +++ b/provider/job_action_resource.go @@ -0,0 +1,163 @@ +package provider + +import ( + "errors" + "log" + "strings" + + "github.com/google/uuid" + "github.com/hashicorp/terraform/helper/schema" + "github.com/mitchellh/mapstructure" +) + +// ErrInvalidJobActionId +var ErrInvalidJobActionId = errors.New("Invalid action id, must be jobName\xactionId") + +func resourceJobActionId(input string) (jobName string, actionId string, err error) { + parts := strings.Split(input, IdDelimiter) + if len(parts) != 2 { + err = ErrInvalidJobActionId + return + } + jobName = parts[0] + actionId = parts[1] + return +} + +func resourceJobActionCreate(d *schema.ResourceData, m interface{}, createJobAction func() jobAction) error { + jobName := d.Get("job").(string) + + action := createJobAction() + configRaw := d.Get("").(map[string]interface{}) + if err := mapstructure.Decode(configRaw, &action); err != nil { + return err + } + + id, err := uuid.NewRandom() + if err != nil { + return err + } + actionId := id.String() + + jobService := m.(*Services).JobService + jobLock.Lock(jobName) + j, err := jobService.GetJob(jobName) + if err != nil { + jobLock.Unlock(jobName) + return err + } + + clientAction, err := action.toClientAction(actionId) + if err != nil { + jobLock.Unlock(jobName) + return err + } + j.Actions = j.Actions.Append(clientAction) + err = jobService.UpdateJob(j) + jobLock.Unlock(jobName) + if err != nil { + return err + } + + d.SetId(strings.Join([]string{jobName, actionId}, IdDelimiter)) + log.Println("[DEBUG] Creating job action:", d.Id()) + return resourceJobActionRead(d, m, createJobAction) +} + +func resourceJobActionRead(d *schema.ResourceData, m interface{}, createJobAction func() jobAction) error { + jobName, actionId, err := resourceJobActionId(d.Id()) + if err != nil { + return err + } + + jobService := m.(*Services).JobService + jobLock.RLock(jobName) + j, err := jobService.GetJob(jobName) + jobLock.RUnlock(jobName) + if err != nil { + log.Println("[WARN] No Job found:", err) + d.SetId("") + return nil + } + clientAction, err := j.GetAction(actionId) + if err != nil { + return err + } + action, err := createJobAction().fromClientAction(clientAction) + if err != nil { + return err + } + + log.Println("[INFO] Updating state for job action", d.Id()) + return action.setResourceData(d) +} + +func resourceJobActionUpdate(d *schema.ResourceData, m interface{}, createJobAction func() jobAction) error { + jobName, actionId, err := resourceJobActionId(d.Id()) + if err != nil { + return err + } + + action := createJobAction() + configRaw := d.Get("").(map[string]interface{}) + if err := mapstructure.Decode(configRaw, &action); err != nil { + return err + } + + jobService := m.(*Services).JobService + jobLock.Lock(jobName) + j, err := jobService.GetJob(jobName) + if err != nil { + jobLock.Unlock(jobName) + return err + } + + clientAction, err := action.toClientAction(actionId) + if err != nil { + jobLock.Unlock(jobName) + return err + } + err = j.UpdateAction(clientAction) + if err != nil { + jobLock.Unlock(jobName) + return err + } + err = jobService.UpdateJob(j) + jobLock.Unlock(jobName) + if err != nil { + return err + } + + log.Println("[DEBUG] Updating job action", d.Id()) + return resourceJobActionRead(d, m, createJobAction) +} + +func resourceJobActionDelete(d *schema.ResourceData, m interface{}, createJobAction func() jobAction) error { + jobName, actionId, err := resourceJobActionId(d.Id()) + if err != nil { + return err + } + + jobService := m.(*Services).JobService + jobLock.Lock(jobName) + j, err := jobService.GetJob(jobName) + if err != nil { + jobLock.Unlock(jobName) + return err + } + + err = j.DeleteAction(actionId) + if err != nil { + jobLock.Unlock(jobName) + return err + } + + err = jobService.UpdateJob(j) + jobLock.Unlock(jobName) + if err != nil { + return err + } + + d.SetId("") + return nil +} diff --git a/provider/job_action_test.go b/provider/job_action_test.go new file mode 100644 index 0000000..c1ac08e --- /dev/null +++ b/provider/job_action_test.go @@ -0,0 +1,47 @@ +package provider + +import ( + "fmt" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/jgramoll/terraform-provider-jenkins/client" +) + +func testAccCheckJobActions( + jobRef *client.Job, + expectedResourceNames []string, + returnActions *[]client.JobAction, + ensureAction func(client.JobAction, *terraform.ResourceState) error, +) resource.TestCheckFunc { + return func(s *terraform.State) error { + + if len(*jobRef.Actions.Items) != len(expectedResourceNames) { + return fmt.Errorf("Expected %v actions, found %v", len(expectedResourceNames), len(*jobRef.Actions.Items)) + } + for _, resourceName := range expectedResourceNames { + resource, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Job Action Resource not found: %s", resourceName) + } + + _, actionId, err := resourceJobActionId(resource.Primary.Attributes["id"]) + if err != nil { + return err + } + + actionInterface, err := jobRef.GetAction(actionId) + if err != nil { + return err + } + + err = ensureAction(actionInterface, resource) + if err != nil { + return err + } + *returnActions = append(*returnActions, actionInterface) + } + + return nil + } +} diff --git a/provider/job_declarative_job_action.go b/provider/job_declarative_job_action.go new file mode 100644 index 0000000..75c736b --- /dev/null +++ b/provider/job_declarative_job_action.go @@ -0,0 +1,34 @@ +package provider + +import ( + "fmt" + "github.com/hashicorp/terraform/helper/schema" + "github.com/jgramoll/terraform-provider-jenkins/client" + "reflect" +) + +type jobDeclarativeJobAction struct{} + +func newJobDeclarativeJobAction() *jobDeclarativeJobAction { + return &jobDeclarativeJobAction{} +} + +func (a *jobDeclarativeJobAction) fromClientAction(clientActionInterface client.JobAction) (jobAction, error) { + _, ok := clientActionInterface.(*client.JobDeclarativeJobAction) + if !ok { + return nil, fmt.Errorf("Failed to parse client action, expected *client.JobDeclarativeJobAction, got %s", + reflect.TypeOf(clientActionInterface).String()) + } + action := newJobDeclarativeJobAction() + return action, nil +} + +func (a *jobDeclarativeJobAction) toClientAction(id string) (client.JobAction, error) { + clientAction := client.NewJobDeclarativeJobAction() + clientAction.Id = id + return clientAction, nil +} + +func (a *jobDeclarativeJobAction) setResourceData(d *schema.ResourceData) error { + return nil +} diff --git a/provider/job_declarative_job_action_resource.go b/provider/job_declarative_job_action_resource.go new file mode 100644 index 0000000..6e6a690 --- /dev/null +++ b/provider/job_declarative_job_action_resource.go @@ -0,0 +1,31 @@ +package provider + +import ( + "github.com/hashicorp/terraform/helper/schema" +) + +func jobDeclarativeJobActionResource() *schema.Resource { + newJobActionInterface := func() jobAction { + return newJobDeclarativeJobAction() + } + return &schema.Resource{ + Create: func(d *schema.ResourceData, m interface{}) error { + return resourceJobActionCreate(d, m, newJobActionInterface) + }, + Read: func(d *schema.ResourceData, m interface{}) error { + return resourceJobActionRead(d, m, newJobActionInterface) + }, + Delete: func(d *schema.ResourceData, m interface{}) error { + return resourceJobActionDelete(d, m, newJobActionInterface) + }, + + Schema: map[string]*schema.Schema{ + "job": &schema.Schema{ + Type: schema.TypeString, + Description: "Name of the job", + Required: true, + ForceNew: true, + }, + }, + } +} diff --git a/provider/job_declarative_job_action_test.go b/provider/job_declarative_job_action_test.go new file mode 100644 index 0000000..6222afb --- /dev/null +++ b/provider/job_declarative_job_action_test.go @@ -0,0 +1,61 @@ +package provider + +import ( + "fmt" + "reflect" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/jgramoll/terraform-provider-jenkins/client" +) + +func TestAccJobDeclarativeJobActionBasic(t *testing.T) { + var jobRef client.Job + var actions []client.JobAction + jobName := fmt.Sprintf("%s/tf-acc-test-%s", jenkinsFolder, acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)) + jobResourceName := "jenkins_job.main" + actionResourceName := "jenkins_job_declarative_job_action.main" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccJobDeclarativeJobActionConfig(jobName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckJobExists(jobResourceName, &jobRef), + testAccCheckJobActions(&jobRef, []string{ + actionResourceName, + }, &actions, ensureJobDeclarativeJobAction), + ), + }, + { + Config: testAccJobConfigBasic(jobName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckJobExists(jobResourceName, &jobRef), + testAccCheckJobActions(&jobRef, []string{}, &actions, ensureJobDeclarativeJobAction), + ), + }, + }, + }) +} + +func testAccJobDeclarativeJobActionConfig(jobName string) string { + return testAccJobConfigBasic(jobName) + ` +resource "jenkins_job_declarative_job_action" "main" { + job = "${jenkins_job.main.id}" +} +` +} + +func ensureJobDeclarativeJobAction(actionInterface client.JobAction, rs *terraform.ResourceState) error { + _, ok := actionInterface.(*client.JobDeclarativeJobAction) + if !ok { + return fmt.Errorf("Action is not of expected type, expected *client.JobDeclarativeJobAction, actually %s", + reflect.TypeOf(actionInterface).String()) + } + + return nil +} diff --git a/provider/job_declarative_job_property_tracker_action.go b/provider/job_declarative_job_property_tracker_action.go new file mode 100644 index 0000000..ca57c9f --- /dev/null +++ b/provider/job_declarative_job_property_tracker_action.go @@ -0,0 +1,35 @@ +package provider + +import ( + "fmt" + "reflect" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/jgramoll/terraform-provider-jenkins/client" +) + +type jobDeclarativeJobPropertyTrackerAction struct{} + +func newJobDeclarativeJobPropertyTrackerAction() *jobDeclarativeJobPropertyTrackerAction { + return &jobDeclarativeJobPropertyTrackerAction{} +} + +func (a *jobDeclarativeJobPropertyTrackerAction) fromClientAction(clientActionInterface client.JobAction) (jobAction, error) { + _, ok := clientActionInterface.(*client.JobDeclarativeJobPropertyTrackerAction) + if !ok { + return nil, fmt.Errorf("Failed to parse client action, expected *client.JobDeclarativeJobPropertyTrackerAction, got %s", + reflect.TypeOf(clientActionInterface).String()) + } + action := newJobDeclarativeJobPropertyTrackerAction() + return action, nil +} + +func (a *jobDeclarativeJobPropertyTrackerAction) toClientAction(id string) (client.JobAction, error) { + clientAction := client.NewJobDeclarativeJobPropertyTrackerAction() + clientAction.Id = id + return clientAction, nil +} + +func (a *jobDeclarativeJobPropertyTrackerAction) setResourceData(d *schema.ResourceData) error { + return nil +} diff --git a/provider/job_declarative_job_property_tracker_action_resource.go b/provider/job_declarative_job_property_tracker_action_resource.go new file mode 100644 index 0000000..0fa22c8 --- /dev/null +++ b/provider/job_declarative_job_property_tracker_action_resource.go @@ -0,0 +1,31 @@ +package provider + +import ( + "github.com/hashicorp/terraform/helper/schema" +) + +func jobDeclarativeJobPropertyTrackerActionResource() *schema.Resource { + newJobActionInterface := func() jobAction { + return newJobDeclarativeJobPropertyTrackerAction() + } + return &schema.Resource{ + Create: func(d *schema.ResourceData, m interface{}) error { + return resourceJobActionCreate(d, m, newJobActionInterface) + }, + Read: func(d *schema.ResourceData, m interface{}) error { + return resourceJobActionRead(d, m, newJobActionInterface) + }, + Delete: func(d *schema.ResourceData, m interface{}) error { + return resourceJobActionDelete(d, m, newJobActionInterface) + }, + + Schema: map[string]*schema.Schema{ + "job": &schema.Schema{ + Type: schema.TypeString, + Description: "Name of the job", + Required: true, + ForceNew: true, + }, + }, + } +} diff --git a/provider/job_declarative_job_property_tracker_action_test.go b/provider/job_declarative_job_property_tracker_action_test.go new file mode 100644 index 0000000..3ddb95d --- /dev/null +++ b/provider/job_declarative_job_property_tracker_action_test.go @@ -0,0 +1,61 @@ +package provider + +import ( + "fmt" + "reflect" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/jgramoll/terraform-provider-jenkins/client" +) + +func TestAccJobDeclarativeJobPropertyTrackerActionBasic(t *testing.T) { + var jobRef client.Job + var actions []client.JobAction + jobName := fmt.Sprintf("%s/tf-acc-test-%s", jenkinsFolder, acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)) + jobResourceName := "jenkins_job.main" + actionResourceName := "jenkins_job_declarative_job_property_tracker_action.main" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccJobDeclarativeJobPropertyTrackerActionConfig(jobName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckJobExists(jobResourceName, &jobRef), + testAccCheckJobActions(&jobRef, []string{ + actionResourceName, + }, &actions, ensureJobDeclarativeJobPropertyTrackerAction), + ), + }, + { + Config: testAccJobConfigBasic(jobName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckJobExists(jobResourceName, &jobRef), + testAccCheckJobActions(&jobRef, []string{}, &actions, ensureJobDeclarativeJobPropertyTrackerAction), + ), + }, + }, + }) +} + +func testAccJobDeclarativeJobPropertyTrackerActionConfig(jobName string) string { + return testAccJobConfigBasic(jobName) + ` +resource "jenkins_job_declarative_job_property_tracker_action" "main" { + job = "${jenkins_job.main.id}" +} +` +} + +func ensureJobDeclarativeJobPropertyTrackerAction(actionInterface client.JobAction, rs *terraform.ResourceState) error { + _, ok := actionInterface.(*client.JobDeclarativeJobPropertyTrackerAction) + if !ok { + return fmt.Errorf("Action is not of expected type, expected *client.JobDeclarativeJobPropertyTrackerAction, actually %s", + reflect.TypeOf(actionInterface).String()) + } + + return nil +} diff --git a/provider/provider.go b/provider/provider.go index 915dbdc..3465f2c 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -51,7 +51,9 @@ func Provider() terraform.ResourceProvider { ResourcesMap: map[string]*schema.Resource{ "jenkins_job": jobResource(), - "jenkins_job_git_scm": jobGitScmResource(), + "jenkins_job_declarative_job_action": jobDeclarativeJobActionResource(), + "jenkins_job_declarative_job_property_tracker_action": jobDeclarativeJobPropertyTrackerActionResource(), + "jenkins_job_git_scm_user_remote_config": jobGitScmUserRemoteConfigResource(), "jenkins_job_git_scm_branch": jobGitScmBranchResource(),