From 1691e2442f00bb9824d60d1d72fb06546442f69b Mon Sep 17 00:00:00 2001 From: Srikumar Venugopal Date: Tue, 4 Jul 2023 23:07:47 +0100 Subject: [PATCH] feat: support multiple useas modes (#272) Signed-off-by: SRIKUMAR VENUGOPAL --- .../templates/example-pod-mult-useas.yaml | 14 ++++++++ .../admissioncontroller/mutatingwebhook.go | 33 ++++++++++++------- .../mutatingwebhook_test.go | 32 ++++++++++++++++++ 3 files changed, 68 insertions(+), 11 deletions(-) create mode 100644 examples/templates/example-pod-mult-useas.yaml diff --git a/examples/templates/example-pod-mult-useas.yaml b/examples/templates/example-pod-mult-useas.yaml new file mode 100644 index 00000000..9c53a168 --- /dev/null +++ b/examples/templates/example-pod-mult-useas.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Pod +metadata: + name: nginx + labels: + dataset.0.id: "example-dataset" + dataset.0.useas: "mount.configmap" +spec: + containers: + - name: nginx + image: nginx + volumeMounts: + - mountPath: "/mount/dataset1" #optional, if not specified it would be mounted in /mnt/datasets/example-dataset + name: "example-dataset" diff --git a/src/dataset-operator/admissioncontroller/mutatingwebhook.go b/src/dataset-operator/admissioncontroller/mutatingwebhook.go index b8b787b5..9b73c33d 100644 --- a/src/dataset-operator/admissioncontroller/mutatingwebhook.go +++ b/src/dataset-operator/admissioncontroller/mutatingwebhook.go @@ -20,7 +20,8 @@ import ( ) const ( - prefixLabels = "dataset." + prefixLabels = "dataset." + labelSeparator = "." ) var ( @@ -118,7 +119,7 @@ func DatasetInputFromPod(pod *corev1.Pod) (map[int]*DatasetInput, error) { log.V(1).Info("processing label", k, v) if strings.HasPrefix(k, prefixLabels) { log.V(1).Info("Dataset input label in pod") - datasetNameArray := strings.Split(k, ".") + datasetNameArray := strings.Split(k, labelSeparator) if len(datasetNameArray) != 3 { err_out := fmt.Errorf("label %s is not in the right format", k) log.Error(err_out, "Format error in Dataset Labels", k, v) @@ -148,21 +149,25 @@ func DatasetInputFromPod(pod *corev1.Pod) (map[int]*DatasetInput, error) { } case "useas": isPresent := false - for _, u := range dataset.useas { - if u == v { - log.V(0).Info("Repeat declaration of useas in dataset label", k, v) - isPresent = true + uArray := strings.Split(v, labelSeparator) + log.V(1).Info("Dataset useas received", "useas", uArray) + for _, use := range uArray { + + for _, u := range dataset.useas { + if u == strings.TrimSpace(use) { + log.V(0).Info("Repeat declaration of useas in dataset label", k, v) + isPresent = true + } + } + if !isPresent { + dataset = dataset.AddToUseas(strings.TrimSpace(use)) } - } - if !isPresent { - dataset = dataset.AddToUseas(v) } default: err_out := fmt.Errorf("dataset label is in the wrong format %s", k) log.Error(err_out, "Format error in Dataset label", k, v) return nil, err_out } - datasets[idx] = dataset } } @@ -214,10 +219,14 @@ func patchPodWithDatasetLabels(pod *corev1.Pod) ([]jsonpatch.JsonPatchOperation, ds := datasetInfo[idx] log.V(1).Info("dataset label", "index", idx, "dataset", ds) for _, u := range ds.useas { + log.V(1).Info("Processing", "useas", u) switch u { case "mount": // The dataset is already mounted as a PVC no need to add it again + log.V(1).Info("doing", "useas", u) + if _, found := mountedPVCs[ds.name]; !found { + log.V(1).Info("Adding to volumes to mount", "dataset", ds.name) datasets_tomount[d] = ds.name d += 1 } @@ -227,12 +236,14 @@ func patchPodWithDatasetLabels(pod *corev1.Pod) ([]jsonpatch.JsonPatchOperation, c += 1 default: //this is an error - log.V(1).Info("Error: The useas for this dataset is not recognized", idx, ds) + log.V(1).Info("Error: The useas for this dataset is not recognized", "index", idx, "dataset", ds) return nil, fmt.Errorf("encountered an unknown useas") } } } + log.V(1).Info("Num of patches", "mount", len(datasets_tomount), "configmaps", len(configs_toinject)) + if len(datasets_tomount) > 0 { log.V(1).Info("Patching volumes to Pod Spec", "datasets", datasets_tomount) patch_ds := patchPodSpecWithDatasetPVCs(pod, datasets_tomount) diff --git a/src/dataset-operator/admissioncontroller/mutatingwebhook_test.go b/src/dataset-operator/admissioncontroller/mutatingwebhook_test.go index a1e3ace9..0ab19d47 100644 --- a/src/dataset-operator/admissioncontroller/mutatingwebhook_test.go +++ b/src/dataset-operator/admissioncontroller/mutatingwebhook_test.go @@ -208,4 +208,36 @@ var _ = DescribeTable("Pod is mutated correctly", return patchArray }, }), + Entry("Pod with no dataset volumes, 1 dataset label, useas mount, configmap -> 1 mount, 1 configmap for same dataset", &testPodLabels{ + makeInputPodSpec: func() *corev1.Pod { + inputPod := testing.MakePod("test-1", "test"). + AddLabelToPodMetadata("dataset.0.id", "testds"). + AddLabelToPodMetadata("dataset.0.useas", "mount.configmap"). + AddContainerToPod(testing.MakeContainer("foo"). + Obj()). + Obj() + return &inputPod + }, + makeOutputPatchOperations: func() []jsonpatch.JsonPatchOperation { + patchArray := []jsonpatch.JsonPatchOperation{ + testing.MakeJSONPatchOperation(). + SetOperation("add"). + SetVolumeasPath(0). + SetPVCasValue("testds"). + Obj(), + testing.MakeJSONPatchOperation(). + SetOperation("add"). + SetVolumeMountasPath("containers", 0, 0). + SetVolumeMountasValue("testds"). + Obj(), + testing.MakeJSONPatchOperation(). + SetOperation("add"). + SetNewConfigMapRefasPath("containers", 0). + AddConfigMapRefsToValue([]string{"testds"}). + AddSecretRefsToValue([]string{"testds"}). + Obj(), + } + return patchArray + }, + }), )