Skip to content

Commit ff8ba68

Browse files
author
Julien Pivotto
committed
Do not recreate project mirror on every run.
GitLab does not return username and password from the mirrors. Therefore, let's ignore it in the provider. This commit also adds pagination support. Signed-off-by: Julien Pivotto <[email protected]>
1 parent 7676486 commit ff8ba68

File tree

3 files changed

+113
-10
lines changed

3 files changed

+113
-10
lines changed

docs/resources/project_mirror.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ The following arguments are supported:
2525

2626
* `url` - (Required) The URL of the remote repository to be mirrored.
2727

28+
~> Due to limitations of the GitLab API, the provider cannot update the
29+
username and passwords that are present in the URL. To change the username or
30+
the password, we recommend you to [replace](https://www.terraform.io/docs/cli/commands/plan.html#replace-address) the resources.
31+
2832
* `enabled` - Determines if the mirror is enabled.
2933

3034
* `only_protected_branches` - Determines if only protected branches are mirrored.

gitlab/resource_gitlab_project_mirror.go

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package gitlab
22

33
import (
44
"log"
5+
"net/url"
56
"strconv"
67
"strings"
78

@@ -34,6 +35,23 @@ func resourceGitlabProjectMirror() *schema.Resource {
3435
ForceNew: true,
3536
Required: true,
3637
Sensitive: true, // Username and password must be provided in the URL for https.
38+
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
39+
oldURL, err := url.Parse(old)
40+
if err != nil {
41+
return old == new
42+
}
43+
newURL, err := url.Parse(new)
44+
if err != nil {
45+
return old == new
46+
}
47+
if oldURL.User != nil {
48+
oldURL.User = url.UserPassword("redacted", "redacted")
49+
}
50+
if newURL.User != nil {
51+
newURL.User = url.UserPassword("redacted", "redacted")
52+
}
53+
return oldURL.String() == newURL.String()
54+
},
3755
},
3856
"enabled": {
3957
Type: schema.TypeBool,
@@ -141,21 +159,32 @@ func resourceGitlabProjectMirrorRead(d *schema.ResourceData, meta interface{}) e
141159
}
142160
log.Printf("[DEBUG] read gitlab project mirror %s id %v", projectID, mirrorID)
143161

144-
mirrors, _, err := client.ProjectMirrors.ListProjectMirror(projectID, nil)
162+
var mirror *gitlab.ProjectMirror
163+
found := false
145164

146-
if err != nil {
147-
return err
165+
opts := &gitlab.ListProjectMirrorOptions{
166+
Page: 1,
167+
PerPage: 20,
148168
}
149169

150-
var mirror *gitlab.ProjectMirror
151-
found := false
170+
for {
171+
mirrors, response, err := client.ProjectMirrors.ListProjectMirror(projectID, opts)
172+
if err != nil {
173+
return err
174+
}
152175

153-
for _, m := range mirrors {
154-
log.Printf("[DEBUG] project mirror found %v", m.ID)
155-
if m.ID == integerMirrorID {
156-
mirror = m
157-
found = true
176+
for _, m := range mirrors {
177+
log.Printf("[DEBUG] project mirror found %v", m.ID)
178+
if m.ID == integerMirrorID {
179+
mirror = m
180+
found = true
181+
break
182+
}
183+
}
184+
if response.CurrentPage >= response.TotalPages {
185+
break
158186
}
187+
opts.Page++
159188
}
160189

161190
if !found {

gitlab/resource_gitlab_project_mirror_test.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,39 @@ func TestAccGitlabProjectMirror_basic(t *testing.T) {
6565
})
6666
}
6767

68+
func TestAccGitlabProjectMirror_withPassword(t *testing.T) {
69+
//var mirror gitlab.ProjectMirror
70+
rInt := acctest.RandInt()
71+
72+
resource.Test(t, resource.TestCase{
73+
PreCheck: func() { testAccPreCheck(t) },
74+
Providers: testAccProviders,
75+
CheckDestroy: testAccCheckGitlabProjectMirrorDestroy,
76+
Steps: []resource.TestStep{
77+
// Create a project and mirror with a username / password.
78+
{
79+
Config: testAccGitlabProjectMirrorConfigWithPassword(rInt),
80+
},
81+
},
82+
})
83+
}
84+
85+
func TestAccGitlabProjectMirror_withCount(t *testing.T) {
86+
//var mirror gitlab.ProjectMirror
87+
rInt := acctest.RandInt()
88+
89+
resource.Test(t, resource.TestCase{
90+
PreCheck: func() { testAccPreCheck(t) },
91+
Providers: testAccProviders,
92+
CheckDestroy: testAccCheckGitlabProjectMirrorDestroy,
93+
Steps: []resource.TestStep{
94+
{
95+
Config: testAccGitlabProjectMirrorConfigWithCount(rInt),
96+
},
97+
},
98+
})
99+
}
100+
68101
// lintignore: AT002 // TODO: Resolve this tfproviderlint issue
69102
func TestAccGitlabProjectMirror_import(t *testing.T) {
70103
rInt := acctest.RandInt()
@@ -188,6 +221,43 @@ resource "gitlab_project_mirror" "foo" {
188221
`, rInt, rInt)
189222
}
190223

224+
func testAccGitlabProjectMirrorConfigWithCount(rInt int) string {
225+
return fmt.Sprintf(`
226+
resource "gitlab_project" "foo" {
227+
name = "foo-%d"
228+
description = "Terraform acceptance tests"
229+
230+
# So that acceptance tests can be run in a gitlab organization
231+
# with no billing
232+
visibility_level = "public"
233+
}
234+
235+
resource "gitlab_project_mirror" "foo" {
236+
project = "${gitlab_project.foo.id}"
237+
url = "https://foo:%[email protected]/mirror-%d"
238+
count = 40
239+
}
240+
`, rInt, rInt, rInt)
241+
}
242+
243+
func testAccGitlabProjectMirrorConfigWithPassword(rInt int) string {
244+
return fmt.Sprintf(`
245+
resource "gitlab_project" "foo" {
246+
name = "foo-%d"
247+
description = "Terraform acceptance tests"
248+
249+
# So that acceptance tests can be run in a gitlab organization
250+
# with no billing
251+
visibility_level = "public"
252+
}
253+
254+
resource "gitlab_project_mirror" "foo" {
255+
project = "${gitlab_project.foo.id}"
256+
url = "https://foo:%[email protected]/mirror-%d"
257+
}
258+
`, rInt, rInt, rInt)
259+
}
260+
191261
func testAccGitlabProjectMirrorUpdateConfig(rInt int) string {
192262
return fmt.Sprintf(`
193263
resource "gitlab_project" "foo" {

0 commit comments

Comments
 (0)