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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package providermain
import (
"context"
"fmt"
"strings"
"time"
"github.com/johnandersen777/socialweb-computer-kcp/api/v1alpha1"
"github.com/johnandersen777/socialweb-computer-kcp/internal/clusterprovider"
"github.com/johnandersen777/socialweb-computer-kcp/internal/nodemarket"
)
const VaultSyncInterval = 30 * time.Second
func (h *nodeHosts) reconcileVault(ctx context.Context, cluster string, claims []v1alpha1.NodeClaim) error {
if h.opts.NodeSecrets == nil {
return nil
}
now := h.opts.now()
h.mu.Lock()
if h.synced == nil {
h.synced = map[string]time.Time{}
}
last, synced := h.synced[cluster]
if synced && now.Sub(last) < VaultSyncInterval {
h.mu.Unlock()
return nil
}
h.synced[cluster] = now
if h.vaultDue == nil {
h.vaultDue = map[string]time.Time{}
}
delete(h.vaultDue, cluster)
if len(claims) > 0 {
h.vaultDue[cluster] = now.Add(VaultSyncInterval)
}
h.mu.Unlock()
dir, err := clusterprovider.ClusterDataDir(h.opts.StateDir, cluster)
if err != nil {
return fmt.Errorf("clusterprovider: the data dir of %s, whose cluster OpenBao holds the roles, "+
"policies and secrets of its market nodes: %w", cluster, err)
}
reconciler, ok := h.opts.NodeSecrets(cluster, dir).(nodemarket.NodeSecretsReconciler)
if !ok {
return nil
}
live := liveNodeGrants(cluster, claims, h.heldNames(cluster))
if err := reconciler.Reconcile(ctx, live); err != nil {
return fmt.Errorf("clusterprovider: making the cluster OpenBao of %s match the %d live market "+
"node(s) it holds: %w -- a role, policy or secret with no live claim is one nothing revokes, "+
"and it stays until a reconcile reads the vault again", cluster, len(live), err)
}
h.log.Info("cluster provider: the cluster OpenBao matches the live market nodes",
"cluster", cluster, "live", len(live))
return nil
}
func liveNodeGrants(cluster string, claims []v1alpha1.NodeClaim, held map[string]bool) map[string]*v1alpha1.NodeClaimGrant {
prefix := strings.ToLower(cluster) + "-node"
byName := map[string]v1alpha1.NodeClaim{}
live := map[string]*v1alpha1.NodeClaimGrant{}
for i := range claims {
claim := claims[i]
if claim.Spec.ClusterRef.Name != cluster {
continue
}
if _, ok := nodeOrdinalInName(prefix, claim.Name); !ok {
continue
}
byName[claim.Name] = claim
if !nodemarket.Adoptable(claim) {
continue
}
live[claim.Name] = claim.Status.Grant
}
for name := range held {
if _, ok := live[name]; ok {
continue
}
claim, ok := byName[name]
if !ok {
live[name] = nil
continue
}
live[name] = claim.Status.Grant
}
return live
}