Skip to content

Commit

Permalink
Add RBAC roles support to Grafana Cloud instance credentials
Browse files Browse the repository at this point in the history
  • Loading branch information
F21 committed Apr 3, 2024
1 parent 5a1ce44 commit eb55564
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 0 deletions.
42 changes: 42 additions & 0 deletions client/stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,3 +145,45 @@ func (g *Grafana) DeleteGrafanaServiceAccountFromCloud(stack string, serviceAcco

return nil
}

func (g *Grafana) CreateTemporaryStackGrafanaClient(stackSlug string, tempSaPrefix string, tempKeyDuration time.Duration) (tempClient *Grafana, cleanup func() error, err error) {
stack, err := g.StackBySlug(stackSlug)
if err != nil {
return nil, nil, err
}

name := fmt.Sprintf("%s%d", tempSaPrefix, time.Now().UnixNano())

req := CreateServiceAccountInput{
Name: name,
Role: "Admin",
}

sa, err := g.CreateGrafanaServiceAccountFromCloud(stackSlug, req)
if err != nil {
return nil, nil, fmt.Errorf("error creating temporary service account: %w", err)
}

tokenRequest := CreateServiceAccountTokenInput{
Name: name,
ServiceAccountID: sa.ID,
SecondsToLive: int64(tempKeyDuration.Seconds()),
}

token, err := g.CreateGrafanaServiceAccountTokenFromCloud(stackSlug, tokenRequest)
if err != nil {
return nil, nil, fmt.Errorf("error creating temporary service account token: %w", err)
}

client, err := New(stack.URL, token.Key)
if err != nil {
return nil, nil, fmt.Errorf("error creating temporary client: %w", err)
}

cleanup = func() error {
err = client.DeleteServiceAccount(sa.ID)
return err
}

return client, cleanup, nil
}
44 changes: 44 additions & 0 deletions path_credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/json"
"errors"
"fmt"
"time"

"github.com/Boostport/vault-plugin-secrets-grafana/client"
"github.com/google/uuid"
Expand Down Expand Up @@ -178,6 +179,49 @@ func createCloudServiceAccountToken(c *client.Grafana, credentialName string, ro
return nil, fmt.Errorf("error creating service account: %w", err)
}

if len(roleEntry.RBACRoles) > 0 {
instanceClient, cleanup, err := c.CreateTemporaryStackGrafanaClient(roleEntry.Stack, "vault-temp-service-account-", 5*time.Minute)

if err != nil {
err := c.DeleteGrafanaServiceAccountFromCloud(roleEntry.Stack, serviceAccount.ID)

if err != nil {
return nil, fmt.Errorf("error deleting service account after error creating temporary client: %w", err)
}

return nil, fmt.Errorf("error creating temporary client: %w", err)
}

defer cleanup()

roleUIDs, err := customRBACRoleNamesToIDs(instanceClient, roleEntry.RBACRoles)

if err != nil {
err := c.DeleteGrafanaServiceAccountFromCloud(roleEntry.Stack, serviceAccount.ID)

if err != nil {
return nil, fmt.Errorf("error deleting service account after error converting role names to IDs: %w", err)
}
return nil, fmt.Errorf("error converting role names to IDs: %w", err)
}

err = instanceClient.SetServiceAccountRoleAssignments(client.ServiceAccountRoleAssignmentsInput{
ServiceAccountID: serviceAccount.ID,
RoleUIDs: roleUIDs,
})

if err != nil {
err := c.DeleteGrafanaServiceAccountFromCloud(roleEntry.Stack, serviceAccount.ID)

if err != nil {
return nil, fmt.Errorf("error deleting service account after error setting role assignments: %w", err)

}

return nil, fmt.Errorf("error setting service account role assignments: %w", err)
}
}

token, err := c.CreateGrafanaServiceAccountTokenFromCloud(roleEntry.Stack, client.CreateServiceAccountTokenInput{
Name: credentialName,
ServiceAccountID: serviceAccount.ID,
Expand Down

0 comments on commit eb55564

Please sign in to comment.