~ knotless Search/
↑↓ move↵ open⇧↵ all results
0
0
main
76 lines · 2.5 KB Raw History
package vault

import (
	"context"
	"errors"
	"fmt"
	"strings"
	"time"

	commonv1 "github.com/johnandersen777/socialweb-computer-kcp/api/common/v1alpha1"
	"github.com/johnandersen777/socialweb-computer-kcp/internal/bus"
	contractvault "github.com/johnandersen777/socialweb-computer-kcp/internal/contract/vault"
)

const SecretRenew = 5 * time.Minute

var ErrNoVault = errors.New("vault: the secret ref names no Vault, mount and path")

func SecretScope(ref commonv1.SecretRef) string {
	return strings.Trim(strings.TrimSpace(ref.Mount), "/") + "/" + strings.Trim(strings.TrimSpace(ref.Path), "/")
}

func secretTarget(from commonv1.ObjectRef, ref commonv1.SecretRef) (commonv1.ObjectRef, string, string, error) {
	mount, path := strings.Trim(strings.TrimSpace(ref.Mount), "/"), strings.Trim(strings.TrimSpace(ref.Path), "/")
	if ref.Vault == nil || strings.TrimSpace(ref.Vault.Name) == "" || mount == "" || path == "" {
		return commonv1.ObjectRef{}, "", "", ErrNoVault
	}
	to := *ref.Vault
	if strings.TrimSpace(to.Kind) == "" {
		to.Kind = VaultGroupKind.Kind
	}
	if strings.TrimSpace(to.Group) == "" {
		to.Group = VaultGroupKind.Group
	}
	to.Workspace = to.InWorkspace(from.Workspace)
	return to, mount, path, nil
}

func ReadSecret(ctx context.Context, b *bus.Bus, from commonv1.ObjectRef, ref commonv1.SecretRef) (map[string]any, error) {
	to, mount, path, err := secretTarget(from, ref)
	if err != nil {
		return nil, err
	}
	kv, err := bus.Resolve[contractvault.KV](ctx, b, from, to,
		bus.Capability{Name: contractvault.CapabilityRead, Scope: []string{mount + "/" + path}})
	if err != nil {
		return nil, fmt.Errorf("vault: %s reading %s/%s from %s: %w", from.String(), mount, path, to.String(), err)
	}
	return kv.Read(ctx, mount, path, 0)
}

func SecretValue(data map[string]any, key string, fallbacks ...string) string {
	keys := fallbacks
	if key = strings.TrimSpace(key); key != "" {
		keys = []string{key}
	}
	for _, k := range keys {
		if value, ok := data[k].(string); ok && strings.TrimSpace(value) != "" {
			return strings.TrimSpace(value)
		}
	}
	return ""
}

func WriteSecret(ctx context.Context, b *bus.Bus, from commonv1.ObjectRef, ref commonv1.SecretRef, data map[string]any) error {
	to, mount, path, err := secretTarget(from, ref)
	if err != nil {
		return err
	}
	kv, err := bus.Resolve[contractvault.KV](ctx, b, from, to,
		bus.Capability{Name: contractvault.CapabilityWrite, Scope: []string{mount + "/" + path}})
	if err != nil {
		return fmt.Errorf("vault: %s writing %s/%s to %s: %w", from.String(), mount, path, to.String(), err)
	}
	return kv.Write(ctx, mount, path, data)
}