Skip to content

Commit be313f1

Browse files
authored
Merge pull request #987 from timofurrer/feature/user-namespace-id
Officially support creating project in user namespace using `namespace_id` from user resources / data sources
2 parents 5bc59f0 + d60393e commit be313f1

File tree

10 files changed

+98
-2
lines changed

10 files changed

+98
-2
lines changed

docs/data-sources/user.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ data "gitlab_user" "example-two" {
3838

3939
- `email` (String) The public email address of the user. **Note**: before GitLab 14.8 the lookup was based on the users primary email address.
4040
- `id` (String) The ID of this resource.
41+
- `namespace_id` (Number) The ID of the user's namespace. Requires admin token to access this field. Available since GitLab 14.10.
4142
- `user_id` (Number) The ID of the user.
4243
- `username` (String) The username of the user.
4344

docs/data-sources/users.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ Read-Only:
7474
- `linkedin` (String)
7575
- `location` (String)
7676
- `name` (String)
77+
- `namespace_id` (Number)
7778
- `organization` (String)
7879
- `projects_limit` (Number)
7980
- `provider` (String)

docs/resources/project.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,17 @@ resource "gitlab_project" "example-two" {
3737
prevent_secrets = true
3838
}
3939
}
40+
41+
# Create a project for a given user (requires admin access)
42+
data "gitlab_user" "peter_parker" {
43+
username = "peter_parker"
44+
}
45+
46+
resource "gitlab_project" "peters_repo" {
47+
name = "peters-repo"
48+
description = "This is a description"
49+
namespace_id = data.gitlab_user.peter_parker.namespace_id
50+
}
4051
```
4152

4253
<!-- schema generated by tfplugindocs -->

docs/resources/user.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ resource "gitlab_user" "example" {
5050
- `id` (String) The ID of this resource.
5151
- `is_admin` (Boolean) Boolean, defaults to false. Whether to enable administrative privileges
5252
- `is_external` (Boolean) Boolean, defaults to false. Whether a user has access only to some internal or private projects. External users can only access projects to which they are explicitly granted access.
53+
- `namespace_id` (Number) The ID of the user's namespace. Available since GitLab 14.10.
5354
- `note` (String) The note associated to the user.
5455
- `password` (String, Sensitive) The password of the user.
5556
- `projects_limit` (Number) Integer, defaults to 0. Number of projects user can create.

examples/resources/gitlab_project/resource.tf

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,14 @@ resource "gitlab_project" "example-two" {
1616
prevent_secrets = true
1717
}
1818
}
19+
20+
# Create a project for a given user (requires admin access)
21+
data "gitlab_user" "peter_parker" {
22+
username = "peter_parker"
23+
}
24+
25+
resource "gitlab_project" "peters_repo" {
26+
name = "peters-repo"
27+
description = "This is a description"
28+
namespace_id = data.gitlab_user.peter_parker.namespace_id
29+
}

internal/provider/data_source_gitlab_user.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,12 @@ var _ = registerDataSource("gitlab_user", func() *schema.Resource {
171171
Type: schema.TypeString,
172172
Computed: true,
173173
},
174+
"namespace_id": {
175+
Description: "The ID of the user's namespace. Requires admin token to access this field. Available since GitLab 14.10.",
176+
Type: schema.TypeInt,
177+
Optional: true,
178+
Computed: true,
179+
},
174180
},
175181
}
176182
})
@@ -223,6 +229,7 @@ func dataSourceGitlabUserRead(ctx context.Context, d *schema.ResourceData, meta
223229
return diag.Errorf("one and only one of user_id, username or email must be set")
224230
}
225231

232+
d.SetId(fmt.Sprintf("%d", user.ID))
226233
d.Set("user_id", user.ID)
227234
d.Set("username", user.Username)
228235
d.Set("email", user.Email)
@@ -254,8 +261,7 @@ func dataSourceGitlabUserRead(ctx context.Context, d *schema.ResourceData, meta
254261
d.Set("website_url", user.WebsiteURL)
255262
d.Set("theme_id", user.ThemeID)
256263
d.Set("color_scheme_id", user.ColorSchemeID)
257-
258-
d.SetId(fmt.Sprintf("%d", user.ID))
264+
d.Set("namespace_id", user.NamespaceID)
259265

260266
return nil
261267
}

internal/provider/data_source_gitlab_users.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,12 @@ var _ = registerDataSource("gitlab_users", func() *schema.Resource {
212212
Type: schema.TypeString,
213213
Computed: true,
214214
},
215+
"namespace_id": {
216+
Description: "The ID of the user's namespace. Requires admin token to access this field. Available since GitLab 14.10.",
217+
Type: schema.TypeInt,
218+
Optional: true,
219+
Computed: true,
220+
},
215221
},
216222
},
217223
},
@@ -274,6 +280,7 @@ func flattenGitlabUsers(users []*gitlab.User) []interface{} {
274280
"organization": user.Organization,
275281
"theme_id": user.ThemeID,
276282
"color_scheme_id": user.ColorSchemeID,
283+
"namespace_id": user.NamespaceID,
277284
}
278285

279286
if user.CreatedAt != nil {

internal/provider/resource_gitlab_project_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -868,6 +868,43 @@ resource "gitlab_project" "foo" {
868868
})
869869
}
870870

871+
func TestAccGitlabProject_CreateProjectInUserNamespace(t *testing.T) {
872+
testAccCheck(t)
873+
874+
var project gitlab.Project
875+
rInt := acctest.RandInt()
876+
877+
user := testAccCreateUsers(t, 1)[0]
878+
879+
resource.Test(t, resource.TestCase{
880+
PreCheck: func() { testAccPreCheck(t) },
881+
ProviderFactories: providerFactories,
882+
CheckDestroy: testAccCheckGitlabProjectDestroy,
883+
Steps: []resource.TestStep{
884+
{
885+
Config: fmt.Sprintf(`
886+
resource "gitlab_project" "foo" {
887+
name = "foo-%d"
888+
description = "Terraform acceptance tests"
889+
visibility_level = "public"
890+
891+
namespace_id = %d
892+
}
893+
`, rInt, user.NamespaceID),
894+
Check: resource.ComposeTestCheckFunc(
895+
testAccCheckGitlabProjectExists("gitlab_project.foo", &project),
896+
func(s *terraform.State) error {
897+
if project.Namespace.ID != user.NamespaceID {
898+
return fmt.Errorf("project was created in namespace %d but expected %d", project.Namespace.ID, user.NamespaceID)
899+
}
900+
return nil
901+
},
902+
),
903+
},
904+
},
905+
})
906+
}
907+
871908
type testAccGitlabProjectMirroredExpectedAttributes struct {
872909
Mirror bool
873910
MirrorTriggerBuilds bool

internal/provider/resource_gitlab_user.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,12 @@ var _ = registerResource("gitlab_user", func() *schema.Resource {
110110
Default: "active",
111111
ValidateDiagFunc: validation.ToDiagFunc(validation.StringInSlice(validUserStateValues, false)),
112112
},
113+
"namespace_id": {
114+
Description: "The ID of the user's namespace. Available since GitLab 14.10.",
115+
Type: schema.TypeInt,
116+
Optional: true,
117+
Computed: true,
118+
},
113119
},
114120
}
115121
})
@@ -124,6 +130,7 @@ func resourceGitlabUserSetToState(d *schema.ResourceData, user *gitlab.User) {
124130
d.Set("is_external", user.External)
125131
d.Set("note", user.Note)
126132
d.Set("state", user.State)
133+
d.Set("namespace_id", user.NamespaceID)
127134
}
128135

129136
func resourceGitlabUserCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {

internal/provider/resource_gitlab_user_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ func TestAccGitlabUser_basic(t *testing.T) {
3030
Email: fmt.Sprintf("listest%[email protected]", rInt),
3131
Username: fmt.Sprintf("listest%d", rInt),
3232
Name: fmt.Sprintf("foo %d", rInt),
33+
NamespaceID: user.NamespaceID,
3334
ProjectsLimit: 0,
3435
Admin: false,
3536
CanCreateGroup: false,
@@ -56,6 +57,7 @@ func TestAccGitlabUser_basic(t *testing.T) {
5657
Email: fmt.Sprintf("listest%[email protected]", rInt),
5758
Username: fmt.Sprintf("listest%d", rInt),
5859
Name: fmt.Sprintf("foo %d", rInt),
60+
NamespaceID: user.NamespaceID,
5961
ProjectsLimit: 0,
6062
Admin: false,
6163
CanCreateGroup: false,
@@ -82,6 +84,7 @@ func TestAccGitlabUser_basic(t *testing.T) {
8284
Email: fmt.Sprintf("listest%[email protected]", rInt),
8385
Username: fmt.Sprintf("listest%d", rInt),
8486
Name: fmt.Sprintf("bar %d", rInt),
87+
NamespaceID: user.NamespaceID,
8588
ProjectsLimit: 10,
8689
Admin: true,
8790
CanCreateGroup: true,
@@ -109,6 +112,7 @@ func TestAccGitlabUser_basic(t *testing.T) {
109112
Email: fmt.Sprintf("listest%[email protected]", rInt),
110113
Username: fmt.Sprintf("listest%d", rInt),
111114
Name: fmt.Sprintf("bar %d", rInt),
115+
NamespaceID: user.NamespaceID,
112116
ProjectsLimit: 10,
113117
Admin: true,
114118
CanCreateGroup: true,
@@ -136,6 +140,7 @@ func TestAccGitlabUser_basic(t *testing.T) {
136140
Email: fmt.Sprintf("listest%[email protected]", rInt),
137141
Username: fmt.Sprintf("listest%d", rInt),
138142
Name: fmt.Sprintf("foo %d", rInt),
143+
NamespaceID: user.NamespaceID,
139144
ProjectsLimit: 0,
140145
Admin: false,
141146
CanCreateGroup: false,
@@ -162,6 +167,7 @@ func TestAccGitlabUser_basic(t *testing.T) {
162167
Email: fmt.Sprintf("listest%[email protected]", rInt),
163168
Username: fmt.Sprintf("listest%d", rInt),
164169
Name: fmt.Sprintf("foo %d", rInt),
170+
NamespaceID: user.NamespaceID,
165171
ProjectsLimit: 0,
166172
Admin: false,
167173
CanCreateGroup: false,
@@ -188,6 +194,7 @@ func TestAccGitlabUser_basic(t *testing.T) {
188194
Email: fmt.Sprintf("listest%[email protected]", rInt),
189195
Username: fmt.Sprintf("listest%d", rInt),
190196
Name: fmt.Sprintf("foo %d", rInt),
197+
NamespaceID: user.NamespaceID,
191198
ProjectsLimit: 0,
192199
Admin: false,
193200
CanCreateGroup: false,
@@ -214,6 +221,7 @@ func TestAccGitlabUser_basic(t *testing.T) {
214221
Email: fmt.Sprintf("listest%[email protected]", rInt),
215222
Username: fmt.Sprintf("listest%d", rInt),
216223
Name: fmt.Sprintf("foo %d", rInt),
224+
NamespaceID: user.NamespaceID,
217225
ProjectsLimit: 0,
218226
Admin: false,
219227
CanCreateGroup: false,
@@ -231,6 +239,7 @@ func TestAccGitlabUser_basic(t *testing.T) {
231239
Email: fmt.Sprintf("listest%[email protected]", rInt),
232240
Username: fmt.Sprintf("listest%d", rInt),
233241
Name: fmt.Sprintf("foo %d", rInt),
242+
NamespaceID: user.NamespaceID,
234243
ProjectsLimit: 0,
235244
Admin: false,
236245
CanCreateGroup: false,
@@ -248,6 +257,7 @@ func TestAccGitlabUser_basic(t *testing.T) {
248257
Email: fmt.Sprintf("listest%[email protected]", rInt),
249258
Username: fmt.Sprintf("listest%d", rInt),
250259
Name: fmt.Sprintf("foo %d", rInt),
260+
NamespaceID: user.NamespaceID,
251261
ProjectsLimit: 0,
252262
Admin: false,
253263
CanCreateGroup: false,
@@ -265,6 +275,7 @@ func TestAccGitlabUser_basic(t *testing.T) {
265275
Email: fmt.Sprintf("listest%[email protected]", rInt),
266276
Username: fmt.Sprintf("listest%d", rInt),
267277
Name: fmt.Sprintf("foo %d", rInt),
278+
NamespaceID: user.NamespaceID,
268279
ProjectsLimit: 0,
269280
Admin: false,
270281
CanCreateGroup: false,
@@ -282,6 +293,7 @@ func TestAccGitlabUser_basic(t *testing.T) {
282293
Email: fmt.Sprintf("listest%[email protected]", rInt),
283294
Username: fmt.Sprintf("listest%d", rInt),
284295
Name: fmt.Sprintf("foo %d", rInt),
296+
NamespaceID: user.NamespaceID,
285297
ProjectsLimit: 0,
286298
Admin: false,
287299
CanCreateGroup: false,
@@ -299,6 +311,7 @@ func TestAccGitlabUser_basic(t *testing.T) {
299311
Email: fmt.Sprintf("listest%[email protected]", rInt),
300312
Username: fmt.Sprintf("listest%d", rInt),
301313
Name: fmt.Sprintf("foo %d", rInt),
314+
NamespaceID: user.NamespaceID,
302315
ProjectsLimit: 0,
303316
Admin: false,
304317
CanCreateGroup: false,
@@ -370,6 +383,7 @@ type testAccGitlabUserExpectedAttributes struct {
370383
Email string
371384
Username string
372385
Name string
386+
NamespaceID int
373387
ProjectsLimit int
374388
Admin bool
375389
CanCreateGroup bool

0 commit comments

Comments
 (0)