Skip to content

Commit

Permalink
provider/gitlab: Add gitlab_group resource (#14490)
Browse files Browse the repository at this point in the history
* vendor: Update go-gitlab to master@e6c11e

Update go-gitlab to master@e6c11e.  This brings in UpdateGroup in
addition to fuller management of other attributes.

* provider/gitlab:  Add `gitlab_group` resource

This adds a gitlab_group resource.

This combined with #14483 will allow you to create projects in a
group.
  • Loading branch information
richardc authored and stack72 committed May 24, 2017
1 parent c3a76c9 commit 9e90e77
Show file tree
Hide file tree
Showing 34 changed files with 1,194 additions and 407 deletions.
1 change: 1 addition & 0 deletions builtin/providers/gitlab/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ func Provider() terraform.ResourceProvider {
},
},
ResourcesMap: map[string]*schema.Resource{
"gitlab_group": resourceGitlabGroup(),
"gitlab_project": resourceGitlabProject(),
"gitlab_project_hook": resourceGitlabProjectHook(),
"gitlab_deploy_key": resourceGitlabDeployKey(),
Expand Down
153 changes: 153 additions & 0 deletions builtin/providers/gitlab/resource_gitlab_group.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
package gitlab

import (
"fmt"
"log"

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

func resourceGitlabGroup() *schema.Resource {
return &schema.Resource{
Create: resourceGitlabGroupCreate,
Read: resourceGitlabGroupRead,
Update: resourceGitlabGroupUpdate,
Delete: resourceGitlabGroupDelete,

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
},
"path": {
Type: schema.TypeString,
Required: true,
},
"description": {
Type: schema.TypeString,
Optional: true,
},
"lfs_enabled": {
Type: schema.TypeBool,
Optional: true,
Default: true,
},
"request_access_enabled": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},
"visibility_level": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{"private", "internal", "public"}, true),
Default: "private",
},
},
}
}

func resourceGitlabGroupCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*gitlab.Client)
options := &gitlab.CreateGroupOptions{
Name: gitlab.String(d.Get("name").(string)),
LFSEnabled: gitlab.Bool(d.Get("lfs_enabled").(bool)),
RequestAccessEnabled: gitlab.Bool(d.Get("request_access_enabled").(bool)),
}

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

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

if v, ok := d.GetOk("visibility_level"); ok {
options.VisibilityLevel = stringToVisibilityLevel(v.(string))
}

log.Printf("[DEBUG] create gitlab group %q", options.Name)

group, _, err := client.Groups.CreateGroup(options)
if err != nil {
return err
}

d.SetId(fmt.Sprintf("%d", group.ID))

return resourceGitlabGroupRead(d, meta)
}

func resourceGitlabGroupRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*gitlab.Client)
log.Printf("[DEBUG] read gitlab group %s", d.Id())

group, response, err := client.Groups.GetGroup(d.Id())
if err != nil {
if response.StatusCode == 404 {
log.Printf("[WARN] removing group %s from state because it no longer exists in gitlab", d.Id())
d.SetId("")
return nil
}

return err
}

d.Set("name", group.Name)
d.Set("path", group.Path)
d.Set("description", group.Description)
d.Set("lfs_enabled", group.LFSEnabled)
d.Set("request_access_enabled", group.RequestAccessEnabled)

return nil
}

func resourceGitlabGroupUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*gitlab.Client)

options := &gitlab.UpdateGroupOptions{}

if d.HasChange("name") {
options.Name = gitlab.String(d.Get("name").(string))
}

if d.HasChange("path") {
options.Path = gitlab.String(d.Get("path").(string))
}

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

if d.HasChange("lfs_enabled") {
options.LFSEnabled = gitlab.Bool(d.Get("lfs_enabled").(bool))
}

if d.HasChange("request_access_enabled") {
options.RequestAccessEnabled = gitlab.Bool(d.Get("request_access_enabled").(bool))
}

if d.HasChange("visibility_level") {
options.VisibilityLevel = stringToVisibilityLevel(d.Get("visibility_level").(string))
}

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

_, _, err := client.Groups.UpdateGroup(d.Id(), options)
if err != nil {
return err
}

return resourceGitlabGroupRead(d, meta)
}

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

_, err := client.Groups.DeleteGroup(d.Id())
return err
}
171 changes: 171 additions & 0 deletions builtin/providers/gitlab/resource_gitlab_group_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
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 TestAccGitlabGroup_basic(t *testing.T) {
var group gitlab.Group
rInt := acctest.RandInt()

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckGitlabGroupDestroy,
Steps: []resource.TestStep{
// Create a group
{
Config: testAccGitlabGroupConfig(rInt),
Check: resource.ComposeTestCheckFunc(
testAccCheckGitlabGroupExists("gitlab_group.foo", &group),
testAccCheckGitlabGroupAttributes(&group, &testAccGitlabGroupExpectedAttributes{
Name: fmt.Sprintf("foo-name-%d", rInt),
Path: fmt.Sprintf("foo-path-%d", rInt),
Description: "Terraform acceptance tests",
LFSEnabled: true,
}),
),
},
// Update the group to change the description
{
Config: testAccGitlabGroupUpdateConfig(rInt),
Check: resource.ComposeTestCheckFunc(
testAccCheckGitlabGroupExists("gitlab_group.foo", &group),
testAccCheckGitlabGroupAttributes(&group, &testAccGitlabGroupExpectedAttributes{
Name: fmt.Sprintf("bar-name-%d", rInt),
Path: fmt.Sprintf("bar-path-%d", rInt),
Description: "Terraform acceptance tests! Updated description",
RequestAccessEnabled: true,
}),
),
},
// Update the group to put the anem and description back
{
Config: testAccGitlabGroupConfig(rInt),
Check: resource.ComposeTestCheckFunc(
testAccCheckGitlabGroupExists("gitlab_group.foo", &group),
testAccCheckGitlabGroupAttributes(&group, &testAccGitlabGroupExpectedAttributes{
Name: fmt.Sprintf("foo-name-%d", rInt),
Path: fmt.Sprintf("foo-path-%d", rInt),
Description: "Terraform acceptance tests",
LFSEnabled: true,
}),
),
},
},
})
}

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

groupID := rs.Primary.ID
if groupID == "" {
return fmt.Errorf("No group ID is set")
}
conn := testAccProvider.Meta().(*gitlab.Client)

gotGroup, _, err := conn.Groups.GetGroup(groupID)
if err != nil {
return err
}
*group = *gotGroup
return nil
}
}

type testAccGitlabGroupExpectedAttributes struct {
Name string
Path string
Description string
LFSEnabled bool
RequestAccessEnabled bool
}

func testAccCheckGitlabGroupAttributes(group *gitlab.Group, want *testAccGitlabGroupExpectedAttributes) resource.TestCheckFunc {
return func(s *terraform.State) error {
if group.Name != want.Name {
return fmt.Errorf("got repo %q; want %q", group.Name, want.Name)
}

if group.Path != want.Path {
return fmt.Errorf("got path %q; want %q", group.Path, want.Path)
}

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

if group.LFSEnabled != want.LFSEnabled {
return fmt.Errorf("got lfs_enabled %t; want %t", group.LFSEnabled, want.LFSEnabled)
}

if group.RequestAccessEnabled != want.RequestAccessEnabled {
return fmt.Errorf("got request_access_enabled %t; want %t", group.RequestAccessEnabled, want.RequestAccessEnabled)
}

return nil
}
}

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

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

group, resp, err := conn.Groups.GetGroup(rs.Primary.ID)
if err == nil {
if group != nil && fmt.Sprintf("%d", group.ID) == rs.Primary.ID {
return fmt.Errorf("Group still exists")
}
}
if resp.StatusCode != 404 {
return err
}
return nil
}
return nil
}

func testAccGitlabGroupConfig(rInt int) string {
return fmt.Sprintf(`
resource "gitlab_group" "foo" {
name = "foo-name-%d"
path = "foo-path-%d"
description = "Terraform acceptance tests"
# So that acceptance tests can be run in a gitlab organization
# with no billing
visibility_level = "public"
}
`, rInt, rInt)
}

func testAccGitlabGroupUpdateConfig(rInt int) string {
return fmt.Sprintf(`
resource "gitlab_group" "foo" {
name = "bar-name-%d"
path = "bar-path-%d"
description = "Terraform acceptance tests! Updated description"
lfs_enabled = false
request_access_enabled = true
# So that acceptance tests can be run in a gitlab organization
# with no billing
visibility_level = "public"
}
`, rInt, rInt)
}
1 change: 1 addition & 0 deletions vendor/github.com/xanzy/go-gitlab/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 9e90e77

Please sign in to comment.