From 1e1b2858ae2ecd71c59cf56f5c7bef25d3641aaf Mon Sep 17 00:00:00 2001 From: jcechace Date: Thu, 3 Aug 2023 12:19:38 +0200 Subject: [PATCH] DBZ-6738 Suport for watching all namespaces with OLM installation --- README.md | 7 +- k8/kubernetes.yml | 31 ++++--- pom.xml | 31 ++++++- .../operator/DebeziumCsvMetadata.java | 81 +++++++++++++++++++ .../operator/DebeziumServerReconciler.java | 7 +- .../dependent/RoleBindingDependent.java | 14 ++-- .../operator/dependent/RoleDependent.java | 38 +++++++++ .../dependent/ServiceAccountDependent.java | 2 +- src/main/kubernetes/debezium-icon.svg | 1 + 9 files changed, 185 insertions(+), 27 deletions(-) create mode 100644 src/main/java/io/debezium/operator/DebeziumCsvMetadata.java create mode 100644 src/main/java/io/debezium/operator/dependent/RoleDependent.java create mode 100644 src/main/kubernetes/debezium-icon.svg diff --git a/README.md b/README.md index 051118d..9e1724d 100644 --- a/README.md +++ b/README.md @@ -3,14 +3,15 @@ Debezium operator provides an easy way to run the Debezium Server on Kubernetes or Openshift. ## Installation steps - -The debezium operator currently support per namespace installation. To install the operator to your kubernetes cluster, +The debezium operator currently support only per namespace installation unless installing via OLM. To install the operator to your kubernetes cluster, simply create the descriptors available in the `k8` directory. ```bash -kubectl create -f k8/ -n $NAMESPACE +kubectl create -f k8/ -n $NAMESPACE ``` +_Note: In the future the operator will support OLM and Helm chart installations._ + ### Quickstart Example The `exmaples/postgres` directory contains an example deployment of debezium server with PostgreSQL source and kafka diff --git a/k8/kubernetes.yml b/k8/kubernetes.yml index 9d5fe4e..171c7a9 100644 --- a/k8/kubernetes.yml +++ b/k8/kubernetes.yml @@ -3,8 +3,8 @@ apiVersion: v1 kind: ServiceAccount metadata: labels: - app.kubernetes.io/name: debezium-operator app.kubernetes.io/managed-by: quarkus + app.kubernetes.io/name: debezium-operator name: debezium-operator --- apiVersion: rbac.authorization.k8s.io/v1 @@ -49,10 +49,10 @@ rules: - get - list - watch - - create - patch - update - delete + - create - apiGroups: - rbac.authorization.k8s.io resources: @@ -61,10 +61,22 @@ rules: - get - list - watch + - patch + - update + - delete - create + - apiGroups: + - rbac.authorization.k8s.io + resources: + - roles + verbs: + - get + - list + - watch - patch - update - delete + - create - apiGroups: - "" resources: @@ -73,10 +85,10 @@ rules: - get - list - watch - - create - patch - update - delete + - create - apiGroups: - apps resources: @@ -85,10 +97,10 @@ rules: - get - list - watch - - create - patch - update - delete + - create --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding @@ -135,10 +147,6 @@ metadata: name: debezium-operator spec: ports: - - name: https - port: 443 - protocol: TCP - targetPort: 8443 - name: http port: 80 protocol: TCP @@ -151,8 +159,8 @@ apiVersion: apps/v1 kind: Deployment metadata: labels: - app.kubernetes.io/name: debezium-operator app.kubernetes.io/managed-by: quarkus + app.kubernetes.io/name: debezium-operator name: debezium-operator spec: replicas: 1 @@ -162,8 +170,8 @@ spec: template: metadata: labels: - app.kubernetes.io/name: debezium-operator app.kubernetes.io/managed-by: quarkus + app.kubernetes.io/name: debezium-operator spec: containers: - env: @@ -188,9 +196,6 @@ spec: - containerPort: 8080 name: http protocol: TCP - - containerPort: 8443 - name: https - protocol: TCP readinessProbe: failureThreshold: 3 httpGet: diff --git a/pom.xml b/pom.xml index aaff174..4ccaace 100644 --- a/pom.xml +++ b/pom.xml @@ -22,6 +22,7 @@ ${project.version} + ${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.x 3.11.0 17 @@ -29,9 +30,9 @@ UTF-8 UTF-8 quarkus-bom - io.quarkus.platform - 3.0.1.Final - 6.1.0 + io.quarkus + 3.2.4.Final + 6.3.0 true 3.0.0 3.24.2 @@ -39,7 +40,6 @@ false ${project.artifactId} - alpha quay.io debezium operator @@ -120,6 +120,20 @@ + + org.codehaus.mojo + build-helper-maven-plugin + 3.4.0 + + + initialize + parse-version + + parse-version + + + + ${quarkus.platform.group-id} quarkus-maven-plugin @@ -194,6 +208,15 @@ stable ${project.parent.version} + debezium-${version.debezium.channel} + + + + + + olmStable + + debezium-stable,debezium-${version.debezium.channel} diff --git a/src/main/java/io/debezium/operator/DebeziumCsvMetadata.java b/src/main/java/io/debezium/operator/DebeziumCsvMetadata.java new file mode 100644 index 0000000..9921757 --- /dev/null +++ b/src/main/java/io/debezium/operator/DebeziumCsvMetadata.java @@ -0,0 +1,81 @@ +/* + * 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; + +import io.quarkiverse.operatorsdk.bundle.runtime.CSVMetadata; +import io.quarkiverse.operatorsdk.bundle.runtime.CSVMetadata.Annotations; +import io.quarkiverse.operatorsdk.bundle.runtime.CSVMetadata.Icon; +import io.quarkiverse.operatorsdk.bundle.runtime.CSVMetadata.InstallMode; +import io.quarkiverse.operatorsdk.bundle.runtime.CSVMetadata.Link; +import io.quarkiverse.operatorsdk.bundle.runtime.CSVMetadata.Maintainer; +import io.quarkiverse.operatorsdk.bundle.runtime.CSVMetadata.Provider; +import io.quarkiverse.operatorsdk.bundle.runtime.SharedCSVMetadata; + +// @formatter:off +@CSVMetadata( + name = "debezium-operator", + displayName = "Debezium Operator", + version = "DBZOP_NEXT", replaces = "DBZOP_REPLACES", + icon = @Icon(fileName = "debezium-icon.svg"), + provider = @Provider(name = "Debezium Authors", url = "https://debezium.io/"), + maintainers = @Maintainer(name = "Debezium Authors", email = "debezium@googlegroups.com"), + keywords = { + "Debezium", + "CDC", + "Data", + "Streaming"}, + links = { + @Link(url = "https://debezium.io/", name = "Debezium"), + @Link(url = "https://debezium.io/documentation/reference/stable/", name = "Documentation"), + @Link(url = "debezium.zulipchat.com", name = "Debezium Zulip Chat")}, + installModes = { + @InstallMode(type = "OwnNamespace"), + @InstallMode(type = "SingleNamespace"), + @InstallMode(type = "AllNamespaces"), + @InstallMode(type = "MultiNamespace")}, + annotations = @Annotations( + capabilities = "Basic Install", + categories = "Big Data, Database, Integration & Delivery, Streaming & Messaging", + containerImage = "DBZOP_IMAGE_PULL_URL:DBZOP_NEXT", + others = { + @Annotations.Annotation( + name = "support", + value = "Debezium Authors"), + @Annotations.Annotation( + name = "description", + value = "An Operator for installing and managing Debezium")}, + almExamples =""" + [ + { + apiVersion: debezium.io/v1alpha1 + kind: DebeziumServer + metadata: + name: debezium-test + spec: + quarkus: + config: + log.console.json: false + sink: + type: kafka + config: + producer.bootstrap.servers: dbz-kafka-kafka-bootstrap.debezium:9092 + producer.key.serializer: org.apache.kafka.common.serialization.StringSerializer + producer.value.serializer: org.apache.kafka.common.serialization.StringSerializer + source: + class: io.debezium.connector.mongodb.MongoDbConnector + config: + topic.prefix: dbserver1 + offset.storage.file.filename: /debezium/data/offsets.dat + database.history: io.debezium.relational.history.FileDatabaseHistory + mongodb.connection.string: mongodb://debezium:dbz@mongo.debezium:27017/?replicaSet=rs0 + } + ] + """), + description = "Debezium is an open source distributed platform for change data capture. " + + "Start it up, point it at your databases, and your apps can start responding " + + "to all of the inserts, updates, and deletes that other apps commit to your databases") +public class DebeziumCsvMetadata implements SharedCSVMetadata { +} diff --git a/src/main/java/io/debezium/operator/DebeziumServerReconciler.java b/src/main/java/io/debezium/operator/DebeziumServerReconciler.java index 641d625..1add5bb 100644 --- a/src/main/java/io/debezium/operator/DebeziumServerReconciler.java +++ b/src/main/java/io/debezium/operator/DebeziumServerReconciler.java @@ -12,6 +12,7 @@ import io.debezium.operator.dependent.ConfigMapDependent; import io.debezium.operator.dependent.DeploymentDependent; import io.debezium.operator.dependent.RoleBindingDependent; +import io.debezium.operator.dependent.RoleDependent; import io.debezium.operator.dependent.ServiceAccountDependent; import io.debezium.operator.dependent.conditions.DeploymentReady; import io.debezium.operator.model.status.Condition; @@ -26,7 +27,11 @@ @ControllerConfiguration(namespaces = Constants.WATCH_CURRENT_NAMESPACE, name = "debeziumserver", dependents = { @Dependent(name = "service-account", type = ServiceAccountDependent.class), - @Dependent(name = "role-binding", type = RoleBindingDependent.class, dependsOn = { "service-account" }), + @Dependent(name = "role", type = RoleDependent.class), + @Dependent(name = "role-binding", type = RoleBindingDependent.class, dependsOn = { + "service-account", + "role" + }), @Dependent(name = "config", type = ConfigMapDependent.class), @Dependent(name = "deployment", type = DeploymentDependent.class, dependsOn = { "config", diff --git a/src/main/java/io/debezium/operator/dependent/RoleBindingDependent.java b/src/main/java/io/debezium/operator/dependent/RoleBindingDependent.java index 03f4208..46cfc98 100644 --- a/src/main/java/io/debezium/operator/dependent/RoleBindingDependent.java +++ b/src/main/java/io/debezium/operator/dependent/RoleBindingDependent.java @@ -8,6 +8,7 @@ import io.debezium.operator.DebeziumServer; import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; import io.fabric8.kubernetes.api.model.ServiceAccount; +import io.fabric8.kubernetes.api.model.rbac.Role; import io.fabric8.kubernetes.api.model.rbac.RoleBinding; import io.fabric8.kubernetes.api.model.rbac.RoleBindingBuilder; import io.fabric8.kubernetes.api.model.rbac.RoleRefBuilder; @@ -17,8 +18,7 @@ public class RoleBindingDependent extends CRUDKubernetesDependentResource { - public static final String ROLE_NAME = "config-view"; - public static final String BINDING_NAME = "%s-" + ROLE_NAME; + public static final String BINDING_NAME = "%s-role-binding"; public RoleBindingDependent() { super(RoleBinding.class); @@ -30,14 +30,18 @@ protected RoleBinding desired(DebeziumServer primary, Context co .map(r -> r.getMetadata().getName()) .orElseThrow(); + var role = context.getSecondaryResource(Role.class) + .map(r -> r.getMetadata().getName()) + .orElseThrow(); + return new RoleBindingBuilder() .withMetadata(new ObjectMetaBuilder() - .withName(BINDING_NAME.formatted(sa)) + .withName(BINDING_NAME.formatted(role)) .withNamespace(primary.getMetadata().getNamespace()) .build()) .withRoleRef(new RoleRefBuilder() - .withKind("ClusterRole") - .withName(ROLE_NAME) + .withKind("Role") + .withName(role) .build()) .withSubjects(new SubjectBuilder() .withKind("ServiceAccount") diff --git a/src/main/java/io/debezium/operator/dependent/RoleDependent.java b/src/main/java/io/debezium/operator/dependent/RoleDependent.java new file mode 100644 index 0000000..17d2300 --- /dev/null +++ b/src/main/java/io/debezium/operator/dependent/RoleDependent.java @@ -0,0 +1,38 @@ +/* + * 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.dependent; + +import io.debezium.operator.DebeziumServer; +import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; +import io.fabric8.kubernetes.api.model.rbac.PolicyRuleBuilder; +import io.fabric8.kubernetes.api.model.rbac.Role; +import io.fabric8.kubernetes.api.model.rbac.RoleBuilder; +import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.processing.dependent.kubernetes.CRUDKubernetesDependentResource; + +public class RoleDependent + extends CRUDKubernetesDependentResource { + public static final String ROLE_NAME = "%s-config-view"; + + public RoleDependent() { + super(Role.class); + } + + @Override + protected Role desired(DebeziumServer primary, Context context) { + return new RoleBuilder() + .withMetadata(new ObjectMetaBuilder() + .withName(ROLE_NAME.formatted(primary.getMetadata().getName())) + .withNamespace(primary.getMetadata().getNamespace()) + .build()) + .withRules(new PolicyRuleBuilder() + .withApiGroups("") + .withResources("secrets", "configmaps") + .withVerbs("get", "list", "watch") + .build()) + .build(); + } +} diff --git a/src/main/java/io/debezium/operator/dependent/ServiceAccountDependent.java b/src/main/java/io/debezium/operator/dependent/ServiceAccountDependent.java index 5d018a3..c44ba9e 100644 --- a/src/main/java/io/debezium/operator/dependent/ServiceAccountDependent.java +++ b/src/main/java/io/debezium/operator/dependent/ServiceAccountDependent.java @@ -15,7 +15,7 @@ public class ServiceAccountDependent extends CRUDKubernetesDependentResource { - public static final String SA_NAME = "%s-debezium-server"; + public static final String SA_NAME = "%s-sa"; public ServiceAccountDependent() { super(ServiceAccount.class); diff --git a/src/main/kubernetes/debezium-icon.svg b/src/main/kubernetes/debezium-icon.svg new file mode 100644 index 0000000..aea8428 --- /dev/null +++ b/src/main/kubernetes/debezium-icon.svg @@ -0,0 +1 @@ +color \ No newline at end of file