Skip to content

Commit 940777b

Browse files
deanhuynhmarcelopv
andauthored
User data source (#48)
Co-authored-by: Marcelo Vargas <[email protected]>
1 parent 2f8c4cb commit 940777b

File tree

8 files changed

+381
-3
lines changed

8 files changed

+381
-3
lines changed

docs/data-sources/user.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "segment_user Data Source - terraform-provider-segment"
4+
subcategory: ""
5+
description: |-
6+
A user belonging to a Segment Workspace.
7+
---
8+
9+
# segment_user (Data Source)
10+
11+
A user belonging to a Segment Workspace.
12+
13+
## Example Usage
14+
15+
```terraform
16+
# Gets the user info
17+
data "segment_user" "me" {
18+
id = "abc123"
19+
}
20+
```
21+
22+
<!-- schema generated by tfplugindocs -->
23+
## Schema
24+
25+
### Required
26+
27+
- `id` (String) The unique identifier for this user.
28+
29+
### Read-Only
30+
31+
- `email` (String) The email address associated with this user.
32+
- `name` (String) The human-readable name of this user.
33+
- `permissions` (Attributes Set) The permissions associated with this user. (see [below for nested schema](#nestedatt--permissions))
34+
35+
<a id="nestedatt--permissions"></a>
36+
### Nested Schema for `permissions`
37+
38+
Read-Only:
39+
40+
- `resources` (Attributes Set) The resources associated with this permission. (see [below for nested schema](#nestedatt--permissions--resources))
41+
- `role_id` (String) The id of the role associated with this permission.
42+
43+
<a id="nestedatt--permissions--resources"></a>
44+
### Nested Schema for `permissions.resources`
45+
46+
Read-Only:
47+
48+
- `id` (String) The id of this resource.
49+
- `labels` (Attributes Set) The labels that further refine access to this resource. Labels are exclusive to Workspace-level permissions. (see [below for nested schema](#nestedatt--permissions--resources--labels))
50+
- `type` (String) The type for this resource.
51+
52+
<a id="nestedatt--permissions--resources--labels"></a>
53+
### Nested Schema for `permissions.resources.labels`
54+
55+
Read-Only:
56+
57+
- `description` (String) An optional description of the purpose of this label.
58+
- `key` (String) The key that represents the name of this label.
59+
- `value` (String) The value associated with the key of this label.

docs/resources/user.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
page_title: "segment_user Resource - terraform-provider-segment"
44
subcategory: ""
55
description: |-
6-
A user or invite belonging to a Segment Workspace. Only users may be imported
6+
A user or invite belonging to a Segment Workspace. Only users may be imported.
77
---
88

99
# segment_user (Resource)
1010

11-
A user or invite belonging to a Segment Workspace. Only users may be imported
11+
A user or invite belonging to a Segment Workspace. Only users may be imported.
1212

1313
## Example Usage
1414

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Gets the user info
2+
data "segment_user" "me" {
3+
id = "abc123"
4+
}

internal/provider/models/user.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,31 @@ func (u *UserState) Fill(user api.UserV1) error {
3434
return nil
3535
}
3636

37+
type UserDataSourceState struct {
38+
ID types.String `tfsdk:"id"`
39+
Name types.String `tfsdk:"name"`
40+
Email types.String `tfsdk:"email"`
41+
Permissions []PermissionState `tfsdk:"permissions"`
42+
}
43+
44+
func (u *UserDataSourceState) Fill(user api.UserV1) error {
45+
u.ID = types.StringValue(user.Id)
46+
u.Name = types.StringValue(user.Name)
47+
u.Email = types.StringValue(user.Email)
48+
49+
u.Permissions = []PermissionState{}
50+
for _, p := range user.Permissions {
51+
var permission PermissionState
52+
err := permission.Fill(p)
53+
if err != nil {
54+
return err
55+
}
56+
u.Permissions = append(u.Permissions, permission)
57+
}
58+
59+
return nil
60+
}
61+
3762
type PermissionState struct {
3863
RoleID types.String `tfsdk:"role_id"`
3964
Resources []ResourceState `tfsdk:"resources"`

internal/provider/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ func (p *segmentProvider) DataSources(_ context.Context) []func() datasource.Dat
164164
NewWarehouseDataSource,
165165
NewTrackingPlanDataSource,
166166
NewRoleDataSource,
167+
NewUserDataSource,
167168
}
168169
}
169170

internal/provider/user_data_source.go

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
package provider
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/segmentio/terraform-provider-segment/internal/provider/models"
8+
9+
"github.com/hashicorp/terraform-plugin-framework/datasource"
10+
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
11+
"github.com/segmentio/public-api-sdk-go/api"
12+
)
13+
14+
var (
15+
_ datasource.DataSource = &userDataSource{}
16+
_ datasource.DataSourceWithConfigure = &userDataSource{}
17+
)
18+
19+
type userDataSource struct {
20+
client *api.APIClient
21+
authContext context.Context
22+
}
23+
24+
func NewUserDataSource() datasource.DataSource {
25+
return &userDataSource{}
26+
}
27+
28+
func (d *userDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
29+
if req.ProviderData == nil {
30+
return
31+
}
32+
33+
config, ok := req.ProviderData.(*ClientInfo)
34+
if !ok {
35+
resp.Diagnostics.AddError(
36+
"Unexpected Data Source Configure Type",
37+
fmt.Sprintf("Expected ClientInfo, got: %T. Please report this issue to the provider developers.", req.ProviderData),
38+
)
39+
40+
return
41+
}
42+
43+
d.client = config.client
44+
d.authContext = config.authContext
45+
}
46+
47+
func (d *userDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
48+
resp.TypeName = req.ProviderTypeName + "_user"
49+
}
50+
51+
func (d *userDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
52+
resp.Schema = schema.Schema{
53+
Description: "A user belonging to a Segment Workspace.",
54+
Attributes: map[string]schema.Attribute{
55+
"id": schema.StringAttribute{
56+
Required: true,
57+
Description: "The unique identifier for this user.",
58+
},
59+
"name": schema.StringAttribute{
60+
Description: "The human-readable name of this user.",
61+
Computed: true,
62+
},
63+
"email": schema.StringAttribute{
64+
Description: "The email address associated with this user.",
65+
Computed: true,
66+
},
67+
"permissions": schema.SetNestedAttribute{
68+
Description: "The permissions associated with this user.",
69+
Computed: true,
70+
NestedObject: schema.NestedAttributeObject{
71+
Attributes: map[string]schema.Attribute{
72+
"role_id": schema.StringAttribute{
73+
Description: "The id of the role associated with this permission.",
74+
Computed: true,
75+
},
76+
"resources": schema.SetNestedAttribute{
77+
Description: "The resources associated with this permission.",
78+
Computed: true,
79+
NestedObject: schema.NestedAttributeObject{
80+
Attributes: map[string]schema.Attribute{
81+
"id": schema.StringAttribute{
82+
Description: "The id of this resource.",
83+
Computed: true,
84+
},
85+
"type": schema.StringAttribute{
86+
Description: "The type for this resource.",
87+
Computed: true,
88+
},
89+
"labels": schema.SetNestedAttribute{
90+
Description: "The labels that further refine access to this resource. Labels are exclusive to Workspace-level permissions.",
91+
Computed: true,
92+
NestedObject: schema.NestedAttributeObject{
93+
Attributes: map[string]schema.Attribute{
94+
"key": schema.StringAttribute{
95+
Description: "The key that represents the name of this label.",
96+
Computed: true,
97+
},
98+
"value": schema.StringAttribute{
99+
Description: "The value associated with the key of this label.",
100+
Computed: true,
101+
},
102+
"description": schema.StringAttribute{
103+
Description: "An optional description of the purpose of this label.",
104+
Computed: true,
105+
},
106+
},
107+
},
108+
},
109+
},
110+
},
111+
},
112+
},
113+
},
114+
},
115+
},
116+
}
117+
}
118+
119+
func (d *userDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
120+
var config models.UserDataSourceState
121+
diags := req.Config.Get(ctx, &config)
122+
resp.Diagnostics.Append(diags...)
123+
if resp.Diagnostics.HasError() {
124+
return
125+
}
126+
127+
id := config.ID.ValueString()
128+
if id == "" {
129+
resp.Diagnostics.AddError("Unable to read user", "ID is empty")
130+
131+
return
132+
}
133+
134+
out, body, err := d.client.IAMUsersApi.GetUser(d.authContext, id).Execute()
135+
if body != nil {
136+
defer body.Body.Close()
137+
}
138+
if err != nil {
139+
resp.Diagnostics.AddError(
140+
"Unable to read user",
141+
getError(err, body),
142+
)
143+
144+
return
145+
}
146+
147+
var state models.UserDataSourceState
148+
err = state.Fill(api.UserV1(out.Data.User))
149+
if err != nil {
150+
resp.Diagnostics.AddError(
151+
"Unable to read user",
152+
err.Error(),
153+
)
154+
155+
return
156+
}
157+
158+
diags = resp.State.Set(ctx, &state)
159+
resp.Diagnostics.Append(diags...)
160+
if resp.Diagnostics.HasError() {
161+
return
162+
}
163+
}

0 commit comments

Comments
 (0)