Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1b8e938

Browse files
committed
feat: add coder_user datasource
1 parentc683ad5 commit1b8e938

File tree

4 files changed

+352
-0
lines changed

4 files changed

+352
-0
lines changed

‎docs/data-sources/user.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title:"coder_user Data Source - terraform-provider-coder"
4+
subcategory:""
5+
description:|-
6+
Use this data source to fetch information about a user.
7+
---
8+
9+
#coder_user (Data Source)
10+
11+
Use this data source to fetch information about a user.
12+
13+
14+
15+
<!-- schema generated by tfplugindocs-->
16+
##Schema
17+
18+
###Read-Only
19+
20+
-`avatar_url` (String) The URL of the user's avatar.
21+
-`created_at` (String) The time the user was created in RFC3339 format.
22+
-`email` (String) The email address of the user.
23+
-`groups` (List of String) The groups of which the user is a member.
24+
-`id` (String) The UUID of the user.
25+
-`last_seen_at` (String) The time the user was last active in RFC3339 format.
26+
-`login_type` (String) The user's login type.
27+
-`name` (String) The full name of the user.
28+
-`organization_ids` (List of String) The organization IDs of which the user is a member.
29+
-`roles` (List of Object) The roles assigned to the user. (see[below for nested schema](#nestedatt--roles))
30+
-`ssh_private_key` (String, Sensitive) The user's generated SSH private key.
31+
-`ssh_public_key` (String) The user's generated SSH public key.
32+
-`status` (String) The status of the user.
33+
-`theme_preference` (String) The user's theme preference.
34+
-`username` (String) The username of the user.
35+
36+
<aid="nestedatt--roles"></a>
37+
###Nested Schema for`roles`
38+
39+
Read-Only:
40+
41+
-`display_name` (String)
42+
-`name` (String)

‎provider/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ func New() *schema.Provider {
7474
"coder_parameter":parameterDataSource(),
7575
"coder_git_auth":gitAuthDataSource(),
7676
"coder_external_auth":externalAuthDataSource(),
77+
"coder_user":userDataSource(),
7778
},
7879
ResourcesMap:map[string]*schema.Resource{
7980
"coder_agent":agentResource(),

‎provider/user.go

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
package provider
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"os"
7+
"strings"
8+
9+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
10+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
11+
)
12+
13+
typeRolestruct {
14+
Namestring`json:"name"`
15+
DisplayNamestring`json:"display-name"`
16+
}
17+
18+
funcuserDataSource()*schema.Resource {
19+
return&schema.Resource{
20+
Description:"Use this data source to fetch information about a user.",
21+
ReadContext:func(ctx context.Context,rd*schema.ResourceData,iinterface{}) diag.Diagnostics {
22+
ifidStr,ok:=os.LookupEnv("CODER_USER_ID");!ok {
23+
returndiag.Errorf("missing user id")
24+
}else {
25+
rd.SetId(idStr)
26+
}
27+
28+
ifusername,ok:=os.LookupEnv("CODER_USER_USERNAME");!ok {
29+
returndiag.Errorf("missing user username")
30+
}else {
31+
_=rd.Set("username",username)
32+
}
33+
34+
ifavatarURL,ok:=os.LookupEnv("CODER_USER_AVATAR_URL");!ok {
35+
returndiag.Errorf("missing user avatar_url")
36+
}else {
37+
_=rd.Set("avatar_url",avatarURL)
38+
}
39+
40+
iffullname,ok:=os.LookupEnv("CODER_USER_NAME");!ok {
41+
_=rd.Set("name","default")// compat
42+
}else {
43+
_=rd.Set("name",fullname)
44+
}
45+
46+
ifemail,ok:=os.LookupEnv("CODER_USER_EMAIL");!ok {
47+
returndiag.Errorf("missing user email")
48+
}else {
49+
_=rd.Set("email",email)
50+
}
51+
52+
ifcreatedAt,ok:=os.LookupEnv("CODER_USER_CREATED_AT");!ok {
53+
returndiag.Errorf("missing user created_at")
54+
}else {
55+
_=rd.Set("created_at",createdAt)
56+
}
57+
58+
iflastSeenAt,ok:=os.LookupEnv("CODER_USER_LAST_SEEN_AT");!ok {
59+
returndiag.Errorf("missing user last_seen_at")
60+
}else {
61+
_=rd.Set("last_seen_at",lastSeenAt)
62+
}
63+
64+
ifstatus,ok:=os.LookupEnv("CODER_USER_STATUS");!ok {
65+
returndiag.Errorf("missing user status")
66+
}else {
67+
_=rd.Set("status",status)
68+
}
69+
70+
ifloginType,ok:=os.LookupEnv("CODER_USER_LOGIN_TYPE");!ok {
71+
returndiag.Errorf("missing user login_type")
72+
}else {
73+
_=rd.Set("login_type",loginType)
74+
}
75+
76+
ifthemePref,ok:=os.LookupEnv("CODER_USER_THEME_PREFERENCE");!ok {
77+
returndiag.Errorf("missing user theme_preference")
78+
}else {
79+
_=rd.Set("theme_preference",themePref)
80+
}
81+
82+
orgIDsRaw,ok:=os.LookupEnv("CODER_USER_ORGANIZATION_IDS")
83+
if!ok {
84+
returndiag.Errorf("missing user organization_ids")
85+
}
86+
varorgIDs []string
87+
iferr:=json.NewDecoder(strings.NewReader(orgIDsRaw)).Decode(&orgIDs);err!=nil {
88+
returndiag.Errorf("invalid user organization_ids: %s",err.Error())
89+
}
90+
_=rd.Set("organization_ids",orgIDs)
91+
92+
ifsshPubKey,ok:=os.LookupEnv("CODER_USER_SSH_PUBLIC_KEY");!ok {
93+
returndiag.Errorf("missing user ssh_public_key")
94+
}else {
95+
_=rd.Set("ssh_public_key",sshPubKey)
96+
}
97+
98+
ifsshPrivKey,ok:=os.LookupEnv("CODER_USER_SSH_PRIVATE_KEY");!ok {
99+
returndiag.Errorf("missing user ssh_private_key")
100+
}else {
101+
_=rd.Set("ssh_private_key",sshPrivKey)
102+
}
103+
104+
groupsRaw,ok:=os.LookupEnv("CODER_USER_GROUPS")
105+
if!ok {
106+
returndiag.Errorf("missing user groups")
107+
}
108+
vargroups []string
109+
iferr:=json.NewDecoder(strings.NewReader(groupsRaw)).Decode(&groups);err!=nil {
110+
returndiag.Errorf("invalid user groups: %s",err.Error())
111+
}else {
112+
_=rd.Set("groups",groups)
113+
}
114+
115+
rolesRaw,ok:=os.LookupEnv("CODER_USER_ROLES")
116+
if!ok {
117+
returndiag.Errorf("missing user roles")
118+
}
119+
varroles []Role
120+
iferr:=json.NewDecoder(strings.NewReader(rolesRaw)).Decode(&roles);err!=nil {
121+
returndiag.Errorf("invalid user roles: %s",err.Error())
122+
}else {
123+
_=rd.Set("roles",roles)
124+
}
125+
126+
returnnil
127+
},
128+
Schema:map[string]*schema.Schema{
129+
"id": {
130+
Type:schema.TypeString,
131+
Computed:true,
132+
Description:"The UUID of the user.",
133+
},
134+
"username": {
135+
Type:schema.TypeString,
136+
Computed:true,
137+
Description:"The username of the user.",
138+
},
139+
"avatar_url": {
140+
Type:schema.TypeString,
141+
Computed:true,
142+
Description:"The URL of the user's avatar.",
143+
},
144+
"name": {
145+
Type:schema.TypeString,
146+
Computed:true,
147+
Description:"The full name of the user.",
148+
},
149+
"email": {
150+
Type:schema.TypeString,
151+
Computed:true,
152+
Description:"The email address of the user.",
153+
},
154+
"created_at": {
155+
Type:schema.TypeString,
156+
Computed:true,
157+
Description:"The time the user was created in RFC3339 format.",
158+
},
159+
"last_seen_at": {
160+
Type:schema.TypeString,
161+
Computed:true,
162+
Description:"The time the user was last active in RFC3339 format.",
163+
},
164+
"status": {
165+
Type:schema.TypeString,
166+
Computed:true,
167+
Description:"The status of the user.",
168+
},
169+
"login_type": {
170+
Type:schema.TypeString,
171+
Computed:true,
172+
Description:"The user's login type.",
173+
},
174+
"theme_preference": {
175+
Type:schema.TypeString,
176+
Computed:true,
177+
Description:"The user's theme preference.",
178+
},
179+
"organization_ids": {
180+
Type:schema.TypeList,
181+
Elem:&schema.Schema{
182+
Type:schema.TypeString,
183+
},
184+
Computed:true,
185+
Description:"The organization IDs of which the user is a member.",
186+
},
187+
"ssh_public_key": {
188+
Type:schema.TypeString,
189+
Computed:true,
190+
Description:"The user's generated SSH public key.",
191+
},
192+
"ssh_private_key": {
193+
Type:schema.TypeString,
194+
Computed:true,
195+
Description:"The user's generated SSH private key.",
196+
Sensitive:true,
197+
},
198+
"groups": {
199+
Type:schema.TypeList,
200+
Elem:&schema.Schema{
201+
Type:schema.TypeString,
202+
},
203+
Computed:true,
204+
Description:"The groups of which the user is a member.",
205+
},
206+
"roles": {
207+
Type:schema.TypeList,
208+
Elem:&schema.Resource{
209+
Schema:map[string]*schema.Schema{
210+
"name": {
211+
Type:schema.TypeString,
212+
Computed:true,
213+
Description:"The internal name of the role.",
214+
},
215+
"display_name": {
216+
Type:schema.TypeString,
217+
Computed:true,
218+
Description:"The display name of the role in the UI.",
219+
},
220+
},
221+
},
222+
Computed:true,
223+
Description:"The roles assigned to the user.",
224+
},
225+
},
226+
}
227+
}

‎provider/user_test.go

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package provider_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/coder/terraform-provider-coder/provider"
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
9+
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
10+
"github.com/stretchr/testify/assert"
11+
"github.com/stretchr/testify/require"
12+
)
13+
14+
const (
15+
testSSHEd25519PublicKey=`ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJeNcdBMtd4Jo9f2W8RZef0ld7Ypye5zTQEf0vUXa/Eq owner123@host456`
16+
// nolint:gosec // This key was generated specifically for this purpose.
17+
testSSHEd25519PrivateKey=`-----BEGIN OPENSSH PRIVATE KEY-----
18+
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
19+
QyNTUxOQAAACCXjXHQTLXeCaPX9lvEWXn9JXe2Kcnuc00BH9L1F2vxKgAAAJgp3mfQKd5n
20+
0AAAAAtzc2gtZWQyNTUxOQAAACCXjXHQTLXeCaPX9lvEWXn9JXe2Kcnuc00BH9L1F2vxKg
21+
AAAEBia7mAQFoLBILlvTJroTkOUomzfcPY9ckpViQOjYFkAZeNcdBMtd4Jo9f2W8RZef0l
22+
d7Ypye5zTQEf0vUXa/EqAAAAE3ZzY29kZUAzY2Y4MWY5YmM3MmQBAg==
23+
-----END OPENSSH PRIVATE KEY-----`
24+
)
25+
26+
funcTestUserDatasource(t*testing.T) {
27+
t.Setenv("CODER_USER_ID","11111111-1111-1111-1111-111111111111")
28+
t.Setenv("CODER_USER_USERNAME","owner123")
29+
t.Setenv("CODER_USER_AVATAR_URL","https://example.com/avatar.png")
30+
t.Setenv("CODER_USER_NAME","Mr Owner")
31+
t.Setenv("CODER_USER_EMAIL","owner123@example.com")
32+
t.Setenv("CODER_USER_CREATED_AT","2022-08-15T08:30:10.343828Z")
33+
t.Setenv("CODER_USER_LAST_SEEN_AT","2024-05-23T13:37:49.193203Z")
34+
t.Setenv("CODER_USER_STATUS","active")
35+
t.Setenv("CODER_USER_LOGIN_TYPE","oidc")
36+
t.Setenv("CODER_USER_THEME_PREFERENCE","hackerGreen")
37+
t.Setenv("CODER_USER_ORGANIZATION_IDS",`["22222222-2222-2222-2222-222222222222","33333333-3333-3333-3333-333333333333"]`)
38+
t.Setenv("CODER_USER_SSH_PUBLIC_KEY",testSSHEd25519PublicKey)
39+
t.Setenv("CODER_USER_SSH_PRIVATE_KEY",testSSHEd25519PrivateKey)
40+
t.Setenv("CODER_USER_GROUPS",`["group1", "group2"]`)
41+
t.Setenv("CODER_USER_ROLES",`[{"name": "template-admin", "display_name": "Template Admin"}]`)
42+
43+
resource.Test(t, resource.TestCase{
44+
Providers:map[string]*schema.Provider{
45+
"coder":provider.New(),
46+
},
47+
IsUnitTest:true,
48+
Steps: []resource.TestStep{{
49+
Config:`
50+
provider "coder" {}
51+
data "coder_user" "me" {}
52+
`,
53+
Check:func(s*terraform.State)error {
54+
require.Len(t,s.Modules,1)
55+
require.Len(t,s.Modules[0].Resources,1)
56+
resource:=s.Modules[0].Resources["data.coder_user.me"]
57+
require.NotNil(t,resource)
58+
59+
attrs:=resource.Primary.Attributes
60+
assert.Equal(t,"11111111-1111-1111-1111-111111111111",attrs["id"])
61+
assert.Equal(t,"owner123",attrs["username"])
62+
assert.Equal(t,"https://example.com/avatar.png",attrs["avatar_url"])
63+
assert.Equal(t,"Mr Owner",attrs["name"])
64+
assert.Equal(t,"owner123@example.com",attrs["email"])
65+
assert.Equal(t,"2022-08-15T08:30:10.343828Z",attrs["created_at"])
66+
assert.Equal(t,"2024-05-23T13:37:49.193203Z",attrs["last_seen_at"])
67+
assert.Equal(t,"active",attrs["status"])
68+
assert.Equal(t,"oidc",attrs["login_type"])
69+
assert.Equal(t,"hackerGreen",attrs["theme_preference"])
70+
assert.Equal(t,"22222222-2222-2222-2222-222222222222",attrs["organization_ids.0"])
71+
assert.Equal(t,"33333333-3333-3333-3333-333333333333",attrs["organization_ids.1"])
72+
assert.Equal(t,testSSHEd25519PublicKey,attrs["ssh_public_key"])
73+
assert.Equal(t,testSSHEd25519PrivateKey,attrs["ssh_private_key"])
74+
assert.Equal(t,`group1`,attrs["groups.0"])
75+
assert.Equal(t,`group2`,attrs["groups.1"])
76+
assert.Equal(t,`template-admin`,attrs["roles.0.name"])
77+
assert.Equal(t,`Template Admin`,attrs["roles.0.display_name"])
78+
returnnil
79+
},
80+
}},
81+
})
82+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp