Skip to content

Commit

Permalink
New resource: gitlab_label
Browse files Browse the repository at this point in the history
Fixes #18

Signed-off-by: Julien Pivotto <roidelapluie@inuits.eu>
  • Loading branch information
roidelapluie committed Sep 23, 2017
1 parent 67a90da commit 93d6eb2
Show file tree
Hide file tree
Showing 5 changed files with 350 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 @@ -27,6 +27,7 @@ func Provider() terraform.ResourceProvider {
ResourcesMap: map[string]*schema.Resource{
"gitlab_group": resourceGitlabGroup(),
"gitlab_project": resourceGitlabProject(),
"gitlab_label": resourceGitlabLabel(),
"gitlab_project_hook": resourceGitlabProjectHook(),
"gitlab_deploy_key": resourceGitlabDeployKey(),
},
Expand Down
129 changes: 129 additions & 0 deletions gitlab/resource_gitlab_label.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package gitlab

import (
"log"

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

func resourceGitlabLabel() *schema.Resource {
return &schema.Resource{
Create: resourceGitlabLabelCreate,
Read: resourceGitlabLabelRead,
Update: resourceGitlabLabelUpdate,
Delete: resourceGitlabLabelDelete,

Schema: map[string]*schema.Schema{
"project": {
Type: schema.TypeString,
Required: true,
},
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"color": {
Type: schema.TypeString,
Required: true,
},
"description": {
Type: schema.TypeString,
Optional: true,
},
},
}
}

func resourceGitlabLabelCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*gitlab.Client)
project := d.Get("project").(string)
options := &gitlab.CreateLabelOptions{
Name: gitlab.String(d.Get("name").(string)),
Color: gitlab.String(d.Get("color").(string)),
}

if v, ok := d.GetOk("description"); ok {
options.Description = gitlab.String(v.(string))
}

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

label, _, err := client.Labels.CreateLabel(project, options)
if err != nil {
return err
}

d.SetId(label.Name)

return resourceGitlabLabelRead(d, meta)
}

func resourceGitlabLabelRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*gitlab.Client)
project := d.Get("project").(string)
labelName := d.Id()
log.Printf("[DEBUG] read gitlab label %s/%s", project, labelName)

labels, response, err := client.Labels.ListLabels(project)
if err != nil {
if response.StatusCode == 404 {
log.Printf("[WARN] removing label %s from state because it no longer exists in gitlab", labelName)
d.SetId("")
return nil
}

return err
}
found := false
for _, label := range labels {
if label.Name == labelName {
d.Set("description", label.Description)
d.Set("color", label.Color)
d.Set("name", label.Name)
found = true
break
}
}
if !found {
log.Printf("[WARN] removing label %s from state because it no longer exists in gitlab", labelName)
d.SetId("")
}

return nil
}

func resourceGitlabLabelUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*gitlab.Client)
project := d.Get("project").(string)
options := &gitlab.UpdateLabelOptions{
Name: gitlab.String(d.Get("name").(string)),
Color: gitlab.String(d.Get("color").(string)),
}

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

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

_, _, err := client.Labels.UpdateLabel(project, options)
if err != nil {
return err
}

return resourceGitlabLabelRead(d, meta)
}

func resourceGitlabLabelDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*gitlab.Client)
project := d.Get("project").(string)
log.Printf("[DEBUG] Delete gitlab label %s", d.Id())
options := &gitlab.DeleteLabelOptions{
Name: gitlab.String(d.Id()),
}

_, err := client.Labels.DeleteLabel(project, options)
return err
}
174 changes: 174 additions & 0 deletions gitlab/resource_gitlab_label_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
package gitlab

import (
"fmt"
"testing"

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

func TestAccGitlabLabel_basic(t *testing.T) {
var label gitlab.Label
rInt := acctest.RandInt()

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckGitlabLabelDestroy,
Steps: []resource.TestStep{
// Create a project and label with default options
{
Config: testAccGitlabLabelConfig(rInt),
Check: resource.ComposeTestCheckFunc(
testAccCheckGitlabLabelExists("gitlab_label.fixme", &label),
testAccCheckGitlabLabelAttributes(&label, &testAccGitlabLabelExpectedAttributes{
Name: fmt.Sprintf("FIXME-%d", rInt),
Color: "#ffcc00",
Description: "fix this test",
}),
),
},
// Update the label to change the parameters
{
Config: testAccGitlabLabelUpdateConfig(rInt),
Check: resource.ComposeTestCheckFunc(
testAccCheckGitlabLabelExists("gitlab_label.fixme", &label),
testAccCheckGitlabLabelAttributes(&label, &testAccGitlabLabelExpectedAttributes{
Name: fmt.Sprintf("FIXME-%d", rInt),
Color: "#ff0000",
Description: "red label",
}),
),
},
// Update the label to get back to initial settings
{
Config: testAccGitlabLabelConfig(rInt),
Check: resource.ComposeTestCheckFunc(
testAccCheckGitlabLabelExists("gitlab_label.fixme", &label),
testAccCheckGitlabLabelAttributes(&label, &testAccGitlabLabelExpectedAttributes{
Name: fmt.Sprintf("FIXME-%d", rInt),
Color: "#ffcc00",
Description: "fix this test",
}),
),
},
},
})
}

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

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

labels, _, err := conn.Labels.ListLabels(repoName)
if err != nil {
return err
}
for _, gotLabel := range labels {
if gotLabel.Name == labelName {
*label = *gotLabel
return nil
}
}
return fmt.Errorf("Label does not exist")
}
}

type testAccGitlabLabelExpectedAttributes struct {
Name string
Color string
Description string
}

func testAccCheckGitlabLabelAttributes(label *gitlab.Label, want *testAccGitlabLabelExpectedAttributes) resource.TestCheckFunc {
return func(s *terraform.State) error {
if label.Name != want.Name {
return fmt.Errorf("got name %q; want %q", label.Name, want.Name)
}

if label.Description != want.Description {
return fmt.Errorf("got description %q; want %q", label.Description, want.Description)
}

if label.Color != want.Color {
return fmt.Errorf("got color %q; want %q", label.Color, want.Color)
}

return nil
}
}

func testAccCheckGitlabLabelDestroy(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)
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 testAccGitlabLabelConfig(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_label" "fixme" {
project = "${gitlab_project.foo.id}"
name = "FIXME-%d"
color = "#ffcc00"
description = "fix this test"
}
`, rInt, rInt)
}

func testAccGitlabLabelUpdateConfig(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_label" "fixme" {
project = "${gitlab_project.foo.id}"
name = "FIXME-%d"
color = "#ff0000"
description = "red label"
}
`, rInt, rInt)
}
43 changes: 43 additions & 0 deletions website/docs/r/label.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
layout: "gitlab"
page_title: "GitLab: gitlab_label"
sidebar_current: "docs-gitlab-resource-label"
description: |-
Creates and manages labels for GitLab projects
---

# gitlab\_label

This resource allows you to create and manage labels for your GitLab projects.
For further information on labels, consult the [gitlab
documentation](https://docs.gitlab.com/ee/user/project/labels.htm).


## Example Usage

```hcl
resource "gitlab_label" "fixme" {
project = "example"
name = "fixme"
description = "issue with failing tests"
color = "#ffcc00"
}
```

## Argument Reference

The following arguments are supported:

* `project` - (Required) The name or id of the project to add the label to.

* `name` - (Required) The name of the label.

* `color` - (Required) The color of the label given in 6-digit hex notation with leading '#' sign (e.g. #FFAABB) or one of the [CSS color names](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#Color_keywords).

* `description` - (Optional) The description of the label.

## Attributes Reference

The resource exports the following attributes:

* `id` - The unique id assigned to the label by the GitLab server (the name of the label).
3 changes: 3 additions & 0 deletions website/gitlab.erb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
<li<%= sidebar_current("docs-gitlab-resource-group") %>>
<a href="/docs/providers/gitlab/r/group.html">gitlab_group</a>
</li>
<li<%= sidebar_current("docs-gitlab-resource-label") %>>
<a href="/docs/providers/gitlab/r/label.html">gitlab_label</a>
</li>
<li<%= sidebar_current("docs-gitlab-resource-project-hook") %>>
<a href="/docs/providers/gitlab/r/project_hook.html">gitlab_project_hook</a>
</li>
Expand Down

0 comments on commit 93d6eb2

Please sign in to comment.