Skip to content

Commit 9f5d13c

Browse files
committed
reorder members and formatting
1 parent 26b9f53 commit 9f5d13c

3 files changed

Lines changed: 93 additions & 78 deletions

File tree

operator/src/main/java/it/aboutbits/postgresql/core/KubernetesService.java

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,12 @@
2020
@RequiredArgsConstructor
2121
@NullMarked
2222
public final class KubernetesService {
23-
private final ObjectMapper objectMapper;
24-
25-
/// The JSON file may carry more keys than we need, for example, the AWS Secrets Manager
26-
/// format also has `engine`, `host`, `port` and `dbname`. Unknown keys are ignored.
27-
@JsonIgnoreProperties(ignoreUnknown = true)
28-
private record FileCredentials(
29-
@Nullable String username,
30-
@Nullable String password
31-
) {
32-
}
33-
3423
public static final String SECRET_TYPE_BASIC_AUTH = "kubernetes.io/basic-auth";
3524
public static final String SECRET_DATA_BASIC_AUTH_USERNAME_KEY = "username";
3625
public static final String SECRET_DATA_BASIC_AUTH_PASSWORD_KEY = "password";
3726

27+
private final ObjectMapper objectMapper;
28+
3829
public Credentials getAdminCredentials(
3930
KubernetesClient kubernetesClient,
4031
ClusterConnection clusterConnection
@@ -43,13 +34,15 @@ public Credentials getAdminCredentials(
4334
if (spec.getAdminSecretRef() != null) {
4435
var secretRef = spec.getAdminSecretRef();
4536
var defaultNamespace = clusterConnection.getMetadata().getNamespace();
37+
4638
var credentials = getSecretRefCredentials(kubernetesClient, secretRef, defaultNamespace);
4739
if (credentials.username() == null) {
4840
var secretNamespace = getSecretNamespace(secretRef, defaultNamespace);
4941
throw new IllegalStateException(
5042
"The Secret reference is missing required data username [secret.namespace=%s, secret.name=%s]".formatted(
5143
secretNamespace, secretRef.getName()));
5244
}
45+
5346
return credentials;
5447
} else if (spec.getAdminSecretFileRef() != null) {
5548
return getSecretFileRefCredentials(spec.getAdminSecretFileRef());
@@ -64,20 +57,17 @@ public Credentials getSecretFileRefCredentials(FileRef fileRef) {
6457
try (var in = Files.newInputStream(path)) {
6558
var file = objectMapper.readValue(in, FileCredentials.class);
6659
if (file.username() == null) {
67-
throw new IllegalStateException(
68-
"Credentials file is missing required field 'username' [path=%s]".formatted(path));
60+
throw new IllegalStateException("Credentials file is missing required field 'username' [path=%s]".formatted(path));
6961
}
7062
if (file.password() == null) {
71-
throw new IllegalStateException(
72-
"Credentials file is missing required field 'password' [path=%s]".formatted(path));
63+
throw new IllegalStateException("Credentials file is missing required field 'password' [path=%s]".formatted(path));
7364
}
65+
7466
return new Credentials(file.username(), file.password());
7567
} catch (NoSuchFileException e) {
76-
throw new IllegalStateException(
77-
"Credentials file not found [path=%s]".formatted(path), e);
68+
throw new IllegalStateException("Credentials file not found [path=%s]".formatted(path), e);
7869
} catch (IOException e) {
79-
throw new IllegalStateException(
80-
"Failed to read the credentials file [path=%s]".formatted(path), e);
70+
throw new IllegalStateException("Failed to read the credentials file [path=%s]".formatted(path), e);
8171
}
8272
}
8373

@@ -145,9 +135,21 @@ public Credentials getSecretRefCredentials(
145135
);
146136
}
147137

148-
private String getSecretNamespace(ResourceRef secretRef, String defaultNamespace) {
138+
private String getSecretNamespace(
139+
ResourceRef secretRef,
140+
String defaultNamespace
141+
) {
149142
return secretRef.getNamespace() != null
150143
? secretRef.getNamespace()
151144
: defaultNamespace;
152145
}
146+
147+
/// The JSON file may carry more keys than we need, for example, the AWS Secrets Manager
148+
/// format also has `engine`, `host`, `port` and `dbname`. Unknown keys are ignored.
149+
@JsonIgnoreProperties(ignoreUnknown = true)
150+
private record FileCredentials(
151+
@Nullable String username,
152+
@Nullable String password
153+
) {
154+
}
153155
}

operator/src/test/java/it/aboutbits/postgresql/core/KubernetesServiceTest.java

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package it.aboutbits.postgresql.core;
22

3+
import com.fasterxml.jackson.databind.ObjectMapper;
34
import io.fabric8.kubernetes.api.model.ObjectMeta;
45
import io.fabric8.kubernetes.api.model.Secret;
56
import io.fabric8.kubernetes.api.model.SecretBuilder;
@@ -17,8 +18,6 @@
1718
import org.junit.jupiter.params.ParameterizedTest;
1819
import org.junit.jupiter.params.provider.ValueSource;
1920

20-
import com.fasterxml.jackson.databind.ObjectMapper;
21-
2221
import java.io.IOException;
2322
import java.nio.charset.Charset;
2423
import java.nio.file.Files;
@@ -32,14 +31,14 @@
3231
@NullMarked
3332
@EnableKubernetesMockClient(crud = true)
3433
class KubernetesServiceTest {
35-
private final KubernetesService service = new KubernetesService(new ObjectMapper());
36-
3734
@SuppressWarnings("NullAway.Init")
3835
static KubernetesClient client;
3936

4037
@TempDir
4138
Path tempDir;
4239

40+
private final KubernetesService service = new KubernetesService(new ObjectMapper());
41+
4342
@BeforeEach
4443
void clearSecrets() {
4544
client.secrets().inAnyNamespace().delete();
@@ -52,9 +51,12 @@ class GetSecretFileRefCredentials {
5251
void whenBothUsernameAndPassword_shouldReturnCredentials() throws IOException {
5352
// given
5453
var file = tempDir.resolve("secret.json");
55-
Files.writeString(file, """
54+
Files.writeString(
55+
file,
56+
"""
5657
{"username": "admin", "password": "s3cret"}
57-
""");
58+
"""
59+
);
5860

5961
var fileRef = new FileRef();
6062
fileRef.setPath(file.toString());
@@ -72,7 +74,9 @@ void whenBothUsernameAndPassword_shouldReturnCredentials() throws IOException {
7274
void whenFileHasExtraKeys_shouldIgnoreThem() throws IOException {
7375
// given
7476
var file = tempDir.resolve("secret.json");
75-
Files.writeString(file, """
77+
Files.writeString(
78+
file,
79+
"""
7680
{
7781
"engine": "postgres",
7882
"host": "db.example.com",
@@ -81,7 +85,8 @@ void whenFileHasExtraKeys_shouldIgnoreThem() throws IOException {
8185
"dbname": "postgres",
8286
"port": 5432
8387
}
84-
""");
88+
"""
89+
);
8590

8691
var fileRef = new FileRef();
8792
fileRef.setPath(file.toString());
@@ -340,9 +345,12 @@ void whenOnlyAdminSecretRefSet_shouldDelegateToSecretRef() {
340345
void whenOnlyAdminSecretFileRefSet_shouldDelegateToFileRef() throws IOException {
341346
// given
342347
var file = tempDir.resolve("secret.json");
343-
Files.writeString(file, """
348+
Files.writeString(
349+
file,
350+
"""
344351
{"username": "file-admin", "password": "file-s3cret"}
345-
""");
352+
"""
353+
);
346354

347355
var fileRef = new FileRef();
348356
fileRef.setPath(file.toString());
@@ -415,8 +423,10 @@ private static ResourceRef secretRef(@Nullable String namespace, String name) {
415423
return ref;
416424
}
417425

418-
private static Secret basicAuthSecret(String namespace, String name,
419-
@Nullable String username, String password) {
426+
private static Secret basicAuthSecret(
427+
String namespace, String name,
428+
@Nullable String username, String password
429+
) {
420430
var builder = new SecretBuilder()
421431
.withNewMetadata().withNamespace(namespace).withName(name).endMetadata()
422432
.withType(KubernetesService.SECRET_TYPE_BASIC_AUTH)

operator/src/test/java/it/aboutbits/postgresql/crd/clusterconnection/ClusterConnectionReconcilerTest.java

Lines changed: 49 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,50 @@ void resetEnvironment() {
5757
TestUtil.resetEnvironment(kubernetesClient);
5858
}
5959

60+
@Nested
61+
class CRDValidation {
62+
@Test
63+
@DisplayName("when both adminSecretRef and adminSecretFileRef set, should reject")
64+
void whenBothSet_shouldReject() {
65+
var fileRef = new FileRef();
66+
fileRef.setPath("/mnt/secrets/db-credentials.json");
67+
68+
assertThatThrownBy(() -> given.one()
69+
.clusterConnection()
70+
.withAdminSecretFileRef(fileRef)
71+
.returnFirst()
72+
).isInstanceOf(KubernetesClientException.class)
73+
.hasMessageContaining("Exactly one of");
74+
}
75+
76+
@Test
77+
@DisplayName("when neither adminSecretRef nor adminSecretFileRef set, should reject")
78+
void whenNeitherSet_shouldReject() {
79+
assertThatThrownBy(() -> given.one()
80+
.clusterConnection()
81+
.withoutAdminSecret()
82+
.returnFirst()
83+
).isInstanceOf(KubernetesClientException.class)
84+
.hasMessageContaining("Exactly one of");
85+
}
86+
87+
@ParameterizedTest
88+
@BlankSource
89+
@DisplayName("when adminSecretFileRef has blank path, should reject")
90+
void whenFileRefBlankPath_shouldReject(String blankOrEmptyString) {
91+
var fileRef = new FileRef();
92+
fileRef.setPath(blankOrEmptyString);
93+
94+
assertThatThrownBy(() -> given.one()
95+
.clusterConnection()
96+
.withoutAdminSecret()
97+
.withAdminSecretFileRef(fileRef)
98+
.returnFirst()
99+
).isInstanceOf(KubernetesClientException.class)
100+
.hasMessageContaining("must not be empty");
101+
}
102+
}
103+
60104
@Test
61105
@DisplayName("When a ClusterConnection is created, the status should be ready")
62106
void createsCustomResource_andReconcilerStatusIsReady() {
@@ -92,9 +136,12 @@ void createsCustomResourceWithFileRef_andReconcilerStatusIsReady() throws IOExce
92136
// given
93137
var credentialsFile = Files.createTempFile("db-credentials", ".json");
94138
try {
95-
Files.writeString(credentialsFile, """
139+
Files.writeString(
140+
credentialsFile,
141+
"""
96142
{"username": "%s", "password": "%s"}
97-
""".formatted(dbUsername, dbPassword));
143+
""".formatted(dbUsername, dbPassword)
144+
);
98145

99146
var fileRef = new FileRef();
100147
fileRef.setPath(credentialsFile.toAbsolutePath().toString());
@@ -130,50 +177,6 @@ void createsCustomResourceWithFileRef_andReconcilerStatusIsReady() throws IOExce
130177
}
131178
}
132179

133-
@Nested
134-
class CRDValidation {
135-
@Test
136-
@DisplayName("when both adminSecretRef and adminSecretFileRef set, should reject")
137-
void whenBothSet_shouldReject() {
138-
var fileRef = new FileRef();
139-
fileRef.setPath("/mnt/secrets/db-credentials.json");
140-
141-
assertThatThrownBy(() -> given.one()
142-
.clusterConnection()
143-
.withAdminSecretFileRef(fileRef)
144-
.returnFirst()
145-
).isInstanceOf(KubernetesClientException.class)
146-
.hasMessageContaining("Exactly one of");
147-
}
148-
149-
@Test
150-
@DisplayName("when neither adminSecretRef nor adminSecretFileRef set, should reject")
151-
void whenNeitherSet_shouldReject() {
152-
assertThatThrownBy(() -> given.one()
153-
.clusterConnection()
154-
.withoutAdminSecret()
155-
.returnFirst()
156-
).isInstanceOf(KubernetesClientException.class)
157-
.hasMessageContaining("Exactly one of");
158-
}
159-
160-
@ParameterizedTest
161-
@BlankSource
162-
@DisplayName("when adminSecretFileRef has blank path, should reject")
163-
void whenFileRefBlankPath_shouldReject(String blankOrEmptyString) {
164-
var fileRef = new FileRef();
165-
fileRef.setPath(blankOrEmptyString);
166-
167-
assertThatThrownBy(() -> given.one()
168-
.clusterConnection()
169-
.withoutAdminSecret()
170-
.withAdminSecretFileRef(fileRef)
171-
.returnFirst()
172-
).isInstanceOf(KubernetesClientException.class)
173-
.hasMessageContaining("must not be empty");
174-
}
175-
}
176-
177180
private static void assertThatClusterConnectionHasExpectedStatus(
178181
ClusterConnection clusterConnection,
179182
CRStatus expectedStatus,

0 commit comments

Comments
 (0)