Add support to the Operator for setting default labels on Keycloak pods (#20661)
Closes #20625
This commit is contained in:
parent
cd9dce68da
commit
f627e9535f
9 changed files with 73 additions and 5 deletions
|
@ -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>
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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
|
||||||
|
|
7
operator/src/main/resources/application-rhbk.properties
Normal file
7
operator/src/main/resources/application-rhbk.properties
Normal 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
|
|
@ -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) {
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
12
pom.xml
|
@ -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>
|
||||||
|
|
Loading…
Reference in a new issue