/
unionrevisionedpod.go
91 lines (74 loc) · 2.8 KB
/
unionrevisionedpod.go
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
91
package deployer
import (
"context"
"reflect"
corev1 "k8s.io/api/core/v1"
"k8s.io/client-go/tools/cache"
"github.com/openshift/library-go/pkg/operator/encryption/encryptionconfig"
"github.com/openshift/library-go/pkg/operator/encryption/statemachine"
)
// UnionRevisionLabelPodDeployer provides unified state from multiple distinct deployers.
type UnionRevisionLabelPodDeployer struct {
delegates []statemachine.Deployer
hasSynced []cache.InformerSynced
}
var _ statemachine.Deployer = &UnionRevisionLabelPodDeployer{}
// NewUnionRevisionLabelPodDeployer creates a deployer that returns a unified state from multiple distinct deployers.
// That means:
// - none has reported an error
// - all have converged
// - all have observed exactly the same encryption configuration
func NewUnionRevisionLabelPodDeployer(delegates ...statemachine.Deployer) *UnionRevisionLabelPodDeployer {
return &UnionRevisionLabelPodDeployer{delegates: delegates}
}
// DeployedEncryptionConfigSecret returns the actual encryption configuration across multiple deployers
func (d *UnionRevisionLabelPodDeployer) DeployedEncryptionConfigSecret(ctx context.Context) (secret *corev1.Secret, converged bool, err error) {
seenSecrets := []*corev1.Secret{}
for _, delegate := range d.delegates {
secret, converged, err := delegate.DeployedEncryptionConfigSecret(ctx)
if !converged || err != nil {
return nil, converged, err
}
seenSecrets = append(seenSecrets, secret)
}
if len(seenSecrets) == 0 {
return nil, false, nil
}
// we need to check that the encryption configuration is exactly the same among deployers
// so we promote the fist secret and compare it with the rest
goldenSecret := seenSecrets[0]
seenSecrets = seenSecrets[1:]
goldenEncryptionCfg, err := encryptionconfig.FromSecret(goldenSecret)
if err != nil {
return nil, false, err
}
for _, secret := range seenSecrets {
currentEncryptionCfg, err := encryptionconfig.FromSecret(secret)
if err != nil {
return nil, false, err
}
if !reflect.DeepEqual(goldenEncryptionCfg.Resources, currentEncryptionCfg.Resources) {
return nil, false, nil
}
}
return goldenSecret, true, nil
}
func (d *UnionRevisionLabelPodDeployer) HasSynced() bool {
for _, hasSynced := range d.hasSynced {
if !hasSynced() {
return false
}
}
return true
}
// AddEventHandler registers a event handler that might influence the result of DeployedEncryptionConfigSecret for all configured deployers.
func (d *UnionRevisionLabelPodDeployer) AddEventHandler(handler cache.ResourceEventHandler) (cache.ResourceEventHandlerRegistration, error) {
d.hasSynced = []cache.InformerSynced{}
for _, delegate := range d.delegates {
if _, err := delegate.AddEventHandler(handler); err != nil {
return nil, err
}
d.hasSynced = append(d.hasSynced, delegate.HasSynced)
}
return nil, nil
}