Skip to content

Commit ee2810b

Browse files
merge variables from thibault
2 parents a645fe2 + d053338 commit ee2810b

File tree

7 files changed

+342
-1
lines changed

7 files changed

+342
-1
lines changed

gitlab/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ func Provider() terraform.ResourceProvider {
5555
"gitlab_user": resourceGitlabUser(),
5656
"gitlab_project_membership": resourceGitlabProjectMembership(),
5757
"gitlab_group_membership": resourceGitlabGroupMembership(),
58+
"gitlab_project_variable": resourceGitlabProjectVariable(),
5859
},
5960

6061
ConfigureFunc: providerConfigure,
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package gitlab
2+
3+
import (
4+
"log"
5+
6+
"github.com/hashicorp/terraform/helper/schema"
7+
"github.com/xanzy/go-gitlab"
8+
)
9+
10+
func resourceGitlabProjectVariable() *schema.Resource {
11+
return &schema.Resource{
12+
Create: resourceGitlabProjectVariableCreate,
13+
Read: resourceGitlabProjectVariableRead,
14+
Update: resourceGitlabProjectVariableUpdate,
15+
Delete: resourceGitlabProjectVariableDelete,
16+
17+
Schema: map[string]*schema.Schema{
18+
"project": {
19+
Type: schema.TypeString,
20+
Required: true,
21+
},
22+
"key": {
23+
Type: schema.TypeString,
24+
Required: true,
25+
ValidateFunc: StringIsGitlabVariableName(),
26+
},
27+
"value": {
28+
Type: schema.TypeString,
29+
Required: true,
30+
Sensitive: true,
31+
},
32+
"protected": {
33+
Type: schema.TypeBool,
34+
Optional: true,
35+
Default: false,
36+
},
37+
},
38+
}
39+
}
40+
41+
func resourceGitlabProjectVariableCreate(d *schema.ResourceData, meta interface{}) error {
42+
client := meta.(*gitlab.Client)
43+
project := d.Get("project").(string)
44+
key := d.Get("key").(string)
45+
options := &gitlab.CreateBuildVariableOptions{
46+
Key: gitlab.String(key),
47+
Value: gitlab.String(d.Get("value").(string)),
48+
Protected: gitlab.Bool(d.Get("protected").(bool)),
49+
}
50+
log.Printf("[DEBUG] create gitlab project variable %s/%s", project, key)
51+
52+
_, _, err := client.BuildVariables.CreateBuildVariable(project, options)
53+
if err != nil {
54+
return err
55+
}
56+
57+
return resourceGitlabProjectVariableRead(d, meta)
58+
}
59+
60+
func resourceGitlabProjectVariableRead(d *schema.ResourceData, meta interface{}) error {
61+
client := meta.(*gitlab.Client)
62+
project := d.Get("project").(string)
63+
key := d.Get("key").(string)
64+
log.Printf("[DEBUG] read gitlab project variable %s/%s", project, key)
65+
66+
v, _, err := client.BuildVariables.GetBuildVariable(project, key)
67+
if err != nil {
68+
return err
69+
}
70+
71+
d.Set("value", v.Value)
72+
d.Set("protected", v.Protected)
73+
return nil
74+
}
75+
76+
func resourceGitlabProjectVariableUpdate(d *schema.ResourceData, meta interface{}) error {
77+
client := meta.(*gitlab.Client)
78+
project := d.Get("project").(string)
79+
key := d.Get("key").(string)
80+
options := &gitlab.UpdateBuildVariableOptions{
81+
Key: gitlab.String(d.Get("key").(string)),
82+
Value: gitlab.String(d.Get("value").(string)),
83+
Protected: gitlab.Bool(d.Get("protected").(bool)),
84+
}
85+
log.Printf("[DEBUG] update gitlab project variable %s/%s", project, key)
86+
87+
_, _, err := client.BuildVariables.UpdateBuildVariable(project, key, options)
88+
if err != nil {
89+
return err
90+
}
91+
92+
return resourceGitlabProjectVariableRead(d, meta)
93+
}
94+
95+
func resourceGitlabProjectVariableDelete(d *schema.ResourceData, meta interface{}) error {
96+
client := meta.(*gitlab.Client)
97+
project := d.Get("project").(string)
98+
key := d.Get("key").(string)
99+
log.Printf("[DEBUG] Delete gitlab project variable %s/%s", project, key)
100+
101+
_, err := client.BuildVariables.RemoveBuildVariable(project, key)
102+
return err
103+
}
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
package gitlab
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/hashicorp/terraform/helper/acctest"
8+
"github.com/hashicorp/terraform/helper/resource"
9+
"github.com/hashicorp/terraform/terraform"
10+
"github.com/xanzy/go-gitlab"
11+
)
12+
13+
func TestAccGitlabProjectVariable_basic(t *testing.T) {
14+
var projectVariable gitlab.BuildVariable
15+
rString := acctest.RandString(5)
16+
17+
resource.Test(t, resource.TestCase{
18+
PreCheck: func() { testAccPreCheck(t) },
19+
Providers: testAccProviders,
20+
CheckDestroy: testAccCheckGitlabProjectVariableDestroy,
21+
Steps: []resource.TestStep{
22+
// Create a project and variable with default options
23+
{
24+
Config: testAccGitlabProjectVariableConfig(rString),
25+
Check: resource.ComposeTestCheckFunc(
26+
testAccCheckGitlabProjectVariableExists("gitlab_project_variable.foo", &projectVariable),
27+
testAccCheckGitlabProjectVariableAttributes(&projectVariable, &testAccGitlabProjectVariableExpectedAttributes{
28+
Key: fmt.Sprintf("key-%s", rString),
29+
Value: fmt.Sprintf("value-%s", rString),
30+
}),
31+
),
32+
},
33+
// Update the project variable to toggle all the values to their inverse
34+
{
35+
Config: testAccGitlabProjectVariableUpdateConfig(rString),
36+
Check: resource.ComposeTestCheckFunc(
37+
testAccCheckGitlabProjectVariableExists("gitlab_project_variable.foo", &projectVariable),
38+
testAccCheckGitlabProjectVariableAttributes(&projectVariable, &testAccGitlabProjectVariableExpectedAttributes{
39+
Key: fmt.Sprintf("key-%s", rString),
40+
Value: fmt.Sprintf("value-inverse-%s", rString),
41+
Protected: true,
42+
}),
43+
),
44+
},
45+
// Update the project variable to toggle the options back
46+
{
47+
Config: testAccGitlabProjectVariableConfig(rString),
48+
Check: resource.ComposeTestCheckFunc(
49+
testAccCheckGitlabProjectVariableExists("gitlab_project_variable.foo", &projectVariable),
50+
testAccCheckGitlabProjectVariableAttributes(&projectVariable, &testAccGitlabProjectVariableExpectedAttributes{
51+
Key: fmt.Sprintf("key-%s", rString),
52+
Value: fmt.Sprintf("value-%s", rString),
53+
Protected: false,
54+
}),
55+
),
56+
},
57+
},
58+
})
59+
}
60+
61+
func testAccCheckGitlabProjectVariableExists(n string, projectVariable *gitlab.BuildVariable) resource.TestCheckFunc {
62+
return func(s *terraform.State) error {
63+
rs, ok := s.RootModule().Resources[n]
64+
if !ok {
65+
return fmt.Errorf("Not Found: %s", n)
66+
}
67+
68+
repoName := rs.Primary.Attributes["project"]
69+
if repoName == "" {
70+
return fmt.Errorf("No project ID is set")
71+
}
72+
key := rs.Primary.Attributes["key"]
73+
if key == "" {
74+
return fmt.Errorf("No variable key is set")
75+
}
76+
conn := testAccProvider.Meta().(*gitlab.Client)
77+
78+
gotVariable, _, err := conn.BuildVariables.GetBuildVariable(repoName, key)
79+
if err != nil {
80+
return err
81+
}
82+
*projectVariable = *gotVariable
83+
return nil
84+
}
85+
}
86+
87+
type testAccGitlabProjectVariableExpectedAttributes struct {
88+
Key string
89+
Value string
90+
Protected bool
91+
}
92+
93+
func testAccCheckGitlabProjectVariableAttributes(variable *gitlab.BuildVariable, want *testAccGitlabProjectVariableExpectedAttributes) resource.TestCheckFunc {
94+
return func(s *terraform.State) error {
95+
if variable.Key != want.Key {
96+
return fmt.Errorf("got key %s; want %s", variable.Key, want.Key)
97+
}
98+
99+
if variable.Value != want.Value {
100+
return fmt.Errorf("got value %s; value %s", variable.Value, want.Value)
101+
}
102+
103+
if variable.Protected != want.Protected {
104+
return fmt.Errorf("got protected %t; want %t", variable.Protected, want.Protected)
105+
}
106+
107+
return nil
108+
}
109+
}
110+
111+
func testAccCheckGitlabProjectVariableDestroy(s *terraform.State) error {
112+
conn := testAccProvider.Meta().(*gitlab.Client)
113+
114+
for _, rs := range s.RootModule().Resources {
115+
if rs.Type != "gitlab_project" {
116+
continue
117+
}
118+
119+
gotRepo, resp, err := conn.Projects.GetProject(rs.Primary.ID)
120+
if err == nil {
121+
if gotRepo != nil && fmt.Sprintf("%d", gotRepo.ID) == rs.Primary.ID {
122+
return fmt.Errorf("Repository still exists")
123+
}
124+
}
125+
if resp.StatusCode != 404 {
126+
return err
127+
}
128+
return nil
129+
}
130+
return nil
131+
}
132+
133+
func testAccGitlabProjectVariableConfig(rString string) string {
134+
return fmt.Sprintf(`
135+
resource "gitlab_project" "foo" {
136+
name = "foo-%s"
137+
description = "Terraform acceptance tests"
138+
139+
# So that acceptance tests can be run in a gitlab organization
140+
# with no billing
141+
visibility_level = "public"
142+
}
143+
144+
resource "gitlab_project_variable" "foo" {
145+
project = "${gitlab_project.foo.id}"
146+
key = "key-%s"
147+
value = "value-%s"
148+
}
149+
`, rString, rString, rString)
150+
}
151+
152+
func testAccGitlabProjectVariableUpdateConfig(rString string) string {
153+
return fmt.Sprintf(`
154+
resource "gitlab_project" "foo" {
155+
name = "foo-%s"
156+
description = "Terraform acceptance tests"
157+
158+
# So that acceptance tests can be run in a gitlab organization
159+
# with no billing
160+
visibility_level = "public"
161+
}
162+
163+
resource "gitlab_project_variable" "foo" {
164+
project = "${gitlab_project.foo.id}"
165+
key = "key-%s"
166+
value = "value-%s"
167+
protected = true
168+
}
169+
`, rString, rString, rString)
170+
}

gitlab/util.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import (
44
"fmt"
55

66
"github.com/hashicorp/terraform/helper/schema"
7-
gitlab "github.com/xanzy/go-gitlab"
7+
"github.com/xanzy/go-gitlab"
8+
"regexp"
89
)
910

1011
// copied from ../github/util.go
@@ -39,3 +40,22 @@ func stringToVisibilityLevel(s string) *gitlab.VisibilityValue {
3940
}
4041
return &value
4142
}
43+
44+
func StringIsGitlabVariableName() schema.SchemaValidateFunc {
45+
return func(v interface{}, k string) (s []string, es []error) {
46+
value, ok := v.(string)
47+
if !ok {
48+
es = append(es, fmt.Errorf("expected type of %s to be string", k))
49+
return
50+
}
51+
if len(value) < 1 || len(value) > 255 {
52+
es = append(es, fmt.Errorf("expected length of %s to be in the range (%d - %d), got %s", k, 1, 255, v))
53+
}
54+
55+
match, _ := regexp.MatchString("[a-zA-Z0-9_]+", value)
56+
if !match {
57+
es = append(es, fmt.Errorf("%s is an invalid value for argument %s. Only A-Z, a-z, 0-9, and _ are allowed", value, k))
58+
}
59+
return
60+
}
61+
}

website/docs/index.html.markdown

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ resource "gitlab_project_hook" "sample_project_hook" {
3333
url = "https://example.com/project_hook"
3434
}
3535
36+
# Add a variable to the project
37+
resource "gitlab_project_variable" "sample_project_variable" {
38+
project = "${gitlab_project.sample_project.id}"
39+
key = "project_variable_key"
40+
value = "project_variable_value"
41+
}
42+
3643
# Add a deploy key to the project
3744
resource "gitlab_deploy_key" "sample_deploy_key" {
3845
project = "${gitlab_project.sample_project.id}"
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
---
2+
layout: "gitlab"
3+
page_title: "GitLab: gitlab_project_variable"
4+
sidebar_current: "docs-gitlab-resource-project-variable"
5+
description: |-
6+
Creates and manages CI/CD variables for GitLab projects
7+
---
8+
9+
# gitlab\_project\_variable
10+
11+
This resource allows you to create and manage CI/CD variables for your GitLab projects.
12+
For further information on variables, consult the [gitlab
13+
documentation](https://docs.gitlab.com/ce/ci/variables/README.html).
14+
15+
16+
## Example Usage
17+
18+
```hcl
19+
resource "gitlab_project_variable" "example" {
20+
project = "example/project_with_variables"
21+
key = "project_variable_key"
22+
value = "project_variable_value"
23+
protected = false
24+
}
25+
```
26+
27+
## Argument Reference
28+
29+
The following arguments are supported:
30+
31+
* `project` - (Required, string) The name or id of the project to add the hook to.
32+
33+
* `key` - (Required, string) The name of the variable.
34+
35+
* `value` - (Required, string) The value of the variable.
36+
37+
* `protected` - (Optional, boolean) If set to `true`, the variable will be passed only to pipelines running on protected branches and tags. Defaults to `false`.

website/gitlab.erb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@
4646
<li<%= sidebar_current("docs-gitlab-resource-user") %>>
4747
<a href="/docs/providers/gitlab/r/user.html">gitlab_user</a>
4848
</li>
49+
<li<%= sidebar_current("docs-gitlab-resource-project-variable") %>>
50+
<a href="/docs/providers/gitlab/r/project_variable.html">gitlab_project_variable</a>
51+
</li>
4952
</ul>
5053
</li>
5154
</ul>

0 commit comments

Comments
 (0)