Skip to content

Commit

Permalink
initial terraform job resource
Browse files Browse the repository at this point in the history
  • Loading branch information
jgramoll committed Jul 9, 2019
1 parent 3eb44f3 commit 2d3ef7e
Show file tree
Hide file tree
Showing 13 changed files with 506 additions and 86 deletions.
52 changes: 25 additions & 27 deletions client/job.go
Original file line number Diff line number Diff line change
@@ -1,37 +1,35 @@
package client

import (
"strings"
)

// Job
type Job struct {
// actions
Description string `xml:"description"`
DisplayName string `xml:"displayName"`
DisplayNameOrNull string `xml:"displayNameOrNull"`
FullDisplayName string `xml:"fullDisplayName"`
FullName string `xml:"fullName"`
Name string `xml:"name"`
URL string `xml:"url"`
Buildable bool `xml:"buildable"`
// builds
Color string `xml:"color"`
// firstBuild
// healthReport
// inQueue
// keepDependencies
// lastBuild
// lastCompletedBuild
// lastFailedBuild
// lastStableBuild
// lastSuccessfulBuild
// lastUnstableBuild
// lastUnsuccessfulBuild
NextBuildNumber int64 `xml:"nextBuildNumber"`
Property *[]*JobConfigProperty `xml:"property"`
// queueItem
ConcurrentBuild bool `xml:"concurrentBuild"`
ResumeBlocked bool `xml:"resumeBlocked"`
Name string
Disabled bool
Description string
}

// NewJob return Job object with default values
func NewJob() *Job {
return &Job{}
}

func (job *Job) Folder() string {
nameParts := strings.Split(job.Name, "/")
return strings.Join(nameParts[:len(nameParts)-1], "/")
}

func (job *Job) NameOnly() string {
nameParts := strings.Split(job.Name, "/")
return nameParts[len(nameParts)-1]
}

func newJobFromConfigAndDetails(config *jobConfig, details *jobDetails) *Job {
return &Job{
Name: details.FullName,
Disabled: config.Disabled,
Description: details.Description,
}
}
8 changes: 3 additions & 5 deletions client/job_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ package client

import "encoding/xml"

// JobConfig
type JobConfig struct {
type jobConfig struct {
XMLName xml.Name `xml:"flow-definition"`
// actions
Description string `xml:"description"`
Expand All @@ -14,7 +13,6 @@ type JobConfig struct {
Disabled bool `xml:"disabled"`
}

// NewJobConfig return JobConfig object with default values
func NewJobConfig() *JobConfig {
return &JobConfig{}
func JobConfigFromJob(job *Job) *jobConfig {
return &jobConfig{}
}
31 changes: 31 additions & 0 deletions client/job_details.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package client

type jobDetails struct {
// actions
Description string `xml:"description"`
DisplayName string `xml:"displayName"`
DisplayNameOrNull string `xml:"displayNameOrNull"`
FullDisplayName string `xml:"fullDisplayName"`
FullName string `xml:"fullName"`
Name string `xml:"name"`
URL string `xml:"url"`
Buildable bool `xml:"buildable"`
// builds
Color string `xml:"color"`
// firstBuild
// healthReport
// inQueue
// keepDependencies
// lastBuild
// lastCompletedBuild
// lastFailedBuild
// lastStableBuild
// lastSuccessfulBuild
// lastUnstableBuild
// lastUnsuccessfulBuild
NextBuildNumber int64 `xml:"nextBuildNumber"`
Property *[]*JobConfigProperty `xml:"property"`
// queueItem
ConcurrentBuild bool `xml:"concurrentBuild"`
ResumeBlocked bool `xml:"resumeBlocked"`
}
46 changes: 30 additions & 16 deletions client/job_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package client

import (
"fmt"
"strings"
)

// JobService for interacting with jenkins jobs
Expand All @@ -13,8 +14,9 @@ type JobsResponse struct {
Jobs *[]*Job `xml:"job"`
}

func fullName(folder string, jobName string) string {
return fmt.Sprintf("%s/job/%s", folder, jobName)
func jobNameToUrl(jobName string) string {
nameParts := strings.Split(jobName, "/")
return "job/" + strings.Join(nameParts[:], "/job/")
}

// GetJobs get all jobs
Expand All @@ -34,14 +36,26 @@ func (service *JobService) GetJobs() (*[]*Job, error) {
return response.Jobs, nil
}

func (service *JobService) GetJob(folder, jobName string) (*Job, error) {
path := fmt.Sprintf("/%s/api/xml", fullName(folder, jobName))
func (service *JobService) GetJob(jobFullName string) (*Job, error) {
details, err := service.getJobDetails(jobFullName)
if err != nil {
return nil, err
}
config, configErr := service.getJobConfig(jobFullName)
if configErr != nil {
return nil, configErr
}
return newJobFromConfigAndDetails(config, details), nil
}

func (service *JobService) getJobDetails(jobFullName string) (*jobDetails, error) {
path := fmt.Sprintf("/%s/api/xml", jobNameToUrl(jobFullName))
req, err := service.NewRequest("GET", path)
if err != nil {
return nil, err
}

var response Job
var response jobDetails
_, respErr := service.DoWithResponse(req, &response)
if respErr != nil {
return nil, respErr
Expand All @@ -50,14 +64,14 @@ func (service *JobService) GetJob(folder, jobName string) (*Job, error) {
return &response, nil
}

func (service *JobService) GetJobConfig(folder string, jobName string) (*JobConfig, error) {
path := fmt.Sprintf("/%s/config.xml", fullName(folder, jobName))
func (service *JobService) getJobConfig(jobFullName string) (*jobConfig, error) {
path := fmt.Sprintf("/%s/config.xml", jobNameToUrl(jobFullName))
req, err := service.NewRequest("GET", path)
if err != nil {
return nil, err
}

var response JobConfig
var response jobConfig
_, respErr := service.DoWithResponse(req, &response)
if respErr != nil {
return nil, respErr
Expand All @@ -66,9 +80,9 @@ func (service *JobService) GetJobConfig(folder string, jobName string) (*JobConf
return &response, nil
}

func (service *JobService) CreateJob(folder string, jobName string, config *JobConfig) error {
path := fmt.Sprintf("/%s/createItem?name=%s", folder, jobName)
req, err := service.NewRequestWithBody("POST", path, config)
func (service *JobService) CreateJob(job *Job) error {
path := fmt.Sprintf("/%s/createItem?name=%s", jobNameToUrl(job.Folder()), job.NameOnly())
req, err := service.NewRequestWithBody("POST", path, JobConfigFromJob(job))
if err != nil {
return err
}
Expand All @@ -81,9 +95,9 @@ func (service *JobService) CreateJob(folder string, jobName string, config *JobC
return nil
}

func (service *JobService) UpdateJob(folder string, jobName string, jobConfig *JobConfig) error {
path := fmt.Sprintf("/%s/config.xml", fullName(folder, jobName))
req, err := service.NewRequestWithBody("POST", path, jobConfig)
func (service *JobService) UpdateJob(job *Job) error {
path := fmt.Sprintf("/%s/config.xml", jobNameToUrl(job.Name))
req, err := service.NewRequestWithBody("POST", path, JobConfigFromJob(job))
if err != nil {
return err
}
Expand All @@ -96,8 +110,8 @@ func (service *JobService) UpdateJob(folder string, jobName string, jobConfig *J
return nil
}

func (service *JobService) DeleteJob(folder string, jobName string) error {
path := fmt.Sprintf("/%s/doDelete", fullName(folder, jobName))
func (service *JobService) DeleteJob(jobFullName string) error {
path := fmt.Sprintf("/%s/doDelete", jobNameToUrl(jobFullName))
req, err := service.NewRequest("POST", path)
if err != nil {
return err
Expand Down
65 changes: 28 additions & 37 deletions client/job_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ import (

var jobService *JobService

const folder string = "job/Bridge%20Career"

func init() {
// rand.Seed(time.Now().UTC().UnixNano())
jobService = &JobService{newTestClient()}
}

Expand All @@ -25,57 +22,51 @@ func TestGetJobs(t *testing.T) {
}

func TestGetJob(t *testing.T) {
jobConfig, err := jobService.GetJob(folder, "migrations")
jobName := "Bridge Career/migrations_change"
jobConfig, err := jobService.GetJob(jobName)
if err != nil {
t.Fatal(err)
}
expectedName := "Bridge Career/migrations"
if jobConfig.FullName != expectedName {
t.Fatalf("Job name should be %v, was %v", expectedName, jobConfig.FullName)
if jobConfig.Name != "Bridge Career/migrations_change" {
t.Fatalf("Job name should be %v, was %v", "Bridge Career/migrations_change", jobConfig.Name)
}
if jobConfig.Description != "" {
t.Fatalf("Job config description should be %v, was %v", "", jobConfig.Description)
}
// if jobConfig.Definition.SCM.ConfigVersion != 2 {
// t.Fatalf("Job scm config version should be %v, was %v", 2, jobConfig.Definition.SCM.ConfigVersion)
// }
// if (*jobConfig.Definition.SCM.UserRemoteConfigs.Items)[0].Url != "ssh://gerrit.instructure.com:29418/bridge-career-infrastructure.git" {
// t.Fatalf("Job scm url should be %v, was %v", "ssh://gerrit.instructure.com:29418/bridge-career-infrastructure.git", (*jobConfig.Definition.SCM.UserRemoteConfigs.Items)[0].Url)
// }
// if (*jobConfig.Definition.SCM.UserRemoteConfigs.Items)[0].CredentialsId != "44aa91d6-ab24-498a-b2b4-911bcb17cc35" {
// t.Fatalf("Job scm CredentialsId should be %v, was %v", "44aa91d6-ab24-498a-b2b4-911bcb17cc35", (*jobConfig.Definition.SCM.UserRemoteConfigs.Items)[0].CredentialsId)
// }
// if (*jobConfig.Definition.SCM.Branches.Items)[0].Name != "FETCH_HEAD" {
// t.Fatalf("Job scm branch name should be %v, was %v", "FETCH_HEAD", (*jobConfig.Definition.SCM.Branches.Items)[0].Name)
// }
// if jobConfig.Definition.ScriptPath != "migrations.Jenkinsfile" {
// t.Fatalf("Job scm branch name should be %v, was %v", "migrations.Jenkinsfile", jobConfig.Definition.ScriptPath)
// }
}

func TestCreateJob(t *testing.T) {
name := "my_test_job"
config := JobConfig{}
err := jobService.CreateJob("job/Bridge%20Career/", name, &config)
if err != nil {
t.Fatal(err)
}
job := Job{Name: "Bridge Career/my_test_job"}
jobName := job.Name

config.Description = "my new desc 3"
err = jobService.UpdateJob(folder, name, &config)
err := jobService.CreateJob(&job)
if err != nil {
t.Fatal(err)
}

err = jobService.DeleteJob("job/Bridge%20Career/", name)
job.Description = "my new desc 3"
err = jobService.UpdateJob(&job)
if err != nil {
t.Fatal(err)
}
}

func TestGetJobConfig(t *testing.T) {
jobConfig, err := jobService.GetJobConfig(folder, "migrations")
err = jobService.DeleteJob(jobName)
if err != nil {
t.Fatal(err)
}
if jobConfig.Description != "" {
t.Fatalf("Job config description should be %v, was %v", "", jobConfig.Description)
}
if jobConfig.Definition.SCM.ConfigVersion != 2 {
t.Fatalf("Job scm config version should be %v, was %v", 2, jobConfig.Definition.SCM.ConfigVersion)
}
if (*jobConfig.Definition.SCM.UserRemoteConfigs.Items)[0].Url != "ssh://gerrit.instructure.com:29418/bridge-career-infrastructure.git" {
t.Fatalf("Job scm url should be %v, was %v", "ssh://gerrit.instructure.com:29418/bridge-career-infrastructure.git", (*jobConfig.Definition.SCM.UserRemoteConfigs.Items)[0].Url)
}
if (*jobConfig.Definition.SCM.UserRemoteConfigs.Items)[0].CredentialsId != "44aa91d6-ab24-498a-b2b4-911bcb17cc35" {
t.Fatalf("Job scm CredentialsId should be %v, was %v", "44aa91d6-ab24-498a-b2b4-911bcb17cc35", (*jobConfig.Definition.SCM.UserRemoteConfigs.Items)[0].CredentialsId)
}
if (*jobConfig.Definition.SCM.Branches.Items)[0].Name != "FETCH_HEAD" {
t.Fatalf("Job scm branch name should be %v, was %v", "FETCH_HEAD", (*jobConfig.Definition.SCM.Branches.Items)[0].Name)
}
if jobConfig.Definition.ScriptPath != "migrations.Jenkinsfile" {
t.Fatalf("Job scm branch name should be %v, was %v", "migrations.Jenkinsfile", jobConfig.Definition.ScriptPath)
}
}
21 changes: 21 additions & 0 deletions client/job_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package client

import (
"testing"
)

func TestJobDetailNameOnly(t *testing.T) {
job := Job{Name: "fee fi/fo/fum"}
expected := "fum"
if job.NameOnly() != expected {
t.Fatalf("job name only should be %v, was %v", expected, job.NameOnly())
}
}

func TestJobDetailFolder(t *testing.T) {
job := Job{Name: "fee fi/fo/fum"}
expected := "fee fi/fo"
if job.Folder() != expected {
t.Fatalf("job folder should be %v, was %v", expected, job.Folder())
}
}
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@ module github.com/jgramoll/terraform-provider-jenkins

go 1.12

require github.com/hashicorp/terraform v0.12.3
require (
github.com/hashicorp/terraform v0.12.3
github.com/mitchellh/mapstructure v1.1.2
)
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee
github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dimchansky/utfbom v1.0.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
Expand Down Expand Up @@ -151,11 +152,13 @@ github.com/hashicorp/hcl2 v0.0.0-20190618163856-0b64543c968c h1:P96avlEdjyi6kpx6
github.com/hashicorp/hcl2 v0.0.0-20190618163856-0b64543c968c/go.mod h1:FSQTwDi9qesxGBsII2VqhIzKQ4r0bHvBkOczWfD7llg=
github.com/hashicorp/hil v0.0.0-20190212112733-ab17b08d6590 h1:2yzhWGdgQUWZUCNK+AoO35V+HTsgEmcM4J9IkArh7PI=
github.com/hashicorp/hil v0.0.0-20190212112733-ab17b08d6590/go.mod h1:n2TSygSNwsLJ76m8qFXTSc7beTb+auJxYdqrnoqwZWE=
github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/memberlist v0.1.0/go.mod h1:ncdBp14cuox2iFOq3kDiquKU6fqsTBc3W6JvZwjxxsE=
github.com/hashicorp/serf v0.0.0-20160124182025-e4ec8cc423bb/go.mod h1:h/Ru6tmZazX7WO/GDmwdpS975F019L4t5ng5IgwbNrE=
github.com/hashicorp/terraform v0.12.3 h1:6pdvXmXgUOQDonbwNNQfV113/D6qZ7dt57UJ0Pp6Woc=
github.com/hashicorp/terraform v0.12.3/go.mod h1:qkOSh7ytFDM6avMkFZErKhE810aB/8J+qhIEt5nRifg=
github.com/hashicorp/terraform-config-inspect v0.0.0-20190327195015-8022a2663a70 h1:oZm5nE11yhzsTRz/YrUyDMSvixePqjoZihwn8ipuOYI=
github.com/hashicorp/terraform-config-inspect v0.0.0-20190327195015-8022a2663a70/go.mod h1:ItvqtvbC3K23FFET62ZwnkwtpbKZm8t8eMcWjmVVjD8=
github.com/hashicorp/vault v0.10.4/go.mod h1:KfSyffbKxoVyspOdlaGVjIuwLobi07qD1bAbosPMpP0=
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M=
Expand Down Expand Up @@ -199,6 +202,7 @@ github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00v
github.com/miekg/dns v1.0.8/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mitchellh/cli v1.0.0 h1:iGBIsUe3+HZ/AD/Vd7DErOt5sU9fa8Uj7A2s1aggv1Y=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ=
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ=
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
Expand Down
Loading

0 comments on commit 2d3ef7e

Please sign in to comment.