From 4f86f1b6179589a9c129a3639b6ab650103220fb Mon Sep 17 00:00:00 2001 From: Jakub Cechacek Date: Sat, 21 Oct 2023 19:23:00 +0200 Subject: [PATCH 1/2] DBZ-7052 Initial support for container templating --- k8/debeziumservers.debezium.io-v1.yml | 99 +++++++++++++++++++ .../dependent/DeploymentDependent.java | 19 ++++ .../io/debezium/operator/model/Templates.java | 14 +++ .../model/templates/ContainerEnvVar.java | 36 +++++++ .../model/templates/ContainerTemplate.java | 56 +++++++++++ .../operator/model/templates/PodTemplate.java | 5 +- 6 files changed, 228 insertions(+), 1 deletion(-) create mode 100644 src/main/java/io/debezium/operator/model/templates/ContainerEnvVar.java create mode 100644 src/main/java/io/debezium/operator/model/templates/ContainerTemplate.java diff --git a/k8/debeziumservers.debezium.io-v1.yml b/k8/debeziumservers.debezium.io-v1.yml index 4958606..c3ca1b6 100644 --- a/k8/debeziumservers.debezium.io-v1.yml +++ b/k8/debeziumservers.debezium.io-v1.yml @@ -697,6 +697,105 @@ spec: templates: description: Debezium Server resource templates. properties: + container: + description: Container template + properties: + securityContext: + description: Container security context. + properties: + runAsGroup: + type: integer + runAsNonRoot: + type: boolean + windowsOptions: + properties: + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + gmsaCredentialSpec: + type: string + runAsUserName: + type: string + type: object + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + seLinuxOptions: + properties: + role: + type: string + type: + type: string + user: + type: string + level: + type: string + type: object + readOnlyRootFilesystem: + type: boolean + privileged: + type: boolean + runAsUser: + type: integer + procMount: + type: string + seccompProfile: + properties: + type: + type: string + localhostProfile: + type: string + type: object + type: object + resources: + description: CPU and memory resource requirements. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + claims: + items: + properties: + name: + type: string + type: object + type: array + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: object + env: + description: Environment variables applied to the container. + items: + properties: + value: + description: The environment variable value. + type: string + name: + description: The environment variable name. + type: string + type: object + type: array + type: object pod: description: Pod template. properties: diff --git a/src/main/java/io/debezium/operator/dependent/DeploymentDependent.java b/src/main/java/io/debezium/operator/dependent/DeploymentDependent.java index 92bd1bb..e2b4138 100644 --- a/src/main/java/io/debezium/operator/dependent/DeploymentDependent.java +++ b/src/main/java/io/debezium/operator/dependent/DeploymentDependent.java @@ -13,12 +13,14 @@ import io.debezium.operator.DebeziumServer; import io.debezium.operator.VersionProvider; +import io.debezium.operator.model.templates.ContainerTemplate; import io.debezium.operator.model.templates.PodTemplate; import io.fabric8.kubernetes.api.model.ConfigMapVolumeSourceBuilder; import io.fabric8.kubernetes.api.model.Container; import io.fabric8.kubernetes.api.model.ContainerBuilder; import io.fabric8.kubernetes.api.model.ContainerPortBuilder; import io.fabric8.kubernetes.api.model.EmptyDirVolumeSourceBuilder; +import io.fabric8.kubernetes.api.model.EnvVar; import io.fabric8.kubernetes.api.model.HTTPGetActionBuilder; import io.fabric8.kubernetes.api.model.IntOrString; import io.fabric8.kubernetes.api.model.LabelSelectorBuilder; @@ -117,6 +119,7 @@ protected Deployment desired(DebeziumServer primary, Context con .build(); addPodTemplateConfiguration(templates.getPod(), deployment); + addContainerTemplateConfiguration(templates.getContainer(), deployment); addExternalEnvVariables(primary, deployment); addExternalVolumes(primary, deployment); return deployment; @@ -158,6 +161,22 @@ private void addExternalVolumes(DebeziumServer primary, Deployment deployment) { containers.forEach(container -> container.getVolumeMounts().addAll(volumeMounts)); } + private void addContainerTemplateConfiguration(ContainerTemplate template, Deployment deployment) { + var containerEnv = template.getEnv() + .stream() + .map(ce -> new EnvVar(ce.getName(), ce.getValue(), null)) + .toList(); + + var pod = deployment.getSpec().getTemplate(); + var containers = pod.getSpec().getContainers(); + + containers.forEach(container -> { + container.getEnv().addAll(containerEnv); + container.setSecurityContext(template.getSecurityContext()); + container.setResources(template.getResources()); + }); + } + private Volume desiredDataVolume(DebeziumServer primary) { var storageConfig = primary.getSpec().getStorage(); var builder = new VolumeBuilder().withName(DATA_VOLUME_NAME); diff --git a/src/main/java/io/debezium/operator/model/Templates.java b/src/main/java/io/debezium/operator/model/Templates.java index 0f354df..7a66b2f 100644 --- a/src/main/java/io/debezium/operator/model/Templates.java +++ b/src/main/java/io/debezium/operator/model/Templates.java @@ -6,16 +6,22 @@ package io.debezium.operator.model; import com.fasterxml.jackson.annotation.JsonPropertyDescription; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import io.debezium.operator.model.templates.ContainerTemplate; import io.debezium.operator.model.templates.PodTemplate; +@JsonPropertyOrder({ "container", "pod" }) public class Templates { + @JsonPropertyDescription("Container template") + private ContainerTemplate container; @JsonPropertyDescription("Pod template.") private PodTemplate pod; public Templates() { this.pod = new PodTemplate(); + this.container = new ContainerTemplate(); } public PodTemplate getPod() { @@ -25,4 +31,12 @@ public PodTemplate getPod() { public void setPod(PodTemplate pod) { this.pod = pod; } + + public ContainerTemplate getContainer() { + return container; + } + + public void setContainer(ContainerTemplate container) { + this.container = container; + } } diff --git a/src/main/java/io/debezium/operator/model/templates/ContainerEnvVar.java b/src/main/java/io/debezium/operator/model/templates/ContainerEnvVar.java new file mode 100644 index 0000000..56a28dd --- /dev/null +++ b/src/main/java/io/debezium/operator/model/templates/ContainerEnvVar.java @@ -0,0 +1,36 @@ +/* + * Copyright Debezium Authors. + * + * Licensed under the Apache Software License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.debezium.operator.model.templates; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyDescription; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonPropertyOrder({ "name", "value" }) +public class ContainerEnvVar { + @JsonPropertyDescription("The environment variable name.") + @JsonProperty(required = true) + private String name; + @JsonPropertyDescription("The environment variable value.") + @JsonProperty(required = true) + private String value; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/src/main/java/io/debezium/operator/model/templates/ContainerTemplate.java b/src/main/java/io/debezium/operator/model/templates/ContainerTemplate.java new file mode 100644 index 0000000..69a40ab --- /dev/null +++ b/src/main/java/io/debezium/operator/model/templates/ContainerTemplate.java @@ -0,0 +1,56 @@ +/* + * Copyright Debezium Authors. + * + * Licensed under the Apache Software License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.debezium.operator.model.templates; + +import java.io.Serializable; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonPropertyDescription; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import io.fabric8.kubernetes.api.model.ResourceRequirements; +import io.fabric8.kubernetes.api.model.SecurityContext; + +@JsonPropertyOrder({ "resources", "securityContext" }) +@JsonInclude(JsonInclude.Include.NON_DEFAULT) +public class ContainerTemplate implements Serializable { + public static final long serialVersionUID = 1L; + + @JsonPropertyDescription("Environment variables applied to the container.") + private List env = List.of(); + @JsonPropertyDescription("CPU and memory resource requirements.") + @JsonInclude(JsonInclude.Include.NON_NULL) + private ResourceRequirements resources; + + @JsonPropertyDescription("Container security context.") + @JsonInclude(JsonInclude.Include.NON_NULL) + private SecurityContext securityContext; + + public SecurityContext getSecurityContext() { + return securityContext; + } + + public void setSecurityContext(SecurityContext securityContext) { + this.securityContext = securityContext; + } + + public ResourceRequirements getResources() { + return resources; + } + + public void setResources(ResourceRequirements resources) { + this.resources = resources; + } + + public List getEnv() { + return env; + } + + public void setEnv(List env) { + this.env = env; + } +} diff --git a/src/main/java/io/debezium/operator/model/templates/PodTemplate.java b/src/main/java/io/debezium/operator/model/templates/PodTemplate.java index b696aad..0c0f025 100644 --- a/src/main/java/io/debezium/operator/model/templates/PodTemplate.java +++ b/src/main/java/io/debezium/operator/model/templates/PodTemplate.java @@ -5,6 +5,7 @@ */ package io.debezium.operator.model.templates; +import java.io.Serializable; import java.util.List; import com.fasterxml.jackson.annotation.JsonInclude; @@ -17,7 +18,9 @@ @JsonPropertyOrder({ "metadata", "imagePullSecrets", "affinity" }) @JsonInclude(JsonInclude.Include.NON_DEFAULT) -public class PodTemplate implements HasMetadataTemplate { +public class PodTemplate implements HasMetadataTemplate, Serializable { + + public static final long serialVersionUID = 1L; @JsonPropertyDescription("Metadata applied to the resource.") private MetadataTemplate metadata = new MetadataTemplate(); From 3f433e33f9780f65dcfbc37924a7daa1379500e2 Mon Sep 17 00:00:00 2001 From: Jakub Cechacek Date: Mon, 23 Oct 2023 10:59:24 +0200 Subject: [PATCH 2/2] DBZ-7052 Updated CR reference in README --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index 9e1724d..71dfe8b 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,20 @@ spec: runtime: env: EnvFromSource array # https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#envfromsource-v1-core volumes: Volume array # https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#volume-v1-core + templates: + container: + env: + - name: String + value: String + resources: # https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#resourcerequirements-v1-core + securityContext: # https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core + pod: + metadata: + annotations: Map + labels: Map + imagePullSecrets: List # https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#localobjectreference-v1-core + affinity: # https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#affinity-v1-core + securityContext: # https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core quarkus: config: # quarkus properties