From b73e8aff6a8715e56ad33bdc83d9eaa64cb0d60c Mon Sep 17 00:00:00 2001 From: Andrei Matveyeu Date: Mon, 2 Dec 2024 14:12:21 +0100 Subject: [PATCH 1/7] allow environment provider jobs not bound to cluster --- api/v1alpha1/environmentrequest_types.go | 6 ++-- .../environmentrequest_controller.go | 33 ++++++++++++++----- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/api/v1alpha1/environmentrequest_types.go b/api/v1alpha1/environmentrequest_types.go index 0c6f724..32832bb 100644 --- a/api/v1alpha1/environmentrequest_types.go +++ b/api/v1alpha1/environmentrequest_types.go @@ -61,8 +61,10 @@ type EnvironmentRequestSpec struct { // TODO: Dataset per provider? Dataset *apiextensionsv1.JSON `json:"dataset,omitempty"` - Providers EnvironmentProviders `json:"providers"` - Splitter Splitter `json:"splitter"` + Providers EnvironmentProviders `json:"providers"` + Splitter Splitter `json:"splitter"` + ServiceAccountName string `json:"serviceaccountname,omitempty"` + SecretRefName string `json:"secretrefname,omitempty"` } // EnvironmentRequestStatus defines the observed state of EnvironmentRequest diff --git a/internal/controller/environmentrequest_controller.go b/internal/controller/environmentrequest_controller.go index 368f1c0..7500774 100644 --- a/internal/controller/environmentrequest_controller.go +++ b/internal/controller/environmentrequest_controller.go @@ -227,15 +227,13 @@ func (r EnvironmentRequestReconciler) environmentProviderJob(environmentrequest ttl := int32(300) grace := int64(30) backoff := int32(0) - // TODO: Cluster might not be a part of the environment request. - cluster := environmentrequest.Labels["etos.eiffel-community.github.io/cluster"] - return &batchv1.Job{ + + jobRef := &batchv1.Job{ ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{ - "etos.eiffel-community.github.io/id": environmentrequest.Spec.Identifier, // TODO: omitempty - "etos.eiffel-community.github.io/cluster": cluster, - "app.kubernetes.io/name": "environment-provider", - "app.kubernetes.io/part-of": "etos", + "etos.eiffel-community.github.io/id": environmentrequest.Spec.Identifier, // TODO: omitempty + "app.kubernetes.io/name": "environment-provider", + "app.kubernetes.io/part-of": "etos", }, Annotations: make(map[string]string), GenerateName: "environment-provider-", // unique names to allow multiple environment provider jobs @@ -250,7 +248,6 @@ func (r EnvironmentRequestReconciler) environmentProviderJob(environmentrequest }, Spec: corev1.PodSpec{ TerminationGracePeriodSeconds: &grace, - ServiceAccountName: fmt.Sprintf("%s-provider", cluster), RestartPolicy: "Never", Containers: []corev1.Container{ { @@ -271,7 +268,7 @@ func (r EnvironmentRequestReconciler) environmentProviderJob(environmentrequest { SecretRef: &corev1.SecretEnvSource{ LocalObjectReference: corev1.LocalObjectReference{ - Name: fmt.Sprintf("%s-environment-provider-cfg", cluster), + Name: "", }, }, }, @@ -288,6 +285,24 @@ func (r EnvironmentRequestReconciler) environmentProviderJob(environmentrequest }, }, } + clusterLabelName := "etos.eiffel-community.github.io/cluster" + if environmentrequest.Labels[clusterLabelName] != "" { + cluster := environmentrequest.Labels[clusterLabelName] + jobRef.ObjectMeta.Labels[clusterLabelName] = cluster + jobRef.Spec.Template.Spec.ServiceAccountName = fmt.Sprintf("%s-provider", cluster) + jobRef.Spec.Template.Spec.Containers[0].EnvFrom[0].SecretRef.LocalObjectReference.Name = fmt.Sprintf("%s-environment-provider-cfg", cluster) + } else { + // this allows environment requests for services not bound to a cluster + saName := environmentrequest.Spec.ServiceAccountName + if saName != "" { + jobRef.Spec.Template.Spec.ServiceAccountName = saName + } + srName := environmentrequest.Spec.SecretRefName + if srName != "" { + jobRef.Spec.Template.Spec.Containers[0].EnvFrom[0].SecretRef.LocalObjectReference.Name = srName + } + } + return jobRef } // registerOwnerIndexForJob will set an index of the jobs that an environment request owns. From 88bde4897af84b10b910487b04e88225badad749 Mon Sep 17 00:00:00 2001 From: Andrei Matveyeu Date: Thu, 5 Dec 2024 13:44:31 +0100 Subject: [PATCH 2/7] code review changes --- ...fel-community.github.io_environmentrequests.yaml | 4 ++++ .../controller/environmentrequest_controller.go | 13 ++++++------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/config/crd/bases/etos.eiffel-community.github.io_environmentrequests.yaml b/config/crd/bases/etos.eiffel-community.github.io_environmentrequests.yaml index 467bd8f..4cf06ca 100644 --- a/config/crd/bases/etos.eiffel-community.github.io_environmentrequests.yaml +++ b/config/crd/bases/etos.eiffel-community.github.io_environmentrequests.yaml @@ -105,6 +105,10 @@ spec: - id type: object type: object + secretrefname: + type: string + serviceaccountname: + type: string splitter: properties: tests: diff --git a/internal/controller/environmentrequest_controller.go b/internal/controller/environmentrequest_controller.go index 7500774..d562243 100644 --- a/internal/controller/environmentrequest_controller.go +++ b/internal/controller/environmentrequest_controller.go @@ -292,14 +292,13 @@ func (r EnvironmentRequestReconciler) environmentProviderJob(environmentrequest jobRef.Spec.Template.Spec.ServiceAccountName = fmt.Sprintf("%s-provider", cluster) jobRef.Spec.Template.Spec.Containers[0].EnvFrom[0].SecretRef.LocalObjectReference.Name = fmt.Sprintf("%s-environment-provider-cfg", cluster) } else { - // this allows environment requests for services not bound to a cluster - saName := environmentrequest.Spec.ServiceAccountName - if saName != "" { - jobRef.Spec.Template.Spec.ServiceAccountName = saName - } + // ServiceAccountName is optional in environment request. If not given it will be set to empty string/omitted in jobRef. + jobRef.Spec.Template.Spec.ServiceAccountName = environmentrequest.Spec.ServiceAccountName + + // SecretRefName is optional in environment request. If not given there, it will be set to empty string/omitted in jobRef srName := environmentrequest.Spec.SecretRefName - if srName != "" { - jobRef.Spec.Template.Spec.Containers[0].EnvFrom[0].SecretRef.LocalObjectReference.Name = srName + if srName == "" { + jobRef.Spec.Template.Spec.Containers[0].EnvFrom = []corev1.EnvFromSource{} } } return jobRef From ff7a012e21c9442c4f3e701ae78b89691f11d2b7 Mon Sep 17 00:00:00 2001 From: Andrei Matveyeu Date: Thu, 5 Dec 2024 15:32:32 +0100 Subject: [PATCH 3/7] code review changes --- .../environmentrequest_controller.go | 35 ++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/internal/controller/environmentrequest_controller.go b/internal/controller/environmentrequest_controller.go index d562243..8e97b04 100644 --- a/internal/controller/environmentrequest_controller.go +++ b/internal/controller/environmentrequest_controller.go @@ -264,15 +264,7 @@ func (r EnvironmentRequestReconciler) environmentProviderJob(environmentrequest corev1.ResourceCPU: resource.MustParse("100m"), }, }, - EnvFrom: []corev1.EnvFromSource{ - { - SecretRef: &corev1.SecretEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "", - }, - }, - }, - }, + EnvFrom: []corev1.EnvFromSource{}, Env: []corev1.EnvVar{ { Name: "REQUEST", @@ -290,15 +282,34 @@ func (r EnvironmentRequestReconciler) environmentProviderJob(environmentrequest cluster := environmentrequest.Labels[clusterLabelName] jobRef.ObjectMeta.Labels[clusterLabelName] = cluster jobRef.Spec.Template.Spec.ServiceAccountName = fmt.Sprintf("%s-provider", cluster) - jobRef.Spec.Template.Spec.Containers[0].EnvFrom[0].SecretRef.LocalObjectReference.Name = fmt.Sprintf("%s-environment-provider-cfg", cluster) + + envFrom := corev1.EnvFromSource{ + SecretRef: &corev1.SecretEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: fmt.Sprintf("%s-environment-provider-cfg", cluster), + }, + }, + } + container := &jobRef.Spec.Template.Spec.Containers[0] + container.EnvFrom = append(container.EnvFrom, envFrom) } else { // ServiceAccountName is optional in environment request. If not given it will be set to empty string/omitted in jobRef. jobRef.Spec.Template.Spec.ServiceAccountName = environmentrequest.Spec.ServiceAccountName // SecretRefName is optional in environment request. If not given there, it will be set to empty string/omitted in jobRef srName := environmentrequest.Spec.SecretRefName - if srName == "" { - jobRef.Spec.Template.Spec.Containers[0].EnvFrom = []corev1.EnvFromSource{} + + container := &jobRef.Spec.Template.Spec.Containers[0] + container.EnvFrom = []corev1.EnvFromSource{} + if srName != "" { + envFrom := corev1.EnvFromSource{ + SecretRef: &corev1.SecretEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: srName, + }, + }, + } + container.EnvFrom = append(container.EnvFrom, envFrom) } } return jobRef From 54472e8c63cf3e7622500104992501c51bf47269 Mon Sep 17 00:00:00 2001 From: Andrei Matveyeu Date: Fri, 6 Dec 2024 13:48:10 +0100 Subject: [PATCH 4/7] code review changes --- .../environmentrequest_controller.go | 57 +++++++------------ internal/controller/testrun_controller.go | 4 +- 2 files changed, 22 insertions(+), 39 deletions(-) diff --git a/internal/controller/environmentrequest_controller.go b/internal/controller/environmentrequest_controller.go index 8e97b04..1eb5063 100644 --- a/internal/controller/environmentrequest_controller.go +++ b/internal/controller/environmentrequest_controller.go @@ -228,7 +228,23 @@ func (r EnvironmentRequestReconciler) environmentProviderJob(environmentrequest grace := int64(30) backoff := int32(0) - jobRef := &batchv1.Job{ + envFrom := func(er *etosv1alpha1.EnvironmentRequest) []corev1.EnvFromSource { + result := []corev1.EnvFromSource{} + if er.Spec.SecretRefName == "" { + return result + } + item := corev1.EnvFromSource{ + SecretRef: &corev1.SecretEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: er.Spec.SecretRefName, + }, + }, + } + result = append(result, item) + return result + } + + return &batchv1.Job{ ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{ "etos.eiffel-community.github.io/id": environmentrequest.Spec.Identifier, // TODO: omitempty @@ -247,6 +263,7 @@ func (r EnvironmentRequestReconciler) environmentProviderJob(environmentrequest Name: environmentrequest.Name, }, Spec: corev1.PodSpec{ + ServiceAccountName: environmentrequest.Spec.ServiceAccountName, TerminationGracePeriodSeconds: &grace, RestartPolicy: "Never", Containers: []corev1.Container{ @@ -264,7 +281,7 @@ func (r EnvironmentRequestReconciler) environmentProviderJob(environmentrequest corev1.ResourceCPU: resource.MustParse("100m"), }, }, - EnvFrom: []corev1.EnvFromSource{}, + EnvFrom: envFrom(environmentrequest), Env: []corev1.EnvVar{ { Name: "REQUEST", @@ -277,42 +294,6 @@ func (r EnvironmentRequestReconciler) environmentProviderJob(environmentrequest }, }, } - clusterLabelName := "etos.eiffel-community.github.io/cluster" - if environmentrequest.Labels[clusterLabelName] != "" { - cluster := environmentrequest.Labels[clusterLabelName] - jobRef.ObjectMeta.Labels[clusterLabelName] = cluster - jobRef.Spec.Template.Spec.ServiceAccountName = fmt.Sprintf("%s-provider", cluster) - - envFrom := corev1.EnvFromSource{ - SecretRef: &corev1.SecretEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: fmt.Sprintf("%s-environment-provider-cfg", cluster), - }, - }, - } - container := &jobRef.Spec.Template.Spec.Containers[0] - container.EnvFrom = append(container.EnvFrom, envFrom) - } else { - // ServiceAccountName is optional in environment request. If not given it will be set to empty string/omitted in jobRef. - jobRef.Spec.Template.Spec.ServiceAccountName = environmentrequest.Spec.ServiceAccountName - - // SecretRefName is optional in environment request. If not given there, it will be set to empty string/omitted in jobRef - srName := environmentrequest.Spec.SecretRefName - - container := &jobRef.Spec.Template.Spec.Containers[0] - container.EnvFrom = []corev1.EnvFromSource{} - if srName != "" { - envFrom := corev1.EnvFromSource{ - SecretRef: &corev1.SecretEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: srName, - }, - }, - } - container.EnvFrom = append(container.EnvFrom, envFrom) - } - } - return jobRef } // registerOwnerIndexForJob will set an index of the jobs that an environment request owns. diff --git a/internal/controller/testrun_controller.go b/internal/controller/testrun_controller.go index 2bfc531..451dc19 100644 --- a/internal/controller/testrun_controller.go +++ b/internal/controller/testrun_controller.go @@ -451,7 +451,9 @@ func (r TestRunReconciler) environmentRequest(testrun *etosv1alpha1.TestRun, sui Splitter: etosv1alpha1.Splitter{ Tests: suite.Tests, }, - Image: testrun.Spec.EnvironmentProvider.Image, + Image: testrun.Spec.EnvironmentProvider.Image, + ServiceAccountName: fmt.Sprintf("%s-provider", testrun.Spec.Cluster), + SecretRefName: fmt.Sprintf("%s-environment-provider-cfg", testrun.Spec.Cluster), }, } } From 388353a9ac76dec1b69d639df4083d4f99822577 Mon Sep 17 00:00:00 2001 From: Andrei Matveyeu Date: Fri, 6 Dec 2024 14:56:00 +0100 Subject: [PATCH 5/7] code review changes --- .../environmentrequest_controller.go | 34 +++++++++---------- internal/controller/jobs.go | 1 + 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/internal/controller/environmentrequest_controller.go b/internal/controller/environmentrequest_controller.go index 1eb5063..b3a34d1 100644 --- a/internal/controller/environmentrequest_controller.go +++ b/internal/controller/environmentrequest_controller.go @@ -222,28 +222,28 @@ func (r *EnvironmentRequestReconciler) reconcileEnvironmentProvider(ctx context. return nil } +// envFrom creates list of corev1.EnvFromSource instances from an environment request +func envFrom(environmentrequest *etosv1alpha1.EnvironmentRequest) []corev1.EnvFromSource { + result := []corev1.EnvFromSource{} + if environmentrequest.Spec.SecretRefName == "" { + return result + } + item := corev1.EnvFromSource{ + SecretRef: &corev1.SecretEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: environmentrequest.Spec.SecretRefName, + }, + }, + } + result = append(result, item) + return result +} + // environmentProviderJob is the job definition for an etos environment provider. func (r EnvironmentRequestReconciler) environmentProviderJob(environmentrequest *etosv1alpha1.EnvironmentRequest) *batchv1.Job { ttl := int32(300) grace := int64(30) backoff := int32(0) - - envFrom := func(er *etosv1alpha1.EnvironmentRequest) []corev1.EnvFromSource { - result := []corev1.EnvFromSource{} - if er.Spec.SecretRefName == "" { - return result - } - item := corev1.EnvFromSource{ - SecretRef: &corev1.SecretEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: er.Spec.SecretRefName, - }, - }, - } - result = append(result, item) - return result - } - return &batchv1.Job{ ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{ diff --git a/internal/controller/jobs.go b/internal/controller/jobs.go index c42ff5d..613b141 100644 --- a/internal/controller/jobs.go +++ b/internal/controller/jobs.go @@ -145,6 +145,7 @@ func terminationLog(ctx context.Context, c client.Reader, job *batchv1.Job, cont return &Result{Conclusion: ConclusionFailed}, errors.New("could not read termination log from pod") } var result Result + if err := json.Unmarshal([]byte(status.State.Terminated.Message), &result); err != nil { logger.Error(err, "failed to unmarshal termination log to a result struct") return &Result{Conclusion: ConclusionFailed, Description: status.State.Terminated.Message}, nil From 862f0064f9312b61f2ea30a1caf0acc7cbe7a131 Mon Sep 17 00:00:00 2001 From: Andrei Matveyeu Date: Mon, 9 Dec 2024 10:43:18 +0100 Subject: [PATCH 6/7] New draft without secret ref name (not fully working yet) --- api/v1alpha1/environmentrequest_types.go | 27 +- api/v1alpha1/zz_generated.deepcopy.go | 18 ++ ...mmunity.github.io_environmentrequests.yaml | 230 +++++++++++++++++- config/manager/kustomization.yaml | 2 +- .../environmentrequest_controller.go | 81 ++++-- internal/controller/testrun_controller.go | 58 ++++- internal/etos/etos.go | 14 +- 7 files changed, 393 insertions(+), 37 deletions(-) diff --git a/api/v1alpha1/environmentrequest_types.go b/api/v1alpha1/environmentrequest_types.go index 32832bb..78e0cf3 100644 --- a/api/v1alpha1/environmentrequest_types.go +++ b/api/v1alpha1/environmentrequest_types.go @@ -45,6 +45,25 @@ type Splitter struct { Tests []Test `json:"tests"` } +// EnvironmentRequestJobConfig defines parameters required by +type EnvironmentRequestJobConfig struct { + EiffelMessageBus RabbitMQ `json:"eiffelMessageBus"` + EtosMessageBus RabbitMQ `json:"etosMessageBus"` + EtosApi string `json:"etosApi"` + EtosEtcdHost string `json:"etosEtcdHost"` + EtosEtcdPort string `json:"etosEtcdPort"` + EtosEventDataTimeout string `json:"etosEventDataTimeout"` + EtosGraphQlServer string `json:"etosGraphQlServer"` + EtosRoutingKeyTag string `json:"etosRoutingKeyTag"` + EtosWaitForTimeout string `json:"etosWaitForTimeout"` + + EnvironmentProviderEventDataTimeout string `json:"environmentProviderEventDataTimeout"` + EnvironmentProviderImage string `json:"environmentProviderImage"` + EnvironmentProviderImagePullPolicy corev1.PullPolicy `json:"environmentProviderImagePullPolicy"` + EnvironmentProviderServiceAccount string `json:"environmentProviderServiceAccount"` + EnvironmentProviderTestSuiteTimeout string `json:"environmentProviderTestSuiteTimeout"` +} + // EnvironmentRequestSpec defines the desired state of EnvironmentRequest type EnvironmentRequestSpec struct { // ID is the ID for the environments generated. Will be generated if nil. The ID is a UUID, any version, and regex matches that. @@ -61,10 +80,10 @@ type EnvironmentRequestSpec struct { // TODO: Dataset per provider? Dataset *apiextensionsv1.JSON `json:"dataset,omitempty"` - Providers EnvironmentProviders `json:"providers"` - Splitter Splitter `json:"splitter"` - ServiceAccountName string `json:"serviceaccountname,omitempty"` - SecretRefName string `json:"secretrefname,omitempty"` + Providers EnvironmentProviders `json:"providers"` + Splitter Splitter `json:"splitter"` + ServiceAccountName string `json:"serviceaccountname,omitempty"` + JobConfig EnvironmentRequestJobConfig `json:"jobConfig,omitempty"` } // EnvironmentRequestStatus defines the observed state of EnvironmentRequest diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index ccf7651..c904182 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -452,6 +452,23 @@ func (in *EnvironmentRequest) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EnvironmentRequestJobConfig) DeepCopyInto(out *EnvironmentRequestJobConfig) { + *out = *in + in.EiffelMessageBus.DeepCopyInto(&out.EiffelMessageBus) + in.EtosMessageBus.DeepCopyInto(&out.EtosMessageBus) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvironmentRequestJobConfig. +func (in *EnvironmentRequestJobConfig) DeepCopy() *EnvironmentRequestJobConfig { + if in == nil { + return nil + } + out := new(EnvironmentRequestJobConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *EnvironmentRequestList) DeepCopyInto(out *EnvironmentRequestList) { *out = *in @@ -499,6 +516,7 @@ func (in *EnvironmentRequestSpec) DeepCopyInto(out *EnvironmentRequestSpec) { } out.Providers = in.Providers in.Splitter.DeepCopyInto(&out.Splitter) + in.JobConfig.DeepCopyInto(&out.JobConfig) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvironmentRequestSpec. diff --git a/config/crd/bases/etos.eiffel-community.github.io_environmentrequests.yaml b/config/crd/bases/etos.eiffel-community.github.io_environmentrequests.yaml index 4cf06ca..5e71303 100644 --- a/config/crd/bases/etos.eiffel-community.github.io_environmentrequests.yaml +++ b/config/crd/bases/etos.eiffel-community.github.io_environmentrequests.yaml @@ -72,6 +72,234 @@ spec: description: PullPolicy describes a policy for if/when to pull a container image type: string + jobConfig: + description: EnvironmentRequestJobConfig defines parameters required + by + properties: + eiffelMessageBus: + description: RabbitMQ configuration. + properties: + deploy: + default: false + type: boolean + exchange: + default: amq.topic + type: string + host: + default: rabbitmq + type: string + password: + default: + value: guest + description: Var describes either a string value or a value + from a VarSource. + properties: + value: + type: string + valueFrom: + description: VarSource describes a value from either a + secretmap or configmap. + properties: + configMapKeyRef: + description: Selects a key from a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: SecretKeySelector selects a key of a + Secret. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + port: + default: "5672" + type: string + ssl: + default: "false" + type: string + username: + default: guest + type: string + vhost: + default: / + type: string + type: object + environmentProviderEventDataTimeout: + type: string + environmentProviderImage: + type: string + environmentProviderImagePullPolicy: + description: PullPolicy describes a policy for if/when to pull + a container image + type: string + environmentProviderServiceAccount: + type: string + environmentProviderTestSuiteTimeout: + type: string + etosApi: + type: string + etosEtcdHost: + type: string + etosEtcdPort: + type: string + etosEventDataTimeout: + type: string + etosGraphQlServer: + type: string + etosMessageBus: + description: RabbitMQ configuration. + properties: + deploy: + default: false + type: boolean + exchange: + default: amq.topic + type: string + host: + default: rabbitmq + type: string + password: + default: + value: guest + description: Var describes either a string value or a value + from a VarSource. + properties: + value: + type: string + valueFrom: + description: VarSource describes a value from either a + secretmap or configmap. + properties: + configMapKeyRef: + description: Selects a key from a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: SecretKeySelector selects a key of a + Secret. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + port: + default: "5672" + type: string + ssl: + default: "false" + type: string + username: + default: guest + type: string + vhost: + default: / + type: string + type: object + etosRoutingKeyTag: + type: string + etosWaitForTimeout: + type: string + required: + - eiffelMessageBus + - environmentProviderEventDataTimeout + - environmentProviderImage + - environmentProviderImagePullPolicy + - environmentProviderServiceAccount + - environmentProviderTestSuiteTimeout + - etosApi + - etosEtcdHost + - etosEtcdPort + - etosEventDataTimeout + - etosGraphQlServer + - etosMessageBus + - etosRoutingKeyTag + - etosWaitForTimeout + type: object maximumAmount: type: integer minimumAmount: @@ -105,8 +333,6 @@ spec: - id type: object type: object - secretrefname: - type: string serviceaccountname: type: string splitter: diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index 58c980c..12c775d 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -5,4 +5,4 @@ kind: Kustomization images: - name: controller newName: registry.nordix.org/eiffel/etos-controller - newTag: 61d5b687 + newTag: f5d42ddf diff --git a/internal/controller/environmentrequest_controller.go b/internal/controller/environmentrequest_controller.go index b3a34d1..bc0ad0b 100644 --- a/internal/controller/environmentrequest_controller.go +++ b/internal/controller/environmentrequest_controller.go @@ -222,21 +222,70 @@ func (r *EnvironmentRequestReconciler) reconcileEnvironmentProvider(ctx context. return nil } -// envFrom creates list of corev1.EnvFromSource instances from an environment request -func envFrom(environmentrequest *etosv1alpha1.EnvironmentRequest) []corev1.EnvFromSource { - result := []corev1.EnvFromSource{} - if environmentrequest.Spec.SecretRefName == "" { - return result +func envVarListFrom(environmentrequest *etosv1alpha1.EnvironmentRequest) []corev1.EnvVar { + envList := []corev1.EnvVar{ + { + Name: "REQUEST", + Value: environmentrequest.Name, + }, + { + Name: "ETOS_API", + Value: environmentrequest.Spec.JobConfig.EtosApi, + }, + { + Name: "ETOS_GRAPHQL_SERVER", + Value: environmentrequest.Spec.JobConfig.EtosGraphQlServer, + }, + { + Name: "ETOS_ETCD_HOST", + Value: environmentrequest.Spec.JobConfig.EtosEtcdHost, + }, + { + Name: "ETOS_ETCD_PORT", + Value: environmentrequest.Spec.JobConfig.EtosEtcdPort, + }, } - item := corev1.EnvFromSource{ - SecretRef: &corev1.SecretEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: environmentrequest.Spec.SecretRefName, + + var bus etosv1alpha1.RabbitMQ + for _, prefix := range []string{"", "ETOS_"} { + if prefix == "" { + bus = environmentrequest.Spec.JobConfig.EiffelMessageBus + } else if prefix == "ETOS_" { + bus = environmentrequest.Spec.JobConfig.EtosMessageBus + } + envVars := []corev1.EnvVar{ + { + Name: fmt.Sprintf("%sRABBITMQ_HOST", prefix), + Value: bus.Host, }, - }, + { + Name: fmt.Sprintf("%sRABBITMQ_VHOST", prefix), + Value: bus.Vhost, + }, + { + Name: fmt.Sprintf("%sRABBITMQ_PORT", prefix), + Value: bus.Port, + }, + { + Name: fmt.Sprintf("%sRABBITMQ_SSL", prefix), + Value: bus.SSL, + }, + { + Name: fmt.Sprintf("%sRABBITMQ_EXCHANGE", prefix), + Value: bus.Exchange, + }, + { + Name: fmt.Sprintf("%sRABBITMQ_USERNAME", prefix), + Value: bus.Username, + }, + { + Name: fmt.Sprintf("%sRABBITMQ_PASSWORD", prefix), + Value: bus.Password.Value, + }, + } + envList = append(envList, envVars...) } - result = append(result, item) - return result + return envList } // environmentProviderJob is the job definition for an etos environment provider. @@ -281,13 +330,7 @@ func (r EnvironmentRequestReconciler) environmentProviderJob(environmentrequest corev1.ResourceCPU: resource.MustParse("100m"), }, }, - EnvFrom: envFrom(environmentrequest), - Env: []corev1.EnvVar{ - { - Name: "REQUEST", - Value: environmentrequest.Name, - }, - }, + Env: envVarListFrom(environmentrequest), }, }, }, diff --git a/internal/controller/testrun_controller.go b/internal/controller/testrun_controller.go index 451dc19..40db494 100644 --- a/internal/controller/testrun_controller.go +++ b/internal/controller/testrun_controller.go @@ -59,6 +59,7 @@ type TestRunReconciler struct { client.Client Scheme *runtime.Scheme Clock + Cluster *etosv1alpha1.Cluster } /* @@ -130,9 +131,23 @@ func (r *TestRunReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct return ctrl.Result{RequeueAfter: next}, nil } return ctrl.Result{}, nil + + } + clusterNamespacedName := types.NamespacedName{ + Name: testrun.Spec.Cluster, + Namespace: req.NamespacedName.Namespace, } + msg := fmt.Sprintf("Getting CL by name: %s@%s |||", clusterNamespacedName.Name, clusterNamespacedName.Namespace) + logger.Info(msg) + cluster := &etosv1alpha1.Cluster{} + if err := r.Get(ctx, clusterNamespacedName, cluster); err != nil { + logger.Info("Failed to get cluster resource!") + return ctrl.Result{}, nil + } + msg = fmt.Sprint("Got CL: %s", cluster) + logger.Info(msg) - if err := r.reconcile(ctx, testrun); err != nil { + if err := r.reconcile(ctx, cluster, testrun); err != nil { if apierrors.IsConflict(err) { return ctrl.Result{Requeue: true}, nil } @@ -143,7 +158,7 @@ func (r *TestRunReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct return ctrl.Result{}, nil } -func (r *TestRunReconciler) reconcile(ctx context.Context, testrun *etosv1alpha1.TestRun) error { +func (r *TestRunReconciler) reconcile(ctx context.Context, cluster *etosv1alpha1.Cluster, testrun *etosv1alpha1.TestRun) error { logger := log.FromContext(ctx) // Set initial statuses if not set. @@ -187,7 +202,7 @@ func (r *TestRunReconciler) reconcile(ctx context.Context, testrun *etosv1alpha1 } // Create environment request - err, exit := r.reconcileEnvironmentRequest(ctx, testrun) + err, exit := r.reconcileEnvironmentRequest(ctx, cluster, testrun) if err != nil { return err } @@ -236,7 +251,7 @@ func (r *TestRunReconciler) complete(ctx context.Context, testrun *etosv1alpha1. } // reconcileEnvironmentRequest will check the status of environment requests, create new ones if necessary. -func (r *TestRunReconciler) reconcileEnvironmentRequest(ctx context.Context, testrun *etosv1alpha1.TestRun) (error, bool) { +func (r *TestRunReconciler) reconcileEnvironmentRequest(ctx context.Context, cluster *etosv1alpha1.Cluster, testrun *etosv1alpha1.TestRun) (error, bool) { logger := log.FromContext(ctx) var environmentRequestList etosv1alpha1.EnvironmentRequestList if err := r.List(ctx, &environmentRequestList, client.InNamespace(testrun.Namespace), client.MatchingFields{TestRunOwnerKey: testrun.Name}); err != nil { @@ -261,7 +276,7 @@ func (r *TestRunReconciler) reconcileEnvironmentRequest(ctx context.Context, tes } } if !found { - request := r.environmentRequest(testrun, suite) + request := r.environmentRequest(cluster, testrun, suite) if err := ctrl.SetControllerReference(testrun, request, r.Scheme); err != nil { return err, true } @@ -414,7 +429,20 @@ func (r *TestRunReconciler) checkEnvironment(ctx context.Context, testrun *etosv } // environmentRequest is the definition for an environment request. -func (r TestRunReconciler) environmentRequest(testrun *etosv1alpha1.TestRun, suite etosv1alpha1.Suite) *etosv1alpha1.EnvironmentRequest { +func (r TestRunReconciler) environmentRequest(cluster *etosv1alpha1.Cluster, testrun *etosv1alpha1.TestRun, suite etosv1alpha1.Suite) *etosv1alpha1.EnvironmentRequest { + eventRepository := cluster.Spec.EventRepository.Host + if cluster.Spec.ETOS.Config.ETOSEventRepositoryURL != "" { + eventRepository = cluster.Spec.ETOS.Config.ETOSEventRepositoryURL + } + + eiffelMessageBus := cluster.Spec.MessageBus.EiffelMessageBus + eiffelMessageBus.Host = fmt.Sprintf("%s-%s", cluster.Name, eiffelMessageBus.Host) + + etosMessageBus := cluster.Spec.MessageBus.ETOSMessageBus + etosMessageBus.Host = fmt.Sprintf("%s-%s", cluster.Name, etosMessageBus.Host) + + etosApi := fmt.Sprintf("%s-api", cluster.Name) + return &etosv1alpha1.EnvironmentRequest{ ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{ @@ -453,7 +481,23 @@ func (r TestRunReconciler) environmentRequest(testrun *etosv1alpha1.TestRun, sui }, Image: testrun.Spec.EnvironmentProvider.Image, ServiceAccountName: fmt.Sprintf("%s-provider", testrun.Spec.Cluster), - SecretRefName: fmt.Sprintf("%s-environment-provider-cfg", testrun.Spec.Cluster), + JobConfig: etosv1alpha1.EnvironmentRequestJobConfig{ + EiffelMessageBus: eiffelMessageBus, + EtosMessageBus: etosMessageBus, + EtosApi: etosApi, + + EtosRoutingKeyTag: cluster.Spec.ETOS.Config.RoutingKeyTag, + EtosGraphQlServer: eventRepository, + EtosEtcdHost: fmt.Sprintf("%s-etcd", cluster.Name), + EtosEtcdPort: cluster.Spec.Database.Etcd.Port, + EtosEventDataTimeout: cluster.Spec.ETOS.Config.EventDataTimeout, + EtosWaitForTimeout: cluster.Spec.ETOS.Config.EnvironmentTimeout, + EnvironmentProviderEventDataTimeout: cluster.Spec.ETOS.Config.EventDataTimeout, + EnvironmentProviderImage: cluster.Spec.ETOS.EnvironmentProvider.Image.Image, + EnvironmentProviderImagePullPolicy: cluster.Spec.ETOS.EnvironmentProvider.ImagePullPolicy, + EnvironmentProviderServiceAccount: fmt.Sprintf("%s-provider", cluster.Name), + EnvironmentProviderTestSuiteTimeout: cluster.Spec.ETOS.Config.TestSuiteTimeout, + }, }, } } diff --git a/internal/etos/etos.go b/internal/etos/etos.go index 91ffc4f..d7b81e2 100644 --- a/internal/etos/etos.go +++ b/internal/etos/etos.go @@ -282,7 +282,7 @@ func (r *ETOSDeployment) reconcileSecret(ctx context.Context, logger logr.Logger // reconcileEnvironmentProviderConfig will reconcile the secret to use as configuration for the ETOS environment provider. func (r *ETOSDeployment) reconcileEnvironmentProviderConfig(ctx context.Context, logger logr.Logger, name types.NamespacedName, encryptionKeyName, configmapName string, owner metav1.Object) (*corev1.Secret, error) { name = types.NamespacedName{Name: fmt.Sprintf("%s-environment-provider-cfg", name.Name), Namespace: name.Namespace} - target, err := r.environmentProviderConfig(ctx, name, encryptionKeyName, configmapName) + target, err := r.environmentProviderConfig(ctx, logger, name, encryptionKeyName, configmapName) if err != nil { return nil, err } @@ -305,7 +305,7 @@ func (r *ETOSDeployment) reconcileEnvironmentProviderConfig(ctx context.Context, } // config creates a new Secret to be used as configuration for the ETOS API. -func (r *ETOSDeployment) environmentProviderConfig(ctx context.Context, name types.NamespacedName, encryptionKeyName, configmapName string) (*corev1.Secret, error) { +func (r *ETOSDeployment) environmentProviderConfig(ctx context.Context, logger logr.Logger, name types.NamespacedName, encryptionKeyName, configmapName string) (*corev1.Secret, error) { eiffel := &corev1.Secret{} if err := r.Get(ctx, types.NamespacedName{Name: r.rabbitmqSecret, Namespace: name.Namespace}, eiffel); err != nil { return nil, err @@ -324,13 +324,19 @@ func (r *ETOSDeployment) environmentProviderConfig(ctx context.Context, name typ } data := map[string][]byte{} maps.Copy(data, eiffel.Data) + logger.Info("environmentProviderConfig eiffel data", "data", eiffel.Data) maps.Copy(data, etos.Data) + logger.Info("environmentProviderConfig etos data", "data", etos.Data) maps.Copy(data, encryption.Data) + logger.Info("environmentProviderConfig encryption data", "data", encryption.Data) maps.Copy(data, config.Data) - return &corev1.Secret{ + logger.Info("environmentProviderConfig config data", "data", config.Data) + secret := &corev1.Secret{ ObjectMeta: r.meta(name), Data: data, - }, nil + } + logger.Info("environmentProviderConfig secret", "secret", secret) + return secret, nil } // ingress creates an ingress resource definition for ETOS. From dc5883393b4a88c8d95e3e3d220c30300a25b354 Mon Sep 17 00:00:00 2001 From: Andrei Matveyeu Date: Wed, 11 Dec 2024 09:37:44 +0100 Subject: [PATCH 7/7] Version working with 'etosctl testrun start' --- api/v1alpha1/environmentrequest_types.go | 20 +++--- api/v1alpha1/zz_generated.deepcopy.go | 1 + ...mmunity.github.io_environmentrequests.yaml | 67 +++++++++++++++++++ .../environmentrequest_controller.go | 36 ++++++++-- internal/controller/testrun_controller.go | 15 ++--- internal/etos/etos.go | 5 -- 6 files changed, 114 insertions(+), 30 deletions(-) diff --git a/api/v1alpha1/environmentrequest_types.go b/api/v1alpha1/environmentrequest_types.go index 78e0cf3..a210302 100644 --- a/api/v1alpha1/environmentrequest_types.go +++ b/api/v1alpha1/environmentrequest_types.go @@ -47,15 +47,17 @@ type Splitter struct { // EnvironmentRequestJobConfig defines parameters required by type EnvironmentRequestJobConfig struct { - EiffelMessageBus RabbitMQ `json:"eiffelMessageBus"` - EtosMessageBus RabbitMQ `json:"etosMessageBus"` - EtosApi string `json:"etosApi"` - EtosEtcdHost string `json:"etosEtcdHost"` - EtosEtcdPort string `json:"etosEtcdPort"` - EtosEventDataTimeout string `json:"etosEventDataTimeout"` - EtosGraphQlServer string `json:"etosGraphQlServer"` - EtosRoutingKeyTag string `json:"etosRoutingKeyTag"` - EtosWaitForTimeout string `json:"etosWaitForTimeout"` + EiffelMessageBus RabbitMQ `json:"eiffelMessageBus"` + EtosMessageBus RabbitMQ `json:"etosMessageBus"` + EtosApi string `json:"etosApi"` + EtosEncryptionKey Var `json:"etosEncryptionKeySecretRef"` + EtosEtcdHost string `json:"etosEtcdHost"` + EtosEtcdPort string `json:"etosEtcdPort"` + EtosEventDataTimeout string `json:"etosEventDataTimeout"` + EtosGraphQlServer string `json:"etosGraphQlServer"` + EtosRoutingKeyTag string `json:"etosRoutingKeyTag"` + EtosWaitForTimeout string `json:"etosWaitForTimeout"` + EtosTestRunnerVersion string `json:"etosTestRunnerVersion"` EnvironmentProviderEventDataTimeout string `json:"environmentProviderEventDataTimeout"` EnvironmentProviderImage string `json:"environmentProviderImage"` diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index c904182..44f62e7 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -457,6 +457,7 @@ func (in *EnvironmentRequestJobConfig) DeepCopyInto(out *EnvironmentRequestJobCo *out = *in in.EiffelMessageBus.DeepCopyInto(&out.EiffelMessageBus) in.EtosMessageBus.DeepCopyInto(&out.EtosMessageBus) + in.EtosEncryptionKey.DeepCopyInto(&out.EtosEncryptionKey) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvironmentRequestJobConfig. diff --git a/config/crd/bases/etos.eiffel-community.github.io_environmentrequests.yaml b/config/crd/bases/etos.eiffel-community.github.io_environmentrequests.yaml index 5e71303..c4d7846 100644 --- a/config/crd/bases/etos.eiffel-community.github.io_environmentrequests.yaml +++ b/config/crd/bases/etos.eiffel-community.github.io_environmentrequests.yaml @@ -181,6 +181,69 @@ spec: type: string etosApi: type: string + etosEncryptionKeySecretRef: + description: Var describes either a string value or a value from + a VarSource. + properties: + value: + type: string + valueFrom: + description: VarSource describes a value from either a secretmap + or configmap. + properties: + configMapKeyRef: + description: Selects a key from a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object etosEtcdHost: type: string etosEtcdPort: @@ -282,6 +345,8 @@ spec: type: object etosRoutingKeyTag: type: string + etosTestRunnerVersion: + type: string etosWaitForTimeout: type: string required: @@ -292,12 +357,14 @@ spec: - environmentProviderServiceAccount - environmentProviderTestSuiteTimeout - etosApi + - etosEncryptionKeySecretRef - etosEtcdHost - etosEtcdPort - etosEventDataTimeout - etosGraphQlServer - etosMessageBus - etosRoutingKeyTag + - etosTestRunnerVersion - etosWaitForTimeout type: object maximumAmount: diff --git a/internal/controller/environmentrequest_controller.go b/internal/controller/environmentrequest_controller.go index bc0ad0b..eabbe5b 100644 --- a/internal/controller/environmentrequest_controller.go +++ b/internal/controller/environmentrequest_controller.go @@ -211,7 +211,10 @@ func (r *EnvironmentRequestReconciler) reconcileEnvironmentProvider(ctx context. } // No environment providers, create environment provider if providers.empty() { - environmentProvider := r.environmentProviderJob(environmentrequest) + environmentProvider, _err := r.environmentProviderJob(ctx, environmentrequest) + if _err != nil { + return _err + } if err := ctrl.SetControllerReference(environmentrequest, environmentProvider, r.Scheme); err != nil { return err } @@ -222,7 +225,11 @@ func (r *EnvironmentRequestReconciler) reconcileEnvironmentProvider(ctx context. return nil } -func envVarListFrom(environmentrequest *etosv1alpha1.EnvironmentRequest) []corev1.EnvVar { +func (r EnvironmentRequestReconciler) envVarListFrom(ctx context.Context, environmentrequest *etosv1alpha1.EnvironmentRequest) ([]corev1.EnvVar, error) { + etosEncryptionKey, err := environmentrequest.Spec.JobConfig.EtosEncryptionKey.Get(ctx, r.Client, environmentrequest.Namespace) + if err != nil { + return nil, err + } envList := []corev1.EnvVar{ { Name: "REQUEST", @@ -236,6 +243,10 @@ func envVarListFrom(environmentrequest *etosv1alpha1.EnvironmentRequest) []corev Name: "ETOS_GRAPHQL_SERVER", Value: environmentrequest.Spec.JobConfig.EtosGraphQlServer, }, + { + Name: "ETOS_ENCRYPTION_KEY", + Value: string(etosEncryptionKey), + }, { Name: "ETOS_ETCD_HOST", Value: environmentrequest.Spec.JobConfig.EtosEtcdHost, @@ -244,6 +255,13 @@ func envVarListFrom(environmentrequest *etosv1alpha1.EnvironmentRequest) []corev Name: "ETOS_ETCD_PORT", Value: environmentrequest.Spec.JobConfig.EtosEtcdPort, }, + { + // Optional when environmentrequest is not issued by testrun, i. e. created separately. + // When the environment request is issued by a testrun, this variable is propagated + // further from environment provider to test runner. + Name: "ETR_VERSION", + Value: environmentrequest.Spec.JobConfig.EtosTestRunnerVersion, + }, } var bus etosv1alpha1.RabbitMQ @@ -285,14 +303,20 @@ func envVarListFrom(environmentrequest *etosv1alpha1.EnvironmentRequest) []corev } envList = append(envList, envVars...) } - return envList + return envList, nil } // environmentProviderJob is the job definition for an etos environment provider. -func (r EnvironmentRequestReconciler) environmentProviderJob(environmentrequest *etosv1alpha1.EnvironmentRequest) *batchv1.Job { +func (r EnvironmentRequestReconciler) environmentProviderJob(ctx context.Context, environmentrequest *etosv1alpha1.EnvironmentRequest) (*batchv1.Job, error) { + logger := log.FromContext(ctx) ttl := int32(300) grace := int64(30) backoff := int32(0) + envVarList, err := r.envVarListFrom(ctx, environmentrequest) + if err != nil { + logger.Error(err, "Failed to create environment variable list for environment provider") + return nil, err + } return &batchv1.Job{ ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{ @@ -330,13 +354,13 @@ func (r EnvironmentRequestReconciler) environmentProviderJob(environmentrequest corev1.ResourceCPU: resource.MustParse("100m"), }, }, - Env: envVarListFrom(environmentrequest), + Env: envVarList, }, }, }, }, }, - } + }, nil } // registerOwnerIndexForJob will set an index of the jobs that an environment request owns. diff --git a/internal/controller/testrun_controller.go b/internal/controller/testrun_controller.go index 40db494..c777e16 100644 --- a/internal/controller/testrun_controller.go +++ b/internal/controller/testrun_controller.go @@ -137,15 +137,11 @@ func (r *TestRunReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct Name: testrun.Spec.Cluster, Namespace: req.NamespacedName.Namespace, } - msg := fmt.Sprintf("Getting CL by name: %s@%s |||", clusterNamespacedName.Name, clusterNamespacedName.Namespace) - logger.Info(msg) cluster := &etosv1alpha1.Cluster{} if err := r.Get(ctx, clusterNamespacedName, cluster); err != nil { logger.Info("Failed to get cluster resource!") return ctrl.Result{}, nil } - msg = fmt.Sprint("Got CL: %s", cluster) - logger.Info(msg) if err := r.reconcile(ctx, cluster, testrun); err != nil { if apierrors.IsConflict(err) { @@ -441,8 +437,6 @@ func (r TestRunReconciler) environmentRequest(cluster *etosv1alpha1.Cluster, tes etosMessageBus := cluster.Spec.MessageBus.ETOSMessageBus etosMessageBus.Host = fmt.Sprintf("%s-%s", cluster.Name, etosMessageBus.Host) - etosApi := fmt.Sprintf("%s-api", cluster.Name) - return &etosv1alpha1.EnvironmentRequest{ ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{ @@ -482,10 +476,10 @@ func (r TestRunReconciler) environmentRequest(cluster *etosv1alpha1.Cluster, tes Image: testrun.Spec.EnvironmentProvider.Image, ServiceAccountName: fmt.Sprintf("%s-provider", testrun.Spec.Cluster), JobConfig: etosv1alpha1.EnvironmentRequestJobConfig{ - EiffelMessageBus: eiffelMessageBus, - EtosMessageBus: etosMessageBus, - EtosApi: etosApi, - + EiffelMessageBus: eiffelMessageBus, + EtosMessageBus: etosMessageBus, + EtosApi: cluster.Spec.ETOS.Config.ETOSApiURL, + EtosEncryptionKey: cluster.Spec.ETOS.Config.EncryptionKey, EtosRoutingKeyTag: cluster.Spec.ETOS.Config.RoutingKeyTag, EtosGraphQlServer: eventRepository, EtosEtcdHost: fmt.Sprintf("%s-etcd", cluster.Name), @@ -497,6 +491,7 @@ func (r TestRunReconciler) environmentRequest(cluster *etosv1alpha1.Cluster, tes EnvironmentProviderImagePullPolicy: cluster.Spec.ETOS.EnvironmentProvider.ImagePullPolicy, EnvironmentProviderServiceAccount: fmt.Sprintf("%s-provider", cluster.Name), EnvironmentProviderTestSuiteTimeout: cluster.Spec.ETOS.Config.TestSuiteTimeout, + EtosTestRunnerVersion: cluster.Spec.ETOS.TestRunner.Version, }, }, } diff --git a/internal/etos/etos.go b/internal/etos/etos.go index d7b81e2..6298cde 100644 --- a/internal/etos/etos.go +++ b/internal/etos/etos.go @@ -324,18 +324,13 @@ func (r *ETOSDeployment) environmentProviderConfig(ctx context.Context, logger l } data := map[string][]byte{} maps.Copy(data, eiffel.Data) - logger.Info("environmentProviderConfig eiffel data", "data", eiffel.Data) maps.Copy(data, etos.Data) - logger.Info("environmentProviderConfig etos data", "data", etos.Data) maps.Copy(data, encryption.Data) - logger.Info("environmentProviderConfig encryption data", "data", encryption.Data) maps.Copy(data, config.Data) - logger.Info("environmentProviderConfig config data", "data", config.Data) secret := &corev1.Secret{ ObjectMeta: r.meta(name), Data: data, } - logger.Info("environmentProviderConfig secret", "secret", secret) return secret, nil }