From 31860e8b6fc1e2537cb869e61ee6ed414b161761 Mon Sep 17 00:00:00 2001 From: Thomas Sapelza Date: Wed, 25 Feb 2026 16:38:40 +0100 Subject: [PATCH 1/6] update to Quarkus 3.32.1 and update dependencies to latest versions --- gradle.properties | 4 ++-- gradle/libs.versions.toml | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/gradle.properties b/gradle.properties index f646d00..3b9d1fa 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,9 +7,9 @@ org.gradle.logging.level=INFO # Quarkus quarkusPluginId=io.quarkus -quarkusPluginVersion=3.31.2 +quarkusPluginVersion=3.32.1 # https://mvnrepository.com/artifact/io.quarkus.platform/quarkus-bom quarkusPlatformGroupId=io.quarkus.platform quarkusPlatformArtifactId=quarkus-bom -quarkusPlatformVersion=3.31.2 +quarkusPlatformVersion=3.32.1 systemProp.quarkus.analytics.disabled=true diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8242d32..14846fe 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] ## AboutBits Libraries ## -checkstyleConfig = "2.0.0-RC1" +checkstyleConfig = "2.0.0-RC2" # Axion Release Plugin # axionReleasePlugin = "1.21.1" @@ -9,15 +9,15 @@ axionReleasePlugin = "1.21.1" jooq = "3.20.11" jSpecify = "1.0.0" lombok = "1.18.42" -postgresql = "42.7.9" -quarkiverse-helm = "1.2.7" +postgresql = "42.7.10" +quarkiverse-helm = "1.3.0" scram-client = "3.2" ## Testing ## assertj = "3.27.7" -checkstyle = "13.1.0" -datafaker = "2.5.3" -errorProne = "2.46.0" +checkstyle = "13.2.0" +datafaker = "2.5.4" +errorProne = "2.47.0" errorPronePlugin = "5.0.0" nullAway = "0.13.1" From 841b02d04b71eef300d8714ce6a5aacbe2226dbc Mon Sep 17 00:00:00 2001 From: Thomas Sapelza Date: Thu, 26 Feb 2026 07:57:11 +0100 Subject: [PATCH 2/6] validate K8s resource references against the RFC 1123 hostname format Kubernetes uses --- operator/build.gradle.kts | 1 + .../postgresql/core/ClusterReference.java | 2 + .../core/HostnameRFC1123Customizer.java | 81 +++++++++++++++++++ .../aboutbits/postgresql/core/SecretRef.java | 2 + .../ClusterConnectionSpec.java | 3 + 5 files changed, 89 insertions(+) create mode 100644 operator/src/main/java/it/aboutbits/postgresql/core/HostnameRFC1123Customizer.java diff --git a/operator/build.gradle.kts b/operator/build.gradle.kts index cbe6c1f..1f2f0bb 100644 --- a/operator/build.gradle.kts +++ b/operator/build.gradle.kts @@ -20,6 +20,7 @@ dependencies { * Fabric8 Kubernetes Client */ implementation("io.fabric8:generator-annotations") + implementation("io.fabric8:crd-generator-api-v2") /** * jOOQ diff --git a/operator/src/main/java/it/aboutbits/postgresql/core/ClusterReference.java b/operator/src/main/java/it/aboutbits/postgresql/core/ClusterReference.java index b1b9a7d..237d9de 100644 --- a/operator/src/main/java/it/aboutbits/postgresql/core/ClusterReference.java +++ b/operator/src/main/java/it/aboutbits/postgresql/core/ClusterReference.java @@ -1,5 +1,6 @@ package it.aboutbits.postgresql.core; +import io.fabric8.crdv2.generator.v1.SchemaCustomizer; import io.fabric8.generator.annotation.Required; import io.fabric8.generator.annotation.ValidationRule; import lombok.Getter; @@ -10,6 +11,7 @@ @NullMarked @Getter @Setter +@SchemaCustomizer(HostnameRFC1123Customizer.class) public class ClusterReference { @Required @ValidationRule( diff --git a/operator/src/main/java/it/aboutbits/postgresql/core/HostnameRFC1123Customizer.java b/operator/src/main/java/it/aboutbits/postgresql/core/HostnameRFC1123Customizer.java new file mode 100644 index 0000000..6ec967b --- /dev/null +++ b/operator/src/main/java/it/aboutbits/postgresql/core/HostnameRFC1123Customizer.java @@ -0,0 +1,81 @@ +package it.aboutbits.postgresql.core; + +import io.fabric8.crdv2.generator.v1.SchemaCustomizer; +import io.fabric8.kubernetes.api.model.apiextensions.v1.JSONSchemaProps; +import io.fabric8.kubernetes.client.utils.KubernetesSerialization; +import org.jspecify.annotations.NullMarked; + +import java.util.Arrays; +import java.util.Set; +import java.util.stream.Collectors; + +/// A [SchemaCustomizer.Customizer] that sets the `format` of string properties +/// to `"hostname"` (RFC 1123) in the generated CRD JSON Schema. +/// +/// This customizer is intended to be used with the +/// [@SchemaCustomizer][SchemaCustomizer] annotation on a class whose properties +/// should be validated as RFC 1123 hostnames by the Kubernetes API server. +/// +/// ### Behavior +/// +/// - If `input` is **blank** (the default), the `"hostname"` format +/// is applied to **all** string properties of the annotated class. +/// - If `input` contains a **comma-separated list** of field names, +/// the format is applied **only** to the specified properties. +/// +/// ### Usage examples +/// +/// **Apply to all string properties:** +/// +/// ```java +/// @SchemaCustomizer(HostnameRFC1123Customizer.class) +/// public class SecretRef { +/// private String name = ""; // gets format: "hostname" +/// private String namespace; // gets format: "hostname" +/// } +/// ``` +/// +/// **Apply to specific properties only:** +/// +/// ```java +/// @SchemaCustomizer(value = HostnameRFC1123Customizer.class, input = "host") +/// public class ClusterConnectionSpec { +/// private String host = ""; // gets format: "hostname" +/// private String anotherHost = ""; // gets format: "hostname" +/// private String database = ""; // unchanged +/// } +/// ``` +/// +/// @see SchemaCustomizer +/// @see SchemaCustomizer.Customizer +@NullMarked +public class HostnameRFC1123Customizer implements SchemaCustomizer.Customizer { + @Override + public JSONSchemaProps apply( + JSONSchemaProps jsonSchemaProps, + String input, + KubernetesSerialization kubernetesSerialization + ) { + var properties = jsonSchemaProps.getProperties(); + if (properties == null) { + return jsonSchemaProps; + } + + var targetFields = input.isBlank() + ? Set.of() + : Arrays.stream(input.split(",")) + .map(String::trim) + .collect(Collectors.toSet()); + + for (var entry : properties.entrySet()) { + var prop = entry.getValue(); + if ("string".equals(prop.getType())) { + if (targetFields.isEmpty() || targetFields.contains(entry.getKey())) { + prop.setFormat("hostname"); + } + } + } + + return jsonSchemaProps; + } +} diff --git a/operator/src/main/java/it/aboutbits/postgresql/core/SecretRef.java b/operator/src/main/java/it/aboutbits/postgresql/core/SecretRef.java index 9e4b57a..6f71b88 100644 --- a/operator/src/main/java/it/aboutbits/postgresql/core/SecretRef.java +++ b/operator/src/main/java/it/aboutbits/postgresql/core/SecretRef.java @@ -1,5 +1,6 @@ package it.aboutbits.postgresql.core; +import io.fabric8.crdv2.generator.v1.SchemaCustomizer; import io.fabric8.generator.annotation.Required; import io.fabric8.generator.annotation.ValidationRule; import lombok.Getter; @@ -10,6 +11,7 @@ @NullMarked @Getter @Setter +@SchemaCustomizer(HostnameRFC1123Customizer.class) public class SecretRef { @Required @ValidationRule( diff --git a/operator/src/main/java/it/aboutbits/postgresql/crd/clusterconnection/ClusterConnectionSpec.java b/operator/src/main/java/it/aboutbits/postgresql/crd/clusterconnection/ClusterConnectionSpec.java index 65b4ec8..8e5fc11 100644 --- a/operator/src/main/java/it/aboutbits/postgresql/crd/clusterconnection/ClusterConnectionSpec.java +++ b/operator/src/main/java/it/aboutbits/postgresql/crd/clusterconnection/ClusterConnectionSpec.java @@ -1,10 +1,12 @@ package it.aboutbits.postgresql.crd.clusterconnection; +import io.fabric8.crdv2.generator.v1.SchemaCustomizer; import io.fabric8.generator.annotation.Max; import io.fabric8.generator.annotation.Min; import io.fabric8.generator.annotation.Required; import io.fabric8.generator.annotation.ValidationRule; import it.aboutbits.postgresql.core.SecretRef; +import it.aboutbits.postgresql.core.HostnameRFC1123Customizer; import lombok.Getter; import lombok.Setter; import org.jspecify.annotations.NullMarked; @@ -15,6 +17,7 @@ @NullMarked @Getter @Setter +@SchemaCustomizer(value = HostnameRFC1123Customizer.class, input = "host") public class ClusterConnectionSpec { @Required @ValidationRule( From 638359c428fe9105a7f6e820a522b08c5c80d869 Mon Sep 17 00:00:00 2001 From: Thomas Sapelza Date: Thu, 26 Feb 2026 09:32:06 +0100 Subject: [PATCH 3/6] fix the test by having a own SchemaCustomizer for Kubernetes names --- .../postgresql/core/ClusterReference.java | 3 +- .../aboutbits/postgresql/core/SecretRef.java | 3 +- .../HostCustomizer.java} | 49 ++++++---- .../KubernetesNameCustomizer.java | 90 +++++++++++++++++++ .../ClusterConnectionSpec.java | 4 +- .../PostgreSQLInstanceReadinessCheckTest.java | 36 +++++++- 6 files changed, 161 insertions(+), 24 deletions(-) rename operator/src/main/java/it/aboutbits/postgresql/core/{HostnameRFC1123Customizer.java => schema_customizer/HostCustomizer.java} (55%) create mode 100644 operator/src/main/java/it/aboutbits/postgresql/core/schema_customizer/KubernetesNameCustomizer.java diff --git a/operator/src/main/java/it/aboutbits/postgresql/core/ClusterReference.java b/operator/src/main/java/it/aboutbits/postgresql/core/ClusterReference.java index 237d9de..b5aaa24 100644 --- a/operator/src/main/java/it/aboutbits/postgresql/core/ClusterReference.java +++ b/operator/src/main/java/it/aboutbits/postgresql/core/ClusterReference.java @@ -3,6 +3,7 @@ import io.fabric8.crdv2.generator.v1.SchemaCustomizer; import io.fabric8.generator.annotation.Required; import io.fabric8.generator.annotation.ValidationRule; +import it.aboutbits.postgresql.core.schema_customizer.KubernetesNameCustomizer; import lombok.Getter; import lombok.Setter; import org.jspecify.annotations.NullMarked; @@ -11,7 +12,7 @@ @NullMarked @Getter @Setter -@SchemaCustomizer(HostnameRFC1123Customizer.class) +@SchemaCustomizer(KubernetesNameCustomizer.class) public class ClusterReference { @Required @ValidationRule( diff --git a/operator/src/main/java/it/aboutbits/postgresql/core/SecretRef.java b/operator/src/main/java/it/aboutbits/postgresql/core/SecretRef.java index 6f71b88..8c3bacf 100644 --- a/operator/src/main/java/it/aboutbits/postgresql/core/SecretRef.java +++ b/operator/src/main/java/it/aboutbits/postgresql/core/SecretRef.java @@ -3,6 +3,7 @@ import io.fabric8.crdv2.generator.v1.SchemaCustomizer; import io.fabric8.generator.annotation.Required; import io.fabric8.generator.annotation.ValidationRule; +import it.aboutbits.postgresql.core.schema_customizer.KubernetesNameCustomizer; import lombok.Getter; import lombok.Setter; import org.jspecify.annotations.NullMarked; @@ -11,7 +12,7 @@ @NullMarked @Getter @Setter -@SchemaCustomizer(HostnameRFC1123Customizer.class) +@SchemaCustomizer(KubernetesNameCustomizer.class) public class SecretRef { @Required @ValidationRule( diff --git a/operator/src/main/java/it/aboutbits/postgresql/core/HostnameRFC1123Customizer.java b/operator/src/main/java/it/aboutbits/postgresql/core/schema_customizer/HostCustomizer.java similarity index 55% rename from operator/src/main/java/it/aboutbits/postgresql/core/HostnameRFC1123Customizer.java rename to operator/src/main/java/it/aboutbits/postgresql/core/schema_customizer/HostCustomizer.java index 6ec967b..64d5717 100644 --- a/operator/src/main/java/it/aboutbits/postgresql/core/HostnameRFC1123Customizer.java +++ b/operator/src/main/java/it/aboutbits/postgresql/core/schema_customizer/HostCustomizer.java @@ -1,4 +1,4 @@ -package it.aboutbits.postgresql.core; +package it.aboutbits.postgresql.core.schema_customizer; import io.fabric8.crdv2.generator.v1.SchemaCustomizer; import io.fabric8.kubernetes.api.model.apiextensions.v1.JSONSchemaProps; @@ -6,15 +6,17 @@ import org.jspecify.annotations.NullMarked; import java.util.Arrays; +import java.util.List; import java.util.Set; import java.util.stream.Collectors; /// A [SchemaCustomizer.Customizer] that sets the `format` of string properties -/// to `"hostname"` (RFC 1123) in the generated CRD JSON Schema. +/// to `{"anyOf":[{"format":"hostname"},{"format":"ipv4"},{"format":"ipv6"}]}` +/// in the generated CRD JSON Schema. /// /// This customizer is intended to be used with the /// [@SchemaCustomizer][SchemaCustomizer] annotation on a class whose properties -/// should be validated as RFC 1123 hostnames by the Kubernetes API server. +/// should be validated to valid hosts defined. /// /// ### Behavior /// @@ -28,28 +30,28 @@ /// **Apply to all string properties:** /// /// ```java -/// @SchemaCustomizer(HostnameRFC1123Customizer.class) -/// public class SecretRef { -/// private String name = ""; // gets format: "hostname" -/// private String namespace; // gets format: "hostname" +/// @SchemaCustomizer(value = HostCustomizer.class) +/// public class ClusterConnectionSpec { +/// private String host = ""; // gets custom format +/// private String anotherHost = ""; // gets custom format /// } /// ``` /// /// **Apply to specific properties only:** /// /// ```java -/// @SchemaCustomizer(value = HostnameRFC1123Customizer.class, input = "host") +/// @SchemaCustomizer(value = HostCustomizer.class, input = "host,anotherHost") /// public class ClusterConnectionSpec { -/// private String host = ""; // gets format: "hostname" -/// private String anotherHost = ""; // gets format: "hostname" -/// private String database = ""; // unchanged +/// private String host = ""; // gets custom format +/// private String anotherHost = ""; // gets custom format +/// private String unchangedHost = ""; // unchanged /// } /// ``` /// /// @see SchemaCustomizer /// @see SchemaCustomizer.Customizer @NullMarked -public class HostnameRFC1123Customizer implements SchemaCustomizer.Customizer { +public class HostCustomizer implements SchemaCustomizer.Customizer { @Override public JSONSchemaProps apply( JSONSchemaProps jsonSchemaProps, @@ -69,10 +71,25 @@ public JSONSchemaProps apply( for (var entry : properties.entrySet()) { var prop = entry.getValue(); - if ("string".equals(prop.getType())) { - if (targetFields.isEmpty() || targetFields.contains(entry.getKey())) { - prop.setFormat("hostname"); - } + if ("string".equals(prop.getType()) + && (targetFields.isEmpty() || targetFields.contains(entry.getKey())) + ) { + prop.setFormat(null); + + var hostnameProp = new JSONSchemaProps(); + hostnameProp.setFormat("hostname"); + + var ipv4Prop = new JSONSchemaProps(); + ipv4Prop.setFormat("ipv4"); + + var ipv6Prop = new JSONSchemaProps(); + ipv6Prop.setFormat("ipv6"); + + prop.setAnyOf(List.of( + hostnameProp, + ipv4Prop, + ipv6Prop + )); } } diff --git a/operator/src/main/java/it/aboutbits/postgresql/core/schema_customizer/KubernetesNameCustomizer.java b/operator/src/main/java/it/aboutbits/postgresql/core/schema_customizer/KubernetesNameCustomizer.java new file mode 100644 index 0000000..baf3f5d --- /dev/null +++ b/operator/src/main/java/it/aboutbits/postgresql/core/schema_customizer/KubernetesNameCustomizer.java @@ -0,0 +1,90 @@ +package it.aboutbits.postgresql.core.schema_customizer; + +import io.fabric8.crdv2.generator.v1.SchemaCustomizer; +import io.fabric8.kubernetes.api.model.apiextensions.v1.JSONSchemaProps; +import io.fabric8.kubernetes.client.utils.KubernetesSerialization; +import org.jspecify.annotations.NullMarked; + +import java.util.Arrays; +import java.util.Set; +import java.util.stream.Collectors; + +/// A [SchemaCustomizer.Customizer] that adds a Kubernetes name validation +/// `pattern` (RFC 1123 DNS label) to string properties in the generated CRD +/// JSON Schema. +/// +/// The pattern enforces: +/// - Contain at most 63 characters +/// - Contain only lowercase alphanumeric characters or '-' +/// - Start with an alphabetic character +/// - End with an alphanumeric character +/// +/// This customizer is intended to be used with the +/// [@SchemaCustomizer][SchemaCustomizer] annotation on a class whose string +/// properties represent Kubernetes resource names. +/// +/// ### Behavior +/// +/// - If `input` is **blank** (the default), the `"hostname"` format +/// is applied to **all** string properties of the annotated class. +/// - If `input` contains a **comma-separated list** of field names, +/// the format is applied **only** to the specified properties. +/// +/// ### Usage examples +/// +/// **Apply to all string properties:** +/// +/// ```java +/// @SchemaCustomizer(KubernetesNameCustomizer.class) +/// public class SecretRef { +/// private String name = ""; // gets pattern: Kubernetes name regex +/// private String namespace; // gets pattern: Kubernetes name regex +/// } +/// ``` +/// +/// **Apply to specific properties only:** +/// +/// ```java +/// @SchemaCustomizer(value = KubernetesNameCustomizer.class, input = "name,anotherName") +/// public class SecretRef { +/// private String name = ""; // gets pattern: Kubernetes name regex +/// private String anotherName = ""; // gets pattern: Kubernetes name regex +/// private String namespace; // unchanged +/// } +/// ``` +/// +/// @see SchemaCustomizer +/// @see SchemaCustomizer.Customizer +@NullMarked +public class KubernetesNameCustomizer implements SchemaCustomizer.Customizer { + static final String KUBERNETES_NAME_PATTERN = "^[a-z]([a-z0-9\\-]{0,61}[a-z0-9])?$"; + + @Override + public JSONSchemaProps apply( + JSONSchemaProps jsonSchemaProps, + String input, + KubernetesSerialization kubernetesSerialization + ) { + var properties = jsonSchemaProps.getProperties(); + if (properties == null) { + return jsonSchemaProps; + } + + var targetFields = input.isBlank() + ? Set.of() + : Arrays.stream(input.split(",")) + .map(String::trim) + .collect(Collectors.toSet()); + + for (var entry : properties.entrySet()) { + var prop = entry.getValue(); + if ("string".equals(prop.getType()) + && (targetFields.isEmpty() || targetFields.contains(entry.getKey())) + ) { + prop.setPattern(KUBERNETES_NAME_PATTERN); + } + } + + return jsonSchemaProps; + } +} diff --git a/operator/src/main/java/it/aboutbits/postgresql/crd/clusterconnection/ClusterConnectionSpec.java b/operator/src/main/java/it/aboutbits/postgresql/crd/clusterconnection/ClusterConnectionSpec.java index 8e5fc11..b4c472c 100644 --- a/operator/src/main/java/it/aboutbits/postgresql/crd/clusterconnection/ClusterConnectionSpec.java +++ b/operator/src/main/java/it/aboutbits/postgresql/crd/clusterconnection/ClusterConnectionSpec.java @@ -6,7 +6,7 @@ import io.fabric8.generator.annotation.Required; import io.fabric8.generator.annotation.ValidationRule; import it.aboutbits.postgresql.core.SecretRef; -import it.aboutbits.postgresql.core.HostnameRFC1123Customizer; +import it.aboutbits.postgresql.core.schema_customizer.HostCustomizer; import lombok.Getter; import lombok.Setter; import org.jspecify.annotations.NullMarked; @@ -17,7 +17,7 @@ @NullMarked @Getter @Setter -@SchemaCustomizer(value = HostnameRFC1123Customizer.class, input = "host") +@SchemaCustomizer(value = HostCustomizer.class, input = "host") public class ClusterConnectionSpec { @Required @ValidationRule( diff --git a/operator/src/test/java/it/aboutbits/postgresql/PostgreSQLInstanceReadinessCheckTest.java b/operator/src/test/java/it/aboutbits/postgresql/PostgreSQLInstanceReadinessCheckTest.java index 548a2e0..d2b7464 100644 --- a/operator/src/test/java/it/aboutbits/postgresql/PostgreSQLInstanceReadinessCheckTest.java +++ b/operator/src/test/java/it/aboutbits/postgresql/PostgreSQLInstanceReadinessCheckTest.java @@ -11,6 +11,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.util.Map; import java.util.Objects; import static org.assertj.core.api.Assertions.assertThat; @@ -67,13 +68,35 @@ void call_whenSomeConnectionsDown_shouldReturnDown() { given.one() .clusterConnection() .withName("db-1") - .returnFirst(); + .apply(); given.one() .clusterConnection() .withName("db-2") - .withHost("non-existent-host") - .returnFirst(); + .withHost("localhost") + .withPort(2345) // Wrong port + .apply(); + + given.one() + .clusterConnection() + .withName("db-3") + .withHost("127.0.0.1") + .withPort(2345) // Wrong port + .apply(); + + given.one() + .clusterConnection() + .withName("db-4") + .withHost("::1") + .withPort(2345) // Wrong port + .apply(); + + given.one() + .clusterConnection() + .withName("db-5") + .withHost("0:0:0:0:0:0:0:1") + .withPort(2345) // Wrong port + .apply(); var response = readinessCheck.call(); @@ -93,7 +116,12 @@ void call_whenSomeConnectionsDown_shouldReturnDown() { assertThat(dbStatus.toString()).startsWith("UP (PostgreSQL"); - assertThat(data).containsEntry("db-2", "DOWN"); + assertThat(data).containsAllEntriesOf(Map.of( + "db-2", "DOWN", + "db-3", "DOWN", + "db-4", "DOWN", + "db-5", "DOWN" + )); }); } } From acddd5ab593e87552ffb428fa2fb5f04c17acfb5 Mon Sep 17 00:00:00 2001 From: Thomas Sapelza Date: Thu, 26 Feb 2026 09:42:42 +0100 Subject: [PATCH 4/6] do not short-circuit the PostgreSQLInstanceReadinessCheck check once one instance is down --- .../postgresql/PostgreSQLInstanceReadinessCheck.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/operator/src/main/java/it/aboutbits/postgresql/PostgreSQLInstanceReadinessCheck.java b/operator/src/main/java/it/aboutbits/postgresql/PostgreSQLInstanceReadinessCheck.java index 20f16db..3b86277 100644 --- a/operator/src/main/java/it/aboutbits/postgresql/PostgreSQLInstanceReadinessCheck.java +++ b/operator/src/main/java/it/aboutbits/postgresql/PostgreSQLInstanceReadinessCheck.java @@ -30,10 +30,11 @@ public HealthCheckResponse call() { var connections = kubernetesClient.resources(ClusterConnection.class).list().getItems(); boolean allUp = connections.stream() - .allMatch(connection -> checkInstance( + .map(connection -> checkInstance( connection, builder - )); + )) + .reduce(true, Boolean::logicalAnd); return builder.status(allUp).build(); } From a0f9e2bb4aa80a1c00ff3142326bbf93cccd4cbe Mon Sep 17 00:00:00 2001 From: Thomas Sapelza Date: Thu, 26 Feb 2026 09:42:53 +0100 Subject: [PATCH 5/6] let the PostgreSQLContextFactory exception bubble up --- .../aboutbits/postgresql/core/PostgreSQLContextFactory.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/operator/src/main/java/it/aboutbits/postgresql/core/PostgreSQLContextFactory.java b/operator/src/main/java/it/aboutbits/postgresql/core/PostgreSQLContextFactory.java index fdb5bb8..216a4fe 100644 --- a/operator/src/main/java/it/aboutbits/postgresql/core/PostgreSQLContextFactory.java +++ b/operator/src/main/java/it/aboutbits/postgresql/core/PostgreSQLContextFactory.java @@ -5,6 +5,7 @@ import jakarta.enterprise.context.ApplicationScoped; import lombok.RequiredArgsConstructor; import org.jooq.CloseableDSLContext; +import org.jooq.exception.DataAccessException; import org.jooq.impl.DSL; import org.jspecify.annotations.NullMarked; @@ -21,7 +22,7 @@ public class PostgreSQLContextFactory { private final KubernetesClient kubernetesClient; /// Create a DSLContext with a JDBC connection to the PostgreSQL maintenance database. - public CloseableDSLContext getDSLContext(ClusterConnection clusterConnection) { + public CloseableDSLContext getDSLContext(ClusterConnection clusterConnection) throws DataAccessException { return getDSLContext( clusterConnection, clusterConnection.getSpec().getDatabase() @@ -32,7 +33,7 @@ public CloseableDSLContext getDSLContext(ClusterConnection clusterConnection) { public CloseableDSLContext getDSLContext( ClusterConnection clusterConnection, String database - ) { + ) throws DataAccessException { var credentials = kubernetesService.getSecretRefCredentials( kubernetesClient, clusterConnection From 23b6e70aa4c44525063cf301277c3e429d2529ad Mon Sep 17 00:00:00 2001 From: Thomas Sapelza Date: Thu, 26 Feb 2026 11:00:49 +0100 Subject: [PATCH 6/6] add explicit string max length check of 63 --- .../java/it/aboutbits/postgresql/core/ClusterReference.java | 3 +++ .../src/main/java/it/aboutbits/postgresql/core/SecretRef.java | 3 +++ 2 files changed, 6 insertions(+) diff --git a/operator/src/main/java/it/aboutbits/postgresql/core/ClusterReference.java b/operator/src/main/java/it/aboutbits/postgresql/core/ClusterReference.java index b5aaa24..735b444 100644 --- a/operator/src/main/java/it/aboutbits/postgresql/core/ClusterReference.java +++ b/operator/src/main/java/it/aboutbits/postgresql/core/ClusterReference.java @@ -1,6 +1,7 @@ package it.aboutbits.postgresql.core; import io.fabric8.crdv2.generator.v1.SchemaCustomizer; +import io.fabric8.generator.annotation.Max; import io.fabric8.generator.annotation.Required; import io.fabric8.generator.annotation.ValidationRule; import it.aboutbits.postgresql.core.schema_customizer.KubernetesNameCustomizer; @@ -15,6 +16,7 @@ @SchemaCustomizer(KubernetesNameCustomizer.class) public class ClusterReference { @Required + @Max(63) @ValidationRule( value = "self.trim().size() > 0", message = "The ClusterReference name must not be empty." @@ -22,6 +24,7 @@ public class ClusterReference { private String name = ""; @Nullable + @Max(63) @io.fabric8.generator.annotation.Nullable private String namespace; } diff --git a/operator/src/main/java/it/aboutbits/postgresql/core/SecretRef.java b/operator/src/main/java/it/aboutbits/postgresql/core/SecretRef.java index 8c3bacf..628dfca 100644 --- a/operator/src/main/java/it/aboutbits/postgresql/core/SecretRef.java +++ b/operator/src/main/java/it/aboutbits/postgresql/core/SecretRef.java @@ -1,6 +1,7 @@ package it.aboutbits.postgresql.core; import io.fabric8.crdv2.generator.v1.SchemaCustomizer; +import io.fabric8.generator.annotation.Max; import io.fabric8.generator.annotation.Required; import io.fabric8.generator.annotation.ValidationRule; import it.aboutbits.postgresql.core.schema_customizer.KubernetesNameCustomizer; @@ -15,6 +16,7 @@ @SchemaCustomizer(KubernetesNameCustomizer.class) public class SecretRef { @Required + @Max(63) @ValidationRule( value = "self.trim().size() > 0", message = "The SecretRef name must not be empty." @@ -26,6 +28,7 @@ public class SecretRef { * If it is null, it means the Secret is in the same namespace as the resource referencing it. */ @Nullable + @Max(63) @io.fabric8.generator.annotation.Nullable private String namespace; }