appconfigmgrv2/api/webhooks/builtins/common.go (146 lines of code) (raw):

// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // Copyright 2019 Google LLC. This software is provided as-is, // without warranty or representation for any use or purpose. // package builtins import ( "context" "fmt" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" ) // getConfigMap finds and returns ConfigMap of a given name in a given namespace func getConfigMap(ctx context.Context, name, ns string) (*corev1.ConfigMap, error) { cm := &corev1.ConfigMap{} cl := localMgr.GetClient() if err := cl.Get(ctx, types.NamespacedName{Name: name, Namespace: ns}, cm); err != nil { return cm, fmt.Errorf("finding %s ConfigMap: %s", name, err) } return cm, nil } // injectVolume adds a given volume to the given pod, if not already exists func injectVolume(pod *corev1.Pod, volume corev1.Volume) { log.V(1).Info("injectVolume", "volumeName", volume.Name) idx := -1 for i, v := range pod.Spec.Volumes { if v.Name == volume.Name { idx = i break } } if idx >= 0 { log.V(1).Info("injectVolume:Updated", "element.Name", volume.Name) pod.Spec.Volumes[idx] = volume } else { log.V(1).Info("injectVolume:Added", "element.Name", volume.Name) pod.Spec.Volumes = append(pod.Spec.Volumes, volume) } } // injectEnvVar adds a given EnvVar to all containers in a given pod func injectEnvVar(pod *corev1.Pod, envVar corev1.EnvVar) { log.V(1).Info("injectEnvVar", "element.name", envVar.Name) find := func(c corev1.Container) int { for n, ev := range c.Env { if ev.Name == envVar.Name { return n } } return -1 } for i, c := range pod.Spec.Containers { idx := find(c) if idx < 0 { log.Info("injectEnvVar:Added", "Container.Name", c.Name, "EnvVar.Name", envVar.Name) pod.Spec.Containers[i].Env = append(pod.Spec.Containers[i].Env, envVar) } else { log.Info("injectEnvVar:Updated", "Container.Name", c.Name, "EnvVar.Name", envVar.Name) c.Env[idx] = envVar } } } // injectVolumeMount adds a given volumeMount to all containers in a given pod func injectVolumeMount(pod *corev1.Pod, volumeMount corev1.VolumeMount) { log.V(1).Info("injectVolumeMount", "volumeName", volumeMount.Name) find := func(c corev1.Container) int { for n, vm := range c.VolumeMounts { if vm.Name == volumeMount.Name { return n } } return -1 } for i, c := range pod.Spec.Containers { idx := find(c) if idx < 0 { log.Info("injectVolumeMount:Added", "Container.Name", c.Name, "VolumeMount.Name", volumeMount.Name) pod.Spec.Containers[i].VolumeMounts = append(pod.Spec.Containers[i].VolumeMounts, volumeMount) } else { log.Info("injectVolumeMount:Updated", "Container.Name", c.Name, "VolumeMount.Name", volumeMount.Name) c.VolumeMounts[idx] = volumeMount } } } // injectVolumeMount adds a given volumeMount to all containers in a given pod func getVolumeMountsInExistingContainers(pod *corev1.Pod) *corev1.VolumeMount { log.V(1).Info("getVolumeMountsInExistingContainers", "volumeName", pod.Name) for _, c := range pod.Spec.Containers { for _, vm := range c.VolumeMounts { if vm.MountPath == "/var/run/secrets/kubernetes.io/serviceaccount" { return vm.DeepCopy() } } } return nil } // injectContainer adds a given container to the given pod, if not already exists func injectContainer(pod *corev1.Pod, container corev1.Container) { log.V(1).Info("injectContainer", "containerName", container.Name) idx := -1 for i, c := range pod.Spec.Containers { if c.Name == container.Name { idx = i break } } if idx >= 0 { log.V(1).Info("injectContainer:containerUpdated", "element.Name", container.Name) pod.Spec.Containers[idx] = container } else { log.V(1).Info("injectContainer:containerAdded", "element.Name", container.Name) pod.Spec.Containers = append(pod.Spec.Containers, container) } } // injectInitContainer adds a given init container to the given pod, if not already exists func injectInitContainer(pod *corev1.Pod, container corev1.Container) { log.V(1).Info("injectInitContainer", "containerName", container.Name) idx := -1 for i, c := range pod.Spec.InitContainers { if c.Name == container.Name { idx = i break } } if idx >= 0 { log.V(1).Info("injectInitContainer:containerUpdated", "element.Name", container.Name) pod.Spec.InitContainers[idx] = container } else { log.V(1).Info("injectInitContainer:containerAdded", "element.Name", container.Name) pod.Spec.InitContainers = append(pod.Spec.InitContainers, container) } } // svcAcctJWT looks up the stored JWT secret token for a given service account func svcAcctJWT(ctx context.Context, name, namespace string) (string, error) { log.Info("common:svcAcctJWT") var ( err error cl = localMgr.GetClient() secret = &corev1.Secret{} svcAccount = &corev1.ServiceAccount{} ) log.Info("common:svcAcctJWT:secret", "name", name, "namespace", namespace) // get service account err = cl.Get(ctx, types.NamespacedName{Name: name, Namespace: namespace}, svcAccount) if err != nil { log.Error(err, "get ServiceAccount") return "", fmt.Errorf("%s serviceAccount not found in %s namespace", name, namespace) } if len(svcAccount.Secrets) == 0 { return "", fmt.Errorf("%s serviceAccount token not found", name) } log.Info("common:svcAcctJWT:secret:value", "name", name, "namespace", namespace) ref := svcAccount.Secrets[0] // get service account token secret err = cl.Get(ctx, types.NamespacedName{Name: ref.Name, Namespace: namespace}, secret) if err != nil { return "", fmt.Errorf("%s serviceAccount token not found: %s", name, err) } b := string(secret.Data["token"]) //b, err := base64.StdEncoding.DecodeString(string(secret.Data["token"])) //if err != nil { // return "", err //} return b, nil }