Skip to content

Commit 28bab5a

Browse files
committed
feat: add coder_user datasource
1 parent c683ad5 commit 28bab5a

File tree

4 files changed

+205
-0
lines changed

4 files changed

+205
-0
lines changed

docs/data-sources/user.md

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
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+
- `email` (String) The email address of the user.
21+
- `full_name` (String) The full name of the user.
22+
- `groups` (List of String) The groups of which the user is a member.
23+
- `id` (String) The UUID of the user.
24+
- `name` (String) The username of the user.
25+
- `ssh_private_key` (String, Sensitive) The user's generated SSH private key.
26+
- `ssh_public_key` (String) The user's generated SSH public key.

provider/provider.go

+1
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

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
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+
type Role struct {
14+
Name string `json:"name"`
15+
DisplayName string `json:"display-name"`
16+
}
17+
18+
func userDataSource() *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, i interface{}) diag.Diagnostics {
22+
if idStr, ok := os.LookupEnv("CODER_USER_ID"); !ok {
23+
return diag.Errorf("missing user id")
24+
} else {
25+
rd.SetId(idStr)
26+
}
27+
28+
if username, ok := os.LookupEnv("CODER_USER_NAME"); !ok {
29+
return diag.Errorf("missing user username")
30+
} else {
31+
_ = rd.Set("name", username)
32+
}
33+
34+
if fullname, ok := os.LookupEnv("CODER_USER_FULL_NAME"); !ok {
35+
_ = rd.Set("name", "default") // compat
36+
} else {
37+
_ = rd.Set("full_name", fullname)
38+
}
39+
40+
if email, ok := os.LookupEnv("CODER_USER_EMAIL"); !ok {
41+
return diag.Errorf("missing user email")
42+
} else {
43+
_ = rd.Set("email", email)
44+
}
45+
46+
if sshPubKey, ok := os.LookupEnv("CODER_USER_SSH_PUBLIC_KEY"); !ok {
47+
return diag.Errorf("missing user ssh_public_key")
48+
} else {
49+
_ = rd.Set("ssh_public_key", sshPubKey)
50+
}
51+
52+
if sshPrivKey, ok := os.LookupEnv("CODER_USER_SSH_PRIVATE_KEY"); !ok {
53+
return diag.Errorf("missing user ssh_private_key")
54+
} else {
55+
_ = rd.Set("ssh_private_key", sshPrivKey)
56+
}
57+
58+
groupsRaw, ok := os.LookupEnv("CODER_USER_GROUPS")
59+
if !ok {
60+
return diag.Errorf("missing user groups")
61+
}
62+
var groups []string
63+
if err := json.NewDecoder(strings.NewReader(groupsRaw)).Decode(&groups); err != nil {
64+
return diag.Errorf("invalid user groups: %s", err.Error())
65+
} else {
66+
_ = rd.Set("groups", groups)
67+
}
68+
69+
return nil
70+
},
71+
Schema: map[string]*schema.Schema{
72+
"id": {
73+
Type: schema.TypeString,
74+
Computed: true,
75+
Description: "The UUID of the user.",
76+
},
77+
"name": {
78+
Type: schema.TypeString,
79+
Computed: true,
80+
Description: "The username of the user.",
81+
},
82+
"full_name": {
83+
Type: schema.TypeString,
84+
Computed: true,
85+
Description: "The full name of the user.",
86+
},
87+
"email": {
88+
Type: schema.TypeString,
89+
Computed: true,
90+
Description: "The email address of the user.",
91+
},
92+
"ssh_public_key": {
93+
Type: schema.TypeString,
94+
Computed: true,
95+
Description: "The user's generated SSH public key.",
96+
},
97+
"ssh_private_key": {
98+
Type: schema.TypeString,
99+
Computed: true,
100+
Description: "The user's generated SSH private key.",
101+
Sensitive: true,
102+
},
103+
"groups": {
104+
Type: schema.TypeList,
105+
Elem: &schema.Schema{
106+
Type: schema.TypeString,
107+
},
108+
Computed: true,
109+
Description: "The groups of which the user is a member.",
110+
},
111+
},
112+
}
113+
}

provider/user_test.go

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
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+
func TestUserDatasource(t *testing.T) {
27+
t.Setenv("CODER_USER_ID", "11111111-1111-1111-1111-111111111111")
28+
t.Setenv("CODER_USER_NAME", "owner123")
29+
t.Setenv("CODER_USER_AVATAR_URL", "https://example.com/avatar.png")
30+
t.Setenv("CODER_USER_FULL_NAME", "Mr Owner")
31+
t.Setenv("CODER_USER_EMAIL", "[email protected]")
32+
t.Setenv("CODER_USER_SSH_PUBLIC_KEY", testSSHEd25519PublicKey)
33+
t.Setenv("CODER_USER_SSH_PRIVATE_KEY", testSSHEd25519PrivateKey)
34+
t.Setenv("CODER_USER_GROUPS", `["group1", "group2"]`)
35+
36+
resource.Test(t, resource.TestCase{
37+
Providers: map[string]*schema.Provider{
38+
"coder": provider.New(),
39+
},
40+
IsUnitTest: true,
41+
Steps: []resource.TestStep{{
42+
Config: `
43+
provider "coder" {}
44+
data "coder_user" "me" {}
45+
`,
46+
Check: func(s *terraform.State) error {
47+
require.Len(t, s.Modules, 1)
48+
require.Len(t, s.Modules[0].Resources, 1)
49+
resource := s.Modules[0].Resources["data.coder_user.me"]
50+
require.NotNil(t, resource)
51+
52+
attrs := resource.Primary.Attributes
53+
assert.Equal(t, "11111111-1111-1111-1111-111111111111", attrs["id"])
54+
assert.Equal(t, "owner123", attrs["name"])
55+
assert.Equal(t, "Mr Owner", attrs["full_name"])
56+
assert.Equal(t, "[email protected]", attrs["email"])
57+
assert.Equal(t, testSSHEd25519PublicKey, attrs["ssh_public_key"])
58+
assert.Equal(t, testSSHEd25519PrivateKey, attrs["ssh_private_key"])
59+
assert.Equal(t, `group1`, attrs["groups.0"])
60+
assert.Equal(t, `group2`, attrs["groups.1"])
61+
return nil
62+
},
63+
}},
64+
})
65+
}

0 commit comments

Comments
 (0)