Skip to content

Commit 3705ccd

Browse files
committed
allow managing workflow permissions
1 parent 3a7179b commit 3705ccd

File tree

8 files changed

+410
-3
lines changed

8 files changed

+410
-3
lines changed

internal/client/models.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ type WorkflowStep struct {
8282
Id string `json:"id"`
8383
Name string `json:"name"`
8484
// Action fields
85-
Action *WorkflowStepAction `json:"action"`
85+
Action *WorkflowStepAction `json:"action"`
86+
Permissions []*Permission `json:"permissions"`
8687
}
8788

8889
type WorkflowStepAction struct {
@@ -138,3 +139,23 @@ type DashboardPanelDetails struct {
138139
Query string `json:"query"`
139140
CredentialId string `json:"credential_id"`
140141
}
142+
143+
type Permission struct {
144+
Id string `json:"id"`
145+
Permission string `json:"permission"`
146+
RoleId string `json:"role_id"`
147+
OrganizationUserId string `json:"organization_user_id"`
148+
}
149+
150+
type Role struct {
151+
Id string `json:"id"`
152+
Name string `json:"name"`
153+
Description string `json:"description"`
154+
Managed bool `json:"managed"`
155+
}
156+
157+
type User struct {
158+
Id string `json:"id"`
159+
Name string `json:"name"`
160+
Email string `json:"email"`
161+
}

internal/client/role.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package devhub
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"net/http"
7+
)
8+
9+
func (c *Client) GetRole(name string) (*Role, error) {
10+
req, err := http.NewRequest("GET", fmt.Sprintf("%s/api/v1/roles/lookup?name=%s", c.HostURL, name), nil)
11+
if err != nil {
12+
return nil, err
13+
}
14+
15+
body, err := c.doRequest(req)
16+
if err != nil {
17+
return nil, err
18+
}
19+
20+
role := Role{}
21+
err = json.Unmarshal(body, &role)
22+
if err != nil {
23+
return nil, err
24+
}
25+
26+
return &role, nil
27+
}

internal/client/user.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package devhub
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"net/http"
7+
)
8+
9+
func (c *Client) GetUser(identifier string, lookupBy string) (*User, error) {
10+
req, err := http.NewRequest("GET", fmt.Sprintf("%s/api/v1/users/lookup?%s=%s", c.HostURL, lookupBy, identifier), nil)
11+
if err != nil {
12+
return nil, err
13+
}
14+
15+
body, err := c.doRequest(req)
16+
if err != nil {
17+
return nil, err
18+
}
19+
20+
user := User{}
21+
err = json.Unmarshal(body, &user)
22+
if err != nil {
23+
return nil, err
24+
}
25+
26+
return &user, nil
27+
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package provider
2+
3+
import (
4+
"context"
5+
"fmt"
6+
devhub "terraform-provider-devhub/internal/client"
7+
8+
"github.com/hashicorp/terraform-plugin-framework/datasource"
9+
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
10+
"github.com/hashicorp/terraform-plugin-framework/types"
11+
)
12+
13+
var (
14+
_ datasource.DataSource = &roleDataSource{}
15+
_ datasource.DataSourceWithConfigure = &roleDataSource{}
16+
)
17+
18+
func NewRoleDataSource() datasource.DataSource {
19+
return &roleDataSource{}
20+
}
21+
22+
type roleDataSource struct {
23+
client *devhub.Client
24+
}
25+
26+
type roleDataSourceModel struct {
27+
Id types.String `tfsdk:"id"`
28+
Name types.String `tfsdk:"name"`
29+
Description types.String `tfsdk:"description"`
30+
Managed types.Bool `tfsdk:"managed"`
31+
}
32+
33+
func (d *roleDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
34+
resp.TypeName = req.ProviderTypeName + "_role"
35+
}
36+
37+
func (d *roleDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
38+
resp.Schema = schema.Schema{
39+
Attributes: map[string]schema.Attribute{
40+
"id": schema.StringAttribute{
41+
Computed: true,
42+
},
43+
"name": schema.StringAttribute{
44+
Required: true,
45+
},
46+
"description": schema.StringAttribute{
47+
Computed: true,
48+
},
49+
"managed": schema.BoolAttribute{
50+
Computed: true,
51+
},
52+
},
53+
}
54+
}
55+
56+
// Read refreshes the Terraform state with the latest data.
57+
func (d *roleDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
58+
var state roleDataSourceModel
59+
60+
resp.Diagnostics.Append(req.Config.Get(ctx, &state)...)
61+
if resp.Diagnostics.HasError() {
62+
return
63+
}
64+
65+
role, err := d.client.GetRole(state.Name.ValueString())
66+
if err != nil {
67+
resp.Diagnostics.AddError(
68+
"Error Reading Role",
69+
fmt.Sprintf("Could not read role: %s", err.Error()),
70+
)
71+
return
72+
}
73+
74+
state.Id = types.StringValue(role.Id)
75+
state.Name = types.StringValue(role.Name)
76+
state.Description = types.StringValue(role.Description)
77+
state.Managed = types.BoolValue(role.Managed)
78+
79+
diags := resp.State.Set(ctx, &state)
80+
resp.Diagnostics.Append(diags...)
81+
if resp.Diagnostics.HasError() {
82+
return
83+
}
84+
}
85+
86+
// Configure adds the provider configured client to the data source.
87+
func (d *roleDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
88+
if req.ProviderData == nil {
89+
return
90+
}
91+
92+
client, ok := req.ProviderData.(*devhub.Client)
93+
if !ok {
94+
resp.Diagnostics.AddError(
95+
"Unexpected Data Source Configure Type",
96+
fmt.Sprintf("Expected *devhub.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData),
97+
)
98+
return
99+
}
100+
101+
d.client = client
102+
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package provider
2+
3+
import (
4+
"context"
5+
"fmt"
6+
devhub "terraform-provider-devhub/internal/client"
7+
8+
"github.com/hashicorp/terraform-plugin-framework/datasource"
9+
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
10+
"github.com/hashicorp/terraform-plugin-framework/types"
11+
)
12+
13+
var (
14+
_ datasource.DataSource = &userDataSource{}
15+
_ datasource.DataSourceWithConfigure = &userDataSource{}
16+
)
17+
18+
func NewUserDataSource() datasource.DataSource {
19+
return &userDataSource{}
20+
}
21+
22+
type userDataSource struct {
23+
client *devhub.Client
24+
}
25+
26+
type userDataSourceModel struct {
27+
Id types.String `tfsdk:"id"`
28+
Name types.String `tfsdk:"name"`
29+
Email types.String `tfsdk:"email"`
30+
}
31+
32+
func (d *userDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
33+
resp.TypeName = req.ProviderTypeName + "_user"
34+
}
35+
36+
func (d *userDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
37+
resp.Schema = schema.Schema{
38+
Attributes: map[string]schema.Attribute{
39+
"id": schema.StringAttribute{
40+
Computed: true,
41+
},
42+
"name": schema.StringAttribute{
43+
Optional: true,
44+
},
45+
"email": schema.StringAttribute{
46+
Optional: true,
47+
},
48+
},
49+
}
50+
}
51+
52+
// Read refreshes the Terraform state with the latest data.
53+
func (d *userDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
54+
var state userDataSourceModel
55+
56+
resp.Diagnostics.Append(req.Config.Get(ctx, &state)...)
57+
if resp.Diagnostics.HasError() {
58+
return
59+
}
60+
61+
lookupBy := ""
62+
identifier := ""
63+
64+
if state.Email.ValueString() != "" {
65+
lookupBy = "email"
66+
identifier = state.Email.ValueString()
67+
}
68+
69+
if state.Name.ValueString() != "" {
70+
lookupBy = "name"
71+
identifier = state.Name.ValueString()
72+
}
73+
74+
user, err := d.client.GetUser(identifier, lookupBy)
75+
if err != nil {
76+
resp.Diagnostics.AddError(
77+
"Error Reading User",
78+
fmt.Sprintf("Could not read User: %s", err.Error()),
79+
)
80+
return
81+
}
82+
83+
state.Id = types.StringValue(user.Id)
84+
state.Name = types.StringValue(user.Name)
85+
state.Email = types.StringValue(user.Email)
86+
87+
diags := resp.State.Set(ctx, &state)
88+
resp.Diagnostics.Append(diags...)
89+
if resp.Diagnostics.HasError() {
90+
return
91+
}
92+
}
93+
94+
// Configure adds the provider configured client to the data source.
95+
func (d *userDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
96+
if req.ProviderData == nil {
97+
return
98+
}
99+
100+
client, ok := req.ProviderData.(*devhub.Client)
101+
if !ok {
102+
resp.Diagnostics.AddError(
103+
"Unexpected Data Source Configure Type",
104+
fmt.Sprintf("Expected *devhub.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData),
105+
)
106+
return
107+
}
108+
109+
d.client = client
110+
}

0 commit comments

Comments
 (0)