github.com/caos/orbos@v1.5.14-0.20221103111702-e6cd0cea7ad4/pkg/kubernetes/boom.go (about) 1 package kubernetes 2 3 import ( 4 "fmt" 5 6 "github.com/caos/orbos/mntr" 7 "github.com/caos/orbos/pkg/kubernetes/k8s" 8 "github.com/caos/orbos/pkg/labels" 9 "gopkg.in/yaml.v3" 10 apps "k8s.io/api/apps/v1" 11 core "k8s.io/api/core/v1" 12 rbac "k8s.io/api/rbac/v1" 13 mach "k8s.io/apimachinery/pkg/apis/meta/v1" 14 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 15 "k8s.io/apimachinery/pkg/util/intstr" 16 ) 17 18 func EnsureBoomArtifacts( 19 monitor mntr.Monitor, 20 apiLabels *labels.API, 21 client ClientInt, 22 version string, 23 tolerations k8s.Tolerations, 24 nodeselector map[string]string, 25 resources *k8s.Resources, 26 imageRegistry string, 27 gitops bool, 28 ) error { 29 30 monitor.WithFields(map[string]interface{}{ 31 "boom": version, 32 }).Debug("Ensuring boom artifacts") 33 34 if version == "" { 35 return nil 36 } 37 38 nameLabels := toNameLabels(apiLabels, "boom") 39 k8sNameLabels := labels.MustK8sMap(nameLabels) 40 41 if err := client.ApplyServiceAccount(&core.ServiceAccount{ 42 ObjectMeta: mach.ObjectMeta{ 43 Name: nameLabels.Name(), 44 Namespace: "caos-system", 45 Labels: k8sNameLabels, 46 }, 47 }); err != nil { 48 return err 49 } 50 51 if err := client.ApplyClusterRole(&rbac.ClusterRole{ 52 ObjectMeta: mach.ObjectMeta{ 53 Name: nameLabels.Name(), 54 Labels: k8sNameLabels, 55 }, 56 Rules: []rbac.PolicyRule{{ 57 APIGroups: []string{"*"}, 58 Resources: []string{"*"}, 59 Verbs: []string{"*"}, 60 }}, 61 }); err != nil { 62 return err 63 } 64 65 if err := client.ApplyClusterRoleBinding(&rbac.ClusterRoleBinding{ 66 ObjectMeta: mach.ObjectMeta{ 67 Name: nameLabels.Name(), 68 Labels: k8sNameLabels, 69 }, 70 71 RoleRef: rbac.RoleRef{ 72 APIGroup: "rbac.authorization.k8s.io", 73 Kind: "ClusterRole", 74 Name: nameLabels.Name(), 75 }, 76 Subjects: []rbac.Subject{{ 77 Kind: "ServiceAccount", 78 Name: nameLabels.Name(), 79 Namespace: "caos-system", 80 }}, 81 }); err != nil { 82 return err 83 } 84 85 k8sPodSelector := labels.MustK8sMap(labels.DeriveNameSelector(nameLabels, false)) 86 87 if !gitops { 88 crd := `apiVersion: apiextensions.k8s.io/v1beta1 89 kind: CustomResourceDefinition 90 metadata: 91 annotations: 92 controller-gen.kubebuilder.io/version: v0.2.2 93 creationTimestamp: null 94 name: booms.caos.ch 95 spec: 96 group: caos.ch 97 names: 98 kind: Boom 99 listKind: BoomList 100 plural: booms 101 singular: boom 102 scope: "" 103 validation: 104 openAPIV3Schema: 105 properties: 106 apiVersion: 107 description: 'APIVersion defines the versioned schema of this representation 108 of an object. Servers should convert recognized schemas to the latest 109 internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 110 type: string 111 kind: 112 description: 'Kind is a string value representing the REST resource this 113 object represents. Servers may infer this from the endpoint the client 114 submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 115 type: string 116 metadata: 117 type: object 118 spec: 119 type: object 120 status: 121 type: object 122 type: object 123 version: v1 124 versions: 125 - name: v1 126 served: true 127 storage: true 128 - name: v1beta1 129 served: true 130 storage: false 131 - name: v1beta2 132 served: true 133 storage: false 134 status: 135 acceptedNames: 136 kind: "" 137 plural: "" 138 conditions: [] 139 storedVersions: []` 140 141 crdDefinition := &unstructured.Unstructured{} 142 if err := yaml.Unmarshal([]byte(crd), &crdDefinition.Object); err != nil { 143 return err 144 } 145 146 if err := client.ApplyCRDResource( 147 crdDefinition, 148 ); err != nil { 149 return err 150 } 151 monitor.WithFields(map[string]interface{}{ 152 "version": version, 153 }).Debug("BOOM crd ensured") 154 } 155 156 var ( 157 cmd = []string{"/orbctl", "start", "boom", "--kubeconfig", ""} 158 volumes []core.Volume 159 volumeMounts []core.VolumeMount 160 ) 161 if gitops { 162 cmd = append(cmd, "--gitops", "-f", "/secrets/orbconfig") 163 volumes = []core.Volume{{ 164 Name: "orbconfig", 165 VolumeSource: core.VolumeSource{ 166 Secret: &core.SecretVolumeSource{ 167 SecretName: "caos", 168 }, 169 }, 170 }} 171 volumeMounts = []core.VolumeMount{{ 172 Name: "orbconfig", 173 ReadOnly: true, 174 MountPath: "/secrets", 175 }} 176 } 177 178 if _, _, analyticsEnabled := mntr.Environment(); !analyticsEnabled { 179 cmd = append(cmd, "--disable-analytics") 180 } 181 182 deployment := &apps.Deployment{ 183 ObjectMeta: mach.ObjectMeta{ 184 Name: nameLabels.Name(), 185 Namespace: "caos-system", 186 Labels: k8sNameLabels, 187 }, 188 Spec: apps.DeploymentSpec{ 189 Replicas: int32Ptr(1), 190 Selector: &mach.LabelSelector{ 191 MatchLabels: k8sPodSelector, 192 }, 193 Template: core.PodTemplateSpec{ 194 ObjectMeta: mach.ObjectMeta{ 195 Labels: labels.MustK8sMap(labels.AsSelectable(nameLabels)), 196 }, 197 Spec: core.PodSpec{ 198 ServiceAccountName: nameLabels.Name(), 199 Containers: []core.Container{{ 200 Name: "boom", 201 ImagePullPolicy: core.PullIfNotPresent, 202 Image: fmt.Sprintf("%s/caos/orbos:%s", imageRegistry, version), 203 Command: cmd, 204 Args: []string{}, 205 Ports: []core.ContainerPort{{ 206 Name: "metrics", 207 ContainerPort: 2112, 208 Protocol: "TCP", 209 }}, 210 VolumeMounts: volumeMounts, 211 Resources: core.ResourceRequirements(*resources), 212 }}, 213 NodeSelector: nodeselector, 214 Tolerations: tolerations.K8s(), 215 Volumes: volumes, 216 TerminationGracePeriodSeconds: int64Ptr(10), 217 }, 218 }, 219 }, 220 } 221 222 if err := client.ApplyDeployment(deployment, true); err != nil { 223 return err 224 } 225 monitor.WithFields(map[string]interface{}{ 226 "version": version, 227 }).Debug("BOOM deployment ensured") 228 229 if err := client.ApplyService(&core.Service{ 230 ObjectMeta: mach.ObjectMeta{ 231 Name: nameLabels.Name(), 232 Namespace: "caos-system", 233 Labels: k8sPodSelector, 234 }, 235 Spec: core.ServiceSpec{ 236 Ports: []core.ServicePort{{ 237 Name: "metrics", 238 Protocol: "TCP", 239 Port: 2112, 240 TargetPort: intstr.FromInt(2112), 241 }}, 242 Selector: k8sPodSelector, 243 Type: core.ServiceTypeClusterIP, 244 }, 245 }); err != nil { 246 return err 247 } 248 monitor.Debug("BOOM service ensured") 249 250 return nil 251 }