-
Notifications
You must be signed in to change notification settings - Fork 2
/
service_account.go
147 lines (125 loc) · 5.36 KB
/
service_account.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
package kube
import (
"context"
"encoding/json"
"fmt"
"github.com/equinor/radix-operator/pkg/apis/utils/slice"
log "github.com/sirupsen/logrus"
corev1 "k8s.io/api/core/v1"
errors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/strategicpatch"
)
// CreateServiceAccount create a service account
func (kubeutil *Kube) CreateServiceAccount(namespace, name string) (*corev1.ServiceAccount, error) {
serviceAccount := corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
}
return kubeutil.ApplyServiceAccount(&serviceAccount)
}
// ApplyServiceAccount Creates or updates service account
func (kubeutil *Kube) ApplyServiceAccount(serviceAccount *corev1.ServiceAccount) (*corev1.ServiceAccount, error) {
oldServiceAccount, err := kubeutil.GetServiceAccount(serviceAccount.Namespace, serviceAccount.GetName())
if err != nil && errors.IsNotFound(err) {
createdServiceAccount, err := kubeutil.kubeClient.CoreV1().ServiceAccounts(serviceAccount.GetNamespace()).Create(context.TODO(), serviceAccount, metav1.CreateOptions{})
if err != nil {
return nil, fmt.Errorf("failed to create ServiceAccount object: %w", err)
}
log.Debugf("Created ServiceAccount %s in namespace %s", createdServiceAccount.GetName(), createdServiceAccount.GetNamespace())
return createdServiceAccount, nil
} else if err != nil {
return nil, fmt.Errorf("failed to get ServiceAccount object: %w", err)
}
log.Debugf("ServiceAccount object %s already exists in namespace %s, updating the object now", serviceAccount.GetName(), serviceAccount.GetNamespace())
oldServiceAccountJson, err := json.Marshal(oldServiceAccount)
if err != nil {
return nil, fmt.Errorf("failed to marshal old ServiceAccount object: %w", err)
}
newServiceAccount := oldServiceAccount.DeepCopy()
newServiceAccount.OwnerReferences = serviceAccount.OwnerReferences
newServiceAccount.Labels = serviceAccount.Labels
newServiceAccount.Annotations = serviceAccount.Annotations
newServiceAccount.AutomountServiceAccountToken = serviceAccount.AutomountServiceAccountToken
newServiceAccountJson, err := json.Marshal(newServiceAccount)
if err != nil {
return nil, fmt.Errorf("failed to marshal new ServiceAccount object: %w", err)
}
patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldServiceAccountJson, newServiceAccountJson, corev1.ServiceAccount{})
if err != nil {
return nil, fmt.Errorf("failed to create two way merge patch ServiceAccount objects: %w", err)
}
if !IsEmptyPatch(patchBytes) {
patchedServiceAccount, err := kubeutil.kubeClient.CoreV1().ServiceAccounts(serviceAccount.GetNamespace()).Patch(context.TODO(), serviceAccount.GetName(), types.StrategicMergePatchType, patchBytes, metav1.PatchOptions{})
if err != nil {
return nil, fmt.Errorf("failed to patch ServiceAccount object: %w", err)
}
log.Debugf("Patched ServiceAccount %s in namespace %s", patchedServiceAccount.GetName(), patchedServiceAccount.GetNamespace())
return patchedServiceAccount, nil
} else {
log.Debugf("No need to patch ServiceAccount %s ", serviceAccount.GetName())
}
return oldServiceAccount, nil
}
// DeleteServiceAccount Deletes service account
func (kubeutil *Kube) DeleteServiceAccount(namespace, name string) error {
_, err := kubeutil.GetServiceAccount(namespace, name)
if err != nil && errors.IsNotFound(err) {
return nil
} else if err != nil {
return fmt.Errorf("failed to get service account object: %v", err)
}
err = kubeutil.kubeClient.CoreV1().ServiceAccounts(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{})
if err != nil {
return fmt.Errorf("failed to delete ServiceAccount object: %v", err)
}
return nil
}
func (kubeutil *Kube) GetServiceAccount(namespace, name string) (*corev1.ServiceAccount, error) {
var serviceAccount *corev1.ServiceAccount
var err error
if kubeutil.ServiceAccountLister != nil {
serviceAccount, err = kubeutil.ServiceAccountLister.ServiceAccounts(namespace).Get(name)
if err != nil {
return nil, err
}
} else {
serviceAccount, err = kubeutil.kubeClient.CoreV1().ServiceAccounts(namespace).Get(context.TODO(), name, metav1.GetOptions{})
if err != nil {
return nil, err
}
}
return serviceAccount, nil
}
// ListServiceAccounts List service accounts in namespace
func (kubeutil *Kube) ListServiceAccounts(namespace string) ([]*corev1.ServiceAccount, error) {
return kubeutil.ListServiceAccountsWithSelector(namespace, "")
}
// ListServiceAccountsWithSelector List service accounts with selector in namespace
func (kubeutil *Kube) ListServiceAccountsWithSelector(namespace string, labelSelectorString string) ([]*corev1.ServiceAccount, error) {
var serviceAccounts []*corev1.ServiceAccount
if kubeutil.ServiceAccountLister != nil {
selector, err := labels.Parse(labelSelectorString)
if err != nil {
return nil, err
}
serviceAccounts, err = kubeutil.ServiceAccountLister.ServiceAccounts(namespace).List(selector)
if err != nil {
return nil, err
}
} else {
listOptions := metav1.ListOptions{
LabelSelector: labelSelectorString,
}
list, err := kubeutil.kubeClient.CoreV1().ServiceAccounts(namespace).List(context.TODO(), listOptions)
if err != nil {
return nil, err
}
serviceAccounts = slice.PointersOf(list.Items).([]*corev1.ServiceAccount)
}
return serviceAccounts, nil
}