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
package revocation
import (
"errors"
"fmt"
"github.com/johnandersen777/socialweb-computer-kcp/api/v1alpha1"
)
type ClusterView struct {
Name string
ServiceAccountPresent bool
Cold bool
}
type Effect struct {
Cluster string
State v1alpha1.IdentityState
DeleteSA bool
}
func Plan(clusters []ClusterView) []Effect {
out := make([]Effect, 0, len(clusters))
for _, c := range clusters {
switch {
case c.Cold:
out = append(out, Effect{Cluster: c.Name, State: v1alpha1.IdentityColdDeferred})
case c.ServiceAccountPresent:
out = append(out, Effect{Cluster: c.Name, State: v1alpha1.IdentityRevocationPending, DeleteSA: true})
default:
out = append(out, Effect{Cluster: c.Name, State: v1alpha1.IdentityRevoked})
}
}
return out
}
type ReplyEntry struct {
Name string `json:"name"`
State string `json:"state"`
}
func Reply(effects []Effect) []ReplyEntry {
account := string(v1alpha1.IdentityRevoked)
out := make([]ReplyEntry, 0, len(effects)+1)
for _, e := range effects {
if e.State != v1alpha1.IdentityRevoked {
account = string(v1alpha1.IdentityRevocationPending)
}
out = append(out, ReplyEntry{Name: e.Cluster, State: string(e.State)})
}
return append([]ReplyEntry{{Name: "", State: account}}, out...)
}
type Settled interface{ settled() }
type settled struct{}
func (settled) settled() {}
func WakeSettled(e Effect) (Settled, error) {
if e.State != v1alpha1.IdentityRevoked {
return nil, fmt.Errorf(
"revocation: refusing Ready for cluster %s: its revocation is %s and its ServiceAccount may still exist. "+
"A COLD cluster is only safe to defer BECAUSE this gate runs before phase=Ready",
e.Cluster, e.State)
}
return settled{}, nil
}
func Ready(s Settled) (v1alpha1.ClusterPhase, error) {
if s == nil {
return v1alpha1.ClusterInitializing, errors.New(
"revocation: refusing Ready: the revocation reconcile did not run for this wake. " +
"Set status.URL, run the reconcile, then call Ready with the Settled it returns")
}
return v1alpha1.ClusterReady, nil
}