Skip to content

Commit

Permalink
add gitlab_pipeline_schedule resource
Browse files Browse the repository at this point in the history
  • Loading branch information
thojkooi committed Jun 10, 2019
1 parent 1c000d6 commit 9e711ec
Show file tree
Hide file tree
Showing 5 changed files with 406 additions and 0 deletions.
1 change: 1 addition & 0 deletions gitlab/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ func Provider() terraform.ResourceProvider {
"gitlab_group": resourceGitlabGroup(),
"gitlab_project": resourceGitlabProject(),
"gitlab_label": resourceGitlabLabel(),
"gitlab_pipeline_schedule": resourceGitlabPipelineSchedule(),
"gitlab_pipeline_trigger": resourceGitlabPipelineTrigger(),
"gitlab_project_hook": resourceGitlabProjectHook(),
"gitlab_deploy_key": resourceGitlabDeployKey(),
Expand Down
171 changes: 171 additions & 0 deletions gitlab/resource_gitlab_pipeline_schedule.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
package gitlab

import (
"fmt"
"log"
"strconv"

"github.com/hashicorp/terraform/helper/schema"
gitlab "github.com/xanzy/go-gitlab"
)

func resourceGitlabPipelineSchedule() *schema.Resource {
return &schema.Resource{
Create: resourceGitlabPipelineScheduleCreate,
Read: resourceGitlabPipelineScheduleRead,
Update: resourceGitlabPipelineScheduleUpdate,
Delete: resourceGitlabPipelineScheduleDelete,

Schema: map[string]*schema.Schema{
"project": {
Type: schema.TypeString,
Required: true,
},
"description": {
Type: schema.TypeString,
Required: true,
},
"ref": {
Type: schema.TypeString,
Required: true,
},
"cron": {
Type: schema.TypeString,
Required: true,
},
"cron_timezone": {
Type: schema.TypeString,
Optional: true,
Default: "UTC",
},
"active": {
Type: schema.TypeBool,
Optional: true,
Default: true,
},
},
}
}

func resourceGitlabPipelineScheduleCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*gitlab.Client)
project := d.Get("project").(string)
options := &gitlab.CreatePipelineScheduleOptions{
Description: gitlab.String(d.Get("description").(string)),
Ref: gitlab.String(d.Get("ref").(string)),
Cron: gitlab.String(d.Get("cron").(string)),
CronTimezone: gitlab.String(d.Get("cron_timezone").(string)),
Active: gitlab.Bool(d.Get("active").(bool)),
}

log.Printf("[DEBUG] create gitlab PipelineSchedule %s", *options.Description)

PipelineSchedule, _, err := client.PipelineSchedules.CreatePipelineSchedule(project, options)
if err != nil {
return err
}

d.SetId(strconv.Itoa(PipelineSchedule.ID))

return resourceGitlabPipelineScheduleRead(d, meta)
}

func resourceGitlabPipelineScheduleRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*gitlab.Client)
project := d.Get("project").(string)
pipelineScheduleID, err := strconv.Atoi(d.Id())

if err != nil {
return fmt.Errorf("%s cannot be converted to int", d.Id())
}

log.Printf("[DEBUG] read gitlab PipelineSchedule %s/%d", project, pipelineScheduleID)

pipelineSchedules, response, err := client.PipelineSchedules.ListPipelineSchedules(project, nil)
if err != nil {
return err
}
found := false
for _, pipelineSchedule := range pipelineSchedules {
if pipelineSchedule.ID == pipelineScheduleID {
d.Set("description", pipelineSchedule.Description)
d.Set("ref", pipelineSchedule.Ref)
d.Set("cron", pipelineSchedule.Cron)
d.Set("cron_timezone", pipelineSchedule.CronTimezone)
d.Set("active", pipelineSchedule.Active)
found = true
break
}
}
if !found {
log.Printf("[WARN] removing PipelineSchedule %d from state because it no longer exists in gitlab", pipelineScheduleID)
d.SetId("")
}

return nil
}

func resourceGitlabPipelineScheduleUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*gitlab.Client)
project := d.Get("project").(string)
options := &gitlab.EditPipelineScheduleOptions{
Description: gitlab.String(d.Get("description").(string)),
Ref: gitlab.String(d.Get("ref").(string)),
Cron: gitlab.String(d.Get("cron").(string)),
CronTimezone: gitlab.String(d.Get("cron_timezone").(string)),
Active: gitlab.Bool(d.Get("active").(bool)),
}

pipelineScheduleID, err := strconv.Atoi(d.Id())

if err != nil {
return fmt.Errorf("%s cannot be converted to int", d.Id())
}

if d.HasChange("description") {
options.Description = gitlab.String(d.Get("description").(string))
}

if d.HasChange("ref") {
options.Ref = gitlab.String(d.Get("ref").(string))
}

if d.HasChange("cron") {
options.Cron = gitlab.String(d.Get("cron").(string))
}

if d.HasChange("cron_timezone") {
options.CronTimezone = gitlab.String(d.Get("cron_timezone").(string))
}

if d.HasChange("active") {
options.Active = gitlab.Bool(d.Get("active").(bool))
}

log.Printf("[DEBUG] update gitlab PipelineSchedule %s", d.Id())

_, _, err = client.PipelineSchedules.EditPipelineSchedule(project, pipelineScheduleID, options)
if err != nil {
return err
}

return resourceGitlabPipelineScheduleRead(d, meta)
}

func resourceGitlabPipelineScheduleDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*gitlab.Client)
project := d.Get("project").(string)
log.Printf("[DEBUG] Delete gitlab PipelineSchedule %s", d.Id())

pipelineScheduleID, err := strconv.Atoi(d.Id())

if err != nil {
return fmt.Errorf("%s cannot be converted to int", d.Id())
}

resp, err := client.PipelineSchedules.DeletePipelineSchedule(project, pipelineScheduleID)
if err != nil {
return fmt.Errorf("%s failed to delete pipeline schedule: %s", d.Id(), resp.Status)
}
return err
}
191 changes: 191 additions & 0 deletions gitlab/resource_gitlab_pipeline_schedule_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
package gitlab

import (
"fmt"
"strconv"
"testing"

"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
gitlab "github.com/xanzy/go-gitlab"
)

func TestAccGitlabPipelineSchedule_basic(t *testing.T) {
var schedule gitlab.PipelineSchedule
rInt := acctest.RandInt()

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckGitlabPipelineScheduleDestroy,
Steps: []resource.TestStep{
// Create a project and pipeline schedule with default options
{
Config: testAccGitlabPipelineScheduleConfig(rInt),
Check: resource.ComposeTestCheckFunc(
testAccCheckGitlabPipelineScheduleExists("gitlab_pipeline_schedule.schedule", &schedule),
testAccCheckGitlabPipelineScheduleAttributes(&schedule, &testAccGitlabPipelineScheduleExpectedAttributes{
Description: "Pipeline Schedule",
Ref: "master",
Cron: "0 1 * * *",
CronTimezone: "UTC",
Active: true,
}),
),
},
// Update the pipeline schedule to change the parameters
{
Config: testAccGitlabPipelineScheduleUpdateConfig(rInt),
Check: resource.ComposeTestCheckFunc(
testAccCheckGitlabPipelineScheduleExists("gitlab_pipeline_schedule.schedule", &schedule),
testAccCheckGitlabPipelineScheduleAttributes(&schedule, &testAccGitlabPipelineScheduleExpectedAttributes{
Description: "Schedule",
Ref: "master",
Cron: "0 4 * * *",
CronTimezone: "UTC",
Active: false,
}),
),
},
// Update the pipeline schedule to get back to initial settings
{
Config: testAccGitlabPipelineScheduleConfig(rInt),
Check: resource.ComposeTestCheckFunc(
testAccCheckGitlabPipelineScheduleExists("gitlab_pipeline_schedule.schedule", &schedule),
testAccCheckGitlabPipelineScheduleAttributes(&schedule, &testAccGitlabPipelineScheduleExpectedAttributes{
Description: "Pipeline Schedule",
Ref: "master",
Cron: "0 1 * * *",
CronTimezone: "UTC",
Active: true,
}),
),
},
},
})
}

func testAccCheckGitlabPipelineScheduleExists(n string, schedule *gitlab.PipelineSchedule) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not Found: %s", n)
}

scheduleID := rs.Primary.ID
repoName := rs.Primary.Attributes["project"]
if repoName == "" {
return fmt.Errorf("No project ID is set")
}
conn := testAccProvider.Meta().(*gitlab.Client)

schedules, _, err := conn.PipelineSchedules.ListPipelineSchedules(repoName, nil)
if err != nil {
return err
}
for _, gotSchedule := range schedules {
if strconv.Itoa(gotSchedule.ID) == scheduleID {
*schedule = *gotSchedule
return nil
}
}
return fmt.Errorf("Pipeline Schedule does not exist")
}
}

type testAccGitlabPipelineScheduleExpectedAttributes struct {
Description string
Ref string
Cron string
CronTimezone string
Active bool
}

func testAccCheckGitlabPipelineScheduleAttributes(schedule *gitlab.PipelineSchedule, want *testAccGitlabPipelineScheduleExpectedAttributes) resource.TestCheckFunc {
return func(s *terraform.State) error {
if schedule.Description != want.Description {
return fmt.Errorf("got description %q; want %q", schedule.Description, want.Description)
}
if schedule.Ref != want.Ref {
return fmt.Errorf("got ref %q; want %q", schedule.Ref, want.Ref)
}

if schedule.Cron != want.Cron {
return fmt.Errorf("got cron %q; want %q", schedule.Cron, want.Cron)
}

if schedule.CronTimezone != want.CronTimezone {
return fmt.Errorf("got cron_timezone %q; want %q", schedule.CronTimezone, want.CronTimezone)
}

if schedule.Active != want.Active {
return fmt.Errorf("got active %t; want %t", schedule.Active, want.Active)
}

return nil
}
}

func testAccCheckGitlabPipelineScheduleDestroy(s *terraform.State) error {
conn := testAccProvider.Meta().(*gitlab.Client)

for _, rs := range s.RootModule().Resources {
if rs.Type != "gitlab_project" {
continue
}

gotRepo, resp, err := conn.Projects.GetProject(rs.Primary.ID, nil)
if err == nil {
if gotRepo != nil && fmt.Sprintf("%d", gotRepo.ID) == rs.Primary.ID {
return fmt.Errorf("Repository still exists")
}
}
if resp.StatusCode != 404 {
return err
}
return nil
}
return nil
}

func testAccGitlabPipelineScheduleConfig(rInt int) string {
return fmt.Sprintf(`
resource "gitlab_project" "foo" {
name = "foo-%d"
description = "Terraform acceptance tests"
# So that acceptance tests can be run in a gitlab organization
# with no billing
visibility_level = "public"
}
resource "gitlab_pipeline_schedule" "schedule" {
project = "${gitlab_project.foo.id}"
description = "Pipeline Schedule"
ref = "master"
cron = "0 1 * * *"
}
`, rInt)
}

func testAccGitlabPipelineScheduleUpdateConfig(rInt int) string {
return fmt.Sprintf(`
resource "gitlab_project" "foo" {
name = "foo-%d"
description = "Terraform acceptance tests"
# So that acceptance tests can be run in a gitlab organization
# with no billing
visibility_level = "public"
}
resource "gitlab_pipeline_schedule" "schedule" {
project = "${gitlab_project.foo.id}"
description = "Schedule"
ref = "master"
cron = "0 4 * * *"
active = false
}
`, rInt)
}
Loading

0 comments on commit 9e711ec

Please sign in to comment.