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

Lines changed: 26 additions & 0 deletions
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

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: 113 additions & 0 deletions
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

Lines changed: 65 additions & 0 deletions
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", "owner123@example.com")
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, "owner123@example.com", 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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy