/
accounts.go
129 lines (115 loc) · 3.5 KB
/
accounts.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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package transformer
import (
"context"
"fmt"
"github.com/armory/spinnaker-operator/pkg/accounts"
"github.com/armory/spinnaker-operator/pkg/accounts/account"
"github.com/armory/spinnaker-operator/pkg/apis/spinnaker/interfaces"
"github.com/armory/spinnaker-operator/pkg/generated"
"github.com/armory/spinnaker-operator/pkg/util"
"github.com/go-logr/logr"
appsv1 "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
)
// accountsTransformer inserts accounts defined via CRD into Spinnaker's config
type accountsTransformer struct {
svc interfaces.SpinnakerService
log logr.Logger
client client.Client
}
type AccountsTransformerGenerator struct{}
func (a *AccountsTransformerGenerator) NewTransformer(svc interfaces.SpinnakerService,
client client.Client, log logr.Logger, scheme *runtime.Scheme) (Transformer, error) {
return &accountsTransformer{svc: svc, log: log, client: client}, nil
}
func (g *AccountsTransformerGenerator) GetName() string {
return "AccountsCRD"
}
// TransformConfig is a nop
func (a *accountsTransformer) TransformConfig(ctx context.Context) error {
return nil
}
func (a *accountsTransformer) TransformManifests(ctx context.Context, gen *generated.SpinnakerGeneratedConfig) error {
if !a.svc.GetAccountConfig().Enabled {
a.log.Info("accounts disabled, skipping")
return nil
}
// Enable "accounts" Spring profile for each potential service
svcs := accounts.GetAllServicesWithAccounts()
for k := range gen.Config {
if a.isServiceWithAccount(k, svcs) {
if err := addSpringProfile(gen.Config[k].Deployment, k, accounts.SpringProfile); err != nil {
return err
}
}
}
// Get CRD accounts if enabled
crdAccs, err := accounts.AllValidCRDAccounts(ctx, a.client, a.svc.GetNamespace())
if err != nil {
// Ignore no kind match
if _, ok := err.(*meta.NoKindMatchError); ok {
a.log.Info("SpinnakerAccount CRD not available, skipping account definitions")
return nil
}
return err
}
a.log.Info(fmt.Sprintf("found %d accounts to deploy", len(crdAccs)))
return updateServiceSettings(ctx, crdAccs, gen)
}
func (a *accountsTransformer) isServiceWithAccount(serviceKey string, accountServices []string) bool {
for _, s := range accountServices {
if util.IsServiceLike(serviceKey, s) {
return true
}
}
return false
}
func updateServiceSettings(ctx context.Context, crdAccounts []account.Account, gen *generated.SpinnakerGeneratedConfig) error {
for k := range gen.Config {
settings, err := accounts.PrepareSettings(ctx, k, crdAccounts)
if err != nil {
return err
}
config, ok := gen.Config[k]
if !ok {
continue
}
sec := util.GetSecretConfigFromConfig(config, k)
if sec == nil {
continue
}
if err = util.UpdateSecret(sec, k, settings, accounts.SpringProfile); err != nil {
return err
}
}
return nil
}
func addSpringProfile(dep *appsv1.Deployment, svc string, p string) error {
c := util.GetContainerInDeployment(dep, svc)
if c == nil {
return fmt.Errorf("unable to find container %s in deployment", svc)
}
for i := range c.Env {
ev := &c.Env[i]
if ev.Name == "SPRING_PROFILES_ACTIVE" {
if ev.ValueFrom != nil {
return fmt.Errorf("SPRING_PROFILES_ACTIVE set from a source not supported")
}
if ev.Value != "" {
ev.Value = fmt.Sprintf("%s,%s", ev.Value, p)
} else {
ev.Value = p
}
return nil
}
}
// Add the prop
c.Env = append(c.Env, v1.EnvVar{
Name: "SPRING_PROFILES_ACTIVE",
Value: p,
})
return nil
}