blob: 5c014f630b74568acaa972008909aa446b5e1508 [file] [log] [blame]
// Copyright (C) 2022 The Android Open Source Project
//
// 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 com.google.gerrit.k8s.operator.test;
import static com.google.gerrit.k8s.operator.test.TestGerritCluster.CLUSTER_NAME;
import static java.util.concurrent.TimeUnit.MINUTES;
import static org.awaitility.Awaitility.await;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.extensions.api.GerritApi;
import com.google.gerrit.k8s.operator.gerrit.Gerrit;
import com.google.gerrit.k8s.operator.gerrit.GerritConfigMapDependentResource;
import com.google.gerrit.k8s.operator.gerrit.GerritInitConfigMapDependentResource;
import com.google.gerrit.k8s.operator.gerrit.GerritSite;
import com.google.gerrit.k8s.operator.gerrit.GerritSpec;
import com.google.gerrit.k8s.operator.gerrit.GerritSpec.GerritMode;
import com.google.gerrit.k8s.operator.gerrit.ServiceDependentResource;
import com.urswolfer.gerrit.client.rest.GerritAuthData;
import com.urswolfer.gerrit.client.rest.GerritRestApiFactory;
import io.fabric8.kubernetes.api.model.ObjectMeta;
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
import io.fabric8.kubernetes.api.model.Quantity;
import io.fabric8.kubernetes.api.model.ResourceRequirementsBuilder;
import io.fabric8.kubernetes.api.model.Secret;
import io.fabric8.kubernetes.api.model.SecretBuilder;
import io.fabric8.kubernetes.client.KubernetesClient;
import java.util.Base64;
import java.util.Map;
import java.util.Set;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.Config;
public class TestGerrit {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
public static final String NAME = "gerrit";
private static final String SECURE_CONFIG_SECRET_NAME = "gerrit-secret";
private static final String DEFAULT_GERRIT_CONFIG =
"[gerrit]\n"
+ " serverId = gerrit-1\n"
+ "[index]\n"
+ " type = LUCENE\n"
+ "[auth]\n"
+ " type = LDAP\n"
+ "[ldap]\n"
+ " server = ldap://openldap.openldap.svc.cluster.local:1389\n"
+ " accountBase = dc=example,dc=org\n"
+ " username = cn=admin,dc=example,dc=org\n"
+ "[httpd]\n"
+ " listenUrl = proxy-https://*:8080/\n"
+ " requestLog = true\n"
+ " gracefulStopTimeout = 1m\n"
+ "[sshd]\n"
+ " listenAddress = off\n"
+ "[transfer]\n"
+ " timeout = 120 s\n"
+ "[user]\n"
+ " name = Gerrit Code Review\n"
+ " email = gerrit@example.com\n"
+ " anonymousCoward = Unnamed User\n"
+ "[cache]\n"
+ " directory = cache\n"
+ "[container]\n"
+ " javaOptions = -Xmx4g";
private final KubernetesClient client;
private final String namespace;
private final GerritMode mode;
private final String ingress_domain;
private Secret secureConfigSecret;
private Gerrit gerrit = new Gerrit();
private Config config = defaultConfig();
private Config secureConfig = new Config();
public TestGerrit(
KubernetesClient client, TestProperties testProps, String namespace, GerritMode mode) {
this.client = client;
this.namespace = namespace;
this.mode = mode;
this.ingress_domain = testProps.getIngressDomain();
this.secureConfig.setString("ldap", null, "password", testProps.getLdapAdminPwd());
}
public TestGerrit(KubernetesClient client, TestProperties testProps, String namespace) {
this(client, testProps, namespace, GerritMode.PRIMARY);
}
public void build() {
createGerritCR();
createSecureConfig();
}
public void deploy() {
build();
client.resource(secureConfigSecret).inNamespace(namespace).createOrReplace();
client.resource(gerrit).inNamespace(namespace).createOrReplace();
waitForGerritReadiness();
}
public GerritApi getGerritApiClient() {
return new GerritRestApiFactory()
.create(
new GerritAuthData.Basic(
String.format(
"http://%s.%s", ServiceDependentResource.getName(gerrit), ingress_domain)));
}
public void modifyGerritConfig(String section, String key, String value) {
config.setString(section, null, key, value);
deploy();
}
public void modifySecureConfig(String section, String key, String value) {
secureConfig.setString(section, null, key, value);
createSecureConfig();
client.resource(secureConfigSecret).inNamespace(namespace).createOrReplace();
}
public GerritSpec getSpec() {
return gerrit.getSpec();
}
public void setSpec(GerritSpec spec) {
gerrit.setSpec(spec);
deploy();
}
private static Config defaultConfig() {
Config cfg = new Config();
try {
cfg.fromText(DEFAULT_GERRIT_CONFIG);
} catch (ConfigInvalidException e) {
throw new IllegalStateException("Illegal default test configuration.");
}
return cfg;
}
private void createGerritCR() {
ObjectMeta gerritMeta = new ObjectMetaBuilder().withName(NAME).withNamespace(namespace).build();
gerrit.setMetadata(gerritMeta);
GerritSpec gerritSpec = gerrit.getSpec();
if (gerritSpec == null) {
gerritSpec = new GerritSpec();
GerritSite site = new GerritSite();
site.setSize(new Quantity("1Gi"));
gerritSpec.setSite(site);
gerritSpec.setResources(
new ResourceRequirementsBuilder()
.withRequests(Map.of("cpu", new Quantity("1"), "memory", new Quantity("5Gi")))
.build());
}
gerritSpec.setCluster(CLUSTER_NAME);
gerritSpec.setMode(mode);
gerritSpec.setConfigFiles(Map.of("gerrit.config", config.toText()));
gerritSpec.setSecrets(Set.of(SECURE_CONFIG_SECRET_NAME));
gerrit.setSpec(gerritSpec);
}
private void createSecureConfig() {
secureConfigSecret =
new SecretBuilder()
.withNewMetadata()
.withNamespace(namespace)
.withName(SECURE_CONFIG_SECRET_NAME)
.endMetadata()
.withData(
Map.of(
"secure.config",
Base64.getEncoder().encodeToString(secureConfig.toText().getBytes())))
.build();
}
private void waitForGerritReadiness() {
logger.atInfo().log("Waiting max 1 minutes for the configmaps to be created.");
await()
.atMost(1, MINUTES)
.untilAsserted(
() -> {
assertThat(
client
.configMaps()
.inNamespace(namespace)
.withName(GerritConfigMapDependentResource.getName(gerrit))
.get(),
is(notNullValue()));
assertThat(
client
.configMaps()
.inNamespace(namespace)
.withName(GerritInitConfigMapDependentResource.getName(gerrit))
.get(),
is(notNullValue()));
});
logger.atInfo().log("Waiting max 1 minutes for the Gerrit StatefulSet to be created.");
await()
.atMost(1, MINUTES)
.untilAsserted(
() -> {
assertThat(
client
.apps()
.statefulSets()
.inNamespace(namespace)
.withName(gerrit.getMetadata().getName())
.get(),
is(notNullValue()));
});
logger.atInfo().log("Waiting max 1 minutes for the Gerrit Service to be created.");
await()
.atMost(1, MINUTES)
.untilAsserted(
() -> {
assertThat(
client
.services()
.inNamespace(namespace)
.withName(ServiceDependentResource.getName(gerrit))
.get(),
is(notNullValue()));
});
logger.atInfo().log("Waiting max 2 minutes for the Gerrit StatefulSet to be ready.");
await()
.atMost(2, MINUTES)
.untilAsserted(
() -> {
assertTrue(
client
.apps()
.statefulSets()
.inNamespace(namespace)
.withName(gerrit.getMetadata().getName())
.isReady());
});
}
}