Merge changes I8dc66d3e,I71ae592c
* changes:
Update operator docs
[Operator] As part of build copy updated CRDs to helm-chart
diff --git a/Documentation/operator-api-reference.md b/Documentation/operator-api-reference.md
index 1dbb153..5b05bf4 100644
--- a/Documentation/operator-api-reference.md
+++ b/Documentation/operator-api-reference.md
@@ -711,7 +711,7 @@
| `storage` | [`GerritStorageConfig`](#gerritstorageconfig) | Storage used by Gerrit instances |
| `containerImages` | [`ContainerImageConfig`](#containerimageconfig) | Container images used inside GerritCluster |
| `ingress` | [`GerritClusterIngressConfig`](#gerritclusteringressconfig) | Ingress traffic handling in GerritCluster |
-| `gerrits` | [`GerritTemplate`](#gerrittemplate)-Array | A list of Gerrit instances to be installed in the GerritCluster. Only a single primary Gerrit is permitted. |
+| `gerrits` | [`GerritTemplate`](#gerrittemplate)-Array | A list of Gerrit instances to be installed in the GerritCluster. Only a single primary Gerrit and a single Gerrit Replica is permitted. |
| `receiver` | [`ReceiverTemplate`](#receivertemplate) | A Receiver instance to be installed in the GerritCluster. |
## GerritClusterStatus
@@ -800,7 +800,7 @@
| Value | Description|
|---|---|
| `NONE` | No ingress provider will be configured |
-| `INGRESS` | An [`Ingress`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#ingress-v1-networking-k8s-io) will be provisioned |
+| `INGRESS` | An [`Ingress`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#ingress-v1-networking-k8s-io) will be provisioned. Only the [Nginx-Ingress-Controller](https://docs.nginx.com/nginx-ingress-controller/) is supported. |
| `ISTIO` | [ISTIO](https://istio.io/latest/) will be configured to add the GerritCluster to the ServiceMesh |
## GerritIngressTlsConfig
diff --git a/Documentation/operator.md b/Documentation/operator.md
index dab36d3..61b2cf7 100644
--- a/Documentation/operator.md
+++ b/Documentation/operator.md
@@ -5,13 +5,20 @@
2. [Versioning](#versioning)
3. [Publish](#publish)
4. [Tests](#tests)
- 5. [Deploy](#deploy)
- 6. [CustomResources](#customresources)
+ 5. [Prerequisites](#prerequisites)
+ 1. [Shared Storage (ReadWriteMany)](#shared-storage-readwritemany)
+ 2. [Ingress provider](#ingress-provider)
+ 6. [Deploy](#deploy)
+ 1. [Using helm charts](#using-helm-charts)
+ 1. [gerrit-operator-crds](#gerrit-operator-crds)
+ 2. [gerrit-operator](#gerrit-operator-1)
+ 2. [Without the helm charts](#without-the-helm-charts)
+ 7. [CustomResources](#customresources)
1. [GerritCluster](#gerritcluster)
2. [Gerrit](#gerrit)
3. [GitGarbageCollection](#gitgarbagecollection)
4. [Receiver](#receiver)
- 7. [Configuration of Gerrit](#configuration-of-gerrit)
+ 8. [Configuration of Gerrit](#configuration-of-gerrit)
## Build
@@ -124,6 +131,47 @@
Note, that running the E2E tests will also involve pushing the container image
to the repository configured in the properties file.
+## Prerequisites
+
+Deploying Gerrit using the operator requires some additional prerequisites to be
+fulfilled:
+
+### Shared Storage (ReadWriteMany)
+
+Gerrit instances share the repositories and other data using shared volumes. Thus,
+a StorageClass and a suitable provisioner have to be available in the cluster.
+An example for such a provisioner would be the
+[NFS-subdir-external-provisioner](https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner).
+
+### Ingress provider
+
+The Gerrit Operator will also set up network routing rules and an ingress point
+for the Gerrit instances it manages. The network routing rules ensure that requests
+will be routed to the intended GerritCluster component, e.g. in case a primary
+Gerrit and a Gerrit Replica exist in the cluster, git fetch/clone requests will
+be sent to the Gerrit Replica and all other requests to the primary Gerrit.
+The Gerrit Operator currently supports the following Ingress providers, which
+can be configured for each
+[GerritCluster](operator-api-reference.md#gerritclusteringressconfig):
+
+- **NONE**
+
+ The operator will install no Ingress components. Services will still be available.
+ No prerequisites are required for this case.
+
+- **INGRESS**
+
+ The operator will install an Ingress. Currently only the
+ [Nginx-Ingress-Controller](https://docs.nginx.com/nginx-ingress-controller/) is
+ supported, which will have to be installed in the cluster and has to be configured
+ to [allow snippet configurations](https://docs.nginx.com/nginx-ingress-controller/configuration/ingress-resources/advanced-configuration-with-snippets/).
+ An example of a working deployment can be found [here](../supplements/test-cluster/ingress/).
+
+- **ISTIO**
+
+ The operator supports the use of [Istio](https://istio.io/) as a service mesh.
+ An example on how to set up Istio can be found [here](../istio/gerrit.profile.yaml).
+
## Deploy
You will need to have admin privileges for your k8s cluster in order to be able
to deploy the following resources.
@@ -241,6 +289,12 @@
The same holds true for the [Receiver](#receiver) CustomResource, which without
a Gerrit instance using the same site provides little value.
+For now, only a single Gerrit CustomResource using each [mode](./operator-api-reference.md#gerritmode)
+can be deployed in a GerritCluster, e.g. one primary Gerrit and one Gerrit Replica.
+The reason for that is, that there is currently no sharding implemented and thus
+multiple deployments don't bring any more value than just scaling the existing
+deployment. Instead of a primary Gerrit also a Receiver can be installed.
+
### Gerrit
The Gerrit CustomResource deploys a Gerrit, which can run in multiple modes.
@@ -277,7 +331,7 @@
The Receiver-CustomResource installs a Deployment running Apache with a git-http-
backend that is meant to receive pushes performed by Gerrit's replication plugin.
-It is meant to be installed into a GerritCluster that does not include a primary
+It can only be installed into a GerritCluster that does not include a primary
Gerrit, but only Gerrit Replicas.
The Receiver-CustomResource is mainly meant to be used by the GerritCluster-reconciler
diff --git a/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/dependent/GerritClusterIngress.java b/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/dependent/GerritClusterIngress.java
index 5cf4e31..4940021 100644
--- a/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/dependent/GerritClusterIngress.java
+++ b/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/dependent/GerritClusterIngress.java
@@ -14,11 +14,14 @@
package com.google.gerrit.k8s.operator.cluster.dependent;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.flogger.FluentLogger;
import com.google.gerrit.k8s.operator.cluster.model.GerritCluster;
import com.google.gerrit.k8s.operator.gerrit.dependent.GerritService;
import com.google.gerrit.k8s.operator.gerrit.model.Gerrit;
+import com.google.gerrit.k8s.operator.gerrit.model.GerritTemplate;
+import com.google.gerrit.k8s.operator.gerrit.model.GerritTemplateSpec.GerritMode;
import com.google.gerrit.k8s.operator.receiver.dependent.ReceiverService;
-import com.google.gerrit.k8s.operator.receiver.model.Receiver;
import io.fabric8.kubernetes.api.model.networking.v1.HTTPIngressPath;
import io.fabric8.kubernetes.api.model.networking.v1.HTTPIngressPathBuilder;
import io.fabric8.kubernetes.api.model.networking.v1.Ingress;
@@ -34,11 +37,15 @@
import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependent;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
+import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@KubernetesDependent
public class GerritClusterIngress extends CRUDKubernetesDependentResource<Ingress, GerritCluster> {
+ private static final FluentLogger logger = FluentLogger.forEnclosingClass();
+ private static final String UPLOAD_PACK_URL_PATTERN = "/.*/git-upload-pack";
public static final String INGRESS_NAME = "gerrit-ingress";
public GerritClusterIngress() {
@@ -47,109 +54,131 @@
@Override
protected Ingress desired(GerritCluster gerritCluster, Context<GerritCluster> context) {
- List<Gerrit> gerrits =
- gerritCluster.getSpec().getGerrits().stream()
- .map(g -> g.toGerrit(gerritCluster))
- .collect(Collectors.toList());
-
- List<String> hosts = new ArrayList<>();
- List<IngressRule> ingressRules = new ArrayList<>();
-
- if (gerritCluster.getSpec().getReceiver() != null) {
- Receiver receiver = gerritCluster.getSpec().getReceiver().toReceiver(gerritCluster);
- ingressRules.add(getReceiverIngressRule(gerritCluster, receiver));
- hosts.add(
- gerritCluster
- .getSpec()
- .getIngress()
- .getFullHostnameForService(receiver.getMetadata().getName()));
- }
-
- ingressRules.addAll(getGerritIngressRules(gerritCluster, gerrits));
- for (Gerrit gerrit : gerrits) {
- hosts.add(
- gerritCluster
- .getSpec()
- .getIngress()
- .getFullHostnameForService(gerrit.getMetadata().getName()));
- }
-
Ingress gerritIngress =
new IngressBuilder()
.withNewMetadata()
.withName("gerrit-ingress")
.withNamespace(gerritCluster.getMetadata().getNamespace())
.withLabels(gerritCluster.getLabels("gerrit-ingress", this.getClass().getSimpleName()))
- .withAnnotations(gerritCluster.getSpec().getIngress().getAnnotations())
+ .withAnnotations(getAnnotations(gerritCluster))
.endMetadata()
.withNewSpec()
- .withTls(getIngressTLS(gerritCluster, hosts))
- .withRules(ingressRules)
+ .withTls(getIngressTLS(gerritCluster))
+ .withRules(getIngressRule(gerritCluster))
.endSpec()
.build();
return gerritIngress;
}
- private IngressTLS getIngressTLS(GerritCluster gerritCluster, List<String> hosts) {
+ private Map<String, String> getAnnotations(GerritCluster gerritCluster) {
+ Map<String, String> annotations = gerritCluster.getSpec().getIngress().getAnnotations();
+ annotations.put("nginx.ingress.kubernetes.io/use-regex", "true");
+ annotations.put("kubernetes.io/ingress.class", "nginx");
+
+ Optional<GerritTemplate> gerritReplica =
+ gerritCluster.getSpec().getGerrits().stream()
+ .filter(g -> g.getSpec().getMode().equals(GerritMode.REPLICA))
+ .findFirst();
+ if (gerritReplica.isPresent()) {
+ String svcName = GerritService.getName(gerritReplica.get());
+ StringBuilder configSnippet = new StringBuilder();
+ configSnippet.append("if ($args ~ service=git-upload-pack){");
+ configSnippet.append("\n");
+ configSnippet.append(" set $proxy_upstream_name \"");
+ configSnippet.append(gerritCluster.getMetadata().getNamespace());
+ configSnippet.append("-");
+ configSnippet.append(svcName);
+ configSnippet.append("-");
+ configSnippet.append(GerritService.HTTP_PORT_NAME);
+ configSnippet.append("\";\n");
+ configSnippet.append(" set $proxy_host $proxy_upstream_name;");
+ configSnippet.append("\n");
+ configSnippet.append(" set $service_name \"");
+ configSnippet.append(svcName);
+ configSnippet.append("\";\n}");
+ annotations.put(
+ "nginx.ingress.kubernetes.io/configuration-snippet", configSnippet.toString());
+ }
+ return annotations;
+ }
+
+ private IngressTLS getIngressTLS(GerritCluster gerritCluster) {
if (gerritCluster.getSpec().getIngress().getTls().isEnabled()) {
return new IngressTLSBuilder()
- .withHosts(hosts)
+ .withHosts(gerritCluster.getSpec().getIngress().getHost())
.withSecretName(gerritCluster.getSpec().getIngress().getTls().getSecret())
.build();
}
return new IngressTLS();
}
- private List<IngressRule> getGerritIngressRules(
- GerritCluster gerritCluster, List<Gerrit> gerrits) {
- List<IngressRule> ingressRules = new ArrayList<>();
+ private IngressRule getIngressRule(GerritCluster gerritCluster) {
+ List<HTTPIngressPath> ingressPaths = getGerritHTTPIngressPaths(gerritCluster);
+ ingressPaths.addAll(getReceiverIngressPaths(gerritCluster));
- for (Gerrit gerrit : gerrits) {
- String gerritSvcName = GerritService.getName(gerrit);
- ingressRules.add(
- new IngressRuleBuilder()
- .withHost(
- gerritCluster.getSpec().getIngress().getFullHostnameForService(gerritSvcName))
- .withNewHttp()
- .withPaths(getGerritHTTPIngressPath(gerritSvcName))
- .endHttp()
- .build());
- }
-
- return ingressRules;
- }
-
- private IngressRule getReceiverIngressRule(GerritCluster gerritCluster, Receiver receiver) {
return new IngressRuleBuilder()
- .withHost(
- gerritCluster
- .getSpec()
- .getIngress()
- .getFullHostnameForService(receiver.getMetadata().getName()))
+ .withHost(gerritCluster.getSpec().getIngress().getHost())
.withNewHttp()
- .withPaths(getReceiverIngressPaths(ReceiverService.getName(receiver)))
+ .withPaths(ingressPaths)
.endHttp()
.build();
}
- public HTTPIngressPath getGerritHTTPIngressPath(String svcName) {
+ private List<HTTPIngressPath> getGerritHTTPIngressPaths(GerritCluster gerritCluster) {
ServiceBackendPort port =
new ServiceBackendPortBuilder().withName(GerritService.HTTP_PORT_NAME).build();
- return new HTTPIngressPathBuilder()
- .withPathType("Prefix")
- .withPath("/")
- .withNewBackend()
- .withNewService()
- .withName(svcName)
- .withPort(port)
- .endService()
- .endBackend()
- .build();
+ ArrayListMultimap<GerritMode, HTTPIngressPath> pathsByMode = ArrayListMultimap.create();
+ List<Gerrit> gerrits =
+ gerritCluster.getSpec().getGerrits().stream()
+ .map(g -> g.toGerrit(gerritCluster))
+ .collect(Collectors.toList());
+ for (Gerrit gerrit : gerrits) {
+ switch (gerrit.getSpec().getMode()) {
+ case REPLICA:
+ pathsByMode.put(
+ GerritMode.REPLICA,
+ new HTTPIngressPathBuilder()
+ .withPathType("Prefix")
+ .withPath(UPLOAD_PACK_URL_PATTERN)
+ .withNewBackend()
+ .withNewService()
+ .withName(GerritService.getName(gerrit))
+ .withPort(port)
+ .endService()
+ .endBackend()
+ .build());
+ break;
+ case PRIMARY:
+ pathsByMode.put(
+ GerritMode.PRIMARY,
+ new HTTPIngressPathBuilder()
+ .withPathType("Prefix")
+ .withPath("/")
+ .withNewBackend()
+ .withNewService()
+ .withName(GerritService.getName(gerrit))
+ .withPort(port)
+ .endService()
+ .endBackend()
+ .build());
+ break;
+ default:
+ logger.atFine().log(
+ "Encountered unknown Gerrit mode when reconciling Ingress: %s",
+ gerrit.getSpec().getMode());
+ }
+ }
+
+ List<HTTPIngressPath> paths = new ArrayList<>();
+ paths.addAll(pathsByMode.get(GerritMode.REPLICA));
+ paths.addAll(pathsByMode.get(GerritMode.PRIMARY));
+ return paths;
}
- public List<HTTPIngressPath> getReceiverIngressPaths(String svcName) {
+ private List<HTTPIngressPath> getReceiverIngressPaths(GerritCluster gerritCluster) {
+ String svcName = ReceiverService.getName(gerritCluster.getSpec().getReceiver());
List<HTTPIngressPath> paths = new ArrayList<>();
ServiceBackendPort port =
new ServiceBackendPortBuilder().withName(ReceiverService.HTTP_PORT_NAME).build();
diff --git a/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/model/GerritClusterIngressConfig.java b/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/model/GerritClusterIngressConfig.java
index cb82733..5da60bb 100644
--- a/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/model/GerritClusterIngressConfig.java
+++ b/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/model/GerritClusterIngressConfig.java
@@ -79,20 +79,4 @@
public static String getFullHostnameForService(String svcName, String ingressHost) {
return String.format("%s.%s", svcName, ingressHost);
}
-
- @JsonIgnore
- public String getUrl(String svcName) {
- return getUrl(svcName, getTls().isEnabled(), getHost(), getType());
- }
-
- @JsonIgnore
- public static String getUrl(
- String svcName, boolean tlsEnabled, String ingressHost, IngressType ingressType) {
- String protocol = tlsEnabled ? "https" : "http";
- String hostname =
- ingressType == IngressType.ISTIO
- ? ingressHost
- : getFullHostnameForService(svcName, ingressHost);
- return String.format("%s://%s", protocol, hostname);
- }
}
diff --git a/operator/src/main/java/com/google/gerrit/k8s/operator/gerrit/config/GerritConfigBuilder.java b/operator/src/main/java/com/google/gerrit/k8s/operator/gerrit/config/GerritConfigBuilder.java
index 849a995..d6f5ca9 100644
--- a/operator/src/main/java/com/google/gerrit/k8s/operator/gerrit/config/GerritConfigBuilder.java
+++ b/operator/src/main/java/com/google/gerrit/k8s/operator/gerrit/config/GerritConfigBuilder.java
@@ -60,7 +60,7 @@
boolean ingressEnabled = gerrit.getSpec().getIngress().getType() != IngressType.NONE;
if (ingressEnabled) {
- withUrl(gerrit.getSpec().getIngress().getUrl(GerritService.getName(gerrit)));
+ withUrl(gerrit.getSpec().getIngress().getUrl());
} else {
withUrl(GerritService.getUrl(gerrit));
}
diff --git a/operator/src/main/java/com/google/gerrit/k8s/operator/gerrit/dependent/GerritService.java b/operator/src/main/java/com/google/gerrit/k8s/operator/gerrit/dependent/GerritService.java
index 53c2adf..65ea5e4 100644
--- a/operator/src/main/java/com/google/gerrit/k8s/operator/gerrit/dependent/GerritService.java
+++ b/operator/src/main/java/com/google/gerrit/k8s/operator/gerrit/dependent/GerritService.java
@@ -20,6 +20,7 @@
import com.google.gerrit.k8s.operator.cluster.model.GerritCluster;
import com.google.gerrit.k8s.operator.gerrit.GerritReconciler;
import com.google.gerrit.k8s.operator.gerrit.model.Gerrit;
+import com.google.gerrit.k8s.operator.gerrit.model.GerritTemplate;
import io.fabric8.kubernetes.api.model.Service;
import io.fabric8.kubernetes.api.model.ServiceBuilder;
import io.fabric8.kubernetes.api.model.ServicePort;
@@ -60,6 +61,10 @@
return gerrit.getMetadata().getName();
}
+ public static String getName(GerritTemplate gerrit) {
+ return gerrit.getMetadata().getName();
+ }
+
public static String getHostname(Gerrit gerrit) {
return getHostname(gerrit.getMetadata().getName(), gerrit.getMetadata().getNamespace());
}
diff --git a/operator/src/main/java/com/google/gerrit/k8s/operator/receiver/dependent/ReceiverService.java b/operator/src/main/java/com/google/gerrit/k8s/operator/receiver/dependent/ReceiverService.java
index 7ff3b3c..e5d0cb3 100644
--- a/operator/src/main/java/com/google/gerrit/k8s/operator/receiver/dependent/ReceiverService.java
+++ b/operator/src/main/java/com/google/gerrit/k8s/operator/receiver/dependent/ReceiverService.java
@@ -19,6 +19,7 @@
import com.google.gerrit.k8s.operator.cluster.model.GerritCluster;
import com.google.gerrit.k8s.operator.receiver.ReceiverReconciler;
import com.google.gerrit.k8s.operator.receiver.model.Receiver;
+import com.google.gerrit.k8s.operator.receiver.model.ReceiverTemplate;
import io.fabric8.kubernetes.api.model.Service;
import io.fabric8.kubernetes.api.model.ServiceBuilder;
import io.fabric8.kubernetes.api.model.ServicePort;
@@ -59,6 +60,10 @@
return receiver.getMetadata().getName();
}
+ public static String getName(ReceiverTemplate receiver) {
+ return receiver.getMetadata().getName();
+ }
+
public static Map<String, String> getLabels(Receiver receiver) {
return GerritCluster.getLabels(
receiver.getMetadata().getName(),
diff --git a/operator/src/main/java/com/google/gerrit/k8s/operator/server/GerritClusterAdmissionWebhook.java b/operator/src/main/java/com/google/gerrit/k8s/operator/server/GerritClusterAdmissionWebhook.java
index da4d5a7..a2229ae 100644
--- a/operator/src/main/java/com/google/gerrit/k8s/operator/server/GerritClusterAdmissionWebhook.java
+++ b/operator/src/main/java/com/google/gerrit/k8s/operator/server/GerritClusterAdmissionWebhook.java
@@ -45,6 +45,20 @@
.build();
}
+ if (primaryGerritAndReceiverInCluster(gerritCluster)) {
+ return new StatusBuilder()
+ .withCode(HttpServletResponse.SC_CONFLICT)
+ .withMessage("A primary Gerrit cannot be in the same Gerrit Cluster as a Receiver.")
+ .build();
+ }
+
+ if (multipleGerritReplicaInCluster(gerritCluster)) {
+ return new StatusBuilder()
+ .withCode(HttpServletResponse.SC_CONFLICT)
+ .withMessage("Only a single Gerrit Replica is allowed per Gerrit Cluster.")
+ .build();
+ }
+
GerritAdmissionWebhook gerritAdmission = new GerritAdmissionWebhook();
for (GerritTemplate gerrit : gerritCluster.getSpec().getGerrits()) {
Status status = gerritAdmission.validate(gerrit.toGerrit(gerritCluster));
@@ -63,6 +77,19 @@
> 1;
}
+ private boolean primaryGerritAndReceiverInCluster(GerritCluster gerritCluster) {
+ return gerritCluster.getSpec().getGerrits().stream()
+ .anyMatch(g -> g.getSpec().getMode() == GerritMode.PRIMARY)
+ && gerritCluster.getSpec().getReceiver() != null;
+ }
+
+ private boolean multipleGerritReplicaInCluster(GerritCluster gerritCluster) {
+ return gerritCluster.getSpec().getGerrits().stream()
+ .filter(g -> g.getSpec().getMode() == GerritMode.REPLICA)
+ .count()
+ > 1;
+ }
+
@Override
public String getName() {
return "gerritcluster";
diff --git a/operator/src/main/java/com/google/gerrit/k8s/operator/shared/model/IngressConfig.java b/operator/src/main/java/com/google/gerrit/k8s/operator/shared/model/IngressConfig.java
index 6275d39..7b6b0c3 100644
--- a/operator/src/main/java/com/google/gerrit/k8s/operator/shared/model/IngressConfig.java
+++ b/operator/src/main/java/com/google/gerrit/k8s/operator/shared/model/IngressConfig.java
@@ -52,10 +52,9 @@
}
@JsonIgnore
- public String getUrl(String svcName) {
+ public String getUrl() {
String protocol = isTlsEnabled() ? "https" : "http";
- String hostname =
- getType() == IngressType.ISTIO ? getHost() : getFullHostnameForService(svcName);
+ String hostname = getHost();
return String.format("%s://%s", protocol, hostname);
}
}
diff --git a/operator/src/test/java/com/google/gerrit/k8s/operator/gerrit/ClusterManagedGerritE2E.java b/operator/src/test/java/com/google/gerrit/k8s/operator/gerrit/ClusterManagedGerritE2E.java
index 3188bd9..8e92152 100644
--- a/operator/src/test/java/com/google/gerrit/k8s/operator/gerrit/ClusterManagedGerritE2E.java
+++ b/operator/src/test/java/com/google/gerrit/k8s/operator/gerrit/ClusterManagedGerritE2E.java
@@ -123,37 +123,6 @@
}
@Test
- void testMultipleGerritReplicaAreCreated() throws Exception {
- String gerritName = "gerrit-replica-1";
- TestGerrit gerrit =
- new TestGerrit(client, testProps, GerritMode.REPLICA, gerritName, operator.getNamespace());
- gerritCluster.addGerrit(gerrit.createGerritTemplate());
- String gerritName2 = "gerrit-replica-2";
- TestGerrit gerrit2 =
- new TestGerrit(client, testProps, GerritMode.REPLICA, gerritName2, operator.getNamespace());
- gerritCluster.addGerrit(gerrit2.createGerritTemplate());
- gerritCluster.deploy();
-
- assertTrue(
- client
- .pods()
- .inNamespace(operator.getNamespace())
- .withName(gerritName + "-0")
- .inContainer("gerrit")
- .getLog()
- .contains("Gerrit Code Review [replica]"));
-
- assertTrue(
- client
- .pods()
- .inNamespace(operator.getNamespace())
- .withName(gerritName2 + "-0")
- .inContainer("gerrit")
- .getLog()
- .contains("Gerrit Code Review [replica]"));
- }
-
- @Test
void testGerritReplicaAndPrimaryGerritAreCreated() throws Exception {
String primaryGerritName = "gerrit";
TestGerrit primaryGerrit =
diff --git a/operator/src/test/java/com/google/gerrit/k8s/operator/server/GerritClusterAdmissionWebhookTest.java b/operator/src/test/java/com/google/gerrit/k8s/operator/server/GerritClusterAdmissionWebhookTest.java
index b59540f..c97ab7a 100644
--- a/operator/src/test/java/com/google/gerrit/k8s/operator/server/GerritClusterAdmissionWebhookTest.java
+++ b/operator/src/test/java/com/google/gerrit/k8s/operator/server/GerritClusterAdmissionWebhookTest.java
@@ -24,9 +24,14 @@
import com.google.gerrit.k8s.operator.gerrit.model.GerritTemplate;
import com.google.gerrit.k8s.operator.gerrit.model.GerritTemplateSpec.GerritMode;
import com.google.gerrit.k8s.operator.receiver.model.Receiver;
+import com.google.gerrit.k8s.operator.receiver.model.ReceiverTemplate;
+import com.google.gerrit.k8s.operator.receiver.model.ReceiverTemplateSpec;
+import com.google.gerrit.k8s.operator.test.ReceiverUtil;
import com.google.gerrit.k8s.operator.test.TestAdmissionWebhookServer;
import com.google.gerrit.k8s.operator.test.TestGerrit;
import com.google.gerrit.k8s.operator.test.TestGerritCluster;
+import io.fabric8.kubernetes.api.model.ObjectMeta;
+import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
import io.fabric8.kubernetes.api.model.admission.v1.AdmissionRequest;
import io.fabric8.kubernetes.api.model.admission.v1.AdmissionReview;
import io.fabric8.kubernetes.client.server.mock.KubernetesServer;
@@ -103,6 +108,36 @@
}
@Test
+ public void testPrimaryGerritAndReceiverAreNotAcceptedInSameGerritCluster() throws Exception {
+ Config cfg = new Config();
+ cfg.fromText(TestGerrit.DEFAULT_GERRIT_CONFIG);
+ GerritTemplate gerrit = TestGerrit.createGerritTemplate("gerrit1", GerritMode.PRIMARY, cfg);
+ TestGerritCluster gerritCluster =
+ new TestGerritCluster(kubernetesServer.getClient(), NAMESPACE);
+ gerritCluster.addGerrit(gerrit);
+
+ ReceiverTemplate receiver = new ReceiverTemplate();
+ ObjectMeta receiverMeta = new ObjectMetaBuilder().withName("receiver").build();
+ receiver.setMetadata(receiverMeta);
+ ReceiverTemplateSpec receiverTemplateSpec = new ReceiverTemplateSpec();
+ receiverTemplateSpec.setReplicas(2);
+ receiverTemplateSpec.setCredentialSecretRef(ReceiverUtil.CREDENTIALS_SECRET_NAME);
+ receiver.setSpec(receiverTemplateSpec);
+
+ gerritCluster.setReceiver(receiver);
+ HttpURLConnection http2 = sendAdmissionRequest(gerritCluster.build());
+
+ AdmissionReview response2 =
+ new ObjectMapper().readValue(http2.getInputStream(), AdmissionReview.class);
+
+ assertThat(http2.getResponseCode(), is(equalTo(HttpServletResponse.SC_OK)));
+ assertThat(response2.getResponse().getAllowed(), is(false));
+ assertThat(
+ response2.getResponse().getStatus().getCode(),
+ is(equalTo(HttpServletResponse.SC_CONFLICT)));
+ }
+
+ @Test
public void testPrimaryAndReplicaAreAcceptedInSameGerritCluster() throws Exception {
Config cfg = new Config();
cfg.fromText(TestGerrit.DEFAULT_GERRIT_CONFIG);