Skip to content

Commit 240918b

Browse files
committed
Adding project miorror and tests
1 parent 1ed76d5 commit 240918b

File tree

3 files changed

+390
-0
lines changed

3 files changed

+390
-0
lines changed

gitlab/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ func Provider() terraform.ResourceProvider {
8888
"gitlab_project_share_group": resourceGitlabProjectShareGroup(),
8989
"gitlab_group_cluster": resourceGitlabGroupCluster(),
9090
"gitlab_group_ldap_link": resourceGitlabGroupLdapLink(),
91+
"gitlab_project_mirror": resourceGitlabProjectMirror(),
9192
},
9293

9394
ConfigureFunc: providerConfigure,
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
package gitlab
2+
3+
import (
4+
"log"
5+
"strconv"
6+
"strings"
7+
8+
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
9+
"github.com/xanzy/go-gitlab"
10+
)
11+
12+
func resourceGitlabProjectMirror() *schema.Resource {
13+
return &schema.Resource{
14+
Create: resourceGitlabMirrorCreate,
15+
Read: resourceGitlabProjectMirrorRead,
16+
Update: resourceGitlabMirrorUpdate,
17+
Delete: resourceGitlabMirrorDelete,
18+
Importer: &schema.ResourceImporter{
19+
State: schema.ImportStatePassthrough,
20+
},
21+
22+
Schema: map[string]*schema.Schema{
23+
"project": {
24+
Type: schema.TypeString,
25+
ForceNew: true,
26+
Required: true,
27+
},
28+
"mirror_id": {
29+
Type: schema.TypeInt,
30+
Computed: true,
31+
},
32+
"url": {
33+
Type: schema.TypeString,
34+
ForceNew: true,
35+
Required: true,
36+
},
37+
"enabled": {
38+
Type: schema.TypeBool,
39+
Optional: true,
40+
Default: true,
41+
},
42+
"only_protected_branches": {
43+
Type: schema.TypeBool,
44+
Optional: true,
45+
Default: true,
46+
},
47+
"keep_divergent_refs": {
48+
Type: schema.TypeBool,
49+
Optional: true,
50+
Default: true,
51+
},
52+
},
53+
}
54+
}
55+
56+
func resourceGitlabMirrorCreate(d *schema.ResourceData, meta interface{}) error {
57+
client := meta.(*gitlab.Client)
58+
59+
projectID := d.Get("project").(string)
60+
URL := d.Get("url").(string)
61+
enabled := d.Get("enabled").(bool)
62+
onlyProtectedBranches := d.Get("only_protected_branches").(bool)
63+
keepDivergentRefs := d.Get("keep_divergent_refs").(bool)
64+
65+
options := &gitlab.AddProjectMirrorOptions{
66+
URL: &URL,
67+
Enabled: &enabled,
68+
OnlyProtectedBranches: &onlyProtectedBranches,
69+
KeepDivergentRefs: &keepDivergentRefs,
70+
}
71+
72+
log.Printf("[DEBUG] create gitlab project mirror for project %v", projectID)
73+
74+
mirror, _, err := client.ProjectMirrors.AddProjectMirror(projectID, options)
75+
if err != nil {
76+
return err
77+
}
78+
d.Set("mirror_id", mirror.ID)
79+
80+
mirrorID := strconv.Itoa(mirror.ID)
81+
d.SetId(buildTwoPartID(&projectID, &mirrorID))
82+
return resourceGitlabProjectMirrorRead(d, meta)
83+
}
84+
85+
func resourceGitlabMirrorUpdate(d *schema.ResourceData, meta interface{}) error {
86+
client := meta.(*gitlab.Client)
87+
88+
mirrorID := d.Get("mirror_id").(int)
89+
projectID := d.Get("project").(string)
90+
enabled := d.Get("enabled").(bool)
91+
onlyProtectedBranches := d.Get("only_protected_branches").(bool)
92+
keepDivergentRefs := d.Get("keep_divergent_refs").(bool)
93+
94+
options := gitlab.EditProjectMirrorOptions{
95+
Enabled: &enabled,
96+
OnlyProtectedBranches: &onlyProtectedBranches,
97+
KeepDivergentRefs: &keepDivergentRefs,
98+
}
99+
log.Printf("[DEBUG] update gitlab project mirror %v for %s", mirrorID, projectID)
100+
101+
_, _, err := client.ProjectMirrors.EditProjectMirror(projectID, mirrorID, &options)
102+
if err != nil {
103+
return err
104+
}
105+
return resourceGitlabProjectMirrorRead(d, meta)
106+
}
107+
108+
// Documented remote mirrors API does not support a delete method, instead mirror is disabled.
109+
func resourceGitlabMirrorDelete(d *schema.ResourceData, meta interface{}) error {
110+
client := meta.(*gitlab.Client)
111+
112+
enabled := false
113+
114+
mirrorID := d.Get("mirror_id").(int)
115+
projectID := d.Get("project").(string)
116+
onlyProtectedBranches := d.Get("only_protected_branches").(bool)
117+
keepDivergentRefs := d.Get("keep_divergent_refs").(bool)
118+
119+
options := gitlab.EditProjectMirrorOptions{
120+
Enabled: &enabled,
121+
OnlyProtectedBranches: &onlyProtectedBranches,
122+
KeepDivergentRefs: &keepDivergentRefs,
123+
}
124+
log.Printf("[DEBUG] Disable gitlab project mirror %v for %s", mirrorID, projectID)
125+
126+
_, _, err := client.ProjectMirrors.EditProjectMirror(projectID, mirrorID, &options)
127+
128+
return err
129+
}
130+
131+
func resourceGitlabProjectMirrorRead(d *schema.ResourceData, meta interface{}) error {
132+
client := meta.(*gitlab.Client)
133+
134+
ids := strings.Split(d.Id(), ":")
135+
projectID := ids[0]
136+
mirrorID := ids[1]
137+
integerMirrorID, err := strconv.Atoi(mirrorID)
138+
if err != nil {
139+
return err
140+
}
141+
log.Printf("[DEBUG] read gitlab project mirror %s id %v", projectID, mirrorID)
142+
143+
mirrors, _, err := client.ProjectMirrors.ListProjectMirror(projectID)
144+
145+
if err != nil {
146+
return err
147+
}
148+
149+
var mirror *gitlab.ProjectMirror
150+
found := false
151+
152+
for _, m := range mirrors {
153+
log.Printf("[DEBUG] project mirror found %v", m.ID)
154+
if m.ID == integerMirrorID {
155+
mirror = m
156+
found = true
157+
}
158+
}
159+
160+
if !found {
161+
d.SetId("")
162+
return nil
163+
}
164+
165+
resourceGitlabProjectMirrorSetToState(d, mirror, &projectID)
166+
return nil
167+
}
168+
169+
func resourceGitlabProjectMirrorSetToState(d *schema.ResourceData, projectMirror *gitlab.ProjectMirror, projectID *string) {
170+
171+
mirrorID := strconv.Itoa(projectMirror.ID)
172+
d.Set("enabled", projectMirror.Enabled)
173+
d.Set("only_protected_branches", projectMirror.OnlyProtectedBranches)
174+
d.Set("keep_divergent_refs", projectMirror.KeepDivergentRefs)
175+
d.SetId(buildTwoPartID(projectID, &mirrorID))
176+
}
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
package gitlab
2+
3+
// TODO convert to handle project mirror.
4+
5+
import (
6+
"errors"
7+
"fmt"
8+
"strconv"
9+
"strings"
10+
"testing"
11+
12+
"github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
13+
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
14+
"github.com/hashicorp/terraform-plugin-sdk/terraform"
15+
"github.com/xanzy/go-gitlab"
16+
)
17+
18+
func TestAccGitlabProjectMirror_basic(t *testing.T) {
19+
var hook gitlab.ProjectMirror
20+
rInt := acctest.RandInt()
21+
22+
resource.Test(t, resource.TestCase{
23+
PreCheck: func() { testAccPreCheck(t) },
24+
Providers: testAccProviders,
25+
CheckDestroy: testAccCheckGitlabProjectMirrorDestroy,
26+
Steps: []resource.TestStep{
27+
// Create a project and hook with default options
28+
{
29+
Config: testAccGitlabProjectMirrorConfig(rInt),
30+
Check: resource.ComposeTestCheckFunc(
31+
testAccCheckGitlabProjectMirrorExists("gitlab_project_mirror.foo", &hook),
32+
testAccCheckGitlabProjectMirrorAttributes(&hook, &testAccGitlabProjectMirrorExpectedAttributes{
33+
URL: fmt.Sprintf("https://example.com/hook-%d", rInt),
34+
Enabled: true,
35+
OnlyProtectedBranches: true,
36+
KeepDivergentRefs: true,
37+
}),
38+
),
39+
},
40+
// Update the project hook to toggle all the values to their inverse
41+
{
42+
Config: testAccGitlabProjectMirrorUpdateConfig(rInt),
43+
Check: resource.ComposeTestCheckFunc(
44+
testAccCheckGitlabProjectMirrorExists("gitlab_project_mirror.foo", &hook),
45+
testAccCheckGitlabProjectMirrorAttributes(&hook, &testAccGitlabProjectMirrorExpectedAttributes{
46+
URL: fmt.Sprintf("https://example.com/hook-%d", rInt),
47+
Enabled: false,
48+
OnlyProtectedBranches: false,
49+
KeepDivergentRefs: false,
50+
}),
51+
),
52+
},
53+
// Update the project hook to toggle the options back
54+
{
55+
Config: testAccGitlabProjectMirrorConfig(rInt),
56+
Check: resource.ComposeTestCheckFunc(
57+
testAccCheckGitlabProjectMirrorExists("gitlab_project_mirror.foo", &hook),
58+
testAccCheckGitlabProjectMirrorAttributes(&hook, &testAccGitlabProjectMirrorExpectedAttributes{
59+
URL: fmt.Sprintf("https://example.com/hook-%d", rInt),
60+
Enabled: true,
61+
OnlyProtectedBranches: true,
62+
KeepDivergentRefs: true,
63+
}),
64+
),
65+
},
66+
},
67+
})
68+
}
69+
70+
func TestAccGitlabProjectMirror_import(t *testing.T) {
71+
rInt := acctest.RandInt()
72+
73+
resource.Test(t, resource.TestCase{
74+
PreCheck: func() { testAccPreCheck(t) },
75+
Providers: testAccProviders,
76+
CheckDestroy: testAccCheckGitlabProjectMirrorDestroy,
77+
Steps: []resource.TestStep{
78+
{
79+
Config: testAccGitlabProjectMirrorConfig(rInt),
80+
},
81+
{
82+
ResourceName: "gitlab_project_mirror.foo",
83+
ImportState: true,
84+
ImportStateVerify: true,
85+
ImportStateVerifyIgnore: []string{"enabled", "mirror_id", "project", "url"},
86+
},
87+
},
88+
})
89+
}
90+
91+
func testAccCheckGitlabProjectMirrorExists(n string, mirror *gitlab.ProjectMirror) resource.TestCheckFunc {
92+
return func(s *terraform.State) error {
93+
rs, ok := s.RootModule().Resources[n]
94+
if !ok {
95+
return fmt.Errorf("Not Found: %s", n)
96+
}
97+
98+
splitID := strings.Split(rs.Primary.ID, ":")
99+
100+
mirrorID, err := strconv.Atoi(splitID[len(splitID)-1])
101+
if err != nil {
102+
return err
103+
}
104+
repoName := rs.Primary.Attributes["project"]
105+
if repoName == "" {
106+
return fmt.Errorf("No project ID is set")
107+
}
108+
conn := testAccProvider.Meta().(*gitlab.Client)
109+
110+
mirrors, _, err := conn.ProjectMirrors.ListProjectMirror(repoName, nil)
111+
if err != nil {
112+
return err
113+
}
114+
115+
for _, m := range mirrors {
116+
if m.ID == mirrorID {
117+
*mirror = *m
118+
break
119+
}
120+
return errors.New("unable to find mirror.")
121+
}
122+
return nil
123+
}
124+
}
125+
126+
type testAccGitlabProjectMirrorExpectedAttributes struct {
127+
URL string
128+
Enabled bool
129+
OnlyProtectedBranches bool
130+
KeepDivergentRefs bool
131+
}
132+
133+
func testAccCheckGitlabProjectMirrorAttributes(mirror *gitlab.ProjectMirror, want *testAccGitlabProjectMirrorExpectedAttributes) resource.TestCheckFunc {
134+
return func(s *terraform.State) error {
135+
if mirror.URL != want.URL {
136+
return fmt.Errorf("got url %q; want %q", mirror.URL, want.URL)
137+
}
138+
139+
if mirror.Enabled != want.Enabled {
140+
return fmt.Errorf("got enable_ssl_verification %t; want %t", mirror.Enabled, want.Enabled)
141+
}
142+
if mirror.OnlyProtectedBranches != want.OnlyProtectedBranches {
143+
return fmt.Errorf("got enable_ssl_verification %t; want %t", mirror.OnlyProtectedBranches, want.OnlyProtectedBranches)
144+
}
145+
if mirror.KeepDivergentRefs != want.KeepDivergentRefs {
146+
return fmt.Errorf("got enable_ssl_verification %t; want %t", mirror.KeepDivergentRefs, want.KeepDivergentRefs)
147+
}
148+
return nil
149+
}
150+
}
151+
152+
func testAccCheckGitlabProjectMirrorDestroy(s *terraform.State) error {
153+
conn := testAccProvider.Meta().(*gitlab.Client)
154+
155+
for _, rs := range s.RootModule().Resources {
156+
if rs.Type != "gitlab_project" {
157+
continue
158+
}
159+
160+
gotRepo, resp, err := conn.Projects.GetProject(rs.Primary.ID, nil)
161+
if err == nil {
162+
if gotRepo != nil && fmt.Sprintf("%d", gotRepo.ID) == rs.Primary.ID {
163+
if gotRepo.MarkedForDeletionAt == nil {
164+
return fmt.Errorf("Repository still exists")
165+
}
166+
}
167+
}
168+
if resp.StatusCode != 404 {
169+
return err
170+
}
171+
return nil
172+
}
173+
return nil
174+
}
175+
176+
func testAccGitlabProjectMirrorConfig(rInt int) string {
177+
return fmt.Sprintf(`
178+
resource "gitlab_project" "foo" {
179+
name = "foo-%d"
180+
description = "Terraform acceptance tests"
181+
182+
# So that acceptance tests can be run in a gitlab organization
183+
# with no billing
184+
visibility_level = "public"
185+
}
186+
187+
resource "gitlab_project_mirror" "foo" {
188+
project = "${gitlab_project.foo.id}"
189+
url = "https://example.com/hook-%d"
190+
}
191+
`, rInt, rInt)
192+
}
193+
194+
func testAccGitlabProjectMirrorUpdateConfig(rInt int) string {
195+
return fmt.Sprintf(`
196+
resource "gitlab_project" "foo" {
197+
name = "foo-%d"
198+
description = "Terraform acceptance tests"
199+
200+
# So that acceptance tests can be run in a gitlab organization
201+
# with no billing
202+
visibility_level = "public"
203+
}
204+
205+
resource "gitlab_project_mirror" "foo" {
206+
project = "${gitlab_project.foo.id}"
207+
url = "https://example.com/hook-%d"
208+
enabled = false
209+
only_protected_branches = false
210+
keep_divergent_refs = false
211+
}
212+
`, rInt, rInt)
213+
}

0 commit comments

Comments
 (0)