-
Notifications
You must be signed in to change notification settings - Fork 319
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add resource for project freeze periods (#516)
- Loading branch information
Showing
5 changed files
with
358 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# gitlab_project_freeze_period | ||
|
||
This resource allows you to create and manage freeze periods. For further information on freeze periods, consult the [gitlab documentation](https://docs.gitlab.com/ee/api/freeze_periods.html#create-a-freeze-period). | ||
|
||
## Example Usage | ||
|
||
```hcl | ||
resource "gitlab_project_freeze_period" "schedule" { | ||
project_id = gitlab_project.foo.id | ||
freeze_start = "0 23 * * 5" | ||
freeze_end = "0 7 * * 1" | ||
cron_timezone = "UTC" | ||
} | ||
``` | ||
|
||
## Argument Reference | ||
|
||
The following arguments are supported: | ||
|
||
* `project_id` - (Required, string) The id of the project to add the schedule to. | ||
|
||
* `freeze_start` - (Required,string) Start of the Freeze Period in cron format (e.g. `0 1 * * *`). | ||
|
||
* `freeze_end` - (Required, string) End of the Freeze Period in cron format (e.g. `0 2 * * *`). | ||
|
||
* `cron_timezone` - (Optional, string) The timezone. | ||
|
||
## Import | ||
|
||
GitLab project freeze periods can be imported using an id made up of `project_id:freeze_period_id`, e.g. | ||
|
||
|
||
``` | ||
$ terraform import gitlab_project_freeze_period.schedule "12345:1337" | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
package gitlab | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"net/http" | ||
"strconv" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" | ||
gitlab "github.com/xanzy/go-gitlab" | ||
) | ||
|
||
func resourceGitlabProjectFreezePeriod() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceGitlabProjectFreezePeriodCreate, | ||
Read: resourceGitlabProjectFreezePeriodRead, | ||
Update: resourceGitlabProjectFreezePeriodUpdate, | ||
Delete: resourceGitlabProjectFreezePeriodDelete, | ||
Importer: &schema.ResourceImporter{ | ||
State: schema.ImportStatePassthrough, | ||
}, | ||
Schema: map[string]*schema.Schema{ | ||
"project_id": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
"freeze_start": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
}, | ||
"freeze_end": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
}, | ||
"cron_timezone": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
Default: "UTC", | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceGitlabProjectFreezePeriodCreate(d *schema.ResourceData, meta interface{}) error { | ||
projectID := d.Get("project_id").(string) | ||
|
||
options := gitlab.CreateFreezePeriodOptions{ | ||
FreezeStart: gitlab.String(d.Get("freeze_start").(string)), | ||
FreezeEnd: gitlab.String(d.Get("freeze_end").(string)), | ||
CronTimezone: gitlab.String(d.Get("cron_timezone").(string)), | ||
} | ||
|
||
log.Printf("[DEBUG] Project %s create gitlab project-level freeze period %+v", projectID, options) | ||
|
||
client := meta.(*gitlab.Client) | ||
FreezePeriod, _, err := client.FreezePeriods.CreateFreezePeriodOptions(projectID, &options) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
FreezePeriodIDString := fmt.Sprintf("%d", FreezePeriod.ID) | ||
d.SetId(buildTwoPartID(&projectID, &FreezePeriodIDString)) | ||
|
||
return resourceGitlabProjectFreezePeriodRead(d, meta) | ||
} | ||
|
||
func resourceGitlabProjectFreezePeriodRead(d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*gitlab.Client) | ||
projectID, freezePeriodID, err := projectIDAndFreezePeriodIDFromID(d.Id()) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
log.Printf("[DEBUG] read gitlab FreezePeriod %s/%d", projectID, freezePeriodID) | ||
|
||
freezePeriod, resp, err := client.FreezePeriods.GetFreezePeriod(projectID, freezePeriodID) | ||
if err != nil { | ||
if resp != nil && resp.StatusCode == http.StatusNotFound { | ||
log.Printf("[DEBUG] project freeze period for %s not found so removing it from state", d.Id()) | ||
d.SetId("") | ||
return nil | ||
} | ||
return err | ||
} | ||
|
||
d.Set("freeze_start", freezePeriod.FreezeStart) | ||
d.Set("freeze_end", freezePeriod.FreezeEnd) | ||
d.Set("cron_timezone", freezePeriod.CronTimezone) | ||
d.Set("project_id", projectID) | ||
|
||
return nil | ||
} | ||
|
||
func resourceGitlabProjectFreezePeriodUpdate(d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*gitlab.Client) | ||
projectID, freezePeriodID, err := projectIDAndFreezePeriodIDFromID(d.Id()) | ||
options := &gitlab.UpdateFreezePeriodOptions{} | ||
|
||
if err != nil { | ||
return fmt.Errorf("%s cannot be converted to int", d.Id()) | ||
} | ||
|
||
if d.HasChange("freeze_start") { | ||
options.FreezeStart = gitlab.String(d.Get("freeze_start").(string)) | ||
} | ||
|
||
if d.HasChange("freeze_end") { | ||
options.FreezeEnd = gitlab.String(d.Get("freeze_end").(string)) | ||
} | ||
|
||
if d.HasChange("cron_timezone") { | ||
options.CronTimezone = gitlab.String(d.Get("cron_timezone").(string)) | ||
} | ||
|
||
log.Printf("[DEBUG] update gitlab FreezePeriod %s", d.Id()) | ||
|
||
_, _, err = client.FreezePeriods.UpdateFreezePeriodOptions(projectID, freezePeriodID, options) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return resourceGitlabProjectFreezePeriodRead(d, meta) | ||
} | ||
|
||
func resourceGitlabProjectFreezePeriodDelete(d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*gitlab.Client) | ||
projectID, freezePeriodID, err := projectIDAndFreezePeriodIDFromID(d.Id()) | ||
log.Printf("[DEBUG] Delete gitlab FreezePeriod %s", d.Id()) | ||
|
||
if err != nil { | ||
return fmt.Errorf("%s cannot be converted to int", d.Id()) | ||
} | ||
|
||
if _, err = client.FreezePeriods.DeleteFreezePeriod(projectID, freezePeriodID); err != nil { | ||
return fmt.Errorf("failed to delete pipeline schedule %q: %w", d.Id(), err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func projectIDAndFreezePeriodIDFromID(id string) (string, int, error) { | ||
project, freezePeriodIDString, err := parseTwoPartID(id) | ||
if err != nil { | ||
return "", 0, err | ||
} | ||
|
||
freezePeriodID, err := strconv.Atoi(freezePeriodIDString) | ||
if err != nil { | ||
return "", 0, fmt.Errorf("failed to get freezePeriodId: %v", err) | ||
} | ||
|
||
return project, freezePeriodID, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
package gitlab | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/helper/acctest" | ||
"github.com/hashicorp/terraform-plugin-sdk/helper/resource" | ||
"github.com/hashicorp/terraform-plugin-sdk/terraform" | ||
gitlab "github.com/xanzy/go-gitlab" | ||
) | ||
|
||
func TestAccGitlabProjectFreezePeriod_basic(t *testing.T) { | ||
var schedule gitlab.FreezePeriod | ||
rInt := acctest.RandInt() | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckGitlabProjectDestroy, | ||
Steps: []resource.TestStep{ | ||
// Create a project and freeze period with default options | ||
{ | ||
Config: testAccGitlabProjectFreezePeriodConfig(rInt), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckGitlabProjectFreezePeriodExists("gitlab_project_freeze_period.schedule", &schedule), | ||
testAccCheckGitlabProjectFreezePeriodAttributes(&schedule, &testAccGitlabProjectFreezePeriodExpectedAttributes{ | ||
FreezeStart: "0 23 * * 5", | ||
FreezeEnd: "0 7 * * 1", | ||
CronTimezone: "UTC", | ||
}), | ||
), | ||
}, | ||
// Update the freeze period to change the parameters | ||
{ | ||
Config: testAccGitlabProjectFreezePeriodUpdateConfig(rInt), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckGitlabProjectFreezePeriodExists("gitlab_project_freeze_period.schedule", &schedule), | ||
testAccCheckGitlabProjectFreezePeriodAttributes(&schedule, &testAccGitlabProjectFreezePeriodExpectedAttributes{ | ||
FreezeStart: "0 20 * * 6", | ||
FreezeEnd: "0 7 * * 3", | ||
CronTimezone: "EST", | ||
}), | ||
), | ||
}, | ||
// Update the freeze period to get back to initial settings | ||
{ | ||
Config: testAccGitlabProjectFreezePeriodConfig(rInt), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckGitlabProjectFreezePeriodExists("gitlab_project_freeze_period.schedule", &schedule), | ||
testAccCheckGitlabProjectFreezePeriodAttributes(&schedule, &testAccGitlabProjectFreezePeriodExpectedAttributes{ | ||
FreezeStart: "0 23 * * 5", | ||
FreezeEnd: "0 7 * * 1", | ||
CronTimezone: "UTC", | ||
}), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func TestAccGitlabProjectFreezePeriod_import(t *testing.T) { | ||
rInt := acctest.RandInt() | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckGitlabProjectDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccGitlabProjectFreezePeriodConfig(rInt), | ||
}, | ||
{ | ||
ResourceName: "gitlab_project_freeze_period.schedule", | ||
ImportState: true, | ||
ImportStateVerify: true, | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccCheckGitlabProjectFreezePeriodExists(n string, freezePeriod *gitlab.FreezePeriod) resource.TestCheckFunc { | ||
return func(s *terraform.State) error { | ||
rs, ok := s.RootModule().Resources[n] | ||
if !ok { | ||
return fmt.Errorf("Not Found: %s", n) | ||
} | ||
|
||
projectID, freezePeriodID, err := projectIDAndFreezePeriodIDFromID(rs.Primary.ID) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
conn := testAccProvider.Meta().(*gitlab.Client) | ||
gotFreezePeriod, _, err := conn.FreezePeriods.GetFreezePeriod(projectID, freezePeriodID) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
*freezePeriod = *gotFreezePeriod | ||
|
||
return nil | ||
} | ||
} | ||
|
||
type testAccGitlabProjectFreezePeriodExpectedAttributes struct { | ||
FreezeStart string | ||
FreezeEnd string | ||
CronTimezone string | ||
} | ||
|
||
func testAccCheckGitlabProjectFreezePeriodAttributes(freezePeriod *gitlab.FreezePeriod, want *testAccGitlabProjectFreezePeriodExpectedAttributes) resource.TestCheckFunc { | ||
return func(s *terraform.State) error { | ||
if freezePeriod.FreezeStart != want.FreezeStart { | ||
return fmt.Errorf("got freeze_start %q; want %q", freezePeriod.FreezeStart, want.FreezeStart) | ||
} | ||
if freezePeriod.FreezeEnd != want.FreezeEnd { | ||
return fmt.Errorf("got freeze_end %q; want %q", freezePeriod.FreezeEnd, want.FreezeEnd) | ||
} | ||
|
||
if freezePeriod.CronTimezone != want.CronTimezone { | ||
return fmt.Errorf("got cron_timezone %q; want %q", freezePeriod.CronTimezone, want.CronTimezone) | ||
} | ||
|
||
return nil | ||
} | ||
} | ||
|
||
func testAccGitlabProjectFreezePeriodConfig(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_project_freeze_period" "schedule" { | ||
project_id = gitlab_project.foo.id | ||
freeze_start = "0 23 * * 5" | ||
freeze_end = "0 7 * * 1" | ||
cron_timezone = "UTC" | ||
} | ||
`, rInt) | ||
} | ||
|
||
func testAccGitlabProjectFreezePeriodUpdateConfig(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_project_freeze_period" "schedule" { | ||
project_id = gitlab_project.foo.id | ||
freeze_start = "0 20 * * 6" | ||
freeze_end = "0 7 * * 3" | ||
cron_timezone = "EST" | ||
} | ||
`, rInt) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters