Skip to content

Commit c46b93a

Browse files
committed
datasource/gitlab_current_user: Separate global id from iid for interoperability with other resources
1 parent 8a487be commit c46b93a

File tree

5 files changed

+98
-7
lines changed

5 files changed

+98
-7
lines changed

docs/data-sources/current_user.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,12 @@ data "gitlab_current_user" "example" {}
2525
### Read-Only
2626

2727
- `bot` (Boolean) Indicates if the user is a bot.
28+
- `global_id` (String) Global ID of the user. This is in the form of a GraphQL globally unique ID.
29+
- `global_namespace_id` (String) Personal namespace of the user. This is in the form of a GraphQL globally unique ID.
2830
- `group_count` (Number) Group count for the user.
29-
- `id` (String) ID of the user. This is in the form of a GraphQL globally unique ID.
31+
- `id` (String) ID of the user.
3032
- `name` (String) Human-readable name of the user. Returns **** if the user is a project bot and the requester does not have permission to view the project.
31-
- `namespace_id` (String) Personal namespace of the user. This is in the form of a GraphQL globally unique ID.
33+
- `namespace_id` (String) Personal namespace of the user.
3234
- `public_email` (String) User’s public email.
3335
- `username` (String) Username of the user. Unique within this instance of GitLab.
3436

internal/provider/data_source_gitlab_current_user.go

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package provider
22

33
import (
44
"context"
5+
"fmt"
56
"log"
67

78
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
@@ -18,7 +19,12 @@ var _ = registerDataSource("gitlab_current_user", func() *schema.Resource {
1819
ReadContext: dataSourceGitlabCurrentUserRead,
1920
Schema: map[string]*schema.Schema{
2021
"id": {
21-
Description: "ID of the user. This is in the form of a GraphQL globally unique ID.",
22+
Description: "ID of the user.",
23+
Type: schema.TypeString,
24+
Computed: true,
25+
},
26+
"global_id": {
27+
Description: "Global ID of the user. This is in the form of a GraphQL globally unique ID.",
2228
Type: schema.TypeString,
2329
Computed: true,
2430
},
@@ -43,6 +49,11 @@ var _ = registerDataSource("gitlab_current_user", func() *schema.Resource {
4349
Computed: true,
4450
},
4551
"namespace_id": {
52+
Description: "Personal namespace of the user.",
53+
Type: schema.TypeString,
54+
Computed: true,
55+
},
56+
"global_namespace_id": {
4657
Description: "Personal namespace of the user. This is in the form of a GraphQL globally unique ID.",
4758
Type: schema.TypeString,
4859
Computed: true,
@@ -69,12 +80,24 @@ func dataSourceGitlabCurrentUserRead(ctx context.Context, d *schema.ResourceData
6980
return diag.FromErr(err)
7081
}
7182

72-
d.SetId(response.Data.CurrentUser.ID)
83+
userID, err := extractIIDFromGlobalID(response.Data.CurrentUser.ID)
84+
if err != nil {
85+
return diag.FromErr(err)
86+
}
87+
88+
namespaceID, err := extractIIDFromGlobalID(response.Data.CurrentUser.Namespace.ID)
89+
if err != nil {
90+
return diag.FromErr(err)
91+
}
92+
93+
d.SetId(fmt.Sprintf("%d", userID))
94+
d.Set("global_id", response.Data.CurrentUser.ID)
7395
d.Set("username", response.Data.CurrentUser.Username)
7496
d.Set("name", response.Data.CurrentUser.Name)
7597
d.Set("bot", response.Data.CurrentUser.Bot)
7698
d.Set("group_count", response.Data.CurrentUser.GroupCount)
77-
d.Set("namespace_id", response.Data.CurrentUser.Namespace.ID)
99+
d.Set("namespace_id", fmt.Sprintf("%d", namespaceID))
100+
d.Set("global_namespace_id", response.Data.CurrentUser.Namespace.ID)
78101
d.Set("public_email", response.Data.CurrentUser.PublicEmail)
79102

80103
return nil

internal/provider/data_source_gitlab_current_user_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,14 @@ func TestAccDataSourceGitlabCurrentUser_basic(t *testing.T) {
3030
{
3131
Config: `data "gitlab_current_user" "this" {}`,
3232
Check: resource.ComposeTestCheckFunc(
33-
resource.TestCheckResourceAttr("data.gitlab_current_user.this", "id", "gid://gitlab/User/1"),
33+
resource.TestCheckResourceAttr("data.gitlab_current_user.this", "id", "1"),
34+
resource.TestCheckResourceAttr("data.gitlab_current_user.this", "global_id", "gid://gitlab/User/1"),
3435
resource.TestCheckResourceAttr("data.gitlab_current_user.this", "name", "Administrator"),
3536
resource.TestCheckResourceAttr("data.gitlab_current_user.this", "username", "root"),
3637
resource.TestCheckResourceAttr("data.gitlab_current_user.this", "bot", "false"),
3738
resource.TestCheckResourceAttr("data.gitlab_current_user.this", "group_count", "2"),
38-
resource.TestCheckResourceAttr("data.gitlab_current_user.this", "namespace_id", "gid://gitlab/Namespaces::UserNamespace/1"),
39+
resource.TestCheckResourceAttr("data.gitlab_current_user.this", "namespace_id", "1"),
40+
resource.TestCheckResourceAttr("data.gitlab_current_user.this", "global_namespace_id", "gid://gitlab/Namespaces::UserNamespace/1"),
3941
resource.TestCheckResourceAttr("data.gitlab_current_user.this", "public_email", "[email protected]"),
4042
),
4143
},

internal/provider/util.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,20 @@ import (
1515
"github.com/xanzy/go-gitlab"
1616
)
1717

18+
// extractIIDFromGlobalID extracts the internal model ID from a global GraphQL ID.
19+
//
20+
// e.g. 'gid://gitlab/User/1' -> 1 or 'gid://gitlab/Project/42' -> 42
21+
//
22+
// see https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#global-ids
23+
func extractIIDFromGlobalID(globalID string) (int, error) {
24+
parts := strings.Split(globalID, "/")
25+
iid, err := strconv.Atoi(parts[len(parts)-1])
26+
if err != nil {
27+
return 0, fmt.Errorf("unable to extract iid from global id %q. Was looking for an integer after the last slash (/).", globalID)
28+
}
29+
return iid, nil
30+
}
31+
1832
func renderValueListForDocs(values []string) string {
1933
inlineCodeValues := make([]string, 0, len(values))
2034
for _, v := range values {

internal/provider/util_test.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,56 @@ import (
66
gitlab "github.com/xanzy/go-gitlab"
77
)
88

9+
func TestGitlab_extractIIDFromGlobalID(t *testing.T) {
10+
cases := []struct {
11+
GlobalID string
12+
IID int
13+
}{
14+
{
15+
GlobalID: "gid://gitlab/User/1",
16+
IID: 1,
17+
},
18+
{
19+
GlobalID: "gid://gitlab/Namespaces::UserNamespace/1000",
20+
IID: 1000,
21+
},
22+
}
23+
24+
for _, tc := range cases {
25+
iid, err := extractIIDFromGlobalID(tc.GlobalID)
26+
if err != nil {
27+
t.Fatalf("expected valid global id, got %q: %v", tc.GlobalID, err)
28+
}
29+
30+
if iid != tc.IID {
31+
t.Fatalf("got %v expected %v", iid, tc.IID)
32+
}
33+
}
34+
}
35+
36+
func TestGitlab_extractIIDFromGlobalID_invalidGlobalID(t *testing.T) {
37+
cases := []struct {
38+
GlobalID string
39+
}{
40+
{
41+
GlobalID: "",
42+
},
43+
{
44+
GlobalID: "gid://gitlab/User/",
45+
},
46+
{
47+
GlobalID: "gid://gitlab/Namespaces::UserNamespace",
48+
},
49+
}
50+
51+
for _, tc := range cases {
52+
iid, err := extractIIDFromGlobalID(tc.GlobalID)
53+
if err == nil {
54+
t.Fatalf("expected invalid global id, got id %q instead from global id %q", iid, tc.GlobalID)
55+
}
56+
}
57+
}
58+
959
func TestGitlab_visbilityHelpers(t *testing.T) {
1060
cases := []struct {
1161
String string

0 commit comments

Comments
 (0)