Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add grafana_dashboard_permission_item resource #1481

Merged
merged 1 commit into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions docs/resources/dashboard_permission_item.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "grafana_dashboard_permission_item Resource - terraform-provider-grafana"
subcategory: "Grafana OSS"
description: |-
Manages a single permission item for a dashboard. Conflicts with the "grafanadashboardpermission" resource which manages the entire set of permissions for a dashboard.
---

# grafana_dashboard_permission_item (Resource)

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.

## Example Usage

```terraform
resource "grafana_team" "team" {
name = "Team Name"
}

resource "grafana_user" "user" {
email = "user.name@example.com"
password = "my-password"
login = "user.name"
}

resource "grafana_dashboard" "dashboard" {
config_json = jsonencode({
"title" : "My Dashboard",
"uid" : "my-dashboard-uid"
})
}

resource "grafana_dashboard_permission_item" "role" {
dashboard_uid = grafana_dashboard.dashboard.uid
role = "Viewer"
permission = "View"
}

resource "grafana_dashboard_permission_item" "user" {
dashboard_uid = grafana_dashboard.dashboard.uid
user = grafana_user.user.id
permission = "Admin"
}

resource "grafana_dashboard_permission_item" "team" {
dashboard_uid = grafana_dashboard.dashboard.uid
team = grafana_team.team.id
permission = "Edit"
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `dashboard_uid` (String) The UID of the dashboard.
- `permission` (String) the permission to be assigned

### Optional

- `org_id` (String) The Organization ID. If not set, the Org ID defined in the provider block will be used.
- `role` (String) the role onto which the permission is to be assigned
- `team` (String) the team onto which the permission is to be assigned
- `user` (String) the user or service account onto which the permission is to be assigned

### Read-Only

- `id` (String) The ID of this resource.

## Import

Import is supported using the following syntax:

```shell
terraform import grafana_dashboard_permission_item.name "{{ dashboardUID }}:{{ type (role, team, or user) }}:{{ identifier }}"
terraform import grafana_dashboard_permission_item.name "{{ orgID }}:{{ dashboardUID }}:{{ type (role, team, or user) }}:{{ identifier }}"
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
terraform import grafana_dashboard_permission_item.name "{{ dashboardUID }}:{{ type (role, team, or user) }}:{{ identifier }}"
terraform import grafana_dashboard_permission_item.name "{{ orgID }}:{{ dashboardUID }}:{{ type (role, team, or user) }}:{{ identifier }}"
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
resource "grafana_team" "team" {
name = "Team Name"
}

resource "grafana_user" "user" {
email = "user.name@example.com"
password = "my-password"
login = "user.name"
}

resource "grafana_dashboard" "dashboard" {
config_json = jsonencode({
"title" : "My Dashboard",
"uid" : "my-dashboard-uid"
})
}

resource "grafana_dashboard_permission_item" "role" {
dashboard_uid = grafana_dashboard.dashboard.uid
role = "Viewer"
permission = "View"
}

resource "grafana_dashboard_permission_item" "user" {
dashboard_uid = grafana_dashboard.dashboard.uid
user = grafana_user.user.id
permission = "Admin"
}

resource "grafana_dashboard_permission_item" "team" {
dashboard_uid = grafana_dashboard.dashboard.uid
team = grafana_team.team.id
permission = "Edit"
}
5 changes: 5 additions & 0 deletions internal/resources/grafana/common_resource_permission.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ const (
permissionTargetRole = "role"
permissionTargetTeam = "team"
permissionTargetUser = "user"

dashboardsPermissionsType = "dashboards"
datasourcesPermissionsType = "datasources"
foldersPermissionsType = "folders"
serviceAccountsPermissionsType = "serviceaccounts"
)

type resourcePermissionItemBaseModel struct {
Expand Down
170 changes: 170 additions & 0 deletions internal/resources/grafana/resource_dashboard_permission_item.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
package grafana

import (
"context"

"github.com/grafana/grafana-openapi-client-go/client"
"github.com/grafana/terraform-provider-grafana/v2/internal/common"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/types"
)

var (
resourceDashboardPermissionItemName = "grafana_dashboard_permission_item"
resourceDashboardPermissionItemID = common.NewResourceID(common.OptionalIntIDField("orgID"), common.StringIDField("dashboardUID"), common.StringIDField("type (role, team, or user)"), common.StringIDField("identifier"))

// Check interface
_ resource.ResourceWithImportState = (*resourceDashboardPermissionItem)(nil)
)

func makeResourceDashboardPermissionItem() *common.Resource {
resourceStruct := &resourceDashboardPermissionItem{
resourcePermissionBase: resourcePermissionBase{
resourceType: dashboardsPermissionsType,
},
}
return common.NewResource(resourceDashboardPermissionItemName, resourceDashboardPermissionItemID, resourceStruct)
}

type resourceDashboardPermissionItemModel struct {
ID types.String `tfsdk:"id"`
OrgID types.String `tfsdk:"org_id"`
Role types.String `tfsdk:"role"`
Team types.String `tfsdk:"team"`
User types.String `tfsdk:"user"`
Permission types.String `tfsdk:"permission"`
DashboardUID types.String `tfsdk:"dashboard_uid"`
}

// Framework doesn't support embedding a base struct: https://github.com/hashicorp/terraform-plugin-framework/issues/242
func (m *resourceDashboardPermissionItemModel) ToBase() *resourcePermissionItemBaseModel {
return &resourcePermissionItemBaseModel{
ID: m.ID,
OrgID: m.OrgID,
Role: m.Role,
Team: m.Team,
User: m.User,
Permission: m.Permission,
}
}

func (m *resourceDashboardPermissionItemModel) SetFromBase(base *resourcePermissionItemBaseModel) {
m.DashboardUID = base.ResourceID
m.ID = base.ID
m.OrgID = base.OrgID
m.Role = base.Role
m.Team = base.Team
m.User = base.User
m.Permission = base.Permission
}

type resourceDashboardPermissionItem struct{ resourcePermissionBase }

func (r *resourceDashboardPermissionItem) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
resp.TypeName = resourceDashboardPermissionItemName
}

func (r *resourceDashboardPermissionItem) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
resp.Schema = schema.Schema{
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.`,
Attributes: r.addInSchemaAttributes(map[string]schema.Attribute{
"dashboard_uid": schema.StringAttribute{
Required: true,
Description: "The UID of the dashboard.",
PlanModifiers: []planmodifier.String{
stringplanmodifier.RequiresReplace(),
},
},
}),
}
}

func (r *resourceDashboardPermissionItem) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
readData, diags := r.readItem(req.ID, r.dashboardQuery)
if diags != nil {
resp.Diagnostics = diags
return
}
if readData == nil {
resp.Diagnostics.AddError("Resource not found", "Resource not found")
return
}
var data resourceDashboardPermissionItemModel
data.SetFromBase(readData)

resp.Diagnostics.Append(resp.State.Set(ctx, data)...)
}

func (r *resourceDashboardPermissionItem) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
// Read Terraform plan data into the model
var data resourceDashboardPermissionItemModel
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
if resp.Diagnostics.HasError() {
return
}
base := data.ToBase()
if diags := r.writeItem(data.DashboardUID.ValueString(), base); diags != nil {
resp.Diagnostics = diags
return
}
data.SetFromBase(base)

resp.Diagnostics.Append(resp.State.Set(ctx, data)...)
}

func (r *resourceDashboardPermissionItem) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
// Read Terraform state data into the model
var data resourceDashboardPermissionItemModel
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)

// Read from API
readData, diags := r.readItem(data.ID.ValueString(), r.dashboardQuery)
if diags != nil {
resp.Diagnostics = diags
return
}
if readData == nil {
resp.State.RemoveResource(ctx)
return
}
data.SetFromBase(readData)

// Save data into Terraform state
resp.Diagnostics.Append(resp.State.Set(ctx, data)...)
}

func (r *resourceDashboardPermissionItem) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
// Read Terraform plan data into the model
var data resourceDashboardPermissionItemModel
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
if resp.Diagnostics.HasError() {
return
}
base := data.ToBase()
if diags := r.writeItem(data.DashboardUID.ValueString(), base); diags != nil {
resp.Diagnostics = diags
return
}
data.SetFromBase(base)

resp.Diagnostics.Append(resp.State.Set(ctx, data)...)
}

func (r *resourceDashboardPermissionItem) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
// Read Terraform prior state data into the model
var data resourceDashboardPermissionItemModel
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
data.Permission = types.StringValue("")

if diags := r.writeItem(data.DashboardUID.ValueString(), data.ToBase()); diags != nil {
resp.Diagnostics = diags
}
}

func (r *resourceDashboardPermissionItem) dashboardQuery(client *client.GrafanaHTTPAPI, dashboardUID string) error {
_, err := client.Dashboards.GetDashboardByUID(dashboardUID)
return err
}
Loading
Loading