Add support to the Operator for setting default labels on Keycloak pods (#20661)

Closes #20625
This commit is contained in:
Václav Muzikář 2023-06-01 13:39:41 +02:00 committed by GitHub
parent cd9dce68da
commit f627e9535f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 73 additions and 5 deletions

View file

@ -289,6 +289,12 @@
</goals> </goals>
</execution> </execution>
</executions> </executions>
<configuration>
<systemPropertyVariables>
<!-- Used in KeycloakDeploymentTest#testPreconfiguredPodLabels -->
<OPERATOR_TEST_LABEL_EXPRESSION>my-value</OPERATOR_TEST_LABEL_EXPRESSION>
</systemPropertyVariables>
</configuration>
</plugin> </plugin>
<plugin> <plugin>
@ -317,9 +323,9 @@
<profiles> <profiles>
<profile> <profile>
<id>native</id> <id>operator-prod</id>
<properties> <properties>
<quarkus.package.type>native</quarkus.package.type> <quarkus.profile>rhbk</quarkus.profile>
</properties> </properties>
</profile> </profile>
</profiles> </profiles>

View file

@ -19,6 +19,8 @@ package org.keycloak.operator;
import io.smallrye.config.ConfigMapping; import io.smallrye.config.ConfigMapping;
import java.util.Map;
/** /**
* @author Vaclav Muzikar <vmuzikar@redhat.com> * @author Vaclav Muzikar <vmuzikar@redhat.com>
*/ */
@ -29,5 +31,7 @@ public interface Config {
interface Keycloak { interface Keycloak {
String image(); String image();
String imagePullPolicy(); String imagePullPolicy();
Map<String, String> podLabels();
} }
} }

View file

@ -378,7 +378,12 @@ public class KeycloakDeployment extends OperatorManagedResource implements Statu
baseDeployment.getMetadata().setNamespace(getNamespace()); baseDeployment.getMetadata().setNamespace(getNamespace());
baseDeployment.getSpec().getSelector().setMatchLabels(Constants.DEFAULT_LABELS); baseDeployment.getSpec().getSelector().setMatchLabels(Constants.DEFAULT_LABELS);
baseDeployment.getSpec().setReplicas(keycloakCR.getSpec().getInstances()); baseDeployment.getSpec().setReplicas(keycloakCR.getSpec().getInstances());
baseDeployment.getSpec().getTemplate().getMetadata().setLabels(Constants.DEFAULT_LABELS);
Map<String, String> labels = new HashMap<>(Constants.DEFAULT_LABELS);
if (operatorConfig.keycloak().podLabels() != null) {
labels.putAll(operatorConfig.keycloak().podLabels());
}
baseDeployment.getSpec().getTemplate().getMetadata().setLabels(labels);
Container container = baseDeployment.getSpec().getTemplate().getSpec().getContainers().get(0); Container container = baseDeployment.getSpec().getTemplate().getSpec().getContainers().get(0);
var customImage = Optional.ofNullable(keycloakCR.getSpec().getImage()); var customImage = Optional.ofNullable(keycloakCR.getSpec().getImage());

View file

@ -8,6 +8,5 @@ resources:
- kubernetes/keycloakrealmimports.k8s.keycloak.org-v1.yml - kubernetes/keycloakrealmimports.k8s.keycloak.org-v1.yml
- kubernetes/kubernetes.yml - kubernetes/kubernetes.yml
# patchesStrategicMerge patchesStrategicMerge:
patches:
- kubernetes/minikube.yml - kubernetes/minikube.yml

View file

@ -0,0 +1,7 @@
operator.keycloak.pod-labels."com.company"=Red_Hat
operator.keycloak.pod-labels."rht.prod_name"=Red_Hat_Runtimes
operator.keycloak.pod-labels."rht.prod_ver"=${SSO_QUARTER:sso_quarter_placeholder}
operator.keycloak.pod-labels."rht.comp"=SSO
operator.keycloak.pod-labels."rht.comp_ver"=${SSO_VER:${quarkus.application.version}}
operator.keycloak.pod-labels."rht.subcomp"=SSO_Server
operator.keycloak.pod-labels."rht.subcomp_t"=application

View file

@ -27,6 +27,7 @@ import io.fabric8.kubernetes.api.model.apps.StatefulSetSpecBuilder;
import io.quarkus.logging.Log; import io.quarkus.logging.Log;
import io.quarkus.test.junit.QuarkusTest; import io.quarkus.test.junit.QuarkusTest;
import org.awaitility.Awaitility; import org.awaitility.Awaitility;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledIfSystemProperty; import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
import org.keycloak.operator.Constants; import org.keycloak.operator.Constants;
@ -622,6 +623,30 @@ public class KeycloakDeploymentTest extends BaseOperatorTest {
} }
} }
@Test
public void testPreconfiguredPodLabels() {
Assumptions.assumeTrue(operatorDeployment == OperatorDeployment.local,
"Skipping the test when Operator deployed remotely to keep stuff simple, it's just SmallRye, we don't need to retest it");
try {
var kc = getDefaultKeycloakDeployment();
deployKeycloak(k8sclient, kc, true);
// labels are set in test/resources/application.properties
var labels = k8sclient.apps().statefulSets().inNamespace(namespace).withName(kc.getMetadata().getName()).get()
.getSpec().getTemplate().getMetadata().getLabels();
var expected = Map.of(
"test.label", "foobar",
"testLabelWithExpression", "my-value"
);
assertThat(labels).containsAllEntriesOf(expected);
} catch (Exception e) {
savePodLogs();
throw e;
}
}
private void handleFakeImagePullSecretCreation(Keycloak keycloakCR, private void handleFakeImagePullSecretCreation(Keycloak keycloakCR,
String secretDescriptorFilename) { String secretDescriptorFilename) {

View file

@ -33,6 +33,9 @@ import org.keycloak.operator.crds.v2alpha1.deployment.spec.HostnameSpecBuilder;
import org.keycloak.operator.crds.v2alpha1.deployment.spec.HttpSpecBuilder; import org.keycloak.operator.crds.v2alpha1.deployment.spec.HttpSpecBuilder;
import org.keycloak.operator.crds.v2alpha1.deployment.spec.UnsupportedSpec; import org.keycloak.operator.crds.v2alpha1.deployment.spec.UnsupportedSpec;
import java.util.Collections;
import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
@ -53,6 +56,10 @@ public class PodTemplateTest {
public String imagePullPolicy() { public String imagePullPolicy() {
return "Never"; return "Never";
} }
@Override
public Map<String, String> podLabels() {
return Collections.emptyMap();
}
}; };
} }
}; };

View file

@ -5,3 +5,6 @@ quarkus.operator-sdk.start-operator=false
quarkus.log.level=INFO quarkus.log.level=INFO
quarkus.log.category."io.javaoperatorsdk".level=DEBUG quarkus.log.category."io.javaoperatorsdk".level=DEBUG
operator.keycloak.pod-labels."test.label"=foobar
operator.keycloak.pod-labels."testLabelWithExpression"=${OPERATOR_TEST_LABEL_EXPRESSION}

12
pom.xml
View file

@ -2146,6 +2146,18 @@
</modules> </modules>
</profile> </profile>
<profile>
<id>operator-prod</id>
<activation>
<property>
<name>operator-prod</name>
</property>
</activation>
<modules>
<module>operator</module>
</modules>
</profile>
<profile> <profile>
<id>doclint-java8-disable</id> <id>doclint-java8-disable</id>
<activation> <activation>