github.com/caos/orbos@v1.5.14-0.20221103111702-e6cd0cea7ad4/pkg/kubernetes/networking.go (about) 1 package kubernetes 2 3 import ( 4 "fmt" 5 6 "github.com/caos/orbos/mntr" 7 "github.com/caos/orbos/pkg/labels" 8 "gopkg.in/yaml.v3" 9 apps "k8s.io/api/apps/v1" 10 core "k8s.io/api/core/v1" 11 rbac "k8s.io/api/rbac/v1" 12 "k8s.io/apimachinery/pkg/api/resource" 13 mach "k8s.io/apimachinery/pkg/apis/meta/v1" 14 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 15 ) 16 17 func EnsureNetworkingArtifacts( 18 monitor mntr.Monitor, 19 apiLabels *labels.API, 20 client ClientInt, 21 version string, 22 nodeselector map[string]string, 23 tolerations []core.Toleration, 24 imageRegistry string, 25 gitops bool, 26 ) error { 27 28 monitor.WithFields(map[string]interface{}{ 29 "networking": version, 30 }).Debug("Ensuring networking artifacts") 31 32 if version == "" { 33 return nil 34 } 35 36 nameLabels := toNameLabels(apiLabels, "networking-operator") 37 k8sNameLabels := labels.MustK8sMap(nameLabels) 38 39 if err := client.ApplyServiceAccount(&core.ServiceAccount{ 40 ObjectMeta: mach.ObjectMeta{ 41 Name: nameLabels.Name(), 42 Namespace: "caos-system", 43 Labels: k8sNameLabels, 44 }, 45 }); err != nil { 46 return err 47 } 48 49 if err := client.ApplyClusterRole(&rbac.ClusterRole{ 50 ObjectMeta: mach.ObjectMeta{ 51 Name: nameLabels.Name(), 52 Labels: k8sNameLabels, 53 }, 54 Rules: []rbac.PolicyRule{{ 55 APIGroups: []string{"*"}, 56 Resources: []string{"*"}, 57 Verbs: []string{"*"}, 58 }}, 59 }); err != nil { 60 return err 61 } 62 63 if err := client.ApplyClusterRoleBinding(&rbac.ClusterRoleBinding{ 64 ObjectMeta: mach.ObjectMeta{ 65 Name: nameLabels.Name(), 66 Labels: k8sNameLabels, 67 }, 68 69 RoleRef: rbac.RoleRef{ 70 APIGroup: "rbac.authorization.k8s.io", 71 Kind: "ClusterRole", 72 Name: nameLabels.Name(), 73 }, 74 Subjects: []rbac.Subject{{ 75 Kind: "ServiceAccount", 76 Name: nameLabels.Name(), 77 Namespace: "caos-system", 78 }}, 79 }); err != nil { 80 return err 81 } 82 83 if !gitops { 84 crd := `apiVersion: apiextensions.k8s.io/v1beta1 85 kind: CustomResourceDefinition 86 metadata: 87 annotations: 88 controller-gen.kubebuilder.io/version: v0.2.2 89 creationTimestamp: null 90 name: networkings.caos.ch 91 spec: 92 group: caos.ch 93 names: 94 kind: Networking 95 listKind: NetworkingList 96 plural: networkings 97 singular: networking 98 scope: "" 99 validation: 100 openAPIV3Schema: 101 properties: 102 apiVersion: 103 description: 'APIVersion defines the versioned schema of this representation 104 of an object. Servers should convert recognized schemas to the latest 105 internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 106 type: string 107 kind: 108 description: 'Kind is a string value representing the REST resource this 109 object represents. Servers may infer this from the endpoint the client 110 submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 111 type: string 112 metadata: 113 type: object 114 spec: 115 properties: 116 kind: 117 type: string 118 networking: 119 type: object 120 spec: 121 properties: 122 customImageRegistry: 123 description: 'Use this registry to pull the Networking-operator 124 image from @default: ghcr.io' 125 type: string 126 gitOps: 127 type: boolean 128 nodeSelector: 129 additionalProperties: 130 type: string 131 type: object 132 selfReconciling: 133 type: boolean 134 tolerations: 135 items: 136 description: The pod this Toleration is attached to tolerates 137 any taint that matches the triple <key,value,effect> using the 138 matching operator <operator>. 139 properties: 140 effect: 141 description: Effect indicates the taint effect to match. Empty 142 means match all taint effects. When specified, allowed values 143 are NoSchedule, PreferNoSchedule and NoExecute. 144 type: string 145 key: 146 description: Key is the taint key that the toleration applies 147 to. Empty means match all taint keys. If the key is empty, 148 operator must be Exists; this combination means to match 149 all values and all keys. 150 type: string 151 operator: 152 description: Operator represents a key's relationship to the 153 value. Valid operators are Exists and Equal. Defaults to 154 Equal. Exists is equivalent to wildcard for value, so that 155 a pod can tolerate all taints of a particular category. 156 type: string 157 tolerationSeconds: 158 description: TolerationSeconds represents the period of time 159 the toleration (which must be of effect NoExecute, otherwise 160 this field is ignored) tolerates the taint. By default, 161 it is not set, which means tolerate the taint forever (do 162 not evict). Zero and negative values will be treated as 163 0 (evict immediately) by the system. 164 format: int64 165 type: integer 166 value: 167 description: Value is the taint value the toleration matches 168 to. If the operator is Exists, the value should be empty, 169 otherwise just a regular string. 170 type: string 171 type: object 172 type: array 173 verbose: 174 type: boolean 175 version: 176 type: string 177 required: 178 - selfReconciling 179 - verbose 180 type: object 181 version: 182 type: string 183 required: 184 - kind 185 - networking 186 - spec 187 - version 188 type: object 189 status: 190 type: object 191 type: object 192 version: v1 193 versions: 194 - name: v1 195 served: true 196 storage: true 197 status: 198 acceptedNames: 199 kind: "" 200 plural: "" 201 conditions: [] 202 storedVersions: []` 203 204 crdDefinition := &unstructured.Unstructured{} 205 if err := yaml.Unmarshal([]byte(crd), &crdDefinition.Object); err != nil { 206 return err 207 } 208 209 if err := client.ApplyCRDResource( 210 crdDefinition, 211 ); err != nil { 212 return err 213 } 214 monitor.WithFields(map[string]interface{}{ 215 "version": version, 216 }).Debug("Networking Operator crd ensured") 217 } 218 219 var ( 220 cmd = []string{"/orbctl", "start", "networking", "--kubeconfig", ""} 221 volumes []core.Volume 222 volumeMounts []core.VolumeMount 223 ) 224 if gitops { 225 cmd = append(cmd, "--gitops", "-f", "/secrets/orbconfig") 226 volumes = []core.Volume{{ 227 Name: "orbconfig", 228 VolumeSource: core.VolumeSource{ 229 Secret: &core.SecretVolumeSource{ 230 SecretName: "caos", 231 }, 232 }, 233 }} 234 volumeMounts = []core.VolumeMount{{ 235 Name: "orbconfig", 236 ReadOnly: true, 237 MountPath: "/secrets", 238 }} 239 } 240 241 if _, _, analyticsEnabled := mntr.Environment(); !analyticsEnabled { 242 cmd = append(cmd, "--disable-analytics") 243 } 244 245 deployment := &apps.Deployment{ 246 ObjectMeta: mach.ObjectMeta{ 247 Name: nameLabels.Name(), 248 Namespace: "caos-system", 249 Labels: k8sNameLabels, 250 }, 251 Spec: apps.DeploymentSpec{ 252 Replicas: int32Ptr(1), 253 Selector: &mach.LabelSelector{ 254 MatchLabels: labels.MustK8sMap(labels.DeriveNameSelector(nameLabels, false)), 255 }, 256 Template: core.PodTemplateSpec{ 257 ObjectMeta: mach.ObjectMeta{ 258 Labels: labels.MustK8sMap(labels.AsSelectable(nameLabels)), 259 }, 260 Spec: core.PodSpec{ 261 ServiceAccountName: nameLabels.Name(), 262 Containers: []core.Container{{ 263 Name: "networking", 264 ImagePullPolicy: core.PullIfNotPresent, 265 Image: fmt.Sprintf("%s/caos/orbos:%s", imageRegistry, version), 266 Command: cmd, 267 Args: []string{}, 268 Ports: []core.ContainerPort{{ 269 Name: "metrics", 270 ContainerPort: 2112, 271 Protocol: "TCP", 272 }}, 273 Resources: core.ResourceRequirements{ 274 Limits: core.ResourceList{ 275 "cpu": resource.MustParse("500m"), 276 "memory": resource.MustParse("500Mi"), 277 }, 278 Requests: core.ResourceList{ 279 "cpu": resource.MustParse("250m"), 280 "memory": resource.MustParse("250Mi"), 281 }, 282 }, 283 VolumeMounts: volumeMounts, 284 }}, 285 NodeSelector: nodeselector, 286 Tolerations: tolerations, 287 Volumes: volumes, 288 TerminationGracePeriodSeconds: int64Ptr(10), 289 }, 290 }, 291 }, 292 } 293 if err := client.ApplyDeployment(deployment, true); err != nil { 294 return err 295 } 296 monitor.WithFields(map[string]interface{}{ 297 "version": version, 298 }).Debug("Networking Operator deployment ensured") 299 300 return nil 301 }