Add transaction options to Keycloak CR

Closes #14375
This commit is contained in:
Martin Bartoš 2022-10-11 14:36:40 +02:00 committed by Václav Muzikář
parent ded52c6228
commit 90c1624668
6 changed files with 94 additions and 9 deletions

View file

@ -57,7 +57,8 @@ public class KeycloakDeploymentConfig {
"hostname",
"tlsSecret",
"features",
"features-disabled"
"features-disabled",
"transaction-xa-enabled"
);
/**
@ -67,6 +68,7 @@ public class KeycloakDeploymentConfig {
configureHostname();
configureTLS();
configureFeatures();
configureTransactions();
}
/**
@ -210,6 +212,21 @@ public class KeycloakDeploymentConfig {
}
}
public void configureTransactions() {
var transactionsSpec = keycloakCR.getSpec().getTransactionsSpec();
if (transactionsSpec == null) return;
var kcContainer = deployment.getSpec().getTemplate().getSpec().getContainers().get(0);
var envVars = kcContainer.getEnv();
if (transactionsSpec.isXaEnabled() != null) {
envVars.add(new EnvVarBuilder()
.withName("KC_TRANSACTION_XA_ENABLED")
.withValue(String.valueOf(transactionsSpec.isXaEnabled()))
.build());
}
}
/* ---------- END of configuration of first-class citizen fields ---------- */
protected String readConfigurationValue(String key) {

View file

@ -23,6 +23,7 @@ import com.fasterxml.jackson.annotation.JsonPropertyDescription;
import io.fabric8.kubernetes.api.model.LocalObjectReference;
import org.keycloak.operator.Constants;
import org.keycloak.operator.crds.v2alpha1.deployment.spec.FeatureSpec;
import org.keycloak.operator.crds.v2alpha1.deployment.spec.TransactionsSpec;
import javax.validation.constraints.NotNull;
import java.util.List;
@ -67,6 +68,10 @@ public class KeycloakSpec {
@JsonPropertyDescription("In this section you can configure Keycloak features, which should be enabled/disabled.")
private FeatureSpec featureSpec;
@JsonProperty("transaction")
@JsonPropertyDescription("In this section you can find all properties related to the settings of transaction behavior.")
private TransactionsSpec transactionsSpec;
public String getHostname() {
return hostname;
}
@ -117,6 +122,14 @@ public class KeycloakSpec {
this.featureSpec = featureSpec;
}
public TransactionsSpec getTransactionsSpec() {
return transactionsSpec;
}
public void setTransactionsSpec(TransactionsSpec transactionsSpec) {
this.transactionsSpec = transactionsSpec;
}
public int getInstances() {
return instances;
}

View file

@ -0,0 +1,38 @@
/*
* Copyright 2022 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.operator.crds.v2alpha1.deployment.spec;
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
import io.sundr.builder.annotations.Buildable;
import java.io.Serializable;
@Buildable(editableEnabled = false, builderPackage = "io.fabric8.kubernetes.api.builder")
public class TransactionsSpec implements Serializable {
@JsonPropertyDescription("Determine whether Keycloak should use a non-XA datasource in case the database does not support XA transactions.")
private Boolean xaEnabled;
public Boolean isXaEnabled() {
return xaEnabled;
}
public void setXaEnabled(Boolean xaEnabled) {
this.xaEnabled = xaEnabled;
}
}

View file

@ -22,6 +22,7 @@ import org.hamcrest.CoreMatchers;
import org.junit.jupiter.api.Test;
import org.keycloak.operator.crds.v2alpha1.deployment.Keycloak;
import org.keycloak.operator.crds.v2alpha1.deployment.spec.FeatureSpec;
import org.keycloak.operator.crds.v2alpha1.deployment.spec.TransactionsSpec;
import java.util.List;
@ -40,6 +41,11 @@ public class CRSerializationTest {
assertEquals("my-image", keycloak.getSpec().getImage());
assertEquals("my-tls-secret", keycloak.getSpec().getTlsSecret());
assertTrue(keycloak.getSpec().isDisableDefaultIngress());
final TransactionsSpec transactionsSpec = keycloak.getSpec().getTransactionsSpec();
assertThat(transactionsSpec, notNullValue());
assertThat(transactionsSpec.isXaEnabled(), notNullValue());
assertThat(transactionsSpec.isXaEnabled(), CoreMatchers.is(false));
}
@Test

View file

@ -31,6 +31,7 @@ import org.keycloak.operator.testsuite.utils.K8sUtils;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import static org.assertj.core.api.Assertions.assertThat;
@ -39,29 +40,37 @@ public class KeycloakDeploymentConfigTest {
@Test
public void enabledFeatures() {
testFeatures(true, "docker", "authorization");
testFirstClassCitizenEnvVars("KC_FEATURES", KeycloakDeploymentConfig::configureFeatures, "docker", "authorization");
}
@Test
public void disabledFeatures() {
testFeatures(false, "admin", "step-up-authentication");
testFirstClassCitizenEnvVars("KC_FEATURES_DISABLED", KeycloakDeploymentConfig::configureFeatures, "admin", "step-up-authentication");
}
private void testFeatures(boolean enabledFeatures, String... features) {
final String featureEnvVar = enabledFeatures ? "KC_FEATURES" : "KC_FEATURES_DISABLED";
@Test
public void transactions() {
testFirstClassCitizenEnvVars("KC_TRANSACTION_XA_ENABLED", KeycloakDeploymentConfig::configureTransactions, "false");
}
final Keycloak keycloak = K8sUtils.getResourceFromFile("/test-serialization-keycloak-cr.yml", Keycloak.class);
/* UTILS */
private void testFirstClassCitizenEnvVars(String varName, Consumer<KeycloakDeploymentConfig> config, String... expectedValues) {
testFirstClassCitizenEnvVars("/test-serialization-keycloak-cr.yml", varName, config, expectedValues);
}
private void testFirstClassCitizenEnvVars(String crName, String varName, Consumer<KeycloakDeploymentConfig> config, String... expectedValues) {
final Keycloak keycloak = K8sUtils.getResourceFromFile(crName, Keycloak.class);
final StatefulSet deployment = getBasicKcDeployment();
final KeycloakDeploymentConfig deploymentConfig = new KeycloakDeploymentConfig(keycloak, deployment, null);
final Container container = deployment.getSpec().getTemplate().getSpec().getContainers().get(0);
assertThat(container).isNotNull();
assertEnvVarNotPresent(container.getEnv(), featureEnvVar);
assertEnvVarNotPresent(container.getEnv(), varName);
deploymentConfig.configureFeatures();
config.accept(deploymentConfig);
assertContainerEnvVar(container.getEnv(), featureEnvVar, features);
assertContainerEnvVar(container.getEnv(), varName, expectedValues);
}
/**

View file

@ -20,6 +20,8 @@ spec:
- admin
- step-up-authentication
disableDefaultIngress: true
transaction:
xaEnabled: false
unsupported:
podTemplate:
metadata: