1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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)
}