Skip to content

Commit f7cbf28

Browse files
Add grafana_service_account_permission_item resource
Part of #1000 Just like #1465
1 parent 88a7b1b commit f7cbf28

12 files changed

+438
-16
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "grafana_dashboard_permission_item Resource - terraform-provider-grafana"
4+
subcategory: "Grafana OSS"
5+
description: |-
6+
Manages a single permission item for a dashboard. Conflicts with the "grafanadashboardpermission" resource which manages the entire set of permissions for a dashboard.
7+
---
8+
9+
# grafana_dashboard_permission_item (Resource)
10+
11+
Manages a single permission item for a dashboard. Conflicts with the "grafana_dashboard_permission" resource which manages the entire set of permissions for a dashboard.
12+
13+
## Example Usage
14+
15+
```terraform
16+
resource "grafana_team" "team" {
17+
name = "Team Name"
18+
}
19+
20+
resource "grafana_user" "user" {
21+
22+
password = "my-password"
23+
login = "user.name"
24+
}
25+
26+
resource "grafana_dashboard" "dashboard" {
27+
config_json = jsonencode({
28+
"title" : "My Dashboard",
29+
"uid" : "my-dashboard-uid"
30+
})
31+
}
32+
33+
resource "grafana_dashboard_permission_item" "role" {
34+
dashboard_uid = grafana_dashboard.dashboard.uid
35+
role = "Viewer"
36+
permission = "View"
37+
}
38+
39+
resource "grafana_dashboard_permission_item" "user" {
40+
dashboard_uid = grafana_dashboard.dashboard.uid
41+
user = grafana_user.user.id
42+
permission = "Admin"
43+
}
44+
45+
resource "grafana_dashboard_permission_item" "team" {
46+
dashboard_uid = grafana_dashboard.dashboard.uid
47+
team = grafana_team.team.id
48+
permission = "Edit"
49+
}
50+
```
51+
52+
<!-- schema generated by tfplugindocs -->
53+
## Schema
54+
55+
### Required
56+
57+
- `dashboard_uid` (String) The UID of the dashboard.
58+
- `permission` (String) the permission to be assigned
59+
60+
### Optional
61+
62+
- `org_id` (String) The Organization ID. If not set, the Org ID defined in the provider block will be used.
63+
- `role` (String) the role onto which the permission is to be assigned
64+
- `team` (String) the team onto which the permission is to be assigned
65+
- `user` (String) the user or service account onto which the permission is to be assigned
66+
67+
### Read-Only
68+
69+
- `id` (String) The ID of this resource.
70+
71+
## Import
72+
73+
Import is supported using the following syntax:
74+
75+
```shell
76+
terraform import grafana_dashboard_permission_item.name "{{ dashboardUID }}:{{ type (role, team, or user) }}:{{ identifier }}"
77+
terraform import grafana_dashboard_permission_item.name "{{ orgID }}:{{ dashboardUID }}:{{ type (role, team, or user) }}:{{ identifier }}"
78+
```
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
terraform import grafana_dashboard_permission_item.name "{{ dashboardUID }}:{{ type (role, team, or user) }}:{{ identifier }}"
2+
terraform import grafana_dashboard_permission_item.name "{{ orgID }}:{{ dashboardUID }}:{{ type (role, team, or user) }}:{{ identifier }}"
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
resource "grafana_team" "team" {
2+
name = "Team Name"
3+
}
4+
5+
resource "grafana_user" "user" {
6+
7+
password = "my-password"
8+
login = "user.name"
9+
}
10+
11+
resource "grafana_dashboard" "dashboard" {
12+
config_json = jsonencode({
13+
"title" : "My Dashboard",
14+
"uid" : "my-dashboard-uid"
15+
})
16+
}
17+
18+
resource "grafana_dashboard_permission_item" "role" {
19+
dashboard_uid = grafana_dashboard.dashboard.uid
20+
role = "Viewer"
21+
permission = "View"
22+
}
23+
24+
resource "grafana_dashboard_permission_item" "user" {
25+
dashboard_uid = grafana_dashboard.dashboard.uid
26+
user = grafana_user.user.id
27+
permission = "Admin"
28+
}
29+
30+
resource "grafana_dashboard_permission_item" "team" {
31+
dashboard_uid = grafana_dashboard.dashboard.uid
32+
team = grafana_team.team.id
33+
permission = "Edit"
34+
}

internal/resources/grafana/common_resource_permission.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ const (
2424
permissionTargetRole = "role"
2525
permissionTargetTeam = "team"
2626
permissionTargetUser = "user"
27+
28+
dashboardsPermissionsType = "dashboards"
29+
datasourcesPermissionsType = "datasources"
30+
foldersPermissionsType = "folders"
31+
serviceAccountsPermissionsType = "serviceaccounts"
2732
)
2833

2934
type resourcePermissionItemBaseModel struct {
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
package grafana
2+
3+
import (
4+
"context"
5+
6+
"github.com/grafana/grafana-openapi-client-go/client"
7+
"github.com/grafana/terraform-provider-grafana/v2/internal/common"
8+
"github.com/hashicorp/terraform-plugin-framework/resource"
9+
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
10+
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
11+
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
12+
"github.com/hashicorp/terraform-plugin-framework/types"
13+
)
14+
15+
var (
16+
resourceDashboardPermissionItemName = "grafana_dashboard_permission_item"
17+
resourceDashboardPermissionItemID = common.NewResourceID(common.OptionalIntIDField("orgID"), common.StringIDField("dashboardUID"), common.StringIDField("type (role, team, or user)"), common.StringIDField("identifier"))
18+
19+
// Check interface
20+
_ resource.ResourceWithImportState = (*resourceDashboardPermissionItem)(nil)
21+
)
22+
23+
func makeResourceDashboardPermissionItem() *common.Resource {
24+
resourceStruct := &resourceDashboardPermissionItem{
25+
resourcePermissionBase: resourcePermissionBase{
26+
resourceType: dashboardsPermissionsType,
27+
},
28+
}
29+
return common.NewResource(resourceDashboardPermissionItemName, resourceDashboardPermissionItemID, resourceStruct)
30+
}
31+
32+
type resourceDashboardPermissionItemModel struct {
33+
ID types.String `tfsdk:"id"`
34+
OrgID types.String `tfsdk:"org_id"`
35+
Role types.String `tfsdk:"role"`
36+
Team types.String `tfsdk:"team"`
37+
User types.String `tfsdk:"user"`
38+
Permission types.String `tfsdk:"permission"`
39+
DashboardUID types.String `tfsdk:"dashboard_uid"`
40+
}
41+
42+
// Framework doesn't support embedding a base struct: https://github.com/hashicorp/terraform-plugin-framework/issues/242
43+
func (m *resourceDashboardPermissionItemModel) ToBase() *resourcePermissionItemBaseModel {
44+
return &resourcePermissionItemBaseModel{
45+
ID: m.ID,
46+
OrgID: m.OrgID,
47+
Role: m.Role,
48+
Team: m.Team,
49+
User: m.User,
50+
Permission: m.Permission,
51+
}
52+
}
53+
54+
func (m *resourceDashboardPermissionItemModel) SetFromBase(base *resourcePermissionItemBaseModel) {
55+
m.DashboardUID = base.ResourceID
56+
m.ID = base.ID
57+
m.OrgID = base.OrgID
58+
m.Role = base.Role
59+
m.Team = base.Team
60+
m.User = base.User
61+
m.Permission = base.Permission
62+
}
63+
64+
type resourceDashboardPermissionItem struct{ resourcePermissionBase }
65+
66+
func (r *resourceDashboardPermissionItem) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
67+
resp.TypeName = resourceDashboardPermissionItemName
68+
}
69+
70+
func (r *resourceDashboardPermissionItem) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
71+
resp.Schema = schema.Schema{
72+
MarkdownDescription: `Manages a single permission item for a dashboard. Conflicts with the "grafana_dashboard_permission" resource which manages the entire set of permissions for a dashboard.`,
73+
Attributes: r.addInSchemaAttributes(map[string]schema.Attribute{
74+
"dashboard_uid": schema.StringAttribute{
75+
Required: true,
76+
Description: "The UID of the dashboard.",
77+
PlanModifiers: []planmodifier.String{
78+
stringplanmodifier.RequiresReplace(),
79+
},
80+
},
81+
}),
82+
}
83+
}
84+
85+
func (r *resourceDashboardPermissionItem) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
86+
readData, diags := r.readItem(req.ID, r.dashboardQuery)
87+
if diags != nil {
88+
resp.Diagnostics = diags
89+
return
90+
}
91+
if readData == nil {
92+
resp.Diagnostics.AddError("Resource not found", "Resource not found")
93+
return
94+
}
95+
var data resourceDashboardPermissionItemModel
96+
data.SetFromBase(readData)
97+
98+
resp.Diagnostics.Append(resp.State.Set(ctx, data)...)
99+
}
100+
101+
func (r *resourceDashboardPermissionItem) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
102+
// Read Terraform plan data into the model
103+
var data resourceDashboardPermissionItemModel
104+
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
105+
if resp.Diagnostics.HasError() {
106+
return
107+
}
108+
base := data.ToBase()
109+
if diags := r.writeItem(data.DashboardUID.ValueString(), base); diags != nil {
110+
resp.Diagnostics = diags
111+
return
112+
}
113+
data.SetFromBase(base)
114+
115+
resp.Diagnostics.Append(resp.State.Set(ctx, data)...)
116+
}
117+
118+
func (r *resourceDashboardPermissionItem) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
119+
// Read Terraform state data into the model
120+
var data resourceDashboardPermissionItemModel
121+
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
122+
123+
// Read from API
124+
readData, diags := r.readItem(data.ID.ValueString(), r.dashboardQuery)
125+
if diags != nil {
126+
resp.Diagnostics = diags
127+
return
128+
}
129+
if readData == nil {
130+
resp.State.RemoveResource(ctx)
131+
return
132+
}
133+
data.SetFromBase(readData)
134+
135+
// Save data into Terraform state
136+
resp.Diagnostics.Append(resp.State.Set(ctx, data)...)
137+
}
138+
139+
func (r *resourceDashboardPermissionItem) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
140+
// Read Terraform plan data into the model
141+
var data resourceDashboardPermissionItemModel
142+
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
143+
if resp.Diagnostics.HasError() {
144+
return
145+
}
146+
base := data.ToBase()
147+
if diags := r.writeItem(data.DashboardUID.ValueString(), base); diags != nil {
148+
resp.Diagnostics = diags
149+
return
150+
}
151+
data.SetFromBase(base)
152+
153+
resp.Diagnostics.Append(resp.State.Set(ctx, data)...)
154+
}
155+
156+
func (r *resourceDashboardPermissionItem) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
157+
// Read Terraform prior state data into the model
158+
var data resourceDashboardPermissionItemModel
159+
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
160+
data.Permission = types.StringValue("")
161+
162+
if diags := r.writeItem(data.DashboardUID.ValueString(), data.ToBase()); diags != nil {
163+
resp.Diagnostics = diags
164+
}
165+
}
166+
167+
func (r *resourceDashboardPermissionItem) dashboardQuery(client *client.GrafanaHTTPAPI, dashboardUID string) error {
168+
_, err := client.Dashboards.GetDashboardByUID(dashboardUID)
169+
return err
170+
}

0 commit comments

Comments
 (0)