From ee36b58fa45b7af531613286ddac91698050ce98 Mon Sep 17 00:00:00 2001 From: cliveseldon Date: Mon, 23 Mar 2020 11:28:06 +0000 Subject: [PATCH] Ensure all labels and annotations added to created deployments --- notebooks/resources/model_with_labels.yaml | 31 ++++++ .../seldondeployment_controller.go | 29 ++++- .../seldondeployment_controller_test.go | 103 ++++++++++++++++++ 3 files changed, 158 insertions(+), 5 deletions(-) create mode 100644 notebooks/resources/model_with_labels.yaml diff --git a/notebooks/resources/model_with_labels.yaml b/notebooks/resources/model_with_labels.yaml new file mode 100644 index 0000000000..0ea4212a28 --- /dev/null +++ b/notebooks/resources/model_with_labels.yaml @@ -0,0 +1,31 @@ +apiVersion: machinelearning.seldon.io/v1 +kind: SeldonDeployment +metadata: + name: seldon-model +spec: + name: test-deployment + annotations: + ann1: value1 + predictors: + - componentSpecs: + - spec: + containers: + - image: seldonio/mock_classifier_rest:1.3 + name: classifier + metadata: + annotations: + ann3: value3 + labels: + label2: value2 + graph: + children: [] + endpoint: + type: REST + name: classifier + type: MODEL + name: example + replicas: 1 + labels: + label1: value1 + annotations: + ann2: value2 diff --git a/operator/controllers/seldondeployment_controller.go b/operator/controllers/seldondeployment_controller.go index 489f5ce9e6..ec4b6f60a5 100644 --- a/operator/controllers/seldondeployment_controller.go +++ b/operator/controllers/seldondeployment_controller.go @@ -727,9 +727,10 @@ func createContainerService(deploy *appsv1.Deployment, p machinelearningv1.Predi func createDeploymentWithoutEngine(depName string, seldonId string, seldonPodSpec *machinelearningv1.SeldonPodSpec, p *machinelearningv1.PredictorSpec, mlDep *machinelearningv1.SeldonDeployment) *appsv1.Deployment { deploy := &appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ - Name: depName, - Namespace: getNamespace(mlDep), - Labels: map[string]string{machinelearningv1.Label_seldon_id: seldonId, "app": depName, "fluentd": "true"}, + Name: depName, + Namespace: getNamespace(mlDep), + Labels: map[string]string{machinelearningv1.Label_seldon_id: seldonId, "app": depName, "fluentd": "true"}, + Annotations: map[string]string{}, }, Spec: appsv1.DeploymentSpec{ Selector: &metav1.LabelSelector{ @@ -738,7 +739,7 @@ func createDeploymentWithoutEngine(depName string, seldonId string, seldonPodSpe Template: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{machinelearningv1.Label_seldon_id: seldonId, "app": depName, "fluentd": "true"}, - Annotations: mlDep.Spec.Annotations, + Annotations: map[string]string{}, }, }, Strategy: appsv1.DeploymentStrategy{RollingUpdate: &appsv1.RollingUpdateDeployment{MaxUnavailable: &intstr.IntOrString{StrVal: "10%"}}}, @@ -749,10 +750,21 @@ func createDeploymentWithoutEngine(depName string, seldonId string, seldonPodSpe deploy.Spec.Template.ObjectMeta.Labels["shadow"] = "true" } + //Add annotations from top level + for k, v := range mlDep.Spec.Annotations { + deploy.Annotations[k] = v + deploy.Spec.Template.ObjectMeta.Annotations[k] = v + } + // Add annottaions from predictor + for k, v := range p.Annotations { + deploy.Annotations[k] = v + deploy.Spec.Template.ObjectMeta.Annotations[k] = v + } if seldonPodSpec != nil { deploy.Spec.Template.Spec = seldonPodSpec.Spec - // add more annotations + // add more annotations from metadata for k, v := range seldonPodSpec.Metadata.Annotations { + deploy.Annotations[k] = v deploy.Spec.Template.ObjectMeta.Annotations[k] = v } } @@ -762,6 +774,13 @@ func createDeploymentWithoutEngine(depName string, seldonId string, seldonPodSpe deploy.ObjectMeta.Labels[k] = v deploy.Spec.Template.ObjectMeta.Labels[k] = v } + // add labels from podSpec metadata + if seldonPodSpec != nil { + for k, v := range seldonPodSpec.Metadata.Labels { + deploy.ObjectMeta.Labels[k] = v + deploy.Spec.Template.ObjectMeta.Labels[k] = v + } + } //Add some default to help with diffs in controller if deploy.Spec.Template.Spec.RestartPolicy == "" { diff --git a/operator/controllers/seldondeployment_controller_test.go b/operator/controllers/seldondeployment_controller_test.go index 4dabb9f276..72a32a5dbf 100644 --- a/operator/controllers/seldondeployment_controller_test.go +++ b/operator/controllers/seldondeployment_controller_test.go @@ -30,6 +30,7 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/rand" "path/filepath" + "testing" "time" ) @@ -530,3 +531,105 @@ var _ = Describe("Create a Seldon Deployment with hpa", func() { }) }) + +// --- Non Ginkgo Tests + +func TestCreateDeploymentWithLabelsAndAnnotations(t *testing.T) { + g := NewGomegaWithT(t) + depName := "dep" + labelKey1 := "key1" + labelValue1 := "value1" + labelKey2 := "key2" + labelValue2 := "value2" + annotationKey1 := "key1" + annotationValue1 := "value1" + annotationKey2 := "key2" + annotationValue2 := "value2" + annotationKey3 := "key3" + annotationValue3 := "value3" + modelType := machinelearningv1.MODEL + instance := &machinelearningv1.SeldonDeployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: depName, + Namespace: "default", + }, + Spec: machinelearningv1.SeldonDeploymentSpec{ + Name: "mydep", + Annotations: map[string]string{annotationKey1: annotationValue1}, + Predictors: []machinelearningv1.PredictorSpec{ + { + Name: "p1", + Labels: map[string]string{labelKey1: labelValue1}, + Annotations: map[string]string{annotationKey2: annotationValue2}, + ComponentSpecs: []*machinelearningv1.SeldonPodSpec{ + { + Metadata: metav1.ObjectMeta{ + Labels: map[string]string{labelKey2: labelValue2}, + Annotations: map[string]string{annotationKey3: annotationValue3}, + }, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + Image: "seldonio/mock_classifier:1.0", + Name: "classifier", + }, + }, + }, + }, + }, + Graph: &machinelearningv1.PredictiveUnit{ + Name: "classifier", + Type: &modelType, + }, + }, + }, + }, + } + + dep := createDeploymentWithoutEngine(depName, "a", instance.Spec.Predictors[0].ComponentSpecs[0], &instance.Spec.Predictors[0], instance) + g.Expect(dep.Labels[labelKey1]).To(Equal(labelValue1)) + g.Expect(dep.Labels[labelKey2]).To(Equal(labelValue2)) + g.Expect(dep.Spec.Template.ObjectMeta.Labels[labelKey1]).To(Equal(labelValue1)) + g.Expect(dep.Spec.Template.ObjectMeta.Labels[labelKey2]).To(Equal(labelValue2)) + g.Expect(dep.Annotations[annotationKey1]).To(Equal(annotationValue1)) + g.Expect(dep.Annotations[annotationKey2]).To(Equal(annotationValue2)) + g.Expect(dep.Annotations[annotationKey3]).To(Equal(annotationValue3)) +} + +func TestCreateDeploymentWithNoLabelsAndAnnotations(t *testing.T) { + depName := "dep" + modelType := machinelearningv1.MODEL + instance := &machinelearningv1.SeldonDeployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: depName, + Namespace: "default", + }, + Spec: machinelearningv1.SeldonDeploymentSpec{ + Name: "mydep", + Predictors: []machinelearningv1.PredictorSpec{ + { + Name: "p1", + ComponentSpecs: []*machinelearningv1.SeldonPodSpec{ + { + Metadata: metav1.ObjectMeta{}, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + Image: "seldonio/mock_classifier:1.0", + Name: "classifier", + }, + }, + }, + }, + }, + Graph: &machinelearningv1.PredictiveUnit{ + Name: "classifier", + Type: &modelType, + }, + }, + }, + }, + } + + _ = createDeploymentWithoutEngine(depName, "a", instance.Spec.Predictors[0].ComponentSpecs[0], &instance.Spec.Predictors[0], instance) +}