mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-10 15:32:05 -03:30
add labels and annotations to service (httpSpec) (#39925)
closes #23283 Signed-off-by: Gilvan Filho <gfilho@redhat.com>
This commit is contained in:
parent
d4392779f6
commit
e5bb7f5249
@ -462,4 +462,25 @@ They need to access {project_name} to scrape the available metrics.
|
||||
|
||||
Check the https://kubernetes.io/docs/concepts/services-networking/network-policies/[Kubernetes Network Policies documentation] for more information about NetworkPolicies.
|
||||
|
||||
=== Parameterizing service labels and annotations
|
||||
|
||||
If you need to set custom labels or annotations to keycloak service you can do that through `spec.http.labels` and `spec.http.annotations`
|
||||
|
||||
.Custom service labels and annotations
|
||||
[source,yaml]
|
||||
----
|
||||
apiVersion: k8s.keycloak.org/v2alpha1
|
||||
kind: Keycloak
|
||||
metadata:
|
||||
name: example-kc
|
||||
spec:
|
||||
http:
|
||||
labels:
|
||||
label1: label-value1
|
||||
label2: label-value2
|
||||
annotations:
|
||||
annotation1: annotation-value1
|
||||
annotation2: annotation-value2
|
||||
----
|
||||
|
||||
</@tmpl.guide>
|
||||
|
||||
@ -17,6 +17,9 @@
|
||||
package org.keycloak.operator.controllers;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import io.fabric8.kubernetes.api.model.HasMetadata;
|
||||
import io.fabric8.kubernetes.api.model.Service;
|
||||
@ -76,11 +79,19 @@ public class KeycloakServiceDependentResource extends CRUDKubernetesDependentRes
|
||||
|
||||
@Override
|
||||
protected Service desired(Keycloak primary, Context<Keycloak> context) {
|
||||
|
||||
Map<String,String> labels = Utils.allInstanceLabels(primary);
|
||||
var optionalSpec = Optional.ofNullable(primary.getSpec().getHttpSpec());
|
||||
optionalSpec.map(HttpSpec::getLabels).ifPresent(labels::putAll);
|
||||
|
||||
Map<String,String> annotations = optionalSpec.map(HttpSpec::getAnnotations).orElse(new HashMap<>());
|
||||
|
||||
Service service = new ServiceBuilder()
|
||||
.withNewMetadata()
|
||||
.withName(getServiceName(primary))
|
||||
.withNamespace(primary.getMetadata().getNamespace())
|
||||
.addToLabels(Utils.allInstanceLabels(primary))
|
||||
.addToLabels(labels)
|
||||
.addToAnnotations(annotations)
|
||||
.endMetadata()
|
||||
.withSpec(getServiceSpec(primary))
|
||||
.build();
|
||||
|
||||
@ -18,11 +18,14 @@
|
||||
package org.keycloak.operator.crds.v2alpha1.deployment.spec;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.Map;
|
||||
|
||||
import org.keycloak.operator.Constants;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
|
||||
|
||||
import io.sundr.builder.annotations.Buildable;
|
||||
import org.keycloak.operator.Constants;
|
||||
import org.keycloak.operator.crds.v2alpha1.CRDUtils;
|
||||
import org.keycloak.operator.crds.v2alpha1.deployment.Keycloak;
|
||||
import org.keycloak.operator.crds.v2alpha1.deployment.KeycloakSpec;
|
||||
@ -45,6 +48,12 @@ public class HttpSpec {
|
||||
@JsonPropertyDescription("The used HTTPS port.")
|
||||
private Integer httpsPort = Constants.KEYCLOAK_HTTPS_PORT;
|
||||
|
||||
@JsonPropertyDescription("Annotations to be appended to the Service object")
|
||||
Map<String, String> annotations;
|
||||
|
||||
@JsonPropertyDescription("Labels to be appended to the Service object")
|
||||
Map<String, String> labels;
|
||||
|
||||
public String getTlsSecret() {
|
||||
return tlsSecret;
|
||||
}
|
||||
@ -95,4 +104,20 @@ public class HttpSpec {
|
||||
.map(KeycloakSpec::getHttpSpec);
|
||||
}
|
||||
|
||||
public Map<String, String> getAnnotations() {
|
||||
return annotations;
|
||||
}
|
||||
|
||||
public void setAnnotations(Map<String, String> annotations) {
|
||||
this.annotations = annotations;
|
||||
}
|
||||
|
||||
public Map<String, String> getLabels() {
|
||||
return labels;
|
||||
}
|
||||
|
||||
public void setLabels(Map<String, String> labels) {
|
||||
this.labels = labels;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -31,12 +31,15 @@ import java.time.Duration;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
|
||||
@QuarkusTest
|
||||
public class KeycloakServicesTest extends BaseOperatorTest {
|
||||
@Test
|
||||
public void testMainServiceDurability() {
|
||||
var kc = getTestKeycloakDeployment(true);
|
||||
kc.getSpec().getHttpSpec().setLabels(Map.of("foo","bar"));
|
||||
K8sUtils.deployKeycloak(k8sclient, kc, true);
|
||||
String serviceName = KeycloakServiceDependentResource.getServiceName(kc);
|
||||
var serviceSelector = k8sclient.services().inNamespace(namespace).withName(serviceName);
|
||||
@ -71,6 +74,7 @@ public class KeycloakServicesTest extends BaseOperatorTest {
|
||||
.untilAsserted(() -> {
|
||||
var s = serviceSelector.get();
|
||||
assertThat(s.getMetadata().getLabels().entrySet().containsAll(labels.entrySet())).isTrue(); // additional labels should not be overwritten
|
||||
assertEquals("bar", s.getMetadata().getLabels().get("foo"));
|
||||
// ignoring assigned IP/s and generated config
|
||||
s.getSpec().setClusterIP(null);
|
||||
s.getSpec().setClusterIPs(null);
|
||||
@ -79,6 +83,60 @@ public class KeycloakServicesTest extends BaseOperatorTest {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomServiceAnnotations() {
|
||||
var kc = getTestKeycloakDeployment(true);
|
||||
|
||||
// set 'a'
|
||||
kc.getSpec().getHttpSpec().setAnnotations(Map.of("a", "b"));
|
||||
K8sUtils.deployKeycloak(k8sclient, kc, true);
|
||||
|
||||
String serviceName = KeycloakServiceDependentResource.getServiceName(kc);
|
||||
var serviceSelector = k8sclient.services().inNamespace(namespace).withName(serviceName);
|
||||
|
||||
Awaitility.await()
|
||||
.ignoreExceptions()
|
||||
.untilAsserted(() -> {
|
||||
var s = serviceSelector.get();
|
||||
assertEquals("b", s.getMetadata().getAnnotations().get("a"));
|
||||
});
|
||||
|
||||
// update 'a'
|
||||
kc.getSpec().getHttpSpec().setAnnotations(Map.of("a", "bb"));
|
||||
K8sUtils.deployKeycloak(k8sclient, kc, true);
|
||||
|
||||
Awaitility.await()
|
||||
.ignoreExceptions()
|
||||
.untilAsserted(() -> {
|
||||
var s = serviceSelector.get();
|
||||
assertEquals("bb", s.getMetadata().getAnnotations().get("a"));
|
||||
});
|
||||
|
||||
// remove 'a' and add 'c'
|
||||
kc.getSpec().getHttpSpec().setAnnotations(Map.of("c", "d"));
|
||||
K8sUtils.deployKeycloak(k8sclient, kc, true);
|
||||
|
||||
Awaitility.await()
|
||||
.ignoreExceptions()
|
||||
.untilAsserted(() -> {
|
||||
var s = serviceSelector.get();
|
||||
assertFalse(s.getMetadata().getAnnotations().containsKey("a"));
|
||||
assertEquals("d", s.getMetadata().getAnnotations().get("c"));
|
||||
});
|
||||
|
||||
// remove all
|
||||
kc.getSpec().getHttpSpec().setAnnotations(null);
|
||||
K8sUtils.deployKeycloak(k8sclient, kc, true);
|
||||
|
||||
Awaitility.await()
|
||||
.ignoreExceptions()
|
||||
.untilAsserted(() -> {
|
||||
var s = serviceSelector.get();
|
||||
assertFalse(s.getMetadata().getAnnotations().containsKey("a"));
|
||||
assertFalse(s.getMetadata().getAnnotations().containsKey("c"));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDiscoveryServiceDurability() {
|
||||
var kc = getTestKeycloakDeployment(true);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user