-
Notifications
You must be signed in to change notification settings - Fork 90
/
api.go
125 lines (102 loc) · 4.56 KB
/
api.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
package kotsadm
import (
"context"
"github.com/pkg/errors"
"github.com/replicatedhq/kots/pkg/kotsadm/types"
corev1 "k8s.io/api/core/v1"
kuberneteserrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
)
// removeNodeAPI should be removable when we don't need to support direct upgrade paths from 1.19.6 and before
func removeNodeAPI(deployOptions *types.DeployOptions, clientset *kubernetes.Clientset) error {
ns := deployOptions.Namespace
err := clientset.AppsV1().Deployments(ns).Delete(context.TODO(), "kotsadm-api", metav1.DeleteOptions{})
if err != nil && !kuberneteserrors.IsNotFound(err) {
return errors.Wrap(err, "failed to delete deployment")
}
err = clientset.CoreV1().Services(ns).Delete(context.TODO(), "kotsadm-api-node", metav1.DeleteOptions{})
if err != nil && !kuberneteserrors.IsNotFound(err) {
return errors.Wrap(err, "failed to delete service")
}
if deployOptions.EnsureRBAC {
if err := removeNodeAPIRBAC(deployOptions, clientset); err != nil {
return errors.Wrap(err, "failed to ensure api rbac")
}
}
return nil
}
// removeNodeAPIRBAC should be removable when we don't need to support direct upgrade paths from 1.19.6 and before
func removeNodeAPIRBAC(deployOptions *types.DeployOptions, clientset *kubernetes.Clientset) error {
isClusterScoped, err := isKotsadmClusterScoped(deployOptions)
if err != nil {
return errors.Wrap(err, "failed to check if kotsadm api is cluster scoped")
}
if isClusterScoped {
err := removeNodeAPIClusterRBAC(deployOptions, clientset)
return errors.Wrap(err, "failed to ensure api cluster role")
}
err = clientset.RbacV1().Roles(deployOptions.Namespace).Delete(context.TODO(), "kotsadm-api-role", metav1.DeleteOptions{})
if err != nil && !kuberneteserrors.IsNotFound(err) {
return errors.Wrap(err, "failed to delete kotsadm-api-role role")
}
err = clientset.RbacV1().RoleBindings(deployOptions.Namespace).Delete(context.TODO(), "kotsadm-api-rolebinding", metav1.DeleteOptions{})
if err != nil && !kuberneteserrors.IsNotFound(err) {
return errors.Wrap(err, "failed to delete rolebinding")
}
return nil
}
// removeNodeAPIClusterRBAC should be removable when we don't need to support direct upgrade paths from 1.19.6 and before
func removeNodeAPIClusterRBAC(deployOptions *types.DeployOptions, clientset *kubernetes.Clientset) error {
err := clientset.CoreV1().ServiceAccounts(deployOptions.Namespace).Delete(context.TODO(), "kotsadm-api", metav1.DeleteOptions{})
if err != nil && !kuberneteserrors.IsNotFound(err) {
return errors.Wrap(err, "failed to delete api service account")
}
err = clientset.RbacV1().ClusterRoleBindings().Delete(context.TODO(), "kotsadm-api-rolebinding", metav1.DeleteOptions{})
if err != nil && !kuberneteserrors.IsNotFound(err) {
return errors.Wrap(err, "failed to delete cluster rolebinding")
}
err = clientset.RbacV1().ClusterRoles().Delete(context.TODO(), "kotsadm-api-role", metav1.DeleteOptions{})
if err != nil && !kuberneteserrors.IsNotFound(err) {
return errors.Wrap(err, "failed to delete cluster role")
}
return nil
}
func getAPIAutoCreateClusterToken(namespace string, clientset *kubernetes.Clientset) (string, error) {
autoCreateClusterTokenSecretVal, err := getAPIClusterToken(namespace, clientset)
if err != nil {
return "", errors.Wrap(err, "failed to get autocreate cluster token from secret")
} else if autoCreateClusterTokenSecretVal != "" {
return autoCreateClusterTokenSecretVal, nil
}
var containers []corev1.Container
existingDeployment, err := clientset.AppsV1().Deployments(namespace).Get(context.TODO(), "kotsadm", metav1.GetOptions{})
if err != nil && !kuberneteserrors.IsNotFound(err) {
return "", errors.Wrap(err, "failed to read deployment")
}
if err == nil {
containers = existingDeployment.Spec.Template.Spec.Containers
} else {
// deployment not found, check if there's a statefulset
existingStatefulSet, err := clientset.AppsV1().StatefulSets(namespace).Get(context.TODO(), "kotsadm", metav1.GetOptions{})
if err != nil {
return "", errors.Wrap(err, "failed to read statefulset")
}
containers = existingStatefulSet.Spec.Template.Spec.Containers
}
containerIdx := -1
for idx, c := range containers {
if c.Name == "kotsadm" {
containerIdx = idx
}
}
if containerIdx == -1 {
return "", errors.New("failed to find kotsadm container in statefulset")
}
for _, env := range containers[containerIdx].Env {
if env.Name == "AUTO_CREATE_CLUSTER_TOKEN" {
return env.Value, nil
}
}
return "", errors.New("failed to find autocreateclustertoken env on api statefulset")
}