Files
threshold-plugin-minio/plugin/service/storage/rotation.go
T
Louis Ruch c9e9377b4a chore: update usage of minio admin library (#28)
* chore: update usage of minio admin library
2025-01-21 09:45:04 -08:00

92 lines
2.5 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package storage
import (
"context"
"encoding/json"
"fmt"
"sync"
"time"
"github.com/hashicorp/boundary-plugin-minio/internal/client"
)
const (
defaultPolicyTemplate = `{
"Statement": [
{
"Action": [
"s3:GetObject",
"s3:GetObjectAttributes",
"s3:PutObject",
"s3:DeleteObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::%[1]s/*"
},
{
"Action": "s3:ListBucket",
"Effect": "Allow",
"Resource": "arn:aws:s3:::%[1]s"
},
{
"Action": [
"admin:CreateServiceAccount",
"admin:RemoveServiceAccount"
],
"Effect": "Allow"
}
],
"Version": "2012-10-17"
}`
)
type deleteInputCredsFn func() error
// rotateCredentials uses the incoming service account credentials to generate a
// new service account. It returns a new StorageSecrets object with the new
// service account credentials and a callback function to delete the service
// account provided in the input.
func rotateCredentials(ctx context.Context, bucketName string, sa *StorageAttributes, inSec *StorageSecrets) (*StorageSecrets, deleteInputCredsFn, error) {
err := ensureServiceAccount(ctx, sa, inSec)
if err != nil {
return nil, nil, fmt.Errorf("failed to ensure minio service account credentials: %w", err)
}
ac, err := client.New(sa.EndpointUrl, inSec.AccessKeyId, inSec.SecretAccessKey, client.WithUseSsl(sa.UseSSL))
if err != nil {
return nil, nil, fmt.Errorf("failed to create new client: %w", err)
}
policy := json.RawMessage(fmt.Sprintf(defaultPolicyTemplate, bucketName))
newCreds, err := ac.AddServiceAccount(ctx, client.AddServiceAccountReq{
Name: "Boundary MinIO Service Account",
Description: fmt.Sprintf("Boundary-managed MinIO service account for storage bucket '%s'", bucketName),
Policy: policy,
})
if err != nil {
return nil, nil, fmt.Errorf("failed to create new minio service account: %w", err)
}
newSec := &StorageSecrets{
AccessKeyId: newCreds.AccessKeyId,
SecretAccessKey: newCreds.SecretAccessKey,
LastRotatedTime: time.Now(),
}
inCl := inSec.Clone()
return newSec, sync.OnceValue(func() error {
ac, err := client.New(sa.EndpointUrl, inCl.AccessKeyId, inCl.SecretAccessKey, client.WithUseSsl(sa.UseSSL))
if err != nil {
return fmt.Errorf("failed to create new client: %w", err)
}
err = ac.DeleteServiceAccount(ctx, inCl.AccessKeyId)
if err != nil {
return fmt.Errorf("failed to delete minio service account: %w", err)
}
return nil
}), nil
}