mirror of
https://github.com/keycloak/keycloak.git
synced 2026-05-03 13:40:46 -05:00
support setting periodSeconds and failureThreashold in the Keyclock CR (#40117)
* add probe spec Signed-off-by: AvivGuiser <avivguiser@gmail.com> * make default for probes if not configured, add skeleton test files Signed-off-by: AvivGuiser <avivguiser@gmail.com> * fix tests Signed-off-by: AvivGuiser <avivguiser@gmail.com> * fix tests Signed-off-by: AvivGuiser <avivguiser@gmail.com> * add docs Signed-off-by: AvivGuiser <avivguiser@gmail.com> * move test to unittest and apiserver test Signed-off-by: AvivGuiser <avivguiser@gmail.com> * adding asserts to check new fields Signed-off-by: AvivGuiser <avivguiser@gmail.com> * fix test Signed-off-by: AvivGuiser <aviv.guiser@placer.ai> * update docs Signed-off-by: AvivGuiser <aviv.guiser@placer.ai> --------- Signed-off-by: AvivGuiser <avivguiser@gmail.com> Signed-off-by: AvivGuiser <aviv.guiser@placer.ai>
This commit is contained in:
+10
-6
@@ -48,6 +48,7 @@ import org.keycloak.operator.crds.v2alpha1.deployment.KeycloakSpec;
|
||||
import org.keycloak.operator.crds.v2alpha1.deployment.ValueOrSecret;
|
||||
import org.keycloak.operator.crds.v2alpha1.deployment.spec.CacheSpec;
|
||||
import org.keycloak.operator.crds.v2alpha1.deployment.spec.HttpManagementSpec;
|
||||
import org.keycloak.operator.crds.v2alpha1.deployment.spec.ProbeSpec;
|
||||
import org.keycloak.operator.crds.v2alpha1.deployment.spec.SchedulingSpec;
|
||||
import org.keycloak.operator.crds.v2alpha1.deployment.spec.Truststore;
|
||||
import org.keycloak.operator.crds.v2alpha1.deployment.spec.TruststoreSource;
|
||||
@@ -327,6 +328,9 @@ public class KeycloakDeploymentDependentResource extends CRUDKubernetesDependent
|
||||
// probes
|
||||
var protocol = isTlsConfigured(keycloakCR) ? "HTTPS" : "HTTP";
|
||||
var port = HttpManagementSpec.managementPort(keycloakCR);
|
||||
var readinessOptionalSpec = Optional.ofNullable(keycloakCR.getSpec().getReadinessProbeSpec());
|
||||
var livenessOptionalSpec = Optional.ofNullable(keycloakCR.getSpec().getLivenessProbeSpec());
|
||||
var startupOptionalSpec = Optional.ofNullable(keycloakCR.getSpec().getStartupProbeSpec());
|
||||
var relativePath = readConfigurationValue(Constants.KEYCLOAK_HTTP_MANAGEMENT_RELATIVE_PATH_KEY, keycloakCR, context)
|
||||
.or(() -> readConfigurationValue(Constants.KEYCLOAK_HTTP_RELATIVE_PATH_KEY, keycloakCR, context))
|
||||
.map(path -> !path.endsWith("/") ? path + "/" : path)
|
||||
@@ -334,8 +338,8 @@ public class KeycloakDeploymentDependentResource extends CRUDKubernetesDependent
|
||||
|
||||
if (!containerBuilder.hasReadinessProbe()) {
|
||||
containerBuilder.withNewReadinessProbe()
|
||||
.withPeriodSeconds(10)
|
||||
.withFailureThreshold(3)
|
||||
.withPeriodSeconds(readinessOptionalSpec.map(ProbeSpec::getProbePeriodSeconds).orElse(10))
|
||||
.withFailureThreshold(readinessOptionalSpec.map(ProbeSpec::getProbeFailureThreshold).orElse(3))
|
||||
.withNewHttpGet()
|
||||
.withScheme(protocol)
|
||||
.withNewPort(port)
|
||||
@@ -345,8 +349,8 @@ public class KeycloakDeploymentDependentResource extends CRUDKubernetesDependent
|
||||
}
|
||||
if (!containerBuilder.hasLivenessProbe()) {
|
||||
containerBuilder.withNewLivenessProbe()
|
||||
.withPeriodSeconds(10)
|
||||
.withFailureThreshold(3)
|
||||
.withPeriodSeconds(livenessOptionalSpec.map(ProbeSpec::getProbePeriodSeconds).orElse(10))
|
||||
.withFailureThreshold(livenessOptionalSpec.map(ProbeSpec::getProbeFailureThreshold).orElse(3))
|
||||
.withNewHttpGet()
|
||||
.withScheme(protocol)
|
||||
.withNewPort(port)
|
||||
@@ -356,8 +360,8 @@ public class KeycloakDeploymentDependentResource extends CRUDKubernetesDependent
|
||||
}
|
||||
if (!containerBuilder.hasStartupProbe()) {
|
||||
containerBuilder.withNewStartupProbe()
|
||||
.withPeriodSeconds(1)
|
||||
.withFailureThreshold(600)
|
||||
.withPeriodSeconds(startupOptionalSpec.map(ProbeSpec::getProbePeriodSeconds).orElse(1))
|
||||
.withFailureThreshold(startupOptionalSpec.map(ProbeSpec::getProbeFailureThreshold).orElse(600))
|
||||
.withNewHttpGet()
|
||||
.withScheme(protocol)
|
||||
.withNewPort(port)
|
||||
|
||||
+33
@@ -29,6 +29,7 @@ import org.keycloak.operator.crds.v2alpha1.deployment.spec.HttpManagementSpec;
|
||||
import org.keycloak.operator.crds.v2alpha1.deployment.spec.HttpSpec;
|
||||
import org.keycloak.operator.crds.v2alpha1.deployment.spec.IngressSpec;
|
||||
import org.keycloak.operator.crds.v2alpha1.deployment.spec.NetworkPolicySpec;
|
||||
import org.keycloak.operator.crds.v2alpha1.deployment.spec.ProbeSpec;
|
||||
import org.keycloak.operator.crds.v2alpha1.deployment.spec.ProxySpec;
|
||||
import org.keycloak.operator.crds.v2alpha1.deployment.spec.SchedulingSpec;
|
||||
import org.keycloak.operator.crds.v2alpha1.deployment.spec.TracingSpec;
|
||||
@@ -135,6 +136,20 @@ public class KeycloakSpec {
|
||||
@JsonPropertyDescription("Configuration related to Keycloak deployment updates.")
|
||||
private UpdateSpec updateSpec;
|
||||
|
||||
@JsonProperty("readinessProbe")
|
||||
@JsonPropertyDescription("Configuration for readiness probe, by default it is 10 for periodSeconds and 3 for failureThreshold")
|
||||
private ProbeSpec readinessProbeSpec;
|
||||
|
||||
|
||||
@JsonProperty("livenessProbe")
|
||||
@JsonPropertyDescription("Configuration for liveness probe, by default it is 10 for periodSeconds and 3 for failureThreshold")
|
||||
private ProbeSpec livenessProbeSpec;
|
||||
|
||||
@JsonProperty("startupProbe")
|
||||
@JsonPropertyDescription("Configuration for startup probe, by default it is 1 for periodSeconds and 600 for failureThreshold")
|
||||
private ProbeSpec startupProbeSpec;
|
||||
|
||||
|
||||
public HttpSpec getHttpSpec() {
|
||||
return httpSpec;
|
||||
}
|
||||
@@ -316,4 +331,22 @@ public class KeycloakSpec {
|
||||
public void setUpdateSpec(UpdateSpec updateSpec) {
|
||||
this.updateSpec = updateSpec;
|
||||
}
|
||||
|
||||
public ProbeSpec getLivenessProbeSpec() {return livenessProbeSpec;}
|
||||
|
||||
public void setLivenessProbeSpec(ProbeSpec livenessProbeSpec) {
|
||||
this.livenessProbeSpec = livenessProbeSpec;
|
||||
}
|
||||
|
||||
public ProbeSpec getReadinessProbeSpec() {return readinessProbeSpec;}
|
||||
|
||||
public void setReadinessProbeSpec(ProbeSpec readinessProbeSpec) {
|
||||
this.readinessProbeSpec = readinessProbeSpec;
|
||||
}
|
||||
|
||||
public ProbeSpec getStartupProbeSpec() {return startupProbeSpec;}
|
||||
|
||||
public void setStartupProbeSpec(ProbeSpec startupProbeSpec) {
|
||||
this.startupProbeSpec = startupProbeSpec;
|
||||
}
|
||||
}
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package org.keycloak.operator.crds.v2alpha1.deployment.spec;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.sundr.builder.annotations.Buildable;
|
||||
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
@Buildable(editableEnabled = false, builderPackage = "io.fabric8.kubernetes.api.builder")
|
||||
public class ProbeSpec {
|
||||
|
||||
@JsonProperty("periodSeconds")
|
||||
private int probePeriodSeconds;
|
||||
|
||||
@JsonProperty("failureThreshold")
|
||||
private int probeFailureThreshold;
|
||||
|
||||
public int getProbeFailureThreshold() {return probeFailureThreshold;}
|
||||
public void setProbeFailureThreshold(int probeFailureThreshold) {this.probeFailureThreshold = probeFailureThreshold;}
|
||||
public int getProbePeriodSeconds() {return probePeriodSeconds;}
|
||||
public void setProbePeriodSeconds(int probePeriodSeconds) {this.probePeriodSeconds = probePeriodSeconds;}
|
||||
}
|
||||
+1
@@ -47,6 +47,7 @@ import org.keycloak.operator.crds.v2alpha1.deployment.KeycloakStatusCondition;
|
||||
import org.keycloak.operator.crds.v2alpha1.deployment.ValueOrSecret;
|
||||
import org.keycloak.operator.crds.v2alpha1.deployment.spec.BootstrapAdminSpec;
|
||||
import org.keycloak.operator.crds.v2alpha1.deployment.spec.HostnameSpecBuilder;
|
||||
import org.keycloak.operator.crds.v2alpha1.deployment.spec.ProbeSpec;
|
||||
import org.keycloak.operator.testsuite.apiserver.DisabledIfApiServerTest;
|
||||
import org.keycloak.operator.testsuite.unit.WatchedResourcesTest;
|
||||
import org.keycloak.operator.testsuite.utils.CRAssert;
|
||||
|
||||
@@ -102,6 +102,14 @@ public class CRSerializationTest {
|
||||
HttpManagementSpec managementSpec = keycloak.getSpec().getHttpManagementSpec();
|
||||
assertNotNull(managementSpec);
|
||||
assertEquals(9003, managementSpec.getPort());
|
||||
|
||||
assertEquals(50,keycloak.getSpec().getReadinessProbeSpec().getProbePeriodSeconds());
|
||||
assertEquals(3,keycloak.getSpec().getReadinessProbeSpec().getProbeFailureThreshold());
|
||||
assertEquals(60,keycloak.getSpec().getLivenessProbeSpec().getProbePeriodSeconds());
|
||||
assertEquals(1,keycloak.getSpec().getLivenessProbeSpec().getProbeFailureThreshold());
|
||||
assertEquals(40,keycloak.getSpec().getStartupProbeSpec().getProbePeriodSeconds());
|
||||
assertEquals(2,keycloak.getSpec().getStartupProbeSpec().getProbeFailureThreshold());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -676,6 +676,37 @@ public class PodTemplateTest {
|
||||
assertThat(podTemplate.getSpec().getAffinity()).isNotEqualTo(affinity);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProbe(){
|
||||
PodTemplateSpec additionalPodTemplate = null;
|
||||
var readinessProbe = new ProbeBuilder().withFailureThreshold(1).withPeriodSeconds(2).build();
|
||||
var livenessProbe = new ProbeBuilder().withFailureThreshold(3).withPeriodSeconds(4).build();
|
||||
var startupProbe = new ProbeBuilder().withFailureThreshold(5).withPeriodSeconds(6).build();
|
||||
var readinessPodTemplate = getDeployment(additionalPodTemplate, null,
|
||||
s-> s.withNewReadinessProbeSpec()
|
||||
.withProbeFailureThreshold(1)
|
||||
.withProbePeriodSeconds(2)
|
||||
.endReadinessProbeSpec()).getSpec().getTemplate();
|
||||
assertThat(readinessPodTemplate.getSpec().getContainers().get(0).getReadinessProbe().getPeriodSeconds()).isEqualTo(readinessProbe.getPeriodSeconds());
|
||||
assertThat(readinessPodTemplate.getSpec().getContainers().get(0).getReadinessProbe().getFailureThreshold()).isEqualTo(readinessProbe.getFailureThreshold());
|
||||
|
||||
var livenessPodTemplate = getDeployment(additionalPodTemplate, null,
|
||||
s-> s.withNewLivenessProbeSpec()
|
||||
.withProbeFailureThreshold(3)
|
||||
.withProbePeriodSeconds(4)
|
||||
.endLivenessProbeSpec()).getSpec().getTemplate();
|
||||
assertThat(livenessPodTemplate.getSpec().getContainers().get(0).getLivenessProbe().getPeriodSeconds()).isEqualTo(livenessProbe.getPeriodSeconds());
|
||||
assertThat(livenessPodTemplate.getSpec().getContainers().get(0).getLivenessProbe().getFailureThreshold()).isEqualTo(livenessProbe.getFailureThreshold());
|
||||
|
||||
var startupPodTemplate = getDeployment(additionalPodTemplate, null,
|
||||
s-> s.withNewStartupProbeSpec()
|
||||
.withProbeFailureThreshold(5)
|
||||
.withProbePeriodSeconds(6)
|
||||
.endStartupProbeSpec()).getSpec().getTemplate();
|
||||
assertThat(startupPodTemplate.getSpec().getContainers().get(0).getStartupProbe().getPeriodSeconds()).isEqualTo(startupProbe.getPeriodSeconds());
|
||||
assertThat(startupPodTemplate.getSpec().getContainers().get(0).getStartupProbe().getFailureThreshold()).isEqualTo(startupProbe.getFailureThreshold());
|
||||
}
|
||||
|
||||
private Job getUpdateJob(Consumer<KeycloakSpecBuilder> newSpec, Consumer<KeycloakSpecBuilder> oldSpec, Consumer<StatefulSetBuilder> existingModifier) {
|
||||
// create an existing from the old spec and modifier
|
||||
StatefulSetBuilder existingBuilder = getDeployment(null, null, oldSpec).toBuilder();
|
||||
|
||||
@@ -32,6 +32,15 @@ spec:
|
||||
annotations:
|
||||
myAnnotation: myValue
|
||||
anotherAnnotation: anotherValue
|
||||
readinessProbe:
|
||||
periodSeconds: 50
|
||||
failureThreshold: 3
|
||||
livenessProbe:
|
||||
periodSeconds: 60
|
||||
failureThreshold: 1
|
||||
startupProbe:
|
||||
periodSeconds: 40
|
||||
failureThreshold: 2
|
||||
networkPolicy:
|
||||
enabled: true
|
||||
http:
|
||||
|
||||
Reference in New Issue
Block a user