diff --git a/cmd/web-hooks/internal/handler/handler_test.go b/cmd/web-hooks/internal/handler/handler_test.go index 8bdf193a..a5f3c630 100644 --- a/cmd/web-hooks/internal/handler/handler_test.go +++ b/cmd/web-hooks/internal/handler/handler_test.go @@ -181,7 +181,7 @@ func createAdmissionRequest(operation admissionv1.Operation, crdType string, crd ConsumedBTPServices: []string{}, DeploymentDefinition: &v1alpha1.DeploymentDetails{ Type: v1alpha1.DeploymentCAP, - ContainerDetails: v1alpha1.ContainerDetails{ + CommonDetails: v1alpha1.CommonDetails{ Image: "foo", }, }, @@ -191,7 +191,7 @@ func createAdmissionRequest(operation admissionv1.Operation, crdType string, crd ConsumedBTPServices: []string{}, DeploymentDefinition: &v1alpha1.DeploymentDetails{ Type: v1alpha1.DeploymentRouter, - ContainerDetails: v1alpha1.ContainerDetails{ + CommonDetails: v1alpha1.CommonDetails{ Image: "foo", }, }, @@ -201,7 +201,7 @@ func createAdmissionRequest(operation admissionv1.Operation, crdType string, crd ConsumedBTPServices: []string{}, JobDefinition: &v1alpha1.JobDetails{ Type: v1alpha1.JobContent, - ContainerDetails: v1alpha1.ContainerDetails{ + CommonDetails: v1alpha1.CommonDetails{ Image: "foo", }, }, @@ -897,7 +897,7 @@ func TestCavInvalidity(t *testing.T) { ConsumedBTPServices: []string{}, DeploymentDefinition: &v1alpha1.DeploymentDetails{ Type: v1alpha1.DeploymentCAP, - ContainerDetails: v1alpha1.ContainerDetails{ + CommonDetails: v1alpha1.CommonDetails{ Image: "foo", }, }, @@ -907,7 +907,7 @@ func TestCavInvalidity(t *testing.T) { ConsumedBTPServices: []string{}, DeploymentDefinition: &v1alpha1.DeploymentDetails{ Type: v1alpha1.DeploymentRouter, - ContainerDetails: v1alpha1.ContainerDetails{ + CommonDetails: v1alpha1.CommonDetails{ Image: "foo", }, }, @@ -917,7 +917,7 @@ func TestCavInvalidity(t *testing.T) { ConsumedBTPServices: []string{}, JobDefinition: &v1alpha1.JobDetails{ Type: v1alpha1.JobContent, - ContainerDetails: v1alpha1.ContainerDetails{ + CommonDetails: v1alpha1.CommonDetails{ Image: "foo", }, }, @@ -933,7 +933,7 @@ func TestCavInvalidity(t *testing.T) { ConsumedBTPServices: []string{}, DeploymentDefinition: &v1alpha1.DeploymentDetails{ Type: v1alpha1.DeploymentAdditional, - ContainerDetails: v1alpha1.ContainerDetails{ + CommonDetails: v1alpha1.CommonDetails{ Image: "foo", }, }, @@ -949,7 +949,7 @@ func TestCavInvalidity(t *testing.T) { ConsumedBTPServices: []string{}, DeploymentDefinition: &v1alpha1.DeploymentDetails{ Type: v1alpha1.DeploymentCAP, - ContainerDetails: v1alpha1.ContainerDetails{ + CommonDetails: v1alpha1.CommonDetails{ Image: "foo", }, }, @@ -961,7 +961,7 @@ func TestCavInvalidity(t *testing.T) { ConsumedBTPServices: []string{}, DeploymentDefinition: &v1alpha1.DeploymentDetails{ Type: v1alpha1.DeploymentRouter, - ContainerDetails: v1alpha1.ContainerDetails{ + CommonDetails: v1alpha1.CommonDetails{ Image: "foo", }, }, @@ -989,7 +989,7 @@ func TestCavInvalidity(t *testing.T) { ConsumedBTPServices: []string{}, JobDefinition: &v1alpha1.JobDetails{ Type: v1alpha1.JobCustomTenantOperation, - ContainerDetails: v1alpha1.ContainerDetails{ + CommonDetails: v1alpha1.CommonDetails{ Image: "foo", }, }, @@ -1001,7 +1001,7 @@ func TestCavInvalidity(t *testing.T) { ConsumedBTPServices: []string{}, JobDefinition: &v1alpha1.JobDetails{ Type: v1alpha1.JobTenantOperation, - ContainerDetails: v1alpha1.ContainerDetails{ + CommonDetails: v1alpha1.CommonDetails{ Image: "foo", }, }, @@ -1011,7 +1011,7 @@ func TestCavInvalidity(t *testing.T) { ConsumedBTPServices: []string{}, JobDefinition: &v1alpha1.JobDetails{ Type: v1alpha1.JobCustomTenantOperation, - ContainerDetails: v1alpha1.ContainerDetails{ + CommonDetails: v1alpha1.CommonDetails{ Image: "foo", }, }, @@ -1034,7 +1034,7 @@ func TestCavInvalidity(t *testing.T) { ConsumedBTPServices: []string{}, JobDefinition: &v1alpha1.JobDetails{ Type: v1alpha1.JobTenantOperation, - ContainerDetails: v1alpha1.ContainerDetails{ + CommonDetails: v1alpha1.CommonDetails{ Image: "foo", }, }, @@ -1057,7 +1057,7 @@ func TestCavInvalidity(t *testing.T) { ConsumedBTPServices: []string{}, JobDefinition: &v1alpha1.JobDetails{ Type: v1alpha1.JobTenantOperation, - ContainerDetails: v1alpha1.ContainerDetails{ + CommonDetails: v1alpha1.CommonDetails{ Image: "foo", }, }, @@ -1067,7 +1067,7 @@ func TestCavInvalidity(t *testing.T) { ConsumedBTPServices: []string{}, JobDefinition: &v1alpha1.JobDetails{ Type: v1alpha1.JobCustomTenantOperation, - ContainerDetails: v1alpha1.ContainerDetails{ + CommonDetails: v1alpha1.CommonDetails{ Image: "foo", }, }, @@ -1116,7 +1116,7 @@ func TestCavInvalidity(t *testing.T) { ConsumedBTPServices: []string{}, JobDefinition: &v1alpha1.JobDetails{ Type: v1alpha1.JobContent, - ContainerDetails: v1alpha1.ContainerDetails{ + CommonDetails: v1alpha1.CommonDetails{ Image: "foo", }, }, @@ -1127,7 +1127,7 @@ func TestCavInvalidity(t *testing.T) { ConsumedBTPServices: []string{}, JobDefinition: &v1alpha1.JobDetails{ Type: v1alpha1.JobContent, - ContainerDetails: v1alpha1.ContainerDetails{ + CommonDetails: v1alpha1.CommonDetails{ Image: "foo", }, }, @@ -1139,7 +1139,7 @@ func TestCavInvalidity(t *testing.T) { ConsumedBTPServices: []string{}, JobDefinition: &v1alpha1.JobDetails{ Type: v1alpha1.JobContent, - ContainerDetails: v1alpha1.ContainerDetails{ + CommonDetails: v1alpha1.CommonDetails{ Image: "foo", }, }, diff --git a/crds/sme.sap.com_capapplicationversions.yaml b/crds/sme.sap.com_capapplicationversions.yaml index a03dc8f5..dd337e8b 100644 --- a/crds/sme.sap.com_capapplicationversions.yaml +++ b/crds/sme.sap.com_capapplicationversions.yaml @@ -101,6 +101,371 @@ spec: type: array deploymentDefinition: properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object command: items: type: string @@ -251,6 +616,12 @@ spec: format: int32 type: integer type: object + nodeName: + type: string + nodeSelector: + additionalProperties: + type: string + type: object podSecurityContext: properties: fsGroup: @@ -337,6 +708,8 @@ spec: - port type: object type: array + priorityClassName: + type: string readinessProbe: properties: exec: @@ -510,6 +883,74 @@ spec: type: string type: object type: object + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array type: type: string required: @@ -518,6 +959,371 @@ spec: type: object jobDefinition: properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object backoffLimit: format: int32 type: integer @@ -593,6 +1399,12 @@ spec: type: string imagePullPolicy: type: string + nodeName: + type: string + nodeSelector: + additionalProperties: + type: string + type: object podSecurityContext: properties: fsGroup: @@ -657,6 +1469,8 @@ spec: type: string type: object type: object + priorityClassName: + type: string resources: properties: claims: @@ -749,6 +1563,74 @@ spec: type: string type: object type: object + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array ttlSecondsAfterFinished: format: int32 type: integer diff --git a/internal/controller/reconcile-capapplicationversion.go b/internal/controller/reconcile-capapplicationversion.go index 657577ac..9e7569ce 100644 --- a/internal/controller/reconcile-capapplicationversion.go +++ b/internal/controller/reconcile-capapplicationversion.go @@ -302,9 +302,15 @@ func newContentDeploymentJob(ca *v1alpha1.CAPApplication, cav *v1alpha1.CAPAppli SecurityContext: workload.JobDefinition.SecurityContext, }, }, - SecurityContext: workload.JobDefinition.PodSecurityContext, - ImagePullSecrets: convertToLocalObjectReferences(cav.Spec.RegistrySecrets), - RestartPolicy: corev1.RestartPolicyOnFailure, + SecurityContext: workload.JobDefinition.PodSecurityContext, + ImagePullSecrets: convertToLocalObjectReferences(cav.Spec.RegistrySecrets), + RestartPolicy: corev1.RestartPolicyOnFailure, + NodeSelector: workload.JobDefinition.NodeSelector, + NodeName: workload.JobDefinition.NodeName, + PriorityClassName: workload.JobDefinition.PriorityClassName, + Affinity: workload.JobDefinition.Affinity, + TopologySpreadConstraints: workload.JobDefinition.TopologySpreadConstraints, + Tolerations: workload.JobDefinition.Tolerations, }, }, }, @@ -585,9 +591,15 @@ func createDeployment(params *DeploymentParameters) *appsv1.Deployment { Labels: labels, }, Spec: corev1.PodSpec{ - ImagePullSecrets: convertToLocalObjectReferences(params.CAV.Spec.RegistrySecrets), - Containers: getContainer(params), - SecurityContext: params.WorkloadDetails.DeploymentDefinition.PodSecurityContext, + ImagePullSecrets: convertToLocalObjectReferences(params.CAV.Spec.RegistrySecrets), + Containers: getContainer(params), + SecurityContext: params.WorkloadDetails.DeploymentDefinition.PodSecurityContext, + NodeSelector: params.WorkloadDetails.DeploymentDefinition.NodeSelector, + NodeName: params.WorkloadDetails.DeploymentDefinition.NodeName, + PriorityClassName: params.WorkloadDetails.DeploymentDefinition.PriorityClassName, + Affinity: params.WorkloadDetails.DeploymentDefinition.Affinity, + TopologySpreadConstraints: params.WorkloadDetails.DeploymentDefinition.TopologySpreadConstraints, + Tolerations: params.WorkloadDetails.DeploymentDefinition.Tolerations, }, }, }, diff --git a/internal/controller/reconcile-capapplicationversion_test.go b/internal/controller/reconcile-capapplicationversion_test.go index 6a5fd788..7dad2609 100644 --- a/internal/controller/reconcile-capapplicationversion_test.go +++ b/internal/controller/reconcile-capapplicationversion_test.go @@ -624,3 +624,103 @@ func TestCAV_Annotations(t *testing.T) { }, ) } + +func TestCAV_NodeSelector(t *testing.T) { + reconcileTestItem( + context.TODO(), t, + QueueItem{Key: ResourceCAPApplicationVersion, ResourceKey: NamespacedResourceKey{Namespace: "default", Name: "test-cap-01-cav-v1"}}, + TestData{ + description: "capapplication version with node selector", + initialResources: []string{ + "testdata/common/capapplication.yaml", + "testdata/common/credential-secrets.yaml", + "testdata/capapplicationversion/content-job-completed.yaml", + "testdata/capapplicationversion/cav-node-selector.yaml", + }, + expectedResources: "testdata/capapplicationversion/expected/cav-ready-node-selector.yaml", + backlogItems: []string{ + "ERP4SMEPREPWORKAPPPLAT-3294", // More workload configuration enhancements + }, + }, + ) +} + +func TestCAV_Affinity(t *testing.T) { + reconcileTestItem( + context.TODO(), t, + QueueItem{Key: ResourceCAPApplicationVersion, ResourceKey: NamespacedResourceKey{Namespace: "default", Name: "test-cap-01-cav-v1"}}, + TestData{ + description: "capapplication version with affinity", + initialResources: []string{ + "testdata/common/capapplication.yaml", + "testdata/common/credential-secrets.yaml", + "testdata/capapplicationversion/content-job-completed.yaml", + "testdata/capapplicationversion/cav-affinity.yaml", + }, + expectedResources: "testdata/capapplicationversion/expected/cav-ready-affinity.yaml", + backlogItems: []string{ + "ERP4SMEPREPWORKAPPPLAT-3294", // More workload configuration enhancements + }, + }, + ) +} + +func TestCAV_TopologySpreadConstraints(t *testing.T) { + reconcileTestItem( + context.TODO(), t, + QueueItem{Key: ResourceCAPApplicationVersion, ResourceKey: NamespacedResourceKey{Namespace: "default", Name: "test-cap-01-cav-v1"}}, + TestData{ + description: "capapplication version with topology spread constraints", + initialResources: []string{ + "testdata/common/capapplication.yaml", + "testdata/common/credential-secrets.yaml", + "testdata/capapplicationversion/content-job-completed.yaml", + "testdata/capapplicationversion/cav-topology.yaml", + }, + expectedResources: "testdata/capapplicationversion/expected/cav-ready-topology.yaml", + backlogItems: []string{ + "ERP4SMEPREPWORKAPPPLAT-3294", // More workload configuration enhancements + }, + }, + ) +} + +func TestCAV_Tolerations(t *testing.T) { + reconcileTestItem( + context.TODO(), t, + QueueItem{Key: ResourceCAPApplicationVersion, ResourceKey: NamespacedResourceKey{Namespace: "default", Name: "test-cap-01-cav-v1"}}, + TestData{ + description: "capapplication version with tolerations", + initialResources: []string{ + "testdata/common/capapplication.yaml", + "testdata/common/credential-secrets.yaml", + "testdata/capapplicationversion/content-job-completed.yaml", + "testdata/capapplicationversion/cav-toleration.yaml", + }, + expectedResources: "testdata/capapplicationversion/expected/cav-ready-toleration.yaml", + backlogItems: []string{ + "ERP4SMEPREPWORKAPPPLAT-3294", // More workload configuration enhancements + }, + }, + ) +} + +func TestCAV_Node_PriorityClass_Names(t *testing.T) { + reconcileTestItem( + context.TODO(), t, + QueueItem{Key: ResourceCAPApplicationVersion, ResourceKey: NamespacedResourceKey{Namespace: "default", Name: "test-cap-01-cav-v1"}}, + TestData{ + description: "capapplication version with nodeName and priorityClassName", + initialResources: []string{ + "testdata/common/capapplication.yaml", + "testdata/common/credential-secrets.yaml", + "testdata/capapplicationversion/content-job-completed.yaml", + "testdata/capapplicationversion/cav-node-prio.yaml", + }, + expectedResources: "testdata/capapplicationversion/expected/cav-ready-node-prio.yaml", + backlogItems: []string{ + "ERP4SMEPREPWORKAPPPLAT-3294", // More workload configuration enhancements + }, + }, + ) +} diff --git a/internal/controller/reconcile-captenantoperation.go b/internal/controller/reconcile-captenantoperation.go index ad41565b..34bc8486 100644 --- a/internal/controller/reconcile-captenantoperation.go +++ b/internal/controller/reconcile-captenantoperation.go @@ -38,15 +38,21 @@ type UpgradePayload struct { } type tentantOperationWorkload struct { - image string - imagePullPolicy corev1.PullPolicy - command []string - env []corev1.EnvVar - resources corev1.ResourceRequirements - securityContext *corev1.SecurityContext - podSecurityContext *corev1.PodSecurityContext - backoffLimit *int32 - ttlSecondsAfterFinished *int32 + image string + imagePullPolicy corev1.PullPolicy + command []string + env []corev1.EnvVar + resources corev1.ResourceRequirements + securityContext *corev1.SecurityContext + podSecurityContext *corev1.PodSecurityContext + affinity *corev1.Affinity + nodeSelector map[string]string + nodeName string + priorityClassName string + topologySpreadConstraints []corev1.TopologySpreadConstraint + tolerations []corev1.Toleration + backoffLimit *int32 + ttlSecondsAfterFinished *int32 } const ( @@ -484,10 +490,16 @@ func (c *Controller) createTenantOperationJob(ctx context.Context, ctop *v1alpha Annotations: params.annotations, }, Spec: corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyNever, - ImagePullSecrets: params.imagePullSecrets, - Containers: getContainers(payload, ctop, derivedWorkload, workload, params), - SecurityContext: derivedWorkload.podSecurityContext, + RestartPolicy: corev1.RestartPolicyNever, + ImagePullSecrets: params.imagePullSecrets, + Containers: getContainers(payload, ctop, derivedWorkload, workload, params), + SecurityContext: derivedWorkload.podSecurityContext, + NodeSelector: derivedWorkload.nodeSelector, + NodeName: derivedWorkload.nodeName, + PriorityClassName: derivedWorkload.priorityClassName, + Affinity: derivedWorkload.affinity, + TopologySpreadConstraints: derivedWorkload.topologySpreadConstraints, + Tolerations: derivedWorkload.tolerations, }, }, }, @@ -574,6 +586,12 @@ func deriveWorkloadForTenantOperation(workload *v1alpha1.WorkloadDetails) tentan result.ttlSecondsAfterFinished = &tTLSecondsAfterFinishedValue result.securityContext = workload.DeploymentDefinition.SecurityContext result.podSecurityContext = workload.DeploymentDefinition.PodSecurityContext + result.affinity = workload.DeploymentDefinition.Affinity + result.nodeSelector = workload.DeploymentDefinition.NodeSelector + result.nodeName = workload.DeploymentDefinition.NodeName + result.priorityClassName = workload.DeploymentDefinition.PriorityClassName + result.topologySpreadConstraints = workload.DeploymentDefinition.TopologySpreadConstraints + result.tolerations = workload.DeploymentDefinition.Tolerations } else { // use job definition result.image = workload.JobDefinition.Image @@ -589,6 +607,12 @@ func deriveWorkloadForTenantOperation(workload *v1alpha1.WorkloadDetails) tentan if workload.JobDefinition.TTLSecondsAfterFinished != nil { result.ttlSecondsAfterFinished = workload.JobDefinition.TTLSecondsAfterFinished } + result.affinity = workload.JobDefinition.Affinity + result.nodeSelector = workload.JobDefinition.NodeSelector + result.nodeName = workload.JobDefinition.NodeName + result.priorityClassName = workload.JobDefinition.PriorityClassName + result.topologySpreadConstraints = workload.JobDefinition.TopologySpreadConstraints + result.tolerations = workload.JobDefinition.Tolerations } return result } @@ -612,9 +636,15 @@ func (c *Controller) createCustomTenantOperationJob(ctx context.Context, ctop *v Annotations: params.annotations, }, Spec: corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyNever, - SecurityContext: workload.JobDefinition.PodSecurityContext, - ImagePullSecrets: params.imagePullSecrets, + RestartPolicy: corev1.RestartPolicyNever, + SecurityContext: workload.JobDefinition.PodSecurityContext, + NodeSelector: workload.JobDefinition.NodeSelector, + NodeName: workload.JobDefinition.NodeName, + PriorityClassName: workload.JobDefinition.PriorityClassName, + Affinity: workload.JobDefinition.Affinity, + TopologySpreadConstraints: workload.JobDefinition.TopologySpreadConstraints, + Tolerations: workload.JobDefinition.Tolerations, + ImagePullSecrets: params.imagePullSecrets, Containers: []corev1.Container{ { Name: workload.Name, diff --git a/internal/controller/reconcile-captenantoperation_test.go b/internal/controller/reconcile-captenantoperation_test.go index 1815156a..ba2e9d9c 100644 --- a/internal/controller/reconcile-captenantoperation_test.go +++ b/internal/controller/reconcile-captenantoperation_test.go @@ -660,3 +660,47 @@ func TestMultiXSUAAWithAnnotation(t *testing.T) { }, ) } + +func TestProvisioningWithSchedulingConfig(t *testing.T) { + _ = reconcileTestItem( + context.TODO(), t, + QueueItem{Key: ResourceCAPTenantOperation, ResourceKey: NamespacedResourceKey{Namespace: "default", Name: "test-cap-01-provider-abcd"}}, + TestData{ + backlogItems: []string{"ERP4SMEPREPWORKAPPPLAT-3294"}, // More workload configuration enhancements + description: "Provisioning - With scheduling config", + initialResources: []string{ + "testdata/common/capapplication.yaml", + "testdata/common/captenant-provider-ready.yaml", + "testdata/common/capapplicationversion-v1-scheduling.yaml", + "testdata/common/credential-secrets.yaml", + "testdata/captenantoperation/ctop-scheduling.initial.yaml", // The config in there might not make sense in the real world! + }, + expectedResources: "testdata/captenantoperation/ctop-scheduling.expected.yaml", + expectedRequeue: map[int][]NamespacedResourceKey{ + ResourceCAPTenantOperation: {{Namespace: "default", Name: "test-cap-01-provider-abcd"}}, + }, + }, + ) +} + +func TestProvisioningWithSchedulingConfigCustom(t *testing.T) { + _ = reconcileTestItem( + context.TODO(), t, + QueueItem{Key: ResourceCAPTenantOperation, ResourceKey: NamespacedResourceKey{Namespace: "default", Name: "test-cap-01-provider-abcd"}}, + TestData{ + backlogItems: []string{"ERP4SMEPREPWORKAPPPLAT-3294"}, // More workload configuration enhancements + description: "Provisioning - With scheduling config for CustomTenantOperation", + initialResources: []string{ + "testdata/common/capapplication.yaml", + "testdata/common/captenant-provider-ready.yaml", + "testdata/common/capapplicationversion-v1-scheduling-custom.yaml", + "testdata/common/credential-secrets.yaml", + "testdata/captenantoperation/ctop-scheduling-custom.initial.yaml", // The config in there might not make sense in the real world! + }, + expectedResources: "testdata/captenantoperation/ctop-scheduling-custom.expected.yaml", + expectedRequeue: map[int][]NamespacedResourceKey{ + ResourceCAPTenantOperation: {{Namespace: "default", Name: "test-cap-01-provider-abcd"}}, + }, + }, + ) +} diff --git a/internal/controller/reconcile_test.go b/internal/controller/reconcile_test.go index 3d43e695..9b52a0ee 100644 --- a/internal/controller/reconcile_test.go +++ b/internal/controller/reconcile_test.go @@ -205,7 +205,7 @@ func createCavCRO(name string, state v1alpha1.CAPApplicationVersionState, versio }, DeploymentDefinition: &v1alpha1.DeploymentDetails{ Type: v1alpha1.DeploymentCAP, - ContainerDetails: v1alpha1.ContainerDetails{ + CommonDetails: v1alpha1.CommonDetails{ Image: "test://image", }, }, @@ -214,7 +214,7 @@ func createCavCRO(name string, state v1alpha1.CAPApplicationVersionState, versio Name: "app-router", ConsumedBTPServices: []string{}, DeploymentDefinition: &v1alpha1.DeploymentDetails{ - ContainerDetails: v1alpha1.ContainerDetails{ + CommonDetails: v1alpha1.CommonDetails{ Image: "test://image", }, }, diff --git a/internal/controller/testdata/capapplicationversion/cav-affinity.yaml b/internal/controller/testdata/capapplicationversion/cav-affinity.yaml new file mode 100644 index 00000000..ceebf8f5 --- /dev/null +++ b/internal/controller/testdata/capapplicationversion/cav-affinity.yaml @@ -0,0 +1,179 @@ +apiVersion: sme.sap.com/v1alpha1 +kind: CAPApplicationVersion +metadata: + creationTimestamp: "2022-07-18T06:13:52Z" + generation: 1 + annotations: + sme.sap.com/btp-app-identifier: btp-glo-acc-id.test-cap-01 + sme.sap.com/owner-identifier: default.test-cap-01 + labels: + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/owner-generation: "2" + sme.sap.com/owner-identifier-hash: 1f74ae2fbff71a708786a4df4bb2ca87ec603581 + name: test-cap-01-cav-v1 + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplication + name: test-cap-01 + uid: 3c7ba7cb-dc04-4fd1-be86-3eb3a5c64a98 + resourceVersion: "11371108" + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + capApplicationInstance: test-cap-01 + registrySecrets: + - regcred + version: 1.2.3 + workloads: + - name: cap-backend-srv + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + deploymentDefinition: + image: docker.image.repo/srv/server:latest + type: CAP + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.PodIp + ports: + - name: "app-port" + port: 4004 + routerDestinationName: "srv-api" + appProtocol: http + - name: "app-tech-port" + port: 4005 + networkPolicy: "Cluster" + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4004 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + readinessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4004 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + resources: + limits: + cpu: 200m + memory: 500Mi + requests: + cpu: 20m + memory: 50Mi + - name: app-router + consumedBTPServices: + - cap-uaa + - cap-saas-registry + deploymentDefinition: + image: docker.image.repo/approuter/approuter:latest + type: Router + env: + - name: debug + valueFrom: + configMapKeyRef: + key: someKey + name: someCM + optional: true + ports: + - name: "router-port" + port: 4000 + appProtocol: http + - name: "router-tech-port" + port: 4004 + networkPolicy: "Cluster" + - name: "router-metrics-port" + port: 4007 + networkPolicy: "Cluster" + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4000 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + readinessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4000 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + resources: + limits: + cpu: 200m + memory: 500Mi + requests: + cpu: 20m + memory: 50Mi + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: topology.kubernetes.io/zone + operator: In + values: + - antarctica-east1 + - antarctica-west1 + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + preference: + matchExpressions: + - key: another-node-label-key + operator: In + values: + - another-node-label-value + - name: content-job + consumedBTPServices: + - cap-uaa + jobDefinition: + image: docker.image.repo/content/cap-content:latest + type: Content + env: + - name: SOME_VERSION + value: 0.0.1 + resources: + limits: + cpu: 100m + memory: 200Mi + requests: + cpu: 10m + memory: 20Mi + - name: mtx-job + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + jobDefinition: + image: docker.image.repo/srv/server:latest + type: TenantOperation + - name: job-worker + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + deploymentDefinition: + image: docker.image.repo/srv/server:latest + type: Additional + env: + - name: TEST_SEC_REF + valueFrom: + secretKeyRef: + key: someKey + name: someSecret + optional: true +status: + state: Processing diff --git a/internal/controller/testdata/capapplicationversion/cav-node-prio.yaml b/internal/controller/testdata/capapplicationversion/cav-node-prio.yaml new file mode 100644 index 00000000..e8f61175 --- /dev/null +++ b/internal/controller/testdata/capapplicationversion/cav-node-prio.yaml @@ -0,0 +1,163 @@ +apiVersion: sme.sap.com/v1alpha1 +kind: CAPApplicationVersion +metadata: + creationTimestamp: "2022-07-18T06:13:52Z" + generation: 1 + annotations: + sme.sap.com/btp-app-identifier: btp-glo-acc-id.test-cap-01 + sme.sap.com/owner-identifier: default.test-cap-01 + labels: + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/owner-generation: "2" + sme.sap.com/owner-identifier-hash: 1f74ae2fbff71a708786a4df4bb2ca87ec603581 + name: test-cap-01-cav-v1 + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplication + name: test-cap-01 + uid: 3c7ba7cb-dc04-4fd1-be86-3eb3a5c64a98 + resourceVersion: "11371108" + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + capApplicationInstance: test-cap-01 + registrySecrets: + - regcred + version: 1.2.3 + workloads: + - name: cap-backend-srv + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + deploymentDefinition: + image: docker.image.repo/srv/server:latest + type: CAP + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.PodIp + ports: + - name: "app-port" + port: 4004 + routerDestinationName: "srv-api" + appProtocol: http + - name: "app-tech-port" + port: 4005 + networkPolicy: "Cluster" + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4004 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + readinessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4004 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + resources: + limits: + cpu: 200m + memory: 500Mi + requests: + cpu: 20m + memory: 50Mi + - name: app-router + consumedBTPServices: + - cap-uaa + - cap-saas-registry + deploymentDefinition: + image: docker.image.repo/approuter/approuter:latest + type: Router + env: + - name: debug + valueFrom: + configMapKeyRef: + key: someKey + name: someCM + optional: true + ports: + - name: "router-port" + port: 4000 + appProtocol: http + - name: "router-tech-port" + port: 4004 + networkPolicy: "Cluster" + - name: "router-metrics-port" + port: 4007 + networkPolicy: "Cluster" + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4000 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + readinessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4000 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + resources: + limits: + cpu: 200m + memory: 500Mi + requests: + cpu: 20m + memory: 50Mi + nodeName: app + priorityClassName: some-prio + - name: content-job + consumedBTPServices: + - cap-uaa + jobDefinition: + image: docker.image.repo/content/cap-content:latest + type: Content + env: + - name: SOME_VERSION + value: 0.0.1 + resources: + limits: + cpu: 100m + memory: 200Mi + requests: + cpu: 10m + memory: 20Mi + - name: mtx-job + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + jobDefinition: + image: docker.image.repo/srv/server:latest + type: TenantOperation + - name: job-worker + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + deploymentDefinition: + image: docker.image.repo/srv/server:latest + type: Additional + env: + - name: TEST_SEC_REF + valueFrom: + secretKeyRef: + key: someKey + name: someSecret + optional: true +status: + state: Processing diff --git a/internal/controller/testdata/capapplicationversion/cav-node-selector.yaml b/internal/controller/testdata/capapplicationversion/cav-node-selector.yaml new file mode 100644 index 00000000..adf611df --- /dev/null +++ b/internal/controller/testdata/capapplicationversion/cav-node-selector.yaml @@ -0,0 +1,163 @@ +apiVersion: sme.sap.com/v1alpha1 +kind: CAPApplicationVersion +metadata: + creationTimestamp: "2022-07-18T06:13:52Z" + generation: 1 + annotations: + sme.sap.com/btp-app-identifier: btp-glo-acc-id.test-cap-01 + sme.sap.com/owner-identifier: default.test-cap-01 + labels: + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/owner-generation: "2" + sme.sap.com/owner-identifier-hash: 1f74ae2fbff71a708786a4df4bb2ca87ec603581 + name: test-cap-01-cav-v1 + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplication + name: test-cap-01 + uid: 3c7ba7cb-dc04-4fd1-be86-3eb3a5c64a98 + resourceVersion: "11371108" + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + capApplicationInstance: test-cap-01 + registrySecrets: + - regcred + version: 1.2.3 + workloads: + - name: cap-backend-srv + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + deploymentDefinition: + image: docker.image.repo/srv/server:latest + type: CAP + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.PodIp + ports: + - name: "app-port" + port: 4004 + routerDestinationName: "srv-api" + appProtocol: http + - name: "app-tech-port" + port: 4005 + networkPolicy: "Cluster" + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4004 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + readinessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4004 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + resources: + limits: + cpu: 200m + memory: 500Mi + requests: + cpu: 20m + memory: 50Mi + - name: app-router + consumedBTPServices: + - cap-uaa + - cap-saas-registry + deploymentDefinition: + image: docker.image.repo/approuter/approuter:latest + type: Router + env: + - name: debug + valueFrom: + configMapKeyRef: + key: someKey + name: someCM + optional: true + ports: + - name: "router-port" + port: 4000 + appProtocol: http + - name: "router-tech-port" + port: 4004 + networkPolicy: "Cluster" + - name: "router-metrics-port" + port: 4007 + networkPolicy: "Cluster" + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4000 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + readinessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4000 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + resources: + limits: + cpu: 200m + memory: 500Mi + requests: + cpu: 20m + memory: 50Mi + nodeSelector: + disktype: ssd + - name: content-job + consumedBTPServices: + - cap-uaa + jobDefinition: + image: docker.image.repo/content/cap-content:latest + type: Content + env: + - name: SOME_VERSION + value: 0.0.1 + resources: + limits: + cpu: 100m + memory: 200Mi + requests: + cpu: 10m + memory: 20Mi + - name: mtx-job + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + jobDefinition: + image: docker.image.repo/srv/server:latest + type: TenantOperation + - name: job-worker + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + deploymentDefinition: + image: docker.image.repo/srv/server:latest + type: Additional + env: + - name: TEST_SEC_REF + valueFrom: + secretKeyRef: + key: someKey + name: someSecret + optional: true +status: + state: Processing diff --git a/internal/controller/testdata/capapplicationversion/cav-toleration.yaml b/internal/controller/testdata/capapplicationversion/cav-toleration.yaml new file mode 100644 index 00000000..81a07753 --- /dev/null +++ b/internal/controller/testdata/capapplicationversion/cav-toleration.yaml @@ -0,0 +1,171 @@ +apiVersion: sme.sap.com/v1alpha1 +kind: CAPApplicationVersion +metadata: + creationTimestamp: "2022-07-18T06:13:52Z" + generation: 1 + annotations: + sme.sap.com/btp-app-identifier: btp-glo-acc-id.test-cap-01 + sme.sap.com/owner-identifier: default.test-cap-01 + labels: + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/owner-generation: "2" + sme.sap.com/owner-identifier-hash: 1f74ae2fbff71a708786a4df4bb2ca87ec603581 + name: test-cap-01-cav-v1 + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplication + name: test-cap-01 + uid: 3c7ba7cb-dc04-4fd1-be86-3eb3a5c64a98 + resourceVersion: "11371108" + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + capApplicationInstance: test-cap-01 + registrySecrets: + - regcred + version: 1.2.3 + workloads: + - name: cap-backend-srv + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + deploymentDefinition: + image: docker.image.repo/srv/server:latest + type: CAP + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.PodIp + ports: + - name: "app-port" + port: 4004 + routerDestinationName: "srv-api" + appProtocol: http + - name: "app-tech-port" + port: 4005 + networkPolicy: "Cluster" + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4004 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + readinessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4004 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + resources: + limits: + cpu: 200m + memory: 500Mi + requests: + cpu: 20m + memory: 50Mi + - name: app-router + consumedBTPServices: + - cap-uaa + - cap-saas-registry + deploymentDefinition: + image: docker.image.repo/approuter/approuter:latest + type: Router + env: + - name: debug + valueFrom: + configMapKeyRef: + key: someKey + name: someCM + optional: true + ports: + - name: "router-port" + port: 4000 + appProtocol: http + - name: "router-tech-port" + port: 4004 + networkPolicy: "Cluster" + - name: "router-metrics-port" + port: 4007 + networkPolicy: "Cluster" + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4000 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + readinessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4000 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + resources: + limits: + cpu: 200m + memory: 500Mi + requests: + cpu: 20m + memory: 50Mi + tolerations: + - key: "test" + operator: "Equal" + value: "foo" + effect: "NoExecute" + tolerationSeconds: 300 + - key: "never-exec" + operator: "Equal" + value: "noexec" + effect: "NoExecute" + - name: content-job + consumedBTPServices: + - cap-uaa + jobDefinition: + image: docker.image.repo/content/cap-content:latest + type: Content + env: + - name: SOME_VERSION + value: 0.0.1 + resources: + limits: + cpu: 100m + memory: 200Mi + requests: + cpu: 10m + memory: 20Mi + - name: mtx-job + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + jobDefinition: + image: docker.image.repo/srv/server:latest + type: TenantOperation + - name: job-worker + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + deploymentDefinition: + image: docker.image.repo/srv/server:latest + type: Additional + env: + - name: TEST_SEC_REF + valueFrom: + secretKeyRef: + key: someKey + name: someSecret + optional: true +status: + state: Processing diff --git a/internal/controller/testdata/capapplicationversion/cav-topology.yaml b/internal/controller/testdata/capapplicationversion/cav-topology.yaml new file mode 100644 index 00000000..e2b1fad4 --- /dev/null +++ b/internal/controller/testdata/capapplicationversion/cav-topology.yaml @@ -0,0 +1,170 @@ +apiVersion: sme.sap.com/v1alpha1 +kind: CAPApplicationVersion +metadata: + creationTimestamp: "2022-07-18T06:13:52Z" + generation: 1 + annotations: + sme.sap.com/btp-app-identifier: btp-glo-acc-id.test-cap-01 + sme.sap.com/owner-identifier: default.test-cap-01 + labels: + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/owner-generation: "2" + sme.sap.com/owner-identifier-hash: 1f74ae2fbff71a708786a4df4bb2ca87ec603581 + name: test-cap-01-cav-v1 + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplication + name: test-cap-01 + uid: 3c7ba7cb-dc04-4fd1-be86-3eb3a5c64a98 + resourceVersion: "11371108" + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + capApplicationInstance: test-cap-01 + registrySecrets: + - regcred + version: 1.2.3 + workloads: + - name: cap-backend-srv + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + deploymentDefinition: + image: docker.image.repo/srv/server:latest + type: CAP + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.PodIp + ports: + - name: "app-port" + port: 4004 + routerDestinationName: "srv-api" + appProtocol: http + - name: "app-tech-port" + port: 4005 + networkPolicy: "Cluster" + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4004 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + readinessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4004 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + resources: + limits: + cpu: 200m + memory: 500Mi + requests: + cpu: 20m + memory: 50Mi + - name: app-router + consumedBTPServices: + - cap-uaa + - cap-saas-registry + deploymentDefinition: + image: docker.image.repo/approuter/approuter:latest + type: Router + env: + - name: debug + valueFrom: + configMapKeyRef: + key: someKey + name: someCM + optional: true + ports: + - name: "router-port" + port: 4000 + appProtocol: http + - name: "router-tech-port" + port: 4004 + networkPolicy: "Cluster" + - name: "router-metrics-port" + port: 4007 + networkPolicy: "Cluster" + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4000 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + readinessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4000 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + resources: + limits: + cpu: 200m + memory: 500Mi + requests: + cpu: 20m + memory: 50Mi + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: someZone + whenUnsatisfiable: DoNotSchedule + labelSelector: + matchLabels: + foo: bar + matchLabelKeys: + - dummy-test-1.27 + - name: content-job + consumedBTPServices: + - cap-uaa + jobDefinition: + image: docker.image.repo/content/cap-content:latest + type: Content + env: + - name: SOME_VERSION + value: 0.0.1 + resources: + limits: + cpu: 100m + memory: 200Mi + requests: + cpu: 10m + memory: 20Mi + - name: mtx-job + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + jobDefinition: + image: docker.image.repo/srv/server:latest + type: TenantOperation + - name: job-worker + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + deploymentDefinition: + image: docker.image.repo/srv/server:latest + type: Additional + env: + - name: TEST_SEC_REF + valueFrom: + secretKeyRef: + key: someKey + name: someSecret + optional: true +status: + state: Processing diff --git a/internal/controller/testdata/capapplicationversion/expected/cav-ready-affinity.yaml b/internal/controller/testdata/capapplicationversion/expected/cav-ready-affinity.yaml new file mode 100644 index 00000000..98091488 --- /dev/null +++ b/internal/controller/testdata/capapplicationversion/expected/cav-ready-affinity.yaml @@ -0,0 +1,423 @@ +apiVersion: sme.sap.com/v1alpha1 +kind: CAPApplicationVersion +metadata: + creationTimestamp: "2022-07-18T06:13:52Z" + generation: 1 + annotations: + sme.sap.com/btp-app-identifier: btp-glo-acc-id.test-cap-01 + sme.sap.com/owner-identifier: default.test-cap-01 + labels: + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/owner-generation: "2" + sme.sap.com/owner-identifier-hash: 1f74ae2fbff71a708786a4df4bb2ca87ec603581 + name: test-cap-01-cav-v1 + namespace: default + finalizers: + - "sme.sap.com/capapplicationversion" + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplication + name: test-cap-01 + uid: 3c7ba7cb-dc04-4fd1-be86-3eb3a5c64a98 + resourceVersion: "11371108" + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + capApplicationInstance: test-cap-01 + registrySecrets: + - regcred + version: 1.2.3 + workloads: + - name: cap-backend-srv + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + deploymentDefinition: + image: docker.image.repo/srv/server:latest + type: CAP + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.PodIp + ports: + - name: "app-port" + port: 4004 + routerDestinationName: "srv-api" + appProtocol: http + - name: "app-tech-port" + port: 4005 + networkPolicy: "Cluster" + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4004 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + readinessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4004 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + resources: + limits: + cpu: 200m + memory: 500Mi + requests: + cpu: 20m + memory: 50Mi + - name: app-router + consumedBTPServices: + - cap-uaa + - cap-saas-registry + deploymentDefinition: + image: docker.image.repo/approuter/approuter:latest + type: Router + env: + - name: debug + valueFrom: + configMapKeyRef: + key: someKey + name: someCM + optional: true + ports: + - name: "router-port" + port: 4000 + appProtocol: http + - name: "router-tech-port" + port: 4004 + networkPolicy: "Cluster" + - name: "router-metrics-port" + port: 4007 + networkPolicy: "Cluster" + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4000 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + readinessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4000 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + resources: + limits: + cpu: 200m + memory: 500Mi + requests: + cpu: 20m + memory: 50Mi + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: topology.kubernetes.io/zone + operator: In + values: + - antarctica-east1 + - antarctica-west1 + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + preference: + matchExpressions: + - key: another-node-label-key + operator: In + values: + - another-node-label-value + - name: content-job + consumedBTPServices: + - cap-uaa + jobDefinition: + image: docker.image.repo/content/cap-content:latest + type: Content + env: + - name: SOME_VERSION + value: 0.0.1 + resources: + limits: + cpu: 100m + memory: 200Mi + requests: + cpu: 10m + memory: 20Mi + - name: mtx-job + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + jobDefinition: + image: docker.image.repo/srv/server:latest + type: TenantOperation + - name: job-worker + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + deploymentDefinition: + image: docker.image.repo/srv/server:latest + type: Additional + env: + - name: TEST_SEC_REF + valueFrom: + secretKeyRef: + key: someKey + name: someSecret + optional: true +status: + conditions: + - reason: CreatedDeployments + observedGeneration: 1 + status: "True" + type: Ready + observedGeneration: 1 + finishedJobs: + - "test-cap-01-cav-v1-content" + state: Ready +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: test-cap-01 + sme.sap.com/category: Workload + sme.sap.com/workload-name: test-cap-01-cav-v1-app-router + sme.sap.com/workload-type: Router + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/cav-version: "1.2.3" + sme.sap.com/owner-generation: "1" + sme.sap.com/owner-identifier-hash: e95e0682f33a657e75e1fc435972d19bd407ba3b + annotations: + sme.sap.com/btp-app-identifier: btp-glo-acc-id.test-cap-01 + sme.sap.com/owner-identifier: default.test-cap-01-cav-v1 + name: test-cap-01-cav-v1-app-router + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplicationVersion + name: test-cap-01-cav-v1 + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + selector: + matchLabels: + app: test-cap-01 + sme.sap.com/category: Workload + sme.sap.com/workload-name: test-cap-01-cav-v1-app-router + sme.sap.com/workload-type: Router + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/cav-version: "1.2.3" + sme.sap.com/owner-generation: "1" + sme.sap.com/owner-identifier-hash: e95e0682f33a657e75e1fc435972d19bd407ba3b + template: + metadata: + creationTimestamp: null + labels: + app: test-cap-01 + sme.sap.com/category: Workload + sme.sap.com/workload-name: test-cap-01-cav-v1-app-router + sme.sap.com/workload-type: Router + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/cav-version: "1.2.3" + sme.sap.com/owner-generation: "1" + sme.sap.com/owner-identifier-hash: e95e0682f33a657e75e1fc435972d19bd407ba3b + annotations: + sme.sap.com/btp-app-identifier: btp-glo-acc-id.test-cap-01 + sme.sap.com/owner-identifier: default.test-cap-01-cav-v1 + spec: + containers: + - env: + - name: CAPOP_APP_VERSION + value: "1.2.3" + - name: debug + valueFrom: + configMapKeyRef: + key: someKey + name: someCM + optional: true + - name: destinations + value: '[{"name":"srv-api","url":"http://test-cap-01-cav-v1-cap-backend-srv-svc:4004","forwardAuthToken":true}]' + envFrom: + - secretRef: + name: test-cap-01-cav-v1-app-router-gen + optional: true + image: docker.image.repo/approuter/approuter:latest + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4000 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + readinessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4000 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + resources: + limits: + cpu: 200m + memory: 500Mi + requests: + cpu: 20m + memory: 50Mi + name: app-router + imagePullSecrets: + - name: regcred + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: topology.kubernetes.io/zone + operator: In + values: + - antarctica-east1 + - antarctica-west1 + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + preference: + matchExpressions: + - key: another-node-label-key + operator: In + values: + - another-node-label-value +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: test-cap-01-cav-v1 + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplicationVersion + name: test-cap-01-cav-v1 + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + ingress: + - from: + - podSelector: + matchLabels: + app: test-cap-01 + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/category: Workload + sme.sap.com/cav-version: "1.2.3" + podSelector: + matchLabels: + app: test-cap-01 + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/category: Workload + sme.sap.com/cav-version: "1.2.3" + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: test-cap-01-cav-v1--in + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplicationVersion + name: test-cap-01-cav-v1 + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + ingress: + - from: + - namespaceSelector: {} + podSelector: + matchLabels: + app: istio-ingressgateway + istio: ingressgateway + podSelector: + matchLabels: + app: test-cap-01 + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/category: Workload + sme.sap.com/workload-type: Router + sme.sap.com/cav-version: "1.2.3" + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: test-cap-01-cav-v1-app-router + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplicationVersion + name: test-cap-01-cav-v1 + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + ingress: + - from: + - namespaceSelector: {} + podSelector: {} + ports: + - port: 4004 + - port: 4007 + podSelector: + matchLabels: + app: test-cap-01 + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/category: Workload + sme.sap.com/workload-name: test-cap-01-cav-v1-app-router + sme.sap.com/workload-type: Router + sme.sap.com/cav-version: "1.2.3" + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: test-cap-01-cav-v1-cap-backend-srv + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplicationVersion + name: test-cap-01-cav-v1 + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + ingress: + - from: + - namespaceSelector: {} + podSelector: {} + ports: + - port: 4005 + podSelector: + matchLabels: + app: test-cap-01 + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/category: Workload + sme.sap.com/workload-name: test-cap-01-cav-v1-cap-backend-srv + sme.sap.com/workload-type: CAP + sme.sap.com/cav-version: "1.2.3" + policyTypes: + - Ingress diff --git a/internal/controller/testdata/capapplicationversion/expected/cav-ready-node-prio.yaml b/internal/controller/testdata/capapplicationversion/expected/cav-ready-node-prio.yaml new file mode 100644 index 00000000..14010b39 --- /dev/null +++ b/internal/controller/testdata/capapplicationversion/expected/cav-ready-node-prio.yaml @@ -0,0 +1,391 @@ +apiVersion: sme.sap.com/v1alpha1 +kind: CAPApplicationVersion +metadata: + creationTimestamp: "2022-07-18T06:13:52Z" + generation: 1 + annotations: + sme.sap.com/btp-app-identifier: btp-glo-acc-id.test-cap-01 + sme.sap.com/owner-identifier: default.test-cap-01 + labels: + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/owner-generation: "2" + sme.sap.com/owner-identifier-hash: 1f74ae2fbff71a708786a4df4bb2ca87ec603581 + name: test-cap-01-cav-v1 + namespace: default + finalizers: + - "sme.sap.com/capapplicationversion" + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplication + name: test-cap-01 + uid: 3c7ba7cb-dc04-4fd1-be86-3eb3a5c64a98 + resourceVersion: "11371108" + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + capApplicationInstance: test-cap-01 + registrySecrets: + - regcred + version: 1.2.3 + workloads: + - name: cap-backend-srv + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + deploymentDefinition: + image: docker.image.repo/srv/server:latest + type: CAP + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.PodIp + ports: + - name: "app-port" + port: 4004 + routerDestinationName: "srv-api" + appProtocol: http + - name: "app-tech-port" + port: 4005 + networkPolicy: "Cluster" + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4004 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + readinessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4004 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + resources: + limits: + cpu: 200m + memory: 500Mi + requests: + cpu: 20m + memory: 50Mi + - name: app-router + consumedBTPServices: + - cap-uaa + - cap-saas-registry + deploymentDefinition: + image: docker.image.repo/approuter/approuter:latest + type: Router + env: + - name: debug + valueFrom: + configMapKeyRef: + key: someKey + name: someCM + optional: true + ports: + - name: "router-port" + port: 4000 + appProtocol: http + - name: "router-tech-port" + port: 4004 + networkPolicy: "Cluster" + - name: "router-metrics-port" + port: 4007 + networkPolicy: "Cluster" + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4000 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + readinessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4000 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + resources: + limits: + cpu: 200m + memory: 500Mi + requests: + cpu: 20m + memory: 50Mi + nodeName: app + priorityClassName: some-prio + - name: content-job + consumedBTPServices: + - cap-uaa + jobDefinition: + image: docker.image.repo/content/cap-content:latest + type: Content + env: + - name: SOME_VERSION + value: 0.0.1 + resources: + limits: + cpu: 100m + memory: 200Mi + requests: + cpu: 10m + memory: 20Mi + - name: mtx-job + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + jobDefinition: + image: docker.image.repo/srv/server:latest + type: TenantOperation + - name: job-worker + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + deploymentDefinition: + image: docker.image.repo/srv/server:latest + type: Additional + env: + - name: TEST_SEC_REF + valueFrom: + secretKeyRef: + key: someKey + name: someSecret + optional: true +status: + conditions: + - reason: CreatedDeployments + observedGeneration: 1 + status: "True" + type: Ready + observedGeneration: 1 + finishedJobs: + - "test-cap-01-cav-v1-content" + state: Ready +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: test-cap-01 + sme.sap.com/category: Workload + sme.sap.com/workload-name: test-cap-01-cav-v1-app-router + sme.sap.com/workload-type: Router + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/cav-version: "1.2.3" + sme.sap.com/owner-generation: "1" + sme.sap.com/owner-identifier-hash: e95e0682f33a657e75e1fc435972d19bd407ba3b + annotations: + sme.sap.com/btp-app-identifier: btp-glo-acc-id.test-cap-01 + sme.sap.com/owner-identifier: default.test-cap-01-cav-v1 + name: test-cap-01-cav-v1-app-router + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplicationVersion + name: test-cap-01-cav-v1 + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + selector: + matchLabels: + app: test-cap-01 + sme.sap.com/category: Workload + sme.sap.com/workload-name: test-cap-01-cav-v1-app-router + sme.sap.com/workload-type: Router + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/cav-version: "1.2.3" + sme.sap.com/owner-generation: "1" + sme.sap.com/owner-identifier-hash: e95e0682f33a657e75e1fc435972d19bd407ba3b + template: + metadata: + creationTimestamp: null + labels: + app: test-cap-01 + sme.sap.com/category: Workload + sme.sap.com/workload-name: test-cap-01-cav-v1-app-router + sme.sap.com/workload-type: Router + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/cav-version: "1.2.3" + sme.sap.com/owner-generation: "1" + sme.sap.com/owner-identifier-hash: e95e0682f33a657e75e1fc435972d19bd407ba3b + annotations: + sme.sap.com/btp-app-identifier: btp-glo-acc-id.test-cap-01 + sme.sap.com/owner-identifier: default.test-cap-01-cav-v1 + spec: + containers: + - env: + - name: CAPOP_APP_VERSION + value: "1.2.3" + - name: debug + valueFrom: + configMapKeyRef: + key: someKey + name: someCM + optional: true + - name: destinations + value: '[{"name":"srv-api","url":"http://test-cap-01-cav-v1-cap-backend-srv-svc:4004","forwardAuthToken":true}]' + envFrom: + - secretRef: + name: test-cap-01-cav-v1-app-router-gen + optional: true + image: docker.image.repo/approuter/approuter:latest + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4000 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + readinessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4000 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + resources: + limits: + cpu: 200m + memory: 500Mi + requests: + cpu: 20m + memory: 50Mi + name: app-router + imagePullSecrets: + - name: regcred + nodeName: app + priorityClassName: some-prio +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: test-cap-01-cav-v1 + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplicationVersion + name: test-cap-01-cav-v1 + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + ingress: + - from: + - podSelector: + matchLabels: + app: test-cap-01 + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/category: Workload + sme.sap.com/cav-version: "1.2.3" + podSelector: + matchLabels: + app: test-cap-01 + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/category: Workload + sme.sap.com/cav-version: "1.2.3" + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: test-cap-01-cav-v1--in + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplicationVersion + name: test-cap-01-cav-v1 + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + ingress: + - from: + - namespaceSelector: {} + podSelector: + matchLabels: + app: istio-ingressgateway + istio: ingressgateway + podSelector: + matchLabels: + app: test-cap-01 + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/category: Workload + sme.sap.com/workload-type: Router + sme.sap.com/cav-version: "1.2.3" + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: test-cap-01-cav-v1-app-router + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplicationVersion + name: test-cap-01-cav-v1 + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + ingress: + - from: + - namespaceSelector: {} + podSelector: {} + ports: + - port: 4004 + - port: 4007 + podSelector: + matchLabels: + app: test-cap-01 + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/category: Workload + sme.sap.com/workload-name: test-cap-01-cav-v1-app-router + sme.sap.com/workload-type: Router + sme.sap.com/cav-version: "1.2.3" + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: test-cap-01-cav-v1-cap-backend-srv + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplicationVersion + name: test-cap-01-cav-v1 + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + ingress: + - from: + - namespaceSelector: {} + podSelector: {} + ports: + - port: 4005 + podSelector: + matchLabels: + app: test-cap-01 + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/category: Workload + sme.sap.com/workload-name: test-cap-01-cav-v1-cap-backend-srv + sme.sap.com/workload-type: CAP + sme.sap.com/cav-version: "1.2.3" + policyTypes: + - Ingress diff --git a/internal/controller/testdata/capapplicationversion/expected/cav-ready-node-selector.yaml b/internal/controller/testdata/capapplicationversion/expected/cav-ready-node-selector.yaml new file mode 100644 index 00000000..f712938b --- /dev/null +++ b/internal/controller/testdata/capapplicationversion/expected/cav-ready-node-selector.yaml @@ -0,0 +1,391 @@ +apiVersion: sme.sap.com/v1alpha1 +kind: CAPApplicationVersion +metadata: + creationTimestamp: "2022-07-18T06:13:52Z" + generation: 1 + annotations: + sme.sap.com/btp-app-identifier: btp-glo-acc-id.test-cap-01 + sme.sap.com/owner-identifier: default.test-cap-01 + labels: + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/owner-generation: "2" + sme.sap.com/owner-identifier-hash: 1f74ae2fbff71a708786a4df4bb2ca87ec603581 + name: test-cap-01-cav-v1 + namespace: default + finalizers: + - "sme.sap.com/capapplicationversion" + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplication + name: test-cap-01 + uid: 3c7ba7cb-dc04-4fd1-be86-3eb3a5c64a98 + resourceVersion: "11371108" + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + capApplicationInstance: test-cap-01 + registrySecrets: + - regcred + version: 1.2.3 + workloads: + - name: cap-backend-srv + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + deploymentDefinition: + image: docker.image.repo/srv/server:latest + type: CAP + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.PodIp + ports: + - name: "app-port" + port: 4004 + routerDestinationName: "srv-api" + appProtocol: http + - name: "app-tech-port" + port: 4005 + networkPolicy: "Cluster" + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4004 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + readinessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4004 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + resources: + limits: + cpu: 200m + memory: 500Mi + requests: + cpu: 20m + memory: 50Mi + - name: app-router + consumedBTPServices: + - cap-uaa + - cap-saas-registry + deploymentDefinition: + image: docker.image.repo/approuter/approuter:latest + type: Router + env: + - name: debug + valueFrom: + configMapKeyRef: + key: someKey + name: someCM + optional: true + ports: + - name: "router-port" + port: 4000 + appProtocol: http + - name: "router-tech-port" + port: 4004 + networkPolicy: "Cluster" + - name: "router-metrics-port" + port: 4007 + networkPolicy: "Cluster" + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4000 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + readinessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4000 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + resources: + limits: + cpu: 200m + memory: 500Mi + requests: + cpu: 20m + memory: 50Mi + nodeSelector: + disktype: ssd + - name: content-job + consumedBTPServices: + - cap-uaa + jobDefinition: + image: docker.image.repo/content/cap-content:latest + type: Content + env: + - name: SOME_VERSION + value: 0.0.1 + resources: + limits: + cpu: 100m + memory: 200Mi + requests: + cpu: 10m + memory: 20Mi + - name: mtx-job + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + jobDefinition: + image: docker.image.repo/srv/server:latest + type: TenantOperation + - name: job-worker + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + deploymentDefinition: + image: docker.image.repo/srv/server:latest + type: Additional + env: + - name: TEST_SEC_REF + valueFrom: + secretKeyRef: + key: someKey + name: someSecret + optional: true +status: + conditions: + - reason: CreatedDeployments + observedGeneration: 1 + status: "True" + type: Ready + observedGeneration: 1 + finishedJobs: + - "test-cap-01-cav-v1-content" + state: Ready +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: test-cap-01 + sme.sap.com/category: Workload + sme.sap.com/workload-name: test-cap-01-cav-v1-app-router + sme.sap.com/workload-type: Router + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/cav-version: "1.2.3" + sme.sap.com/owner-generation: "1" + sme.sap.com/owner-identifier-hash: e95e0682f33a657e75e1fc435972d19bd407ba3b + annotations: + sme.sap.com/btp-app-identifier: btp-glo-acc-id.test-cap-01 + sme.sap.com/owner-identifier: default.test-cap-01-cav-v1 + name: test-cap-01-cav-v1-app-router + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplicationVersion + name: test-cap-01-cav-v1 + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + selector: + matchLabels: + app: test-cap-01 + sme.sap.com/category: Workload + sme.sap.com/workload-name: test-cap-01-cav-v1-app-router + sme.sap.com/workload-type: Router + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/cav-version: "1.2.3" + sme.sap.com/owner-generation: "1" + sme.sap.com/owner-identifier-hash: e95e0682f33a657e75e1fc435972d19bd407ba3b + template: + metadata: + creationTimestamp: null + labels: + app: test-cap-01 + sme.sap.com/category: Workload + sme.sap.com/workload-name: test-cap-01-cav-v1-app-router + sme.sap.com/workload-type: Router + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/cav-version: "1.2.3" + sme.sap.com/owner-generation: "1" + sme.sap.com/owner-identifier-hash: e95e0682f33a657e75e1fc435972d19bd407ba3b + annotations: + sme.sap.com/btp-app-identifier: btp-glo-acc-id.test-cap-01 + sme.sap.com/owner-identifier: default.test-cap-01-cav-v1 + spec: + containers: + - env: + - name: CAPOP_APP_VERSION + value: "1.2.3" + - name: debug + valueFrom: + configMapKeyRef: + key: someKey + name: someCM + optional: true + - name: destinations + value: '[{"name":"srv-api","url":"http://test-cap-01-cav-v1-cap-backend-srv-svc:4004","forwardAuthToken":true}]' + envFrom: + - secretRef: + name: test-cap-01-cav-v1-app-router-gen + optional: true + image: docker.image.repo/approuter/approuter:latest + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4000 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + readinessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4000 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + resources: + limits: + cpu: 200m + memory: 500Mi + requests: + cpu: 20m + memory: 50Mi + name: app-router + imagePullSecrets: + - name: regcred + nodeSelector: + disktype: ssd +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: test-cap-01-cav-v1 + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplicationVersion + name: test-cap-01-cav-v1 + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + ingress: + - from: + - podSelector: + matchLabels: + app: test-cap-01 + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/category: Workload + sme.sap.com/cav-version: "1.2.3" + podSelector: + matchLabels: + app: test-cap-01 + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/category: Workload + sme.sap.com/cav-version: "1.2.3" + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: test-cap-01-cav-v1--in + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplicationVersion + name: test-cap-01-cav-v1 + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + ingress: + - from: + - namespaceSelector: {} + podSelector: + matchLabels: + app: istio-ingressgateway + istio: ingressgateway + podSelector: + matchLabels: + app: test-cap-01 + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/category: Workload + sme.sap.com/workload-type: Router + sme.sap.com/cav-version: "1.2.3" + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: test-cap-01-cav-v1-app-router + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplicationVersion + name: test-cap-01-cav-v1 + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + ingress: + - from: + - namespaceSelector: {} + podSelector: {} + ports: + - port: 4004 + - port: 4007 + podSelector: + matchLabels: + app: test-cap-01 + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/category: Workload + sme.sap.com/workload-name: test-cap-01-cav-v1-app-router + sme.sap.com/workload-type: Router + sme.sap.com/cav-version: "1.2.3" + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: test-cap-01-cav-v1-cap-backend-srv + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplicationVersion + name: test-cap-01-cav-v1 + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + ingress: + - from: + - namespaceSelector: {} + podSelector: {} + ports: + - port: 4005 + podSelector: + matchLabels: + app: test-cap-01 + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/category: Workload + sme.sap.com/workload-name: test-cap-01-cav-v1-cap-backend-srv + sme.sap.com/workload-type: CAP + sme.sap.com/cav-version: "1.2.3" + policyTypes: + - Ingress diff --git a/internal/controller/testdata/capapplicationversion/expected/cav-ready-toleration.yaml b/internal/controller/testdata/capapplicationversion/expected/cav-ready-toleration.yaml new file mode 100644 index 00000000..ab576f60 --- /dev/null +++ b/internal/controller/testdata/capapplicationversion/expected/cav-ready-toleration.yaml @@ -0,0 +1,407 @@ +apiVersion: sme.sap.com/v1alpha1 +kind: CAPApplicationVersion +metadata: + creationTimestamp: "2022-07-18T06:13:52Z" + generation: 1 + annotations: + sme.sap.com/btp-app-identifier: btp-glo-acc-id.test-cap-01 + sme.sap.com/owner-identifier: default.test-cap-01 + labels: + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/owner-generation: "2" + sme.sap.com/owner-identifier-hash: 1f74ae2fbff71a708786a4df4bb2ca87ec603581 + name: test-cap-01-cav-v1 + namespace: default + finalizers: + - "sme.sap.com/capapplicationversion" + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplication + name: test-cap-01 + uid: 3c7ba7cb-dc04-4fd1-be86-3eb3a5c64a98 + resourceVersion: "11371108" + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + capApplicationInstance: test-cap-01 + registrySecrets: + - regcred + version: 1.2.3 + workloads: + - name: cap-backend-srv + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + deploymentDefinition: + image: docker.image.repo/srv/server:latest + type: CAP + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.PodIp + ports: + - name: "app-port" + port: 4004 + routerDestinationName: "srv-api" + appProtocol: http + - name: "app-tech-port" + port: 4005 + networkPolicy: "Cluster" + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4004 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + readinessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4004 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + resources: + limits: + cpu: 200m + memory: 500Mi + requests: + cpu: 20m + memory: 50Mi + - name: app-router + consumedBTPServices: + - cap-uaa + - cap-saas-registry + deploymentDefinition: + image: docker.image.repo/approuter/approuter:latest + type: Router + env: + - name: debug + valueFrom: + configMapKeyRef: + key: someKey + name: someCM + optional: true + ports: + - name: "router-port" + port: 4000 + appProtocol: http + - name: "router-tech-port" + port: 4004 + networkPolicy: "Cluster" + - name: "router-metrics-port" + port: 4007 + networkPolicy: "Cluster" + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4000 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + readinessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4000 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + resources: + limits: + cpu: 200m + memory: 500Mi + requests: + cpu: 20m + memory: 50Mi + tolerations: + - key: "test" + operator: "Equal" + value: "foo" + effect: "NoExecute" + tolerationSeconds: 300 + - key: "never-exec" + operator: "Equal" + value: "noexec" + effect: "NoExecute" + - name: content-job + consumedBTPServices: + - cap-uaa + jobDefinition: + image: docker.image.repo/content/cap-content:latest + type: Content + env: + - name: SOME_VERSION + value: 0.0.1 + resources: + limits: + cpu: 100m + memory: 200Mi + requests: + cpu: 10m + memory: 20Mi + - name: mtx-job + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + jobDefinition: + image: docker.image.repo/srv/server:latest + type: TenantOperation + - name: job-worker + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + deploymentDefinition: + image: docker.image.repo/srv/server:latest + type: Additional + env: + - name: TEST_SEC_REF + valueFrom: + secretKeyRef: + key: someKey + name: someSecret + optional: true +status: + conditions: + - reason: CreatedDeployments + observedGeneration: 1 + status: "True" + type: Ready + observedGeneration: 1 + finishedJobs: + - "test-cap-01-cav-v1-content" + state: Ready +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: test-cap-01 + sme.sap.com/category: Workload + sme.sap.com/workload-name: test-cap-01-cav-v1-app-router + sme.sap.com/workload-type: Router + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/cav-version: "1.2.3" + sme.sap.com/owner-generation: "1" + sme.sap.com/owner-identifier-hash: e95e0682f33a657e75e1fc435972d19bd407ba3b + annotations: + sme.sap.com/btp-app-identifier: btp-glo-acc-id.test-cap-01 + sme.sap.com/owner-identifier: default.test-cap-01-cav-v1 + name: test-cap-01-cav-v1-app-router + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplicationVersion + name: test-cap-01-cav-v1 + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + selector: + matchLabels: + app: test-cap-01 + sme.sap.com/category: Workload + sme.sap.com/workload-name: test-cap-01-cav-v1-app-router + sme.sap.com/workload-type: Router + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/cav-version: "1.2.3" + sme.sap.com/owner-generation: "1" + sme.sap.com/owner-identifier-hash: e95e0682f33a657e75e1fc435972d19bd407ba3b + template: + metadata: + creationTimestamp: null + labels: + app: test-cap-01 + sme.sap.com/category: Workload + sme.sap.com/workload-name: test-cap-01-cav-v1-app-router + sme.sap.com/workload-type: Router + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/cav-version: "1.2.3" + sme.sap.com/owner-generation: "1" + sme.sap.com/owner-identifier-hash: e95e0682f33a657e75e1fc435972d19bd407ba3b + annotations: + sme.sap.com/btp-app-identifier: btp-glo-acc-id.test-cap-01 + sme.sap.com/owner-identifier: default.test-cap-01-cav-v1 + spec: + containers: + - env: + - name: CAPOP_APP_VERSION + value: "1.2.3" + - name: debug + valueFrom: + configMapKeyRef: + key: someKey + name: someCM + optional: true + - name: destinations + value: '[{"name":"srv-api","url":"http://test-cap-01-cav-v1-cap-backend-srv-svc:4004","forwardAuthToken":true}]' + envFrom: + - secretRef: + name: test-cap-01-cav-v1-app-router-gen + optional: true + image: docker.image.repo/approuter/approuter:latest + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4000 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + readinessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4000 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + resources: + limits: + cpu: 200m + memory: 500Mi + requests: + cpu: 20m + memory: 50Mi + name: app-router + imagePullSecrets: + - name: regcred + tolerations: + - key: "test" + operator: "Equal" + value: "foo" + effect: "NoExecute" + tolerationSeconds: 300 + - key: "never-exec" + operator: "Equal" + value: "noexec" + effect: "NoExecute" +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: test-cap-01-cav-v1 + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplicationVersion + name: test-cap-01-cav-v1 + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + ingress: + - from: + - podSelector: + matchLabels: + app: test-cap-01 + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/category: Workload + sme.sap.com/cav-version: "1.2.3" + podSelector: + matchLabels: + app: test-cap-01 + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/category: Workload + sme.sap.com/cav-version: "1.2.3" + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: test-cap-01-cav-v1--in + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplicationVersion + name: test-cap-01-cav-v1 + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + ingress: + - from: + - namespaceSelector: {} + podSelector: + matchLabels: + app: istio-ingressgateway + istio: ingressgateway + podSelector: + matchLabels: + app: test-cap-01 + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/category: Workload + sme.sap.com/workload-type: Router + sme.sap.com/cav-version: "1.2.3" + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: test-cap-01-cav-v1-app-router + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplicationVersion + name: test-cap-01-cav-v1 + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + ingress: + - from: + - namespaceSelector: {} + podSelector: {} + ports: + - port: 4004 + - port: 4007 + podSelector: + matchLabels: + app: test-cap-01 + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/category: Workload + sme.sap.com/workload-name: test-cap-01-cav-v1-app-router + sme.sap.com/workload-type: Router + sme.sap.com/cav-version: "1.2.3" + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: test-cap-01-cav-v1-cap-backend-srv + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplicationVersion + name: test-cap-01-cav-v1 + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + ingress: + - from: + - namespaceSelector: {} + podSelector: {} + ports: + - port: 4005 + podSelector: + matchLabels: + app: test-cap-01 + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/category: Workload + sme.sap.com/workload-name: test-cap-01-cav-v1-cap-backend-srv + sme.sap.com/workload-type: CAP + sme.sap.com/cav-version: "1.2.3" + policyTypes: + - Ingress diff --git a/internal/controller/testdata/capapplicationversion/expected/cav-ready-topology.yaml b/internal/controller/testdata/capapplicationversion/expected/cav-ready-topology.yaml new file mode 100644 index 00000000..51b2056f --- /dev/null +++ b/internal/controller/testdata/capapplicationversion/expected/cav-ready-topology.yaml @@ -0,0 +1,405 @@ +apiVersion: sme.sap.com/v1alpha1 +kind: CAPApplicationVersion +metadata: + creationTimestamp: "2022-07-18T06:13:52Z" + generation: 1 + annotations: + sme.sap.com/btp-app-identifier: btp-glo-acc-id.test-cap-01 + sme.sap.com/owner-identifier: default.test-cap-01 + labels: + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/owner-generation: "2" + sme.sap.com/owner-identifier-hash: 1f74ae2fbff71a708786a4df4bb2ca87ec603581 + name: test-cap-01-cav-v1 + namespace: default + finalizers: + - "sme.sap.com/capapplicationversion" + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplication + name: test-cap-01 + uid: 3c7ba7cb-dc04-4fd1-be86-3eb3a5c64a98 + resourceVersion: "11371108" + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + capApplicationInstance: test-cap-01 + registrySecrets: + - regcred + version: 1.2.3 + workloads: + - name: cap-backend-srv + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + deploymentDefinition: + image: docker.image.repo/srv/server:latest + type: CAP + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.PodIp + ports: + - name: "app-port" + port: 4004 + routerDestinationName: "srv-api" + appProtocol: http + - name: "app-tech-port" + port: 4005 + networkPolicy: "Cluster" + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4004 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + readinessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4004 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + resources: + limits: + cpu: 200m + memory: 500Mi + requests: + cpu: 20m + memory: 50Mi + - name: app-router + consumedBTPServices: + - cap-uaa + - cap-saas-registry + deploymentDefinition: + image: docker.image.repo/approuter/approuter:latest + type: Router + env: + - name: debug + valueFrom: + configMapKeyRef: + key: someKey + name: someCM + optional: true + ports: + - name: "router-port" + port: 4000 + appProtocol: http + - name: "router-tech-port" + port: 4004 + networkPolicy: "Cluster" + - name: "router-metrics-port" + port: 4007 + networkPolicy: "Cluster" + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4000 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + readinessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4000 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + resources: + limits: + cpu: 200m + memory: 500Mi + requests: + cpu: 20m + memory: 50Mi + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: someZone + whenUnsatisfiable: DoNotSchedule + labelSelector: + matchLabels: + foo: bar + matchLabelKeys: + - dummy-test-1.27 + - name: content-job + consumedBTPServices: + - cap-uaa + jobDefinition: + image: docker.image.repo/content/cap-content:latest + type: Content + env: + - name: SOME_VERSION + value: 0.0.1 + resources: + limits: + cpu: 100m + memory: 200Mi + requests: + cpu: 10m + memory: 20Mi + - name: mtx-job + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + jobDefinition: + image: docker.image.repo/srv/server:latest + type: TenantOperation + - name: job-worker + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + deploymentDefinition: + image: docker.image.repo/srv/server:latest + type: Additional + env: + - name: TEST_SEC_REF + valueFrom: + secretKeyRef: + key: someKey + name: someSecret + optional: true +status: + conditions: + - reason: CreatedDeployments + observedGeneration: 1 + status: "True" + type: Ready + observedGeneration: 1 + finishedJobs: + - "test-cap-01-cav-v1-content" + state: Ready +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: test-cap-01 + sme.sap.com/category: Workload + sme.sap.com/workload-name: test-cap-01-cav-v1-app-router + sme.sap.com/workload-type: Router + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/cav-version: "1.2.3" + sme.sap.com/owner-generation: "1" + sme.sap.com/owner-identifier-hash: e95e0682f33a657e75e1fc435972d19bd407ba3b + annotations: + sme.sap.com/btp-app-identifier: btp-glo-acc-id.test-cap-01 + sme.sap.com/owner-identifier: default.test-cap-01-cav-v1 + name: test-cap-01-cav-v1-app-router + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplicationVersion + name: test-cap-01-cav-v1 + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + selector: + matchLabels: + app: test-cap-01 + sme.sap.com/category: Workload + sme.sap.com/workload-name: test-cap-01-cav-v1-app-router + sme.sap.com/workload-type: Router + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/cav-version: "1.2.3" + sme.sap.com/owner-generation: "1" + sme.sap.com/owner-identifier-hash: e95e0682f33a657e75e1fc435972d19bd407ba3b + template: + metadata: + creationTimestamp: null + labels: + app: test-cap-01 + sme.sap.com/category: Workload + sme.sap.com/workload-name: test-cap-01-cav-v1-app-router + sme.sap.com/workload-type: Router + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/cav-version: "1.2.3" + sme.sap.com/owner-generation: "1" + sme.sap.com/owner-identifier-hash: e95e0682f33a657e75e1fc435972d19bd407ba3b + annotations: + sme.sap.com/btp-app-identifier: btp-glo-acc-id.test-cap-01 + sme.sap.com/owner-identifier: default.test-cap-01-cav-v1 + spec: + containers: + - env: + - name: CAPOP_APP_VERSION + value: "1.2.3" + - name: debug + valueFrom: + configMapKeyRef: + key: someKey + name: someCM + optional: true + - name: destinations + value: '[{"name":"srv-api","url":"http://test-cap-01-cav-v1-cap-backend-srv-svc:4004","forwardAuthToken":true}]' + envFrom: + - secretRef: + name: test-cap-01-cav-v1-app-router-gen + optional: true + image: docker.image.repo/approuter/approuter:latest + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4000 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + readinessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 4000 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 2 + resources: + limits: + cpu: 200m + memory: 500Mi + requests: + cpu: 20m + memory: 50Mi + name: app-router + imagePullSecrets: + - name: regcred + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: someZone + whenUnsatisfiable: DoNotSchedule + labelSelector: + matchLabels: + foo: bar + matchLabelKeys: + - dummy-test-1.27 +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: test-cap-01-cav-v1 + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplicationVersion + name: test-cap-01-cav-v1 + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + ingress: + - from: + - podSelector: + matchLabels: + app: test-cap-01 + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/category: Workload + sme.sap.com/cav-version: "1.2.3" + podSelector: + matchLabels: + app: test-cap-01 + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/category: Workload + sme.sap.com/cav-version: "1.2.3" + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: test-cap-01-cav-v1--in + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplicationVersion + name: test-cap-01-cav-v1 + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + ingress: + - from: + - namespaceSelector: {} + podSelector: + matchLabels: + app: istio-ingressgateway + istio: ingressgateway + podSelector: + matchLabels: + app: test-cap-01 + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/category: Workload + sme.sap.com/workload-type: Router + sme.sap.com/cav-version: "1.2.3" + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: test-cap-01-cav-v1-app-router + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplicationVersion + name: test-cap-01-cav-v1 + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + ingress: + - from: + - namespaceSelector: {} + podSelector: {} + ports: + - port: 4004 + - port: 4007 + podSelector: + matchLabels: + app: test-cap-01 + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/category: Workload + sme.sap.com/workload-name: test-cap-01-cav-v1-app-router + sme.sap.com/workload-type: Router + sme.sap.com/cav-version: "1.2.3" + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: test-cap-01-cav-v1-cap-backend-srv + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplicationVersion + name: test-cap-01-cav-v1 + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + ingress: + - from: + - namespaceSelector: {} + podSelector: {} + ports: + - port: 4005 + podSelector: + matchLabels: + app: test-cap-01 + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/category: Workload + sme.sap.com/workload-name: test-cap-01-cav-v1-cap-backend-srv + sme.sap.com/workload-type: CAP + sme.sap.com/cav-version: "1.2.3" + policyTypes: + - Ingress diff --git a/internal/controller/testdata/captenantoperation/ctop-scheduling-custom.expected.yaml b/internal/controller/testdata/captenantoperation/ctop-scheduling-custom.expected.yaml new file mode 100644 index 00000000..2ebdb694 --- /dev/null +++ b/internal/controller/testdata/captenantoperation/ctop-scheduling-custom.expected.yaml @@ -0,0 +1,160 @@ +apiVersion: sme.sap.com/v1alpha1 +kind: CAPTenantOperation +metadata: + name: test-cap-01-provider-abcd + namespace: default + generation: 1 + finalizers: + - sme.sap.com/captenantoperation + annotations: + sme.sap.com/owner-identifier: default.test-cap-01-provider + labels: + sme.sap.com/tenant-operation-type: upgrade + sme.sap.com/owner-generation: "0" + sme.sap.com/owner-identifier-hash: db1f1fd7eaeb0e6407c741b7e4b2540044bcc4ec + sme.sap.com/cav-version: 8.9.10 + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPTenant + name: test-cap-01-provider +spec: + tenantId: tenant-id-for-provider + subDomain: my-provider + operation: upgrade + capApplicationVersionInstance: test-cap-01-cav-v2 + steps: + - name: custom-say + type: CustomTenantOperation + - name: ten-op + type: TenantOperation + - name: custom-say + type: CustomTenantOperation +status: + state: Processing + observedGeneration: 1 + conditions: + - type: Ready + status: "False" + observedGeneration: 1 + reason: StepInitiated + message: "step 1/3 : job default.test-cap-01-provider-custom-say-gen created" + currentStep: 1 + activeJob: "test-cap-01-provider-custom-say-gen" +--- +apiVersion: batch/v1 +kind: Job +metadata: + annotations: + sidecar.istio.io/inject: "false" + sme.sap.com/owner-identifier: default.test-cap-01-provider-abcd + sme.sap.com/btp-app-identifier: btp-glo-acc-id.test-cap-01 + labels: + sme.sap.com/tenant-operation-step: "1" + sme.sap.com/tenant-operation-type: upgrade + sme.sap.com/owner-generation: "1" + sme.sap.com/owner-identifier-hash: ce6bb3ae0b5ebbd0116259415ccac00bff0dc431 + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + app: test-cap-01 + sme.sap.com/category: "Workload" + sme.sap.com/workload-name: "custom-say" + sme.sap.com/workload-type: "CustomTenantOperation" + generateName: test-cap-01-provider-custom-say- + name: test-cap-01-provider-custom-say-gen + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPTenantOperation + name: test-cap-01-provider-abcd +spec: + backoffLimit: 1 + ttlSecondsAfterFinished: 150 + template: + metadata: + annotations: + sidecar.istio.io/inject: "false" + sme.sap.com/owner-identifier: default.test-cap-01-provider-abcd + sme.sap.com/btp-app-identifier: btp-glo-acc-id.test-cap-01 + labels: + sme.sap.com/tenant-operation-step: "1" + sme.sap.com/tenant-operation-type: upgrade + sme.sap.com/owner-generation: "1" + sme.sap.com/owner-identifier-hash: ce6bb3ae0b5ebbd0116259415ccac00bff0dc431 + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + app: test-cap-01 + sme.sap.com/category: "Workload" + sme.sap.com/workload-name: "custom-say" + sme.sap.com/workload-type: "CustomTenantOperation" + spec: + containers: + - env: + - name: CAPOP_APP_VERSION + value: 8.9.10 + - name: CAPOP_TENANT_ID + value: tenant-id-for-provider + - name: CAPOP_TENANT_OPERATION + value: upgrade + - name: CAPOP_TENANT_SUBDOMAIN + value: my-provider + - name: close + value: encounter + envFrom: + - secretRef: + name: test-cap-01-provider-abcd-custom-say-gen + optional: true + securityContext: + runAsUser: 1000 + runAsGroup: 2000 + image: docker/whalesay + command: ["cowsay", "$(CAPOP_TENANT_OPERATION)", "$(CAPOP_TENANT_ID)"] + name: custom-say + imagePullSecrets: + - name: regcred + securityContext: + runAsUser: 2000 + runAsGroup: 2000 + nodeSelector: + disktype: ssd + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: topology.kubernetes.io/zone + operator: In + values: + - antarctica-east1 + - antarctica-west1 + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + preference: + matchExpressions: + - key: another-node-label-key + operator: In + values: + - another-node-label-value + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: someZone + whenUnsatisfiable: DoNotSchedule + labelSelector: + matchLabels: + foo: bar + matchLabelKeys: + - dummy-test-1.27 + tolerations: + - key: "test" + operator: "Equal" + value: "foo" + effect: "NoExecute" + tolerationSeconds: 300 + - key: "never-exec" + operator: "Equal" + value: "noexec" + effect: "NoExecute" + nodeName: foo + priorityClassName: prio + restartPolicy: Never diff --git a/internal/controller/testdata/captenantoperation/ctop-scheduling-custom.initial.yaml b/internal/controller/testdata/captenantoperation/ctop-scheduling-custom.initial.yaml new file mode 100644 index 00000000..d95fb1e9 --- /dev/null +++ b/internal/controller/testdata/captenantoperation/ctop-scheduling-custom.initial.yaml @@ -0,0 +1,37 @@ +apiVersion: sme.sap.com/v1alpha1 +kind: CAPTenantOperation +metadata: + name: test-cap-01-provider-abcd + namespace: default + generation: 1 + finalizers: + - sme.sap.com/captenantoperation + annotations: + sme.sap.com/owner-identifier: "default.test-cap-01-provider" + labels: + sme.sap.com/tenant-operation-type: upgrade + sme.sap.com/owner-generation: "0" + sme.sap.com/owner-identifier-hash: db1f1fd7eaeb0e6407c741b7e4b2540044bcc4ec + sme.sap.com/cav-version: "8.9.10" + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPTenant + name: test-cap-01-provider +spec: + tenantId: tenant-id-for-provider + subDomain: my-provider + operation: upgrade + capApplicationVersionInstance: test-cap-01-cav-v2 + steps: + - name: custom-say + type: CustomTenantOperation + - name: ten-op + type: TenantOperation + - name: custom-say + type: CustomTenantOperation +status: + state: Processing + conditions: [] + currentStep: 1 diff --git a/internal/controller/testdata/captenantoperation/ctop-scheduling.expected.yaml b/internal/controller/testdata/captenantoperation/ctop-scheduling.expected.yaml new file mode 100644 index 00000000..dbe8fcb1 --- /dev/null +++ b/internal/controller/testdata/captenantoperation/ctop-scheduling.expected.yaml @@ -0,0 +1,157 @@ +apiVersion: sme.sap.com/v1alpha1 +kind: CAPTenantOperation +metadata: + name: test-cap-01-provider-abcd + namespace: default + generation: 1 + finalizers: + - sme.sap.com/captenantoperation + annotations: + sme.sap.com/owner-identifier: default.test-cap-01-provider + labels: + sme.sap.com/tenant-operation-type: provisioning + sme.sap.com/owner-generation: "0" + sme.sap.com/owner-identifier-hash: db1f1fd7eaeb0e6407c741b7e4b2540044bcc4ec + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPTenant + name: test-cap-01-provider +spec: + tenantId: tenant-id-for-provider + subDomain: my-provider + operation: provisioning + capApplicationVersionInstance: test-cap-01-cav-v1 + steps: + - name: mtx + type: TenantOperation +status: + state: Processing + observedGeneration: 1 + conditions: + - type: Ready + status: "False" + observedGeneration: 1 + reason: StepInitiated + message: "step 1/1 : job default.test-cap-01-provider-mtx-gen created" + currentStep: 1 + activeJob: "test-cap-01-provider-mtx-gen" +--- +apiVersion: batch/v1 +kind: Job +metadata: + annotations: + sidecar.istio.io/inject: "false" + sme.sap.com/owner-identifier: default.test-cap-01-provider-abcd + sme.sap.com/btp-app-identifier: btp-glo-acc-id.test-cap-01 + labels: + sme.sap.com/tenant-operation-step: "1" + sme.sap.com/tenant-operation-type: provisioning + sme.sap.com/owner-generation: "1" + sme.sap.com/owner-identifier-hash: ce6bb3ae0b5ebbd0116259415ccac00bff0dc431 + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + app: test-cap-01 + sme.sap.com/category: "Workload" + sme.sap.com/workload-name: "mtx" + sme.sap.com/workload-type: "TenantOperation" + generateName: test-cap-01-provider-mtx- + name: test-cap-01-provider-mtx-gen + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPTenantOperation + name: test-cap-01-provider-abcd +spec: + template: + metadata: + annotations: + sidecar.istio.io/inject: "false" + sme.sap.com/owner-identifier: default.test-cap-01-provider-abcd + sme.sap.com/btp-app-identifier: btp-glo-acc-id.test-cap-01 + labels: + sme.sap.com/tenant-operation-step: "1" + sme.sap.com/tenant-operation-type: provisioning + sme.sap.com/owner-generation: "1" + sme.sap.com/owner-identifier-hash: ce6bb3ae0b5ebbd0116259415ccac00bff0dc431 + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + app: test-cap-01 + sme.sap.com/category: "Workload" + sme.sap.com/workload-name: "mtx" + sme.sap.com/workload-type: "TenantOperation" + spec: + containers: + - env: + - name: CAPOP_APP_VERSION + value: 5.6.7 + - name: CAPOP_TENANT_ID + value: tenant-id-for-provider + - name: CAPOP_TENANT_OPERATION + value: provisioning + - name: CAPOP_TENANT_SUBDOMAIN + value: my-provider + envFrom: + - secretRef: + name: test-cap-01-provider-abcd-mtx-gen + optional: true + command: + - node + - ./node_modules/@sap/cds-mtxs/bin/cds-mtx + - subscribe + - tenant-id-for-provider + resources: + limits: + cpu: 200m + memory: 200Mi + requests: + cpu: 20m + memory: 20Mi + securityContext: + runAsUser: 1000 + runAsGroup: 2000 + image: docker.image.repo/srv/server:latest + name: mtx + nodeSelector: + disktype: ssd + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: topology.kubernetes.io/zone + operator: In + values: + - antarctica-east1 + - antarctica-west1 + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + preference: + matchExpressions: + - key: another-node-label-key + operator: In + values: + - another-node-label-value + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: someZone + whenUnsatisfiable: DoNotSchedule + labelSelector: + matchLabels: + foo: bar + matchLabelKeys: + - dummy-test-1.27 + tolerations: + - key: "test" + operator: "Equal" + value: "foo" + effect: "NoExecute" + tolerationSeconds: 300 + - key: "never-exec" + operator: "Equal" + value: "noexec" + effect: "NoExecute" + imagePullSecrets: + - name: regcred + restartPolicy: Never diff --git a/internal/controller/testdata/captenantoperation/ctop-scheduling.initial.yaml b/internal/controller/testdata/captenantoperation/ctop-scheduling.initial.yaml new file mode 100644 index 00000000..8086d460 --- /dev/null +++ b/internal/controller/testdata/captenantoperation/ctop-scheduling.initial.yaml @@ -0,0 +1,32 @@ +apiVersion: sme.sap.com/v1alpha1 +kind: CAPTenantOperation +metadata: + name: test-cap-01-provider-abcd + namespace: default + generation: 1 + finalizers: + - sme.sap.com/captenantoperation + annotations: + sme.sap.com/owner-identifier: default.test-cap-01-provider + labels: + sme.sap.com/tenant-operation-type: provisioning + sme.sap.com/owner-generation: "0" + sme.sap.com/owner-identifier-hash: db1f1fd7eaeb0e6407c741b7e4b2540044bcc4ec + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPTenant + name: test-cap-01-provider +spec: + tenantId: tenant-id-for-provider + subDomain: my-provider + operation: provisioning + capApplicationVersionInstance: test-cap-01-cav-v1 + steps: + - name: mtx + type: TenantOperation +status: + state: Processing + conditions: [] + currentStep: 1 diff --git a/internal/controller/testdata/common/capapplicationversion-v1-scheduling-custom.yaml b/internal/controller/testdata/common/capapplicationversion-v1-scheduling-custom.yaml new file mode 100644 index 00000000..fea549e5 --- /dev/null +++ b/internal/controller/testdata/common/capapplicationversion-v1-scheduling-custom.yaml @@ -0,0 +1,142 @@ +apiVersion: sme.sap.com/v1alpha1 +kind: CAPApplicationVersion +metadata: + generation: 1 + annotations: + sme.sap.com/btp-app-identifier: btp-glo-acc-id.test-cap-01 + sme.sap.com/owner-identifier: default.test-cap-01 + labels: + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/owner-generation: "2" + sme.sap.com/owner-identifier-hash: 1f74ae2fbff71a708786a4df4bb2ca87ec603581 + name: test-cap-01-cav-v2 + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplication + name: test-cap-01 + uid: 3c7ba7cb-dc04-4fd1-be86-3eb3a5c64a98 + resourceVersion: "11371108" + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + capApplicationInstance: test-cap-01 + version: 8.9.10 + registrySecrets: + - regcred + workloads: + - name: cap-backend + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + deploymentDefinition: + type: CAP + image: docker.image.repo/srv/server:v2 + env: + - name: foo + value: bar + - name: content-job + consumedBTPServices: + - cap-uaa + jobDefinition: + type: Content + image: docker.image.repo/content/cap-content:v2 + - name: app-router + consumedBTPServices: + - cap-uaa + - cap-saas-registry + deploymentDefinition: + type: Router + image: docker.image.repo/approuter/approuter:v2 + - name: ten-op + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + jobDefinition: + type: "TenantOperation" + backoffLimit: 1 + ttlSecondsAfterFinished: 150 + image: docker.image.repo/srv/server:latest + env: + - name: flow + value: glow + - name: custom-say + consumedBTPServices: + - cap-uaa + jobDefinition: + type: "CustomTenantOperation" + image: docker/whalesay + command: ["cowsay", "$(CAPOP_TENANT_OPERATION)", "$(CAPOP_TENANT_ID)"] + backoffLimit: 1 + ttlSecondsAfterFinished: 150 + securityContext: + runAsUser: 1000 + runAsGroup: 2000 + podSecurityContext: + runAsUser: 2000 + runAsGroup: 2000 + nodeSelector: + disktype: ssd + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: topology.kubernetes.io/zone + operator: In + values: + - antarctica-east1 + - antarctica-west1 + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + preference: + matchExpressions: + - key: another-node-label-key + operator: In + values: + - another-node-label-value + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: someZone + whenUnsatisfiable: DoNotSchedule + labelSelector: + matchLabels: + foo: bar + matchLabelKeys: + - dummy-test-1.27 + tolerations: + - key: "test" + operator: "Equal" + value: "foo" + effect: "NoExecute" + tolerationSeconds: 300 + - key: "never-exec" + operator: "Equal" + value: "noexec" + effect: "NoExecute" + nodeName: foo + priorityClassName: prio + env: + - name: close + value: encounter + tenantOperations: + provisioning: + - workloadName: custom-say + - workloadName: content-job # this will be ignored + - workloadName: ten-op + upgrade: + - workloadName: custom-say + - workloadName: ten-op + - workloadName: custom-say +status: + conditions: + - lastTransitionTime: "2022-03-18T23:07:47Z" + lastUpdateTime: "2022-03-18T23:07:47Z" + reason: CreatedDeployments + status: "True" + type: Ready + observedGeneration: 1 + state: Ready diff --git a/internal/controller/testdata/common/capapplicationversion-v1-scheduling.yaml b/internal/controller/testdata/common/capapplicationversion-v1-scheduling.yaml new file mode 100644 index 00000000..5913388f --- /dev/null +++ b/internal/controller/testdata/common/capapplicationversion-v1-scheduling.yaml @@ -0,0 +1,116 @@ +apiVersion: sme.sap.com/v1alpha1 +kind: CAPApplicationVersion +metadata: + creationTimestamp: "2022-03-18T22:14:33Z" + generation: 1 + annotations: + sme.sap.com/btp-app-identifier: btp-glo-acc-id.test-cap-01 + sme.sap.com/owner-identifier: default.test-cap-01 + labels: + sme.sap.com/btp-app-identifier-hash: f20cc8aeb2003b3abc33f749a16bd53544b6bab2 + sme.sap.com/owner-generation: "2" + sme.sap.com/owner-identifier-hash: 1f74ae2fbff71a708786a4df4bb2ca87ec603581 + name: test-cap-01-cav-v1 + namespace: default + ownerReferences: + - apiVersion: sme.sap.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CAPApplication + name: test-cap-01 + uid: 3c7ba7cb-dc04-4fd1-be86-3eb3a5c64a98 + resourceVersion: "11371108" + uid: 5e64489b-7346-4984-8617-e8c37338b3d8 +spec: + capApplicationInstance: test-cap-01 + registrySecrets: + - regcred + version: 5.6.7 + workloads: + - name: cap-backend + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + deploymentDefinition: + type: CAP + image: docker.image.repo/srv/server:latest + - name: content-job + consumedBTPServices: + - cap-uaa + jobDefinition: + type: Content + image: docker.image.repo/content/cap-content:latest + - name: mtx + consumedBTPServices: + - cap-uaa + - cap-service-manager + - cap-saas-registry + jobDefinition: + type: "TenantOperation" + resources: + limits: + cpu: 200m + memory: 200Mi + requests: + cpu: 20m + memory: 20Mi + securityContext: + runAsUser: 1000 + runAsGroup: 2000 + nodeSelector: + disktype: ssd + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: topology.kubernetes.io/zone + operator: In + values: + - antarctica-east1 + - antarctica-west1 + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + preference: + matchExpressions: + - key: another-node-label-key + operator: In + values: + - another-node-label-value + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: someZone + whenUnsatisfiable: DoNotSchedule + labelSelector: + matchLabels: + foo: bar + matchLabelKeys: + - dummy-test-1.27 + tolerations: + - key: "test" + operator: "Equal" + value: "foo" + effect: "NoExecute" + tolerationSeconds: 300 + - key: "never-exec" + operator: "Equal" + value: "noexec" + effect: "NoExecute" + image: docker.image.repo/srv/server:latest + - name: app-router + consumedBTPServices: + - cap-uaa + - cap-saas-registry + deploymentDefinition: + type: Router + image: docker.image.repo/approuter/approuter:latest +status: + conditions: + - lastTransitionTime: "2022-03-18T23:07:47Z" + lastUpdateTime: "2022-03-18T23:07:47Z" + reason: CreatedDeployments + status: "True" + type: Ready + observedGeneration: 1 + state: Ready diff --git a/pkg/apis/sme.sap.com/v1alpha1/types.go b/pkg/apis/sme.sap.com/v1alpha1/types.go index 15e1ea8c..7ce1d8e1 100644 --- a/pkg/apis/sme.sap.com/v1alpha1/types.go +++ b/pkg/apis/sme.sap.com/v1alpha1/types.go @@ -240,7 +240,7 @@ type WorkloadDetails struct { // DeploymentDetails specifies the details of the Deployment type DeploymentDetails struct { - ContainerDetails `json:",inline"` + CommonDetails `json:",inline"` // Type of the Deployment Type DeploymentType `json:"type"` // Number of replicas @@ -267,7 +267,7 @@ const ( // JobDetails specifies the details of the Job type JobDetails struct { - ContainerDetails `json:",inline"` + CommonDetails `json:",inline"` // Type of Job Type JobType `json:"type"` // Specifies the number of retries before marking this job failed. @@ -288,8 +288,8 @@ const ( JobCustomTenantOperation JobType = "CustomTenantOperation" ) -// ContainerDetails specifies the details of the Container -type ContainerDetails struct { +// CommonDetails specifies the common details of the Container/Pod that may be relevant for both Deployments and Jobs +type CommonDetails struct { // Image info for the container Image string `json:"image"` // Pull policy for the container image @@ -304,6 +304,18 @@ type ContainerDetails struct { SecurityContext *corev1.SecurityContext `json:"securityContext,omitempty"` // SecurityContext for the Pod PodSecurityContext *corev1.PodSecurityContext `json:"podSecurityContext,omitempty"` + // The name of the node to which the Pod should be assigned to. See: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodename + NodeName string `json:"nodeName,omitempty"` + // The label selectors using which node for the Pod would be determined. See: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector + NodeSelector map[string]string `json:"nodeSelector,omitempty"` + // Priority class name mapping used to prioritize and schedule the Pod. See: https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/#priorityclass + PriorityClassName string `json:"priorityClassName,omitempty"` + // Affinity/anti-affinity used to provide more constraints for node selection. See: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity + Affinity *corev1.Affinity `json:"affinity,omitempty"` + // Tolerations used to schedule the Pod. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/ + Tolerations []corev1.Toleration `json:"tolerations,omitempty"` + // The Topology spread constraints used to control how Pods are spread across regions, zones, nodes etc. See: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#pod-topology-spread-constraints + TopologySpreadConstraints []corev1.TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty"` } // Configuration of Service Ports for the deployment diff --git a/pkg/apis/sme.sap.com/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/sme.sap.com/v1alpha1/zz_generated.deepcopy.go index 3e8bd3ec..a5cc505d 100644 --- a/pkg/apis/sme.sap.com/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/sme.sap.com/v1alpha1/zz_generated.deepcopy.go @@ -526,7 +526,7 @@ func (in *CAPTenantStatus) DeepCopy() *CAPTenantStatus { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ContainerDetails) DeepCopyInto(out *ContainerDetails) { +func (in *CommonDetails) DeepCopyInto(out *CommonDetails) { *out = *in if in.Command != nil { in, out := &in.Command, &out.Command @@ -551,15 +551,41 @@ func (in *ContainerDetails) DeepCopyInto(out *ContainerDetails) { *out = new(v1.PodSecurityContext) (*in).DeepCopyInto(*out) } + if in.NodeSelector != nil { + in, out := &in.NodeSelector, &out.NodeSelector + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Affinity != nil { + in, out := &in.Affinity, &out.Affinity + *out = new(v1.Affinity) + (*in).DeepCopyInto(*out) + } + if in.Tolerations != nil { + in, out := &in.Tolerations, &out.Tolerations + *out = make([]v1.Toleration, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.TopologySpreadConstraints != nil { + in, out := &in.TopologySpreadConstraints, &out.TopologySpreadConstraints + *out = make([]v1.TopologySpreadConstraint, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerDetails. -func (in *ContainerDetails) DeepCopy() *ContainerDetails { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CommonDetails. +func (in *CommonDetails) DeepCopy() *CommonDetails { if in == nil { return nil } - out := new(ContainerDetails) + out := new(CommonDetails) in.DeepCopyInto(out) return out } @@ -567,7 +593,7 @@ func (in *ContainerDetails) DeepCopy() *ContainerDetails { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DeploymentDetails) DeepCopyInto(out *DeploymentDetails) { *out = *in - in.ContainerDetails.DeepCopyInto(&out.ContainerDetails) + in.CommonDetails.DeepCopyInto(&out.CommonDetails) if in.Replicas != nil { in, out := &in.Replicas, &out.Replicas *out = new(int32) @@ -629,7 +655,7 @@ func (in *GenericStatus) DeepCopy() *GenericStatus { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *JobDetails) DeepCopyInto(out *JobDetails) { *out = *in - in.ContainerDetails.DeepCopyInto(&out.ContainerDetails) + in.CommonDetails.DeepCopyInto(&out.CommonDetails) if in.BackoffLimit != nil { in, out := &in.BackoffLimit, &out.BackoffLimit *out = new(int32) diff --git a/pkg/client/applyconfiguration/sme.sap.com/v1alpha1/commondetails.go b/pkg/client/applyconfiguration/sme.sap.com/v1alpha1/commondetails.go new file mode 100644 index 00000000..20dff581 --- /dev/null +++ b/pkg/client/applyconfiguration/sme.sap.com/v1alpha1/commondetails.go @@ -0,0 +1,154 @@ +/* +SPDX-FileCopyrightText: 2023 SAP SE or an SAP affiliate company and cap-operator contributors +SPDX-License-Identifier: Apache-2.0 +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/api/core/v1" +) + +// CommonDetailsApplyConfiguration represents an declarative configuration of the CommonDetails type for use +// with apply. +type CommonDetailsApplyConfiguration struct { + Image *string `json:"image,omitempty"` + ImagePullPolicy *v1.PullPolicy `json:"imagePullPolicy,omitempty"` + Command []string `json:"command,omitempty"` + Env []v1.EnvVar `json:"env,omitempty"` + Resources *v1.ResourceRequirements `json:"resources,omitempty"` + SecurityContext *v1.SecurityContext `json:"securityContext,omitempty"` + PodSecurityContext *v1.PodSecurityContext `json:"podSecurityContext,omitempty"` + NodeName *string `json:"nodeName,omitempty"` + NodeSelector map[string]string `json:"nodeSelector,omitempty"` + PriorityClassName *string `json:"priorityClassName,omitempty"` + Affinity *v1.Affinity `json:"affinity,omitempty"` + Tolerations []v1.Toleration `json:"tolerations,omitempty"` + TopologySpreadConstraints []v1.TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty"` +} + +// CommonDetailsApplyConfiguration constructs an declarative configuration of the CommonDetails type for use with +// apply. +func CommonDetails() *CommonDetailsApplyConfiguration { + return &CommonDetailsApplyConfiguration{} +} + +// WithImage sets the Image field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Image field is set to the value of the last call. +func (b *CommonDetailsApplyConfiguration) WithImage(value string) *CommonDetailsApplyConfiguration { + b.Image = &value + return b +} + +// WithImagePullPolicy sets the ImagePullPolicy field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ImagePullPolicy field is set to the value of the last call. +func (b *CommonDetailsApplyConfiguration) WithImagePullPolicy(value v1.PullPolicy) *CommonDetailsApplyConfiguration { + b.ImagePullPolicy = &value + return b +} + +// WithCommand adds the given value to the Command field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Command field. +func (b *CommonDetailsApplyConfiguration) WithCommand(values ...string) *CommonDetailsApplyConfiguration { + for i := range values { + b.Command = append(b.Command, values[i]) + } + return b +} + +// WithEnv adds the given value to the Env field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Env field. +func (b *CommonDetailsApplyConfiguration) WithEnv(values ...v1.EnvVar) *CommonDetailsApplyConfiguration { + for i := range values { + b.Env = append(b.Env, values[i]) + } + return b +} + +// WithResources sets the Resources field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Resources field is set to the value of the last call. +func (b *CommonDetailsApplyConfiguration) WithResources(value v1.ResourceRequirements) *CommonDetailsApplyConfiguration { + b.Resources = &value + return b +} + +// WithSecurityContext sets the SecurityContext field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the SecurityContext field is set to the value of the last call. +func (b *CommonDetailsApplyConfiguration) WithSecurityContext(value v1.SecurityContext) *CommonDetailsApplyConfiguration { + b.SecurityContext = &value + return b +} + +// WithPodSecurityContext sets the PodSecurityContext field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the PodSecurityContext field is set to the value of the last call. +func (b *CommonDetailsApplyConfiguration) WithPodSecurityContext(value v1.PodSecurityContext) *CommonDetailsApplyConfiguration { + b.PodSecurityContext = &value + return b +} + +// WithNodeName sets the NodeName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the NodeName field is set to the value of the last call. +func (b *CommonDetailsApplyConfiguration) WithNodeName(value string) *CommonDetailsApplyConfiguration { + b.NodeName = &value + return b +} + +// WithNodeSelector puts the entries into the NodeSelector field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the NodeSelector field, +// overwriting an existing map entries in NodeSelector field with the same key. +func (b *CommonDetailsApplyConfiguration) WithNodeSelector(entries map[string]string) *CommonDetailsApplyConfiguration { + if b.NodeSelector == nil && len(entries) > 0 { + b.NodeSelector = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.NodeSelector[k] = v + } + return b +} + +// WithPriorityClassName sets the PriorityClassName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the PriorityClassName field is set to the value of the last call. +func (b *CommonDetailsApplyConfiguration) WithPriorityClassName(value string) *CommonDetailsApplyConfiguration { + b.PriorityClassName = &value + return b +} + +// WithAffinity sets the Affinity field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Affinity field is set to the value of the last call. +func (b *CommonDetailsApplyConfiguration) WithAffinity(value v1.Affinity) *CommonDetailsApplyConfiguration { + b.Affinity = &value + return b +} + +// WithTolerations adds the given value to the Tolerations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Tolerations field. +func (b *CommonDetailsApplyConfiguration) WithTolerations(values ...v1.Toleration) *CommonDetailsApplyConfiguration { + for i := range values { + b.Tolerations = append(b.Tolerations, values[i]) + } + return b +} + +// WithTopologySpreadConstraints adds the given value to the TopologySpreadConstraints field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the TopologySpreadConstraints field. +func (b *CommonDetailsApplyConfiguration) WithTopologySpreadConstraints(values ...v1.TopologySpreadConstraint) *CommonDetailsApplyConfiguration { + for i := range values { + b.TopologySpreadConstraints = append(b.TopologySpreadConstraints, values[i]) + } + return b +} diff --git a/pkg/client/applyconfiguration/sme.sap.com/v1alpha1/containerdetails.go b/pkg/client/applyconfiguration/sme.sap.com/v1alpha1/containerdetails.go deleted file mode 100644 index 7ac396a6..00000000 --- a/pkg/client/applyconfiguration/sme.sap.com/v1alpha1/containerdetails.go +++ /dev/null @@ -1,90 +0,0 @@ -/* -SPDX-FileCopyrightText: 2023 SAP SE or an SAP affiliate company and cap-operator contributors -SPDX-License-Identifier: Apache-2.0 -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - v1 "k8s.io/api/core/v1" -) - -// ContainerDetailsApplyConfiguration represents an declarative configuration of the ContainerDetails type for use -// with apply. -type ContainerDetailsApplyConfiguration struct { - Image *string `json:"image,omitempty"` - ImagePullPolicy *v1.PullPolicy `json:"imagePullPolicy,omitempty"` - Command []string `json:"command,omitempty"` - Env []v1.EnvVar `json:"env,omitempty"` - Resources *v1.ResourceRequirements `json:"resources,omitempty"` - SecurityContext *v1.SecurityContext `json:"securityContext,omitempty"` - PodSecurityContext *v1.PodSecurityContext `json:"podSecurityContext,omitempty"` -} - -// ContainerDetailsApplyConfiguration constructs an declarative configuration of the ContainerDetails type for use with -// apply. -func ContainerDetails() *ContainerDetailsApplyConfiguration { - return &ContainerDetailsApplyConfiguration{} -} - -// WithImage sets the Image field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Image field is set to the value of the last call. -func (b *ContainerDetailsApplyConfiguration) WithImage(value string) *ContainerDetailsApplyConfiguration { - b.Image = &value - return b -} - -// WithImagePullPolicy sets the ImagePullPolicy field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the ImagePullPolicy field is set to the value of the last call. -func (b *ContainerDetailsApplyConfiguration) WithImagePullPolicy(value v1.PullPolicy) *ContainerDetailsApplyConfiguration { - b.ImagePullPolicy = &value - return b -} - -// WithCommand adds the given value to the Command field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Command field. -func (b *ContainerDetailsApplyConfiguration) WithCommand(values ...string) *ContainerDetailsApplyConfiguration { - for i := range values { - b.Command = append(b.Command, values[i]) - } - return b -} - -// WithEnv adds the given value to the Env field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Env field. -func (b *ContainerDetailsApplyConfiguration) WithEnv(values ...v1.EnvVar) *ContainerDetailsApplyConfiguration { - for i := range values { - b.Env = append(b.Env, values[i]) - } - return b -} - -// WithResources sets the Resources field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Resources field is set to the value of the last call. -func (b *ContainerDetailsApplyConfiguration) WithResources(value v1.ResourceRequirements) *ContainerDetailsApplyConfiguration { - b.Resources = &value - return b -} - -// WithSecurityContext sets the SecurityContext field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the SecurityContext field is set to the value of the last call. -func (b *ContainerDetailsApplyConfiguration) WithSecurityContext(value v1.SecurityContext) *ContainerDetailsApplyConfiguration { - b.SecurityContext = &value - return b -} - -// WithPodSecurityContext sets the PodSecurityContext field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the PodSecurityContext field is set to the value of the last call. -func (b *ContainerDetailsApplyConfiguration) WithPodSecurityContext(value v1.PodSecurityContext) *ContainerDetailsApplyConfiguration { - b.PodSecurityContext = &value - return b -} diff --git a/pkg/client/applyconfiguration/sme.sap.com/v1alpha1/deploymentdetails.go b/pkg/client/applyconfiguration/sme.sap.com/v1alpha1/deploymentdetails.go index d351a4e5..b33ce679 100644 --- a/pkg/client/applyconfiguration/sme.sap.com/v1alpha1/deploymentdetails.go +++ b/pkg/client/applyconfiguration/sme.sap.com/v1alpha1/deploymentdetails.go @@ -15,12 +15,12 @@ import ( // DeploymentDetailsApplyConfiguration represents an declarative configuration of the DeploymentDetails type for use // with apply. type DeploymentDetailsApplyConfiguration struct { - ContainerDetailsApplyConfiguration `json:",inline"` - Type *smesapcomv1alpha1.DeploymentType `json:"type,omitempty"` - Replicas *int32 `json:"replicas,omitempty"` - Ports []PortsApplyConfiguration `json:"ports,omitempty"` - LivenessProbe *v1.Probe `json:"livenessProbe,omitempty"` - ReadinessProbe *v1.Probe `json:"readinessProbe,omitempty"` + CommonDetailsApplyConfiguration `json:",inline"` + Type *smesapcomv1alpha1.DeploymentType `json:"type,omitempty"` + Replicas *int32 `json:"replicas,omitempty"` + Ports []PortsApplyConfiguration `json:"ports,omitempty"` + LivenessProbe *v1.Probe `json:"livenessProbe,omitempty"` + ReadinessProbe *v1.Probe `json:"readinessProbe,omitempty"` } // DeploymentDetailsApplyConfiguration constructs an declarative configuration of the DeploymentDetails type for use with @@ -89,6 +89,64 @@ func (b *DeploymentDetailsApplyConfiguration) WithPodSecurityContext(value v1.Po return b } +// WithNodeName sets the NodeName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the NodeName field is set to the value of the last call. +func (b *DeploymentDetailsApplyConfiguration) WithNodeName(value string) *DeploymentDetailsApplyConfiguration { + b.NodeName = &value + return b +} + +// WithNodeSelector puts the entries into the NodeSelector field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the NodeSelector field, +// overwriting an existing map entries in NodeSelector field with the same key. +func (b *DeploymentDetailsApplyConfiguration) WithNodeSelector(entries map[string]string) *DeploymentDetailsApplyConfiguration { + if b.NodeSelector == nil && len(entries) > 0 { + b.NodeSelector = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.NodeSelector[k] = v + } + return b +} + +// WithPriorityClassName sets the PriorityClassName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the PriorityClassName field is set to the value of the last call. +func (b *DeploymentDetailsApplyConfiguration) WithPriorityClassName(value string) *DeploymentDetailsApplyConfiguration { + b.PriorityClassName = &value + return b +} + +// WithAffinity sets the Affinity field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Affinity field is set to the value of the last call. +func (b *DeploymentDetailsApplyConfiguration) WithAffinity(value v1.Affinity) *DeploymentDetailsApplyConfiguration { + b.Affinity = &value + return b +} + +// WithTolerations adds the given value to the Tolerations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Tolerations field. +func (b *DeploymentDetailsApplyConfiguration) WithTolerations(values ...v1.Toleration) *DeploymentDetailsApplyConfiguration { + for i := range values { + b.Tolerations = append(b.Tolerations, values[i]) + } + return b +} + +// WithTopologySpreadConstraints adds the given value to the TopologySpreadConstraints field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the TopologySpreadConstraints field. +func (b *DeploymentDetailsApplyConfiguration) WithTopologySpreadConstraints(values ...v1.TopologySpreadConstraint) *DeploymentDetailsApplyConfiguration { + for i := range values { + b.TopologySpreadConstraints = append(b.TopologySpreadConstraints, values[i]) + } + return b +} + // WithType sets the Type field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Type field is set to the value of the last call. diff --git a/pkg/client/applyconfiguration/sme.sap.com/v1alpha1/jobdetails.go b/pkg/client/applyconfiguration/sme.sap.com/v1alpha1/jobdetails.go index 0a5427ed..6a6452fb 100644 --- a/pkg/client/applyconfiguration/sme.sap.com/v1alpha1/jobdetails.go +++ b/pkg/client/applyconfiguration/sme.sap.com/v1alpha1/jobdetails.go @@ -15,10 +15,10 @@ import ( // JobDetailsApplyConfiguration represents an declarative configuration of the JobDetails type for use // with apply. type JobDetailsApplyConfiguration struct { - ContainerDetailsApplyConfiguration `json:",inline"` - Type *smesapcomv1alpha1.JobType `json:"type,omitempty"` - BackoffLimit *int32 `json:"backoffLimit,omitempty"` - TTLSecondsAfterFinished *int32 `json:"ttlSecondsAfterFinished,omitempty"` + CommonDetailsApplyConfiguration `json:",inline"` + Type *smesapcomv1alpha1.JobType `json:"type,omitempty"` + BackoffLimit *int32 `json:"backoffLimit,omitempty"` + TTLSecondsAfterFinished *int32 `json:"ttlSecondsAfterFinished,omitempty"` } // JobDetailsApplyConfiguration constructs an declarative configuration of the JobDetails type for use with @@ -87,6 +87,64 @@ func (b *JobDetailsApplyConfiguration) WithPodSecurityContext(value v1.PodSecuri return b } +// WithNodeName sets the NodeName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the NodeName field is set to the value of the last call. +func (b *JobDetailsApplyConfiguration) WithNodeName(value string) *JobDetailsApplyConfiguration { + b.NodeName = &value + return b +} + +// WithNodeSelector puts the entries into the NodeSelector field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the NodeSelector field, +// overwriting an existing map entries in NodeSelector field with the same key. +func (b *JobDetailsApplyConfiguration) WithNodeSelector(entries map[string]string) *JobDetailsApplyConfiguration { + if b.NodeSelector == nil && len(entries) > 0 { + b.NodeSelector = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.NodeSelector[k] = v + } + return b +} + +// WithPriorityClassName sets the PriorityClassName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the PriorityClassName field is set to the value of the last call. +func (b *JobDetailsApplyConfiguration) WithPriorityClassName(value string) *JobDetailsApplyConfiguration { + b.PriorityClassName = &value + return b +} + +// WithAffinity sets the Affinity field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Affinity field is set to the value of the last call. +func (b *JobDetailsApplyConfiguration) WithAffinity(value v1.Affinity) *JobDetailsApplyConfiguration { + b.Affinity = &value + return b +} + +// WithTolerations adds the given value to the Tolerations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Tolerations field. +func (b *JobDetailsApplyConfiguration) WithTolerations(values ...v1.Toleration) *JobDetailsApplyConfiguration { + for i := range values { + b.Tolerations = append(b.Tolerations, values[i]) + } + return b +} + +// WithTopologySpreadConstraints adds the given value to the TopologySpreadConstraints field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the TopologySpreadConstraints field. +func (b *JobDetailsApplyConfiguration) WithTopologySpreadConstraints(values ...v1.TopologySpreadConstraint) *JobDetailsApplyConfiguration { + for i := range values { + b.TopologySpreadConstraints = append(b.TopologySpreadConstraints, values[i]) + } + return b +} + // WithType sets the Type field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Type field is set to the value of the last call. diff --git a/pkg/client/applyconfiguration/utils.go b/pkg/client/applyconfiguration/utils.go index ba69b318..ef3e30af 100644 --- a/pkg/client/applyconfiguration/utils.go +++ b/pkg/client/applyconfiguration/utils.go @@ -50,8 +50,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &smesapcomv1alpha1.CAPTenantSpecApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("CAPTenantStatus"): return &smesapcomv1alpha1.CAPTenantStatusApplyConfiguration{} - case v1alpha1.SchemeGroupVersion.WithKind("ContainerDetails"): - return &smesapcomv1alpha1.ContainerDetailsApplyConfiguration{} + case v1alpha1.SchemeGroupVersion.WithKind("CommonDetails"): + return &smesapcomv1alpha1.CommonDetailsApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("DeploymentDetails"): return &smesapcomv1alpha1.DeploymentDetailsApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("GenericStatus"): diff --git a/website/includes/api-reference.html b/website/includes/api-reference.html index 3798ce63..b0bf4dca 100644 --- a/website/includes/api-reference.html +++ b/website/includes/api-reference.html @@ -1478,13 +1478,13 @@

CAPTenantStatus -

ContainerDetails +

CommonDetails

(Appears on: DeploymentDetails, JobDetails)

-

ContainerDetails specifies the details of the Container

+

CommonDetails specifies the common details of the Container/Pod that may be relevant for both Deployments and Jobs

@@ -1581,6 +1581,78 @@

ContainerDetails

SecurityContext for the Pod

+

+ + + + + + + + + + + + + + + + + + + + + + +
+nodeName
+ +string + +
+

The name of the node to which the Pod should be assigned to. See: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodename

+
+nodeSelector
+ +map[string]string + +
+

The label selectors using which node for the Pod would be determined. See: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector

+
+priorityClassName
+ +string + +
+

Priority class name mapping used to prioritize and schedule the Pod. See: https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/#priorityclass

+
+affinity
+ + +Kubernetes core/v1.Affinity + + +
+

Affinity/anti-affinity used to provide more constraints for node selection. See: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity

+
+tolerations
+ + +[]Kubernetes core/v1.Toleration + + +
+

Tolerations used to schedule the Pod. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/

+
+topologySpreadConstraints
+ + +[]Kubernetes core/v1.TopologySpreadConstraint + + +
+

The Topology spread constraints used to control how Pods are spread across regions, zones, nodes etc. See: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#pod-topology-spread-constraints

+

DeploymentDetails @@ -1601,16 +1673,16 @@

DeploymentDetails -ContainerDetails
+CommonDetails
- -ContainerDetails + +CommonDetails

-(Members of ContainerDetails are embedded into this type.) +(Members of CommonDetails are embedded into this type.)

@@ -1765,16 +1837,16 @@

JobDetails -ContainerDetails
+CommonDetails
- -ContainerDetails + +CommonDetails

-(Members of ContainerDetails are embedded into this type.) +(Members of CommonDetails are embedded into this type.)

@@ -2252,5 +2324,5 @@

WorkloadDetails

Generated with gen-crd-api-reference-docs -on git commit 0db0df0. +on git commit b107e81.