provider/gitlab: add gitlab provider and `gitlab_project` resource
Here we add a basic provider with a single resource type. It's copied heavily from the `github` provider and `github_repository` resource, as there is some overlap in those types/apis. ~~~ resource "gitlab_project" "test1" { name = "test1" visibility_level = "public" } ~~~ We implement in terms of the [go-gitlab](https://github.com/xanzy/go-gitlab) library, which provides a wrapping of the [gitlab api](https://docs.gitlab.com/ee/api/) We have been a little selective in the properties we surface for the project resource, as not all properties are very instructive. Notable is the removal of the `public` bool as the `visibility_level` will take precedent if both are supplied which leads to confusing interactions if they disagree.
This commit is contained in:
parent
1a21a388f5
commit
631b0b865c
|
@ -0,0 +1,12 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hashicorp/terraform/builtin/providers/gitlab"
|
||||||
|
"github.com/hashicorp/terraform/plugin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
plugin.Serve(&plugin.ServeOpts{
|
||||||
|
ProviderFunc: gitlab.Provider,
|
||||||
|
})
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package gitlab
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/xanzy/go-gitlab"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Config is per-provider, specifies where to connect to gitlab
|
||||||
|
type Config struct {
|
||||||
|
Token string
|
||||||
|
BaseURL string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Client returns a *gitlab.Client to interact with the configured gitlab instance
|
||||||
|
func (c *Config) Client() (interface{}, error) {
|
||||||
|
client := gitlab.NewClient(nil, c.Token)
|
||||||
|
if c.BaseURL != "" {
|
||||||
|
err := client.SetBaseURL(c.BaseURL)
|
||||||
|
if err != nil {
|
||||||
|
// The BaseURL supplied wasn't valid, bail.
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test the credentials by checking we can get information about the authenticated user.
|
||||||
|
_, _, err := client.Users.CurrentUser()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return client, nil
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package gitlab
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Provider returns a terraform.ResourceProvider.
|
||||||
|
func Provider() terraform.ResourceProvider {
|
||||||
|
|
||||||
|
// The actual provider
|
||||||
|
return &schema.Provider{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"token": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
DefaultFunc: schema.EnvDefaultFunc("GITLAB_TOKEN", nil),
|
||||||
|
Description: descriptions["token"],
|
||||||
|
},
|
||||||
|
"base_url": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
DefaultFunc: schema.EnvDefaultFunc("GITLAB_BASE_URL", ""),
|
||||||
|
Description: descriptions["base_url"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ResourcesMap: map[string]*schema.Resource{
|
||||||
|
"gitlab_project": resourceGitlabProject(),
|
||||||
|
},
|
||||||
|
|
||||||
|
ConfigureFunc: providerConfigure,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var descriptions map[string]string
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
descriptions = map[string]string{
|
||||||
|
"token": "The OAuth token used to connect to GitLab.",
|
||||||
|
|
||||||
|
"base_url": "The GitLab Base API URL",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func providerConfigure(d *schema.ResourceData) (interface{}, error) {
|
||||||
|
config := Config{
|
||||||
|
Token: d.Get("token").(string),
|
||||||
|
BaseURL: d.Get("base_url").(string),
|
||||||
|
}
|
||||||
|
|
||||||
|
return config.Client()
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package gitlab
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
)
|
||||||
|
|
||||||
|
var testAccProviders map[string]terraform.ResourceProvider
|
||||||
|
var testAccProvider *schema.Provider
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
testAccProvider = Provider().(*schema.Provider)
|
||||||
|
testAccProviders = map[string]terraform.ResourceProvider{
|
||||||
|
"gitlab": testAccProvider,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestProvider(t *testing.T) {
|
||||||
|
if err := Provider().(*schema.Provider).InternalValidate(); err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestProvider_impl(t *testing.T) {
|
||||||
|
var _ terraform.ResourceProvider = Provider()
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccPreCheck(t *testing.T) {
|
||||||
|
if v := os.Getenv("GITLAB_TOKEN"); v == "" {
|
||||||
|
t.Fatal("GITLAB_TOKEN must be set for acceptance tests")
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,207 @@
|
||||||
|
package gitlab
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
gitlab "github.com/xanzy/go-gitlab"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceGitlabProject() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: resourceGitlabProjectCreate,
|
||||||
|
Read: resourceGitlabProjectRead,
|
||||||
|
Update: resourceGitlabProjectUpdate,
|
||||||
|
Delete: resourceGitlabProjectDelete,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"description": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
"default_branch": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
"issues_enabled": &schema.Schema{
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Default: true,
|
||||||
|
},
|
||||||
|
"merge_requests_enabled": &schema.Schema{
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Default: true,
|
||||||
|
},
|
||||||
|
"wiki_enabled": &schema.Schema{
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Default: true,
|
||||||
|
},
|
||||||
|
"snippets_enabled": &schema.Schema{
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Default: true,
|
||||||
|
},
|
||||||
|
"visibility_level": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ValidateFunc: validateValueFunc([]string{"private", "internal", "public"}),
|
||||||
|
Default: "private",
|
||||||
|
},
|
||||||
|
|
||||||
|
"ssh_url_to_repo": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"http_url_to_repo": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"web_url": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceGitlabProjectUpdateFromAPI(d *schema.ResourceData, project *gitlab.Project) {
|
||||||
|
d.Set("name", project.Name)
|
||||||
|
d.Set("description", project.Description)
|
||||||
|
d.Set("default_branch", project.DefaultBranch)
|
||||||
|
d.Set("issues_enabled", project.IssuesEnabled)
|
||||||
|
d.Set("merge_requests_enabled", project.MergeRequestsEnabled)
|
||||||
|
d.Set("wiki_enabled", project.WikiEnabled)
|
||||||
|
d.Set("snippets_enabled", project.SnippetsEnabled)
|
||||||
|
d.Set("visibility_level", visibilityLevelToString(project.VisibilityLevel))
|
||||||
|
|
||||||
|
d.Set("ssh_url_to_repo", project.SSHURLToRepo)
|
||||||
|
d.Set("http_url_to_repo", project.HTTPURLToRepo)
|
||||||
|
d.Set("web_url", project.WebURL)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceGitlabProjectCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
client := meta.(*gitlab.Client)
|
||||||
|
options := &gitlab.CreateProjectOptions{
|
||||||
|
Name: gitlab.String(d.Get("name").(string)),
|
||||||
|
}
|
||||||
|
|
||||||
|
if v, ok := d.GetOk("description"); ok {
|
||||||
|
options.Description = gitlab.String(v.(string))
|
||||||
|
}
|
||||||
|
|
||||||
|
if v, ok := d.GetOk("issues_enabled"); ok {
|
||||||
|
options.IssuesEnabled = gitlab.Bool(v.(bool))
|
||||||
|
}
|
||||||
|
|
||||||
|
if v, ok := d.GetOk("merge_requests_enabled"); ok {
|
||||||
|
options.MergeRequestsEnabled = gitlab.Bool(v.(bool))
|
||||||
|
}
|
||||||
|
|
||||||
|
if v, ok := d.GetOk("wiki_enabled"); ok {
|
||||||
|
options.WikiEnabled = gitlab.Bool(v.(bool))
|
||||||
|
}
|
||||||
|
|
||||||
|
if v, ok := d.GetOk("snippets_enabled"); ok {
|
||||||
|
options.SnippetsEnabled = gitlab.Bool(v.(bool))
|
||||||
|
}
|
||||||
|
|
||||||
|
if v, ok := d.GetOk("visibility_level"); ok {
|
||||||
|
options.VisibilityLevel = stringToVisibilityLevel(v.(string))
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] create gitlab project %q", options.Name)
|
||||||
|
|
||||||
|
project, _, err := client.Projects.CreateProject(options)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(fmt.Sprintf("%d", project.ID))
|
||||||
|
|
||||||
|
resourceGitlabProjectUpdateFromAPI(d, project)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceGitlabProjectRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
client := meta.(*gitlab.Client)
|
||||||
|
log.Printf("[DEBUG] read gitlab project %s", d.Id())
|
||||||
|
|
||||||
|
project, response, err := client.Projects.GetProject(d.Id())
|
||||||
|
if err != nil {
|
||||||
|
if response.StatusCode == 404 {
|
||||||
|
log.Printf("[WARN] removing project %s from state because it no longer exists in gitlab", d.Id())
|
||||||
|
d.SetId("")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
resourceGitlabProjectUpdateFromAPI(d, project)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceGitlabProjectUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
client := meta.(*gitlab.Client)
|
||||||
|
|
||||||
|
options := &gitlab.EditProjectOptions{}
|
||||||
|
|
||||||
|
if d.HasChange("name") {
|
||||||
|
options.Name = gitlab.String(d.Get("name").(string))
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.HasChange("description") {
|
||||||
|
options.Description = gitlab.String(d.Get("description").(string))
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.HasChange("default_branch") {
|
||||||
|
options.DefaultBranch = gitlab.String(d.Get("description").(string))
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.HasChange("visibility_level") {
|
||||||
|
options.VisibilityLevel = stringToVisibilityLevel(d.Get("visibility_level").(string))
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.HasChange("issues_enabled") {
|
||||||
|
options.IssuesEnabled = gitlab.Bool(d.Get("issues_enabled").(bool))
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.HasChange("merge_requests_enabled") {
|
||||||
|
options.MergeRequestsEnabled = gitlab.Bool(d.Get("merge_requests_enabled").(bool))
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.HasChange("wiki_enabled") {
|
||||||
|
options.WikiEnabled = gitlab.Bool(d.Get("wiki_enabled").(bool))
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.HasChange("snippets_enabled") {
|
||||||
|
options.SnippetsEnabled = gitlab.Bool(d.Get("snippets_enabled").(bool))
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] update gitlab project %s", d.Id())
|
||||||
|
|
||||||
|
project, _, err := client.Projects.EditProject(d.Id(), options)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
resourceGitlabProjectUpdateFromAPI(d, project)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceGitlabProjectDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
client := meta.(*gitlab.Client)
|
||||||
|
log.Printf("[DEBUG] update gitlab project %s", d.Id())
|
||||||
|
|
||||||
|
_, err := client.Projects.DeleteProject(d.Id())
|
||||||
|
return err
|
||||||
|
}
|
|
@ -0,0 +1,185 @@
|
||||||
|
package gitlab
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
"github.com/xanzy/go-gitlab"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccGitlabProject_basic(t *testing.T) {
|
||||||
|
var project gitlab.Project
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckGitlabProjectDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
// Create a project with all the features on
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccGitlabProjectConfig,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckGitlabProjectExists("gitlab_project.foo", &project),
|
||||||
|
testAccCheckGitlabProjectAttributes(&project, &testAccGitlabProjectExpectedAttributes{
|
||||||
|
Name: "foo",
|
||||||
|
Description: "Terraform acceptance tests",
|
||||||
|
IssuesEnabled: true,
|
||||||
|
MergeRequestsEnabled: true,
|
||||||
|
WikiEnabled: true,
|
||||||
|
SnippetsEnabled: true,
|
||||||
|
VisibilityLevel: 20,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
// Update the project to turn the features off
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccGitlabProjectUpdateConfig,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckGitlabProjectExists("gitlab_project.foo", &project),
|
||||||
|
testAccCheckGitlabProjectAttributes(&project, &testAccGitlabProjectExpectedAttributes{
|
||||||
|
Name: "foo",
|
||||||
|
Description: "Terraform acceptance tests!",
|
||||||
|
VisibilityLevel: 20,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
// Update the project to turn the features on again
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccGitlabProjectConfig,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckGitlabProjectExists("gitlab_project.foo", &project),
|
||||||
|
testAccCheckGitlabProjectAttributes(&project, &testAccGitlabProjectExpectedAttributes{
|
||||||
|
Name: "foo",
|
||||||
|
Description: "Terraform acceptance tests",
|
||||||
|
IssuesEnabled: true,
|
||||||
|
MergeRequestsEnabled: true,
|
||||||
|
WikiEnabled: true,
|
||||||
|
SnippetsEnabled: true,
|
||||||
|
VisibilityLevel: 20,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckGitlabProjectExists(n string, project *gitlab.Project) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
rs, ok := s.RootModule().Resources[n]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Not Found: %s", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
repoName := rs.Primary.ID
|
||||||
|
if repoName == "" {
|
||||||
|
return fmt.Errorf("No project ID is set")
|
||||||
|
}
|
||||||
|
conn := testAccProvider.Meta().(*gitlab.Client)
|
||||||
|
|
||||||
|
gotProject, _, err := conn.Projects.GetProject(repoName)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*project = *gotProject
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type testAccGitlabProjectExpectedAttributes struct {
|
||||||
|
Name string
|
||||||
|
Description string
|
||||||
|
DefaultBranch string
|
||||||
|
IssuesEnabled bool
|
||||||
|
MergeRequestsEnabled bool
|
||||||
|
WikiEnabled bool
|
||||||
|
SnippetsEnabled bool
|
||||||
|
VisibilityLevel gitlab.VisibilityLevelValue
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckGitlabProjectAttributes(project *gitlab.Project, want *testAccGitlabProjectExpectedAttributes) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
if project.Name != want.Name {
|
||||||
|
return fmt.Errorf("got repo %q; want %q", project.Name, want.Name)
|
||||||
|
}
|
||||||
|
if project.Description != want.Description {
|
||||||
|
return fmt.Errorf("got description %q; want %q", project.Description, want.Description)
|
||||||
|
}
|
||||||
|
|
||||||
|
if project.DefaultBranch != want.DefaultBranch {
|
||||||
|
return fmt.Errorf("got default_branch %q; want %q", project.DefaultBranch, want.DefaultBranch)
|
||||||
|
}
|
||||||
|
|
||||||
|
if project.IssuesEnabled != want.IssuesEnabled {
|
||||||
|
return fmt.Errorf("got issues_enabled %t; want %t", project.IssuesEnabled, want.IssuesEnabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
if project.MergeRequestsEnabled != want.MergeRequestsEnabled {
|
||||||
|
return fmt.Errorf("got merge_requests_enabled %t; want %t", project.MergeRequestsEnabled, want.MergeRequestsEnabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
if project.WikiEnabled != want.WikiEnabled {
|
||||||
|
return fmt.Errorf("got wiki_enabled %t; want %t", project.WikiEnabled, want.WikiEnabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
if project.SnippetsEnabled != want.SnippetsEnabled {
|
||||||
|
return fmt.Errorf("got snippets_enabled %t; want %t", project.SnippetsEnabled, want.SnippetsEnabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
if project.VisibilityLevel != want.VisibilityLevel {
|
||||||
|
return fmt.Errorf("got default branch %q; want %q", project.VisibilityLevel, want.VisibilityLevel)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckGitlabProjectDestroy(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
|
||||||
|
}
|
||||||
|
|
||||||
|
const testAccGitlabProjectConfig = `
|
||||||
|
resource "gitlab_project" "foo" {
|
||||||
|
name = "foo"
|
||||||
|
description = "Terraform acceptance tests"
|
||||||
|
|
||||||
|
# So that acceptance tests can be run in a gitlab organization
|
||||||
|
# with no billing
|
||||||
|
visibility_level = "public"
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const testAccGitlabProjectUpdateConfig = `
|
||||||
|
resource "gitlab_project" "foo" {
|
||||||
|
name = "foo"
|
||||||
|
description = "Terraform acceptance tests!"
|
||||||
|
|
||||||
|
# So that acceptance tests can be run in a gitlab organization
|
||||||
|
# with no billing
|
||||||
|
visibility_level = "public"
|
||||||
|
|
||||||
|
issues_enabled = false
|
||||||
|
merge_requests_enabled = false
|
||||||
|
wiki_enabled = false
|
||||||
|
snippets_enabled = false
|
||||||
|
}
|
||||||
|
`
|
|
@ -0,0 +1,54 @@
|
||||||
|
package gitlab
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
gitlab "github.com/xanzy/go-gitlab"
|
||||||
|
)
|
||||||
|
|
||||||
|
// copied from ../github/util.go
|
||||||
|
func validateValueFunc(values []string) schema.SchemaValidateFunc {
|
||||||
|
return func(v interface{}, k string) (we []string, errors []error) {
|
||||||
|
value := v.(string)
|
||||||
|
valid := false
|
||||||
|
for _, role := range values {
|
||||||
|
if value == role {
|
||||||
|
valid = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !valid {
|
||||||
|
errors = append(errors, fmt.Errorf("%s is an invalid value for argument %s", value, k))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func stringToVisibilityLevel(s string) *gitlab.VisibilityLevelValue {
|
||||||
|
lookup := map[string]gitlab.VisibilityLevelValue{
|
||||||
|
"private": gitlab.PrivateVisibility,
|
||||||
|
"internal": gitlab.InternalVisibility,
|
||||||
|
"public": gitlab.PublicVisibility,
|
||||||
|
}
|
||||||
|
|
||||||
|
value, ok := lookup[s]
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &value
|
||||||
|
}
|
||||||
|
|
||||||
|
func visibilityLevelToString(v gitlab.VisibilityLevelValue) *string {
|
||||||
|
lookup := map[gitlab.VisibilityLevelValue]string{
|
||||||
|
gitlab.PrivateVisibility: "private",
|
||||||
|
gitlab.InternalVisibility: "internal",
|
||||||
|
gitlab.PublicVisibility: "public",
|
||||||
|
}
|
||||||
|
value, ok := lookup[v]
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &value
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
package gitlab
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/xanzy/go-gitlab"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGitlab_validation(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
Value string
|
||||||
|
ErrCount int
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Value: "invalid",
|
||||||
|
ErrCount: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Value: "valid_one",
|
||||||
|
ErrCount: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Value: "valid_two",
|
||||||
|
ErrCount: 0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
validationFunc := validateValueFunc([]string{"valid_one", "valid_two"})
|
||||||
|
|
||||||
|
for _, tc := range cases {
|
||||||
|
_, errors := validationFunc(tc.Value, "test_arg")
|
||||||
|
|
||||||
|
if len(errors) != tc.ErrCount {
|
||||||
|
t.Fatalf("Expected 1 validation error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGitlab_visbilityHelpers(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
String string
|
||||||
|
Level gitlab.VisibilityLevelValue
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
String: "private",
|
||||||
|
Level: gitlab.PrivateVisibility,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
String: "public",
|
||||||
|
Level: gitlab.PublicVisibility,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range cases {
|
||||||
|
level := stringToVisibilityLevel(tc.String)
|
||||||
|
if level == nil || *level != tc.Level {
|
||||||
|
t.Fatalf("got %v expected %v", level, tc.Level)
|
||||||
|
}
|
||||||
|
|
||||||
|
sv := visibilityLevelToString(tc.Level)
|
||||||
|
if sv == nil || *sv != tc.String {
|
||||||
|
t.Fatalf("got %v expected %v", sv, tc.String)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,6 +31,7 @@ import (
|
||||||
externalprovider "github.com/hashicorp/terraform/builtin/providers/external"
|
externalprovider "github.com/hashicorp/terraform/builtin/providers/external"
|
||||||
fastlyprovider "github.com/hashicorp/terraform/builtin/providers/fastly"
|
fastlyprovider "github.com/hashicorp/terraform/builtin/providers/fastly"
|
||||||
githubprovider "github.com/hashicorp/terraform/builtin/providers/github"
|
githubprovider "github.com/hashicorp/terraform/builtin/providers/github"
|
||||||
|
gitlabprovider "github.com/hashicorp/terraform/builtin/providers/gitlab"
|
||||||
googleprovider "github.com/hashicorp/terraform/builtin/providers/google"
|
googleprovider "github.com/hashicorp/terraform/builtin/providers/google"
|
||||||
grafanaprovider "github.com/hashicorp/terraform/builtin/providers/grafana"
|
grafanaprovider "github.com/hashicorp/terraform/builtin/providers/grafana"
|
||||||
herokuprovider "github.com/hashicorp/terraform/builtin/providers/heroku"
|
herokuprovider "github.com/hashicorp/terraform/builtin/providers/heroku"
|
||||||
|
@ -107,6 +108,7 @@ var InternalProviders = map[string]plugin.ProviderFunc{
|
||||||
"external": externalprovider.Provider,
|
"external": externalprovider.Provider,
|
||||||
"fastly": fastlyprovider.Provider,
|
"fastly": fastlyprovider.Provider,
|
||||||
"github": githubprovider.Provider,
|
"github": githubprovider.Provider,
|
||||||
|
"gitlab": gitlabprovider.Provider,
|
||||||
"google": googleprovider.Provider,
|
"google": googleprovider.Provider,
|
||||||
"grafana": grafanaprovider.Provider,
|
"grafana": grafanaprovider.Provider,
|
||||||
"heroku": herokuprovider.Provider,
|
"heroku": herokuprovider.Provider,
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
---
|
||||||
|
layout: "gitlab"
|
||||||
|
page_title: "Provider: GitLab"
|
||||||
|
sidebar_current: "docs-gitlab-index"
|
||||||
|
description: |-
|
||||||
|
The GitLab provider is used to interact with GitLab organization resources.
|
||||||
|
---
|
||||||
|
|
||||||
|
# GitLab Provider
|
||||||
|
|
||||||
|
The GitLab provider is used to interact with GitLab organization resources.
|
||||||
|
|
||||||
|
The provider allows you to manage your GitLab organization's members and teams easily.
|
||||||
|
It needs to be configured with the proper credentials before it can be used.
|
||||||
|
|
||||||
|
Use the navigation to the left to read about the available resources.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
# Configure the GitLab Provider
|
||||||
|
provider "gitlab" {
|
||||||
|
token = "${var.github_token}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add a project to the organization
|
||||||
|
resource "gitlab_project" "sample_project" {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported in the `provider` block:
|
||||||
|
|
||||||
|
* `token` - (Optional) This is the GitLab personal access token. It must be provided, but
|
||||||
|
it can also be sourced from the `GITLAB_TOKEN` environment variable.
|
||||||
|
|
||||||
|
* `base_url` - (Optional) This is the target GitLab base API endpoint. Providing a value is a
|
||||||
|
requirement when working with GitLab CE or GitLab Enterprise. It is optional to provide this value and
|
||||||
|
it can also be sourced from the `GITLAB_BASE_URL` environment variable. The value must end with a slash.
|
|
@ -0,0 +1,58 @@
|
||||||
|
---
|
||||||
|
layout: "gitlab"
|
||||||
|
page_title: "GitLab: gitlab_project"
|
||||||
|
sidebar_current: "docs-gitlab-resource-project"
|
||||||
|
description: |-
|
||||||
|
Creates and manages projects within Github organizations
|
||||||
|
---
|
||||||
|
|
||||||
|
# gitlab\_project
|
||||||
|
|
||||||
|
This resource allows you to create and manage projects within your
|
||||||
|
GitLab organization.
|
||||||
|
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
resource "gitlab_repository" "example" {
|
||||||
|
name = "example"
|
||||||
|
description = "My awesome codebase"
|
||||||
|
|
||||||
|
visbility_level = "public"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `name` - (Required) The name of the project.
|
||||||
|
|
||||||
|
* `description` - (Optional) A description of the project.
|
||||||
|
|
||||||
|
* `default_branch` - (Optional) The default branch for the project.
|
||||||
|
|
||||||
|
* `issues_enabled` - (Optional) Enable issue tracking for the project.
|
||||||
|
|
||||||
|
* `merge_requests_enabled` - (Optional) Enable merge requests for the project.
|
||||||
|
|
||||||
|
* `wiki_enabled` - (Optional) Enable wiki for the project.
|
||||||
|
|
||||||
|
* `snippets_enabled` - (Optional) Enable snippets for the project.
|
||||||
|
|
||||||
|
* `visbility_level` - (Optional) Set to `public` to create a public project.
|
||||||
|
Valid values are `private`, `internal`, `public`.
|
||||||
|
Repositories are created as private by default.
|
||||||
|
|
||||||
|
## Attributes Reference
|
||||||
|
|
||||||
|
The following additional attributes are exported:
|
||||||
|
|
||||||
|
* `ssh_url_to_repo` - URL that can be provided to `git clone` to clone the
|
||||||
|
repository via SSH.
|
||||||
|
|
||||||
|
* `http_url_to_repo` - URL that can be provided to `git clone` to clone the
|
||||||
|
repository via HTTP.
|
||||||
|
|
||||||
|
* `web_url` - URL that can be used to find the project in a browser.
|
Loading…
Reference in New Issue