-
Notifications
You must be signed in to change notification settings - Fork 67
/
find.go
160 lines (147 loc) · 4.59 KB
/
find.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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
package util
import (
"context"
"errors"
"fmt"
"github.com/armory/go-yaml-tools/pkg/secrets"
"github.com/armory/spinnaker-operator/pkg/apis/spinnaker/interfaces"
"github.com/armory/spinnaker-operator/pkg/generated"
"github.com/ghodss/yaml"
v12 "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
clientcorev1 "k8s.io/client-go/kubernetes/typed/core/v1"
"k8s.io/client-go/rest"
"sigs.k8s.io/controller-runtime/pkg/client"
"strings"
)
var errSecretNotFound = errors.New("secret not found")
func FindSpinnakerService(c client.Client, ns string, builder interfaces.TypesFactory) (interfaces.SpinnakerService, error) {
l := builder.NewServiceList()
if err := c.List(context.TODO(), l, client.InNamespace(ns)); err != nil {
return nil, err
}
items := l.GetItems()
if len(items) > 0 {
return items[0], nil
}
return nil, nil
}
func FindDeployment(c client.Client, spinsvc interfaces.SpinnakerService, service string) (*v12.Deployment, error) {
dep := &v12.Deployment{}
err := c.Get(context.TODO(), client.ObjectKey{Namespace: spinsvc.GetNamespace(), Name: fmt.Sprintf("spin-%s", service)}, dep)
return dep, err
}
func FindSecretInDeployment(c client.Client, dep *v12.Deployment, containerName, path string) (*v1.Secret, error) {
name := GetMountedSecretNameInDeployment(dep, containerName, path)
if name != "" {
sec := &v1.Secret{}
err := c.Get(context.TODO(), client.ObjectKey{Namespace: dep.Namespace, Name: name}, sec)
return sec, err
}
return nil, fmt.Errorf("unable to find secret at path %s in container %s in deployment %s", path, containerName, dep.Name)
}
func GetSecretContent(c *rest.Config, namespace, name, key string) (string, error) {
cl, err := clientcorev1.NewForConfig(c)
if err != nil {
return "", err
}
sec, err := cl.Secrets(namespace).Get(context.TODO(), name, metav1.GetOptions{})
if err != nil {
return "", err
}
if d, ok := sec.Data[key]; ok {
return string(d), nil
}
return "", errSecretNotFound
}
func GetMountedSecretNameInDeployment(dep *v12.Deployment, containerName, path string) string {
container := GetContainerInDeployment(dep, containerName)
if container == nil {
return ""
}
// Look for the volume mount here
for _, vm := range container.VolumeMounts {
if vm.MountPath != path {
continue
}
// Look for the secret
for _, v := range dep.Spec.Template.Spec.Volumes {
if v.Name == vm.Name {
if v.Secret != nil {
return v.Secret.SecretName
}
return ""
}
}
}
return ""
}
func GetContainerInDeployment(dep *v12.Deployment, containerName string) *v1.Container {
for i := range dep.Spec.Template.Spec.Containers {
c := &dep.Spec.Template.Spec.Containers[i]
if c.Name == containerName {
return c
}
}
return nil
}
func IsServiceLike(svc1, svc2 string) bool {
return svc1 == svc2 || strings.HasPrefix(svc1, svc2+"-")
}
func UpdateSecret(secret *v1.Secret, svc string, settings map[string]interface{}, profileName string) error {
k := fmt.Sprintf("%s-%s.yml", svc, profileName)
b, err := yaml.Marshal(settings)
if err != nil {
return err
}
secret.Data[k] = b
return nil
}
// GetServiceAccountData returns the service account token and temp path to root ca
func GetServiceAccountData(ctx context.Context, name, ns string, c client.Client) (string, string, error) {
list := &v1.SecretList{}
opts := client.InNamespace(ns)
if err := c.List(ctx, list, opts); err != nil {
return "", "", err
}
for i := 0; i < len(list.Items); i++ {
s := list.Items[i]
if s.Type != v1.SecretTypeServiceAccountToken {
continue
}
saName := s.Annotations[v1.ServiceAccountNameKey]
if saName != name {
continue
}
token := string(s.Data[v1.ServiceAccountTokenKey])
caBytes := s.Data[v1.ServiceAccountRootCAKey]
caPath, err := secrets.ToTempFile(caBytes)
if err != nil {
return "", "", err
}
return token, caPath, nil
}
return "", "", fmt.Errorf("no secret for service account %s was found on namespace %s", name, ns)
}
func GetSpinnakerServices(list interfaces.SpinnakerServiceList, ns string, c client.Client) ([]interfaces.SpinnakerService, error) {
var opts client.ListOption
opts = client.InNamespace(ns)
err := c.List(context.TODO(), list, opts)
if err != nil {
return nil, err
}
return list.GetItems(), nil
}
func GetSecretConfigFromConfig(config generated.ServiceConfig, n string) *v1.Secret {
secretName := GetMountedSecretNameInDeployment(config.Deployment, n, "/opt/spinnaker/config")
if secretName != "" {
for i := range config.Resources {
o := config.Resources[i]
if sc, ok := o.(*v1.Secret); ok && sc.GetName() == secretName {
return sc
}
}
}
return nil
}