summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjonmv <venstad@gmail.com>2022-11-15 18:16:23 +0100
committerjonmv <venstad@gmail.com>2022-11-16 09:34:36 +0100
commit18c4b5ec5773ced34eb4700b54799963d74ed0ef (patch)
tree6cfb3e93dd0beafa7ef73bffa2919ced2a753391
parentb88c7d56c33166d7f77c68ca2d5d0d9c684c4017 (diff)
Collapse multiple regions to a single application endpoint
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/RoutingController.java59
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/Endpoint.java65
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/routing/RoutingPolicies.java17
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/routing/RoutingPolicy.java15
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTest.java31
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/EndpointTest.java98
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/certificate/EndpointCertificatesTest.java18
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/TestConfigSerializerTest.java31
8 files changed, 193 insertions, 141 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/RoutingController.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/RoutingController.java
index 38c06e4dac2..aeefc13b7c4 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/RoutingController.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/RoutingController.java
@@ -19,6 +19,7 @@ import com.yahoo.vespa.hosted.controller.api.integration.dns.Record;
import com.yahoo.vespa.hosted.controller.api.integration.dns.RecordData;
import com.yahoo.vespa.hosted.controller.api.integration.dns.RecordName;
import com.yahoo.vespa.hosted.controller.application.Endpoint;
+import com.yahoo.vespa.hosted.controller.application.Endpoint.EndpointFactory;
import com.yahoo.vespa.hosted.controller.application.Endpoint.Port;
import com.yahoo.vespa.hosted.controller.application.EndpointId;
import com.yahoo.vespa.hosted.controller.application.EndpointList;
@@ -71,6 +72,7 @@ public class RoutingController {
private final Controller controller;
private final RoutingPolicies routingPolicies;
private final RotationRepository rotationRepository;
+ private final EndpointFactory endpointFactory;
public RoutingController(Controller controller, RotationsConfig rotationsConfig) {
this.controller = Objects.requireNonNull(controller, "controller must be non-null");
@@ -78,6 +80,7 @@ public class RoutingController {
this.rotationRepository = new RotationRepository(Objects.requireNonNull(rotationsConfig, "rotationsConfig must be non-null"),
controller.applications(),
controller.curator());
+ this.endpointFactory = new EndpointFactory(controller.zoneRegistry());
}
/** Create a routing context for given deployment */
@@ -115,7 +118,7 @@ public class RoutingController {
if (!policy.status().isActive()) continue;
RoutingMethod routingMethod = controller.zoneRegistry().routingMethod(policy.id().zone());
endpoints.addAll(policy.zoneEndpointsIn(controller.system(), routingMethod, controller.zoneRegistry()));
- endpoints.add(policy.regionEndpointIn(controller.system(), routingMethod));
+ endpoints.add(policy.regionEndpointIn(controller.system(), routingMethod, controller.zoneRegistry()));
}
return EndpointList.copyOf(endpoints);
}
@@ -158,23 +161,21 @@ public class RoutingController {
}
// Add application endpoints
for (var declaredEndpoint : deploymentSpec.endpoints()) {
- Map<ZoneId, Map<DeploymentId, Integer>> deployments = declaredEndpoint.targets().stream()
- .collect(groupingBy(t -> ZoneId.from(Environment.prod, t.region()),
- toMap(t -> new DeploymentId(application.id().instance(t.instance()),
- ZoneId.from(Environment.prod, t.region())),
- t -> t.weight())));
-
- deployments.forEach((zone, weightedInstances) -> {
- // Application endpoints are only supported when using direct routing methods
- RoutingMethod routingMethod = usesSharedRouting(zone) ? RoutingMethod.sharedLayer4 : RoutingMethod.exclusive;
- endpoints.add(Endpoint.of(application.id())
- .targetApplication(EndpointId.of(declaredEndpoint.endpointId()),
- ClusterSpec.Id.from(declaredEndpoint.containerId()),
- weightedInstances)
- .routingMethod(routingMethod)
- .on(Port.fromRoutingMethod(routingMethod))
- .in(controller.system()));
- });
+ Map<DeploymentId, Integer> deployments = declaredEndpoint.targets().stream()
+ .collect(toMap(t -> new DeploymentId(application.id().instance(t.instance()),
+ ZoneId.from(Environment.prod, t.region())),
+ t -> t.weight()));
+
+ ZoneId zone = deployments.keySet().iterator().next().zoneId(); // Where multiple zones are possible, they all have the same routing method.
+ // Application endpoints are only supported when using direct routing methods
+ RoutingMethod routingMethod = usesSharedRouting(zone) ? RoutingMethod.sharedLayer4 : RoutingMethod.exclusive;
+ endpoints.add(endpointFactory.of(application.id())
+ .targetApplication(EndpointId.of(declaredEndpoint.endpointId()),
+ ClusterSpec.Id.from(declaredEndpoint.containerId()),
+ deployments)
+ .routingMethod(routingMethod)
+ .on(Port.fromRoutingMethod(routingMethod))
+ .in(controller.system()));
}
return EndpointList.copyOf(endpoints);
}
@@ -207,8 +208,8 @@ public class RoutingController {
List<Endpoint.EndpointBuilder> builders = new ArrayList<>();
if (deployment.zoneId().environment().isProduction()) {
// Add default and wildcard names for global endpoints
- builders.add(Endpoint.of(deployment.applicationId()).target(EndpointId.defaultId()));
- builders.add(Endpoint.of(deployment.applicationId()).wildcard());
+ builders.add(endpointFactory.of(deployment.applicationId()).target(EndpointId.defaultId()));
+ builders.add(endpointFactory.of(deployment.applicationId()).wildcard());
// Add default and wildcard names for each region targeted by application endpoints
List<DeploymentId> deploymentTargets = deploymentSpec.endpoints().stream()
@@ -220,14 +221,14 @@ public class RoutingController {
.toList();
TenantAndApplicationId application = TenantAndApplicationId.from(deployment.applicationId());
for (var targetDeployment : deploymentTargets) {
- builders.add(Endpoint.of(application).targetApplication(EndpointId.defaultId(), targetDeployment));
- builders.add(Endpoint.of(application).wildcardApplication(targetDeployment));
+ builders.add(endpointFactory.of(application).targetApplication(EndpointId.defaultId(), targetDeployment));
+ builders.add(endpointFactory.of(application).wildcardApplication(targetDeployment));
}
}
// Add default and wildcard names for zone endpoints
- builders.add(Endpoint.of(deployment.applicationId()).target(ClusterSpec.Id.from("default"), deployment));
- builders.add(Endpoint.of(deployment.applicationId()).wildcard(deployment));
+ builders.add(endpointFactory.of(deployment.applicationId()).target(ClusterSpec.Id.from("default"), deployment));
+ builders.add(endpointFactory.of(deployment.applicationId()).wildcard(deployment));
// Build all certificate names
for (var builder : builders) {
@@ -398,11 +399,11 @@ public class RoutingController {
throw new IllegalArgumentException("Invalid routing methods for " + routingId + ": Exceeded maximum " +
"direct methods");
}
- endpoints.add(Endpoint.of(routingId.instance())
- .target(routingId.endpointId(), cluster, deployments)
- .on(Port.fromRoutingMethod(method))
- .routingMethod(method)
- .in(controller.system()));
+ endpoints.add(endpointFactory.of(routingId.instance())
+ .target(routingId.endpointId(), cluster, deployments)
+ .on(Port.fromRoutingMethod(method))
+ .routingMethod(method)
+ .in(controller.system()));
}
return endpoints;
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/Endpoint.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/Endpoint.java
index 88366466289..2fe234d6902 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/Endpoint.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/Endpoint.java
@@ -2,6 +2,7 @@
package com.yahoo.vespa.hosted.controller.application;
import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.CloudName;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.InstanceName;
import com.yahoo.config.provision.RegionName;
@@ -10,19 +11,25 @@ import com.yahoo.config.provision.zone.RoutingMethod;
import com.yahoo.config.provision.zone.ZoneId;
import com.yahoo.text.Text;
import com.yahoo.vespa.hosted.controller.api.identifiers.DeploymentId;
+import com.yahoo.vespa.hosted.controller.api.integration.zone.ZoneRegistry;
import java.net.URI;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
+import java.util.Set;
+import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import static java.util.stream.Collectors.toSet;
+
/**
* Represents an application or instance endpoint in hosted Vespa.
- *
+ * <p>
* This encapsulates the logic for building URLs and DNS names for applications in all hosted Vespa systems.
*
* @author mpolden
@@ -160,7 +167,8 @@ public class Endpoint {
}
private static URI createUrl(String name, TenantAndApplicationId application, Optional<InstanceName> instance,
- List<Target> targets, Scope scope, SystemName system, Port port, boolean legacy) {
+ List<Target> targets, Scope scope, SystemName system, Port port, boolean legacy,
+ boolean includeRegionIfApplicationEndpoint) {
String separator = ".";
String portPart = port.isDefault() ? "" : ":" + port.port;
return URI.create("https://" +
@@ -171,7 +179,7 @@ public class Endpoint {
separator +
sanitize(application.tenant().value()) +
"." +
- scopePart(scope, targets, system, legacy) +
+ scopePart(scope, targets, system, legacy, includeRegionIfApplicationEndpoint) +
dnsSuffix(system, legacy) +
portPart +
"/");
@@ -186,9 +194,11 @@ public class Endpoint {
return name + separator;
}
- private static String scopePart(Scope scope, List<Target> targets, SystemName system, boolean legacy) {
+ private static String scopePart(Scope scope, List<Target> targets, SystemName system, boolean legacy, boolean includeRegionIfApplicationEndpoint) {
String scopeSymbol = scopeSymbol(scope, system);
+ Set<ZoneId> zones = targets.stream().map(target -> target.deployment.zoneId()).collect(toSet());
if (scope == Scope.global) return scopeSymbol;
+ if (scope == Scope.application && ! includeRegionIfApplicationEndpoint) return scopeSymbol;
ZoneId zone = targets.get(0).deployment().zoneId();
String region = zone.region().value();
@@ -414,14 +424,34 @@ public class Endpoint {
}
- /** Build an endpoint for given instance */
- public static EndpointBuilder of(ApplicationId instance) {
- return new EndpointBuilder(TenantAndApplicationId.from(instance), Optional.of(instance.instance()));
- }
+ public static class EndpointFactory {
+
+ private final Function<ZoneId, CloudName> clouds;
+
+ public EndpointFactory(Function<ZoneId, CloudName> clouds) {
+ this.clouds = clouds;
+ }
+
+ public EndpointFactory(ZoneRegistry zones) {
+ this(zone -> findCloud(zone, zones));
+ }
+
+ /** Build an endpoint for given instance */
+ public EndpointBuilder of(ApplicationId instance) {
+ return new EndpointBuilder(TenantAndApplicationId.from(instance), Optional.of(instance.instance()), clouds);
+ }
+
+ /** Build an endpoint for given application */
+ public EndpointBuilder of(TenantAndApplicationId application) {
+ return new EndpointBuilder(application, Optional.empty(), clouds);
+ }
+
+ private static CloudName findCloud(ZoneId zone, ZoneRegistry zones) {
+ return zones.zones().all().get(zone)
+ .orElseThrow(() -> new IllegalArgumentException("unknown zone '" + zone + "'"))
+ .getCloudName();
+ }
- /** Build an endpoint for given application */
- public static EndpointBuilder of(TenantAndApplicationId application) {
- return new EndpointBuilder(application, Optional.empty());
}
/** A target of an endpoint */
@@ -464,6 +494,8 @@ public class Endpoint {
private final TenantAndApplicationId application;
private final Optional<InstanceName> instance;
+ private final Function<ZoneId, CloudName> cloudFinder;
+ private final Set<CloudName> clouds = new HashSet<>();
private Scope scope;
private List<Target> targets;
private ClusterSpec.Id cluster;
@@ -473,9 +505,10 @@ public class Endpoint {
private boolean legacy = false;
private boolean certificateName = false;
- private EndpointBuilder(TenantAndApplicationId application, Optional<InstanceName> instance) {
+ private EndpointBuilder(TenantAndApplicationId application, Optional<InstanceName> instance, Function<ZoneId, CloudName> cloudFinder) {
this.application = Objects.requireNonNull(application);
this.instance = Objects.requireNonNull(instance);
+ this.cloudFinder = Objects.requireNonNull(cloudFinder);
}
/** Sets the deployment target for this */
@@ -483,6 +516,7 @@ public class Endpoint {
this.cluster = cluster;
this.scope = requireUnset(Scope.zone);
this.targets = List.of(new Target(deployment));
+ this.clouds.add(cloudFinder.apply(deployment.zoneId()));
return this;
}
@@ -492,6 +526,7 @@ public class Endpoint {
this.cluster = cluster;
this.targets = deployments.stream().map(Target::new).toList();
this.scope = requireUnset(Scope.global);
+ for (DeploymentId deployment : deployments) this.clouds.add(cloudFinder.apply(deployment.zoneId()));
return this;
}
@@ -528,6 +563,7 @@ public class Endpoint {
.map(kv -> new Target(kv.getKey(), kv.getValue()))
.toList();
this.scope = Scope.application;
+ for (DeploymentId deploymentId : deployments.keySet()) this.clouds.add(cloudFinder.apply(deploymentId.zoneId()));
return this;
}
@@ -536,6 +572,7 @@ public class Endpoint {
this.cluster = cluster;
this.scope = requireUnset(Scope.weighted);
this.targets = List.of(new Target(new DeploymentId(application.instance(instance.get()), effectiveZone(zone))));
+ this.clouds.add(cloudFinder.apply(zone));
return this;
}
@@ -571,6 +608,7 @@ public class Endpoint {
if (routingMethod.isDirect() && !port.isDefault()) {
throw new IllegalArgumentException("Routing method " + routingMethod + " can only use default port");
}
+ boolean includeRegionIfApplicationEndpoint = ! Set.of(CloudName.AWS, CloudName.GCP).containsAll(clouds);
URI url = createUrl(endpointOrClusterAsString(endpointId, cluster),
Objects.requireNonNull(application, "application must be non-null"),
Objects.requireNonNull(instance, "instance must be non-null"),
@@ -578,7 +616,8 @@ public class Endpoint {
Objects.requireNonNull(scope, "scope must be non-null"),
Objects.requireNonNull(system, "system must be non-null"),
Objects.requireNonNull(port, "port must be non-null"),
- legacy);
+ legacy,
+ includeRegionIfApplicationEndpoint);
return new Endpoint(application,
instance,
endpointId,
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/routing/RoutingPolicies.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/routing/RoutingPolicies.java
index 27247c065ed..d3dbfc0f5e9 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/routing/RoutingPolicies.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/routing/RoutingPolicies.java
@@ -215,7 +215,7 @@ public class RoutingPolicies {
for (var policy : policies) {
if (policy.dnsZone().isEmpty() && policy.canonicalName().isPresent()) continue;
if (controller.zoneRegistry().routingMethod(policy.id().zone()) != RoutingMethod.exclusive) continue;
- Endpoint endpoint = policy.regionEndpointIn(controller.system(), RoutingMethod.exclusive);
+ Endpoint endpoint = policy.regionEndpointIn(controller.system(), RoutingMethod.exclusive, controller.zoneRegistry());
var zonePolicy = db.readZoneRoutingPolicy(policy.id().zone());
long weight = 1;
if (isConfiguredOut(zonePolicy, policy, inactiveZones)) {
@@ -289,12 +289,10 @@ public class RoutingPolicies {
activeTargets.addAll(inactiveTargets);
inactiveTargets.clear();
}
+
targetsByEndpoint.forEach((applicationEndpoint, targets) -> {
- ZoneId targetZone = applicationEndpoint.targets().stream()
- .map(Endpoint.Target::deployment)
- .map(DeploymentId::zoneId)
- .findFirst()
- .get();
+ // Where multiple zones are permitted, they all have the same routing policy, and nameServiceForwarder (below).
+ ZoneId targetZone = applicationEndpoint.targets().iterator().next().deployment().zoneId();
Set<AliasTarget> aliasTargets = new LinkedHashSet<>();
Set<DirectTarget> directTargets = new LinkedHashSet<>();
for (Target target : targets) {
@@ -312,11 +310,8 @@ public class RoutingPolicies {
}
});
inactiveTargetsByEndpoint.forEach((applicationEndpoint, targets) -> {
- ZoneId targetZone = applicationEndpoint.targets().stream()
- .map(Endpoint.Target::deployment)
- .map(DeploymentId::zoneId)
- .findFirst()
- .get();
+ // Where multiple zones are permitted, they all have the same routing policy, and nameServiceForwarder (below).
+ ZoneId targetZone = applicationEndpoint.targets().iterator().next().deployment().zoneId();
targets.forEach(target -> {
nameServiceForwarderIn(targetZone).removeRecords(target.type(),
RecordName.from(applicationEndpoint.dnsName()),
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/routing/RoutingPolicy.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/routing/RoutingPolicy.java
index 04c32590a4c..269ad0a65fd 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/routing/RoutingPolicy.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/routing/RoutingPolicy.java
@@ -9,6 +9,7 @@ import com.yahoo.text.Text;
import com.yahoo.vespa.hosted.controller.api.identifiers.DeploymentId;
import com.yahoo.vespa.hosted.controller.api.integration.zone.ZoneRegistry;
import com.yahoo.vespa.hosted.controller.application.Endpoint;
+import com.yahoo.vespa.hosted.controller.application.Endpoint.EndpointFactory;
import com.yahoo.vespa.hosted.controller.application.Endpoint.Port;
import com.yahoo.vespa.hosted.controller.application.EndpointId;
@@ -96,12 +97,12 @@ public record RoutingPolicy(RoutingPolicyId id,
/** Returns the zone endpoints of this */
public List<Endpoint> zoneEndpointsIn(SystemName system, RoutingMethod routingMethod, ZoneRegistry zoneRegistry) {
DeploymentId deployment = new DeploymentId(id.owner(), id.zone());
- return List.of(endpoint(routingMethod).target(id.cluster(), deployment).in(system));
+ return List.of(endpoint(routingMethod, zoneRegistry).target(id.cluster(), deployment).in(system));
}
/** Returns the region endpoint of this */
- public Endpoint regionEndpointIn(SystemName system, RoutingMethod routingMethod) {
- return endpoint(routingMethod).targetRegion(id.cluster(), id.zone()).in(system);
+ public Endpoint regionEndpointIn(SystemName system, RoutingMethod routingMethod, ZoneRegistry zoneRegistry) {
+ return endpoint(routingMethod, zoneRegistry).targetRegion(id.cluster(), id.zone()).in(system);
}
@Override
@@ -125,10 +126,10 @@ public record RoutingPolicy(RoutingPolicyId id,
id.zone().value());
}
- private Endpoint.EndpointBuilder endpoint(RoutingMethod routingMethod) {
- return Endpoint.of(id.owner())
- .on(Port.fromRoutingMethod(routingMethod))
- .routingMethod(routingMethod);
+ private Endpoint.EndpointBuilder endpoint(RoutingMethod routingMethod, ZoneRegistry zones) {
+ return new EndpointFactory(zones).of(id.owner())
+ .on(Port.fromRoutingMethod(routingMethod))
+ .routingMethod(routingMethod);
}
/** The status of a routing policy */
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTest.java
index c87a4e490b9..2cc3cff455c 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTest.java
@@ -669,12 +669,12 @@ public class ControllerTest {
new DeploymentId(main, east3), Map.of("e.app1.tenant1.us-east-3-r.vespa.oath.cloud", 3),
new DeploymentId(beta, west1), Map.of("d.app1.tenant1.us-west-1-r.vespa.oath.cloud", 3),
new DeploymentId(main, west1), Map.of("d.app1.tenant1.us-west-1-r.vespa.oath.cloud", 7),
- new DeploymentId(beta, east1a), Map.of("a.app1.tenant1.aws-us-east-1a-r.vespa.oath.cloud", 2,
- "b.app1.tenant1.aws-us-east-1a-r.vespa.oath.cloud", 1),
- new DeploymentId(main, east1a), Map.of("a.app1.tenant1.aws-us-east-1a-r.vespa.oath.cloud", 8,
- "b.app1.tenant1.aws-us-east-1a-r.vespa.oath.cloud", 1),
- new DeploymentId(beta, east1b), Map.of("c.app1.tenant1.aws-us-east-1b-r.vespa.oath.cloud", 4),
- new DeploymentId(main, east1b), Map.of("a.app1.tenant1.aws-us-east-1b-r.vespa.oath.cloud", 1)
+ new DeploymentId(beta, east1a), Map.of("a.app1.tenant1.r.vespa.oath.cloud", 2,
+ "b.app1.tenant1.r.vespa.oath.cloud", 1),
+ new DeploymentId(main, east1a), Map.of("a.app1.tenant1.r.vespa.oath.cloud", 8,
+ "b.app1.tenant1.r.vespa.oath.cloud", 1),
+ new DeploymentId(beta, east1b), Map.of("c.app1.tenant1.r.vespa.oath.cloud", 4),
+ new DeploymentId(main, east1b), Map.of("a.app1.tenant1.r.vespa.oath.cloud", 1)
);
deploymentEndpoints.forEach((deployment, endpoints) -> {
Set<ContainerEndpoint> expected = endpoints.entrySet().stream()
@@ -704,22 +704,22 @@ public class ControllerTest {
RecordName.from("main.app1.tenant1.aws-us-east-1b.vespa.oath.cloud"),
RecordData.from("lb-0--tenant1.app1.main--prod.aws-us-east-1b.")),
new Record(Record.Type.ALIAS,
- RecordName.from("a.app1.tenant1.aws-us-east-1a-r.vespa.oath.cloud"),
+ RecordName.from("a.app1.tenant1.r.vespa.oath.cloud"),
RecordData.from("weighted/lb-0--tenant1.app1.beta--prod.aws-us-east-1a/dns-zone-1/prod.aws-us-east-1a/2")),
new Record(Record.Type.ALIAS,
- RecordName.from("a.app1.tenant1.aws-us-east-1a-r.vespa.oath.cloud"),
+ RecordName.from("a.app1.tenant1.r.vespa.oath.cloud"),
RecordData.from("weighted/lb-0--tenant1.app1.main--prod.aws-us-east-1a/dns-zone-1/prod.aws-us-east-1a/8")),
new Record(Record.Type.ALIAS,
- RecordName.from("a.app1.tenant1.aws-us-east-1b-r.vespa.oath.cloud"),
+ RecordName.from("a.app1.tenant1.r.vespa.oath.cloud"),
RecordData.from("weighted/lb-0--tenant1.app1.main--prod.aws-us-east-1b/dns-zone-1/prod.aws-us-east-1b/1")),
new Record(Record.Type.ALIAS,
- RecordName.from("b.app1.tenant1.aws-us-east-1a-r.vespa.oath.cloud"),
+ RecordName.from("b.app1.tenant1.r.vespa.oath.cloud"),
RecordData.from("weighted/lb-0--tenant1.app1.beta--prod.aws-us-east-1a/dns-zone-1/prod.aws-us-east-1a/1")),
new Record(Record.Type.ALIAS,
- RecordName.from("b.app1.tenant1.aws-us-east-1a-r.vespa.oath.cloud"),
+ RecordName.from("b.app1.tenant1.r.vespa.oath.cloud"),
RecordData.from("weighted/lb-0--tenant1.app1.main--prod.aws-us-east-1a/dns-zone-1/prod.aws-us-east-1a/1")),
new Record(Record.Type.ALIAS,
- RecordName.from("c.app1.tenant1.aws-us-east-1b-r.vespa.oath.cloud"),
+ RecordName.from("c.app1.tenant1.r.vespa.oath.cloud"),
RecordData.from("weighted/lb-0--tenant1.app1.beta--prod.aws-us-east-1b/dns-zone-1/prod.aws-us-east-1b/4")),
new Record(Record.Type.CNAME,
RecordName.from("d.app1.tenant1.us-west-1-r.vespa.oath.cloud"),
@@ -732,10 +732,9 @@ public class ControllerTest {
.scope(Endpoint.Scope.application)
.sortedBy(comparing(Endpoint::dnsName))
.mapToList(Endpoint::dnsName);
- assertEquals(List.of("a.app1.tenant1.aws-us-east-1a-r.vespa.oath.cloud",
- "a.app1.tenant1.aws-us-east-1b-r.vespa.oath.cloud",
- "b.app1.tenant1.aws-us-east-1a-r.vespa.oath.cloud",
- "c.app1.tenant1.aws-us-east-1b-r.vespa.oath.cloud",
+ assertEquals(List.of("a.app1.tenant1.r.vespa.oath.cloud",
+ "b.app1.tenant1.r.vespa.oath.cloud",
+ "c.app1.tenant1.r.vespa.oath.cloud",
"d.app1.tenant1.us-west-1-r.vespa.oath.cloud",
"e.app1.tenant1.us-east-3-r.vespa.oath.cloud"),
endpointDnsNames);
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/EndpointTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/EndpointTest.java
index f3324e0c1f3..f56b63dd2d9 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/EndpointTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/EndpointTest.java
@@ -2,11 +2,13 @@
package com.yahoo.vespa.hosted.controller.application;
import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.CloudName;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.SystemName;
import com.yahoo.config.provision.zone.RoutingMethod;
import com.yahoo.config.provision.zone.ZoneId;
import com.yahoo.vespa.hosted.controller.api.identifiers.DeploymentId;
+import com.yahoo.vespa.hosted.controller.application.Endpoint.EndpointFactory;
import com.yahoo.vespa.hosted.controller.application.Endpoint.Port;
import org.junit.jupiter.api.Test;
@@ -24,6 +26,8 @@ public class EndpointTest {
private static final ApplicationId instance2 = ApplicationId.from("t2", "a2", "i2");
private static final TenantAndApplicationId app1 = TenantAndApplicationId.from(instance1);
private static final TenantAndApplicationId app2 = TenantAndApplicationId.from(instance2);
+ private static final EndpointFactory defaultFactory = new EndpointFactory(__ -> CloudName.DEFAULT);
+ private static final EndpointFactory otherFactory = new EndpointFactory(__ -> CloudName.AWS);
@Test
void global_endpoints() {
@@ -35,38 +39,38 @@ public class EndpointTest {
Map<String, Endpoint> tests = Map.of(
// Main endpoint with direct routing and default TLS port
"https://a1.t1.global.vespa.oath.cloud/",
- Endpoint.of(instance1).target(endpointId, cluster, List.of(deployment1)).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.main),
+ defaultFactory.of(instance1).target(endpointId, cluster, List.of(deployment1)).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.main),
// Main endpoint with custom rotation name
"https://r1.a1.t1.global.vespa.oath.cloud/",
- Endpoint.of(instance1).target(EndpointId.of("r1"), cluster, List.of(deployment1)).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.main),
+ defaultFactory.of(instance1).target(EndpointId.of("r1"), cluster, List.of(deployment1)).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.main),
// Main endpoint for custom instance in default rotation
"https://i2.a2.t2.global.vespa.oath.cloud/",
- Endpoint.of(instance2).target(endpointId, cluster, List.of(deployment2)).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.main),
+ defaultFactory.of(instance2).target(endpointId, cluster, List.of(deployment2)).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.main),
// Main endpoint for custom instance with custom rotation name
"https://r2.i2.a2.t2.global.vespa.oath.cloud/",
- Endpoint.of(instance2).target(EndpointId.of("r2"), cluster, List.of(deployment2)).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.main),
+ defaultFactory.of(instance2).target(EndpointId.of("r2"), cluster, List.of(deployment2)).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.main),
// Main endpoint in public system
"https://a1.t1.g.vespa-app.cloud/",
- Endpoint.of(instance1).target(endpointId, cluster, List.of(deployment1)).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.Public)
+ defaultFactory.of(instance1).target(endpointId, cluster, List.of(deployment1)).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.Public)
);
tests.forEach((expected, endpoint) -> assertEquals(expected, endpoint.url().toString()));
Map<String, Endpoint> tests2 = Map.of(
// Default endpoint in public system
"https://a1.t1.g.vespa-app.cloud/",
- Endpoint.of(instance1).target(endpointId, cluster, List.of(deployment1)).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.Public),
+ defaultFactory.of(instance1).target(endpointId, cluster, List.of(deployment1)).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.Public),
// Default endpoint in public CD system
"https://a1.t1.g.cd.vespa-app.cloud/",
- Endpoint.of(instance1).target(endpointId, cluster, List.of(deployment1)).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.PublicCd),
+ defaultFactory.of(instance1).target(endpointId, cluster, List.of(deployment1)).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.PublicCd),
// Custom instance in public system
"https://i2.a2.t2.g.vespa-app.cloud/",
- Endpoint.of(instance2).target(endpointId, cluster, List.of(deployment2)).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.Public)
+ defaultFactory.of(instance2).target(endpointId, cluster, List.of(deployment2)).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.Public)
);
tests2.forEach((expected, endpoint) -> assertEquals(expected, endpoint.url().toString()));
}
@@ -81,34 +85,34 @@ public class EndpointTest {
Map<String, Endpoint> tests = Map.of(
// Main endpoint with direct routing and default TLS port
"https://a1.t1.global.vespa.oath.cloud/",
- Endpoint.of(instance1).target(endpointId, cluster, List.of(deployment1)).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.main),
+ defaultFactory.of(instance1).target(endpointId, cluster, List.of(deployment1)).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.main),
// Main endpoint with custom rotation name
"https://r1.a1.t1.global.vespa.oath.cloud/",
- Endpoint.of(instance1).target(EndpointId.of("r1"), cluster, List.of(deployment1)).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.main),
+ defaultFactory.of(instance1).target(EndpointId.of("r1"), cluster, List.of(deployment1)).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.main),
// Main endpoint for custom instance in default rotation
"https://i2.a2.t2.global.vespa.oath.cloud/",
- Endpoint.of(instance2).target(endpointId, cluster, List.of(deployment2)).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.main),
+ defaultFactory.of(instance2).target(endpointId, cluster, List.of(deployment2)).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.main),
// Main endpoint for custom instance with custom rotation name
"https://r2.i2.a2.t2.global.vespa.oath.cloud/",
- Endpoint.of(instance2).target(EndpointId.of("r2"), cluster, List.of(deployment2)).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.main),
+ defaultFactory.of(instance2).target(EndpointId.of("r2"), cluster, List.of(deployment2)).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.main),
// Main endpoint in public system
"https://a1.t1.g.vespa-app.cloud/",
- Endpoint.of(instance1).target(endpointId, cluster, List.of(deployment1)).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.Public)
+ defaultFactory.of(instance1).target(endpointId, cluster, List.of(deployment1)).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.Public)
);
tests.forEach((expected, endpoint) -> assertEquals(expected, endpoint.url().toString()));
Map<String, Endpoint> tests2 = Map.of(
// Custom endpoint and instance in public CD system)
"https://foo.i2.a2.t2.g.cd.vespa-app.cloud/",
- Endpoint.of(instance2).target(EndpointId.of("foo"), cluster, List.of(deployment2)).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.PublicCd),
+ defaultFactory.of(instance2).target(EndpointId.of("foo"), cluster, List.of(deployment2)).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.PublicCd),
// Custom endpoint and instance in public system
"https://foo.i2.a2.t2.g.vespa-app.cloud/",
- Endpoint.of(instance2).target(EndpointId.of("foo"), cluster, List.of(deployment2)).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.Public)
+ defaultFactory.of(instance2).target(EndpointId.of("foo"), cluster, List.of(deployment2)).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.Public)
);
tests2.forEach((expected, endpoint) -> assertEquals(expected, endpoint.url().toString()));
}
@@ -123,50 +127,50 @@ public class EndpointTest {
Map<String, Endpoint> tests = Map.of(
// Prod endpoint in main
"https://a1.t1.us-north-1.vespa.oath.cloud/",
- Endpoint.of(instance1).target(cluster, prodZone).on(Port.tls()).in(SystemName.main),
+ defaultFactory.of(instance1).target(cluster, prodZone).on(Port.tls()).in(SystemName.main),
// Prod endpoint in CD
"https://cd.a1.t1.us-north-1.vespa.oath.cloud/",
- Endpoint.of(instance1).target(cluster, prodZone).on(Port.tls()).in(SystemName.cd),
+ defaultFactory.of(instance1).target(cluster, prodZone).on(Port.tls()).in(SystemName.cd),
// Test endpoint in main
"https://a1.t1.us-north-2.test.vespa.oath.cloud/",
- Endpoint.of(instance1).target(cluster, testZone).on(Port.tls()).in(SystemName.main),
+ defaultFactory.of(instance1).target(cluster, testZone).on(Port.tls()).in(SystemName.main),
// Non-default cluster in main
"https://c1.a1.t1.us-north-1.vespa.oath.cloud/",
- Endpoint.of(instance1).target(ClusterSpec.Id.from("c1"), prodZone).on(Port.tls()).in(SystemName.main),
+ defaultFactory.of(instance1).target(ClusterSpec.Id.from("c1"), prodZone).on(Port.tls()).in(SystemName.main),
// Non-default instance in main
"https://i2.a2.t2.us-north-1.vespa.oath.cloud/",
- Endpoint.of(instance2).target(cluster, prodZone2).on(Port.tls()).in(SystemName.main),
+ defaultFactory.of(instance2).target(cluster, prodZone2).on(Port.tls()).in(SystemName.main),
// Non-default cluster in public
"https://c1.a1.t1.us-north-1.z.vespa-app.cloud/",
- Endpoint.of(instance1).target(ClusterSpec.Id.from("c1"), prodZone).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.Public),
+ defaultFactory.of(instance1).target(ClusterSpec.Id.from("c1"), prodZone).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.Public),
// Non-default cluster and instance in public
"https://c2.i2.a2.t2.us-north-1.z.vespa-app.cloud/",
- Endpoint.of(instance2).target(ClusterSpec.Id.from("c2"), prodZone2).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.Public)
+ defaultFactory.of(instance2).target(ClusterSpec.Id.from("c2"), prodZone2).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.Public)
);
tests.forEach((expected, endpoint) -> assertEquals(expected, endpoint.url().toString()));
Map<String, Endpoint> tests2 = Map.of(
// Non-default cluster and instance in public CD (legacy)
"https://c2.i2.a2.t2.us-north-1.z.cd.vespa-app.cloud/",
- Endpoint.of(instance2).target(ClusterSpec.Id.from("c2"), prodZone2).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.PublicCd),
+ defaultFactory.of(instance2).target(ClusterSpec.Id.from("c2"), prodZone2).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.PublicCd),
// Custom cluster name in public
"https://c1.a1.t1.us-north-1.z.vespa-app.cloud/",
- Endpoint.of(instance1).target(ClusterSpec.Id.from("c1"), prodZone).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.Public),
+ defaultFactory.of(instance1).target(ClusterSpec.Id.from("c1"), prodZone).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.Public),
// Default cluster name in non-production zone in public
"https://a1.t1.us-north-2.test.z.vespa-app.cloud/",
- Endpoint.of(instance1).target(ClusterSpec.Id.from("default"), testZone).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.Public),
+ defaultFactory.of(instance1).target(ClusterSpec.Id.from("default"), testZone).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.Public),
// Default cluster name in public CD
"https://a1.t1.us-north-1.z.cd.vespa-app.cloud/",
- Endpoint.of(instance1).target(ClusterSpec.Id.from("default"), prodZone).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.PublicCd)
+ defaultFactory.of(instance1).target(ClusterSpec.Id.from("default"), prodZone).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.PublicCd)
);
tests2.forEach((expected, endpoint) -> assertEquals(expected, endpoint.url().toString()));
}
@@ -180,7 +184,7 @@ public class EndpointTest {
var tests = Map.of(
// Default rotation
"https://a1.t1.g.vespa-app.cloud/",
- Endpoint.of(instance1)
+ defaultFactory.of(instance1)
.target(EndpointId.defaultId())
.certificateName()
.routingMethod(RoutingMethod.exclusive)
@@ -189,7 +193,7 @@ public class EndpointTest {
// Wildcard to match other rotations
"https://*.a1.t1.g.vespa-app.cloud/",
- Endpoint.of(instance1)
+ defaultFactory.of(instance1)
.wildcard()
.certificateName()
.routingMethod(RoutingMethod.exclusive)
@@ -198,7 +202,7 @@ public class EndpointTest {
// Default cluster in zone
"https://a1.t1.us-north-1.z.vespa-app.cloud/",
- Endpoint.of(instance1)
+ defaultFactory.of(instance1)
.target(defaultCluster, prodZone)
.certificateName()
.routingMethod(RoutingMethod.exclusive)
@@ -207,7 +211,7 @@ public class EndpointTest {
// Default cluster in test zone
"https://a1.t1.us-north-2.test.z.vespa-app.cloud/",
- Endpoint.of(instance1)
+ defaultFactory.of(instance1)
.target(defaultCluster, testZone)
.certificateName()
.routingMethod(RoutingMethod.exclusive)
@@ -216,7 +220,7 @@ public class EndpointTest {
// Wildcard to match other clusters in test zone
"https://*.a1.t1.us-north-2.test.z.vespa-app.cloud/",
- Endpoint.of(instance1)
+ defaultFactory.of(instance1)
.wildcard(testZone)
.certificateName()
.routingMethod(RoutingMethod.exclusive)
@@ -225,7 +229,7 @@ public class EndpointTest {
// Wildcard to match other clusters in zone
"https://*.a1.t1.us-north-1.z.vespa-app.cloud/",
- Endpoint.of(instance1)
+ defaultFactory.of(instance1)
.wildcard(prodZone)
.certificateName()
.routingMethod(RoutingMethod.exclusive)
@@ -242,25 +246,25 @@ public class EndpointTest {
var prodZone = ZoneId.from("prod", "us-north-2");
Map<String, Endpoint> tests = Map.of(
"https://a1.t1.aws-us-north-1.w.vespa-app.cloud/",
- Endpoint.of(instance1)
+ defaultFactory.of(instance1)
.targetRegion(cluster, ZoneId.from("prod", "aws-us-north-1a"))
.routingMethod(RoutingMethod.exclusive)
.on(Port.tls())
.in(SystemName.Public),
"https://a1.t1.gcp-us-south1.w.vespa-app.cloud/",
- Endpoint.of(instance1)
+ defaultFactory.of(instance1)
.targetRegion(cluster, ZoneId.from("prod", "gcp-us-south1-c"))
.routingMethod(RoutingMethod.exclusive)
.on(Port.tls())
.in(SystemName.Public),
"https://a1.t1.us-north-2.w.vespa-app.cloud/",
- Endpoint.of(instance1)
+ defaultFactory.of(instance1)
.targetRegion(cluster, prodZone)
.routingMethod(RoutingMethod.exclusive)
.on(Port.tls())
.in(SystemName.Public),
"https://c1.a1.t1.us-north-2.w.vespa-app.cloud/",
- Endpoint.of(instance1)
+ defaultFactory.of(instance1)
.targetRegion(ClusterSpec.Id.from("c1"), prodZone)
.routingMethod(RoutingMethod.exclusive)
.on(Port.tls())
@@ -279,29 +283,29 @@ public class EndpointTest {
@Test
void application_endpoints() {
Map<String, Endpoint> tests = Map.of(
- "https://weighted.a1.t1.us-west-1.r.vespa-app.cloud/",
- Endpoint.of(app1)
+ "https://weighted.a1.t1.r.vespa-app.cloud/",
+ otherFactory.of(app1)
.targetApplication(EndpointId.of("weighted"), ClusterSpec.Id.from("qrs"),
Map.of(new DeploymentId(app1.instance("i1"), ZoneId.from("prod", "us-west-1")), 1))
.routingMethod(RoutingMethod.exclusive)
.on(Port.tls())
.in(SystemName.Public),
"https://weighted.a1.t1.us-west-1.r.cd.vespa-app.cloud/",
- Endpoint.of(app1)
+ defaultFactory.of(app1)
.targetApplication(EndpointId.of("weighted"), ClusterSpec.Id.from("qrs"),
Map.of(new DeploymentId(app1.instance("i1"), ZoneId.from("prod", "us-west-1")), 1))
.routingMethod(RoutingMethod.exclusive)
.on(Port.tls())
.in(SystemName.PublicCd),
- "https://a2.t2.us-east-3-r.vespa.oath.cloud/",
- Endpoint.of(app2)
+ "https://a2.t2.r.vespa.oath.cloud/",
+ otherFactory.of(app2)
.targetApplication(EndpointId.defaultId(), ClusterSpec.Id.from("qrs"),
Map.of(new DeploymentId(app2.instance("i1"), ZoneId.from("prod", "us-east-3")), 1))
.routingMethod(RoutingMethod.exclusive)
.on(Port.tls())
.in(SystemName.main),
"https://cd.a2.t2.us-east-3-r.vespa.oath.cloud/",
- Endpoint.of(app2)
+ defaultFactory.of(app2)
.targetApplication(EndpointId.defaultId(), ClusterSpec.Id.from("qrs"),
Map.of(new DeploymentId(app2.instance("i1"), ZoneId.from("prod", "us-east-3")), 1))
.routingMethod(RoutingMethod.exclusive)
@@ -318,15 +322,15 @@ public class EndpointTest {
var tests1 = Map.of(
// With default cluster
"a1.t1.us-north-1.prod",
- Endpoint.of(instance1).target(EndpointId.defaultId(), ClusterSpec.Id.from("default"), List.of(zone)).on(Port.tls()).in(SystemName.main),
+ defaultFactory.of(instance1).target(EndpointId.defaultId(), ClusterSpec.Id.from("default"), List.of(zone)).on(Port.tls()).in(SystemName.main),
// With non-default cluster
"c1.a1.t1.us-north-1.prod",
- Endpoint.of(instance1).target(EndpointId.of("ignored1"), ClusterSpec.Id.from("c1"), List.of(zone)).on(Port.tls()).in(SystemName.main),
+ defaultFactory.of(instance1).target(EndpointId.of("ignored1"), ClusterSpec.Id.from("c1"), List.of(zone)).on(Port.tls()).in(SystemName.main),
// With application endpoint
"c2.a1.t1.us-north-1.prod",
- Endpoint.of(app1).targetApplication(EndpointId.defaultId(), ClusterSpec.Id.from("c2"), Map.of(new DeploymentId(app1.instance("i1"), zone.zoneId()), 1))
+ defaultFactory.of(app1).targetApplication(EndpointId.defaultId(), ClusterSpec.Id.from("c2"), Map.of(new DeploymentId(app1.instance("i1"), zone.zoneId()), 1))
.routingMethod(RoutingMethod.sharedLayer4)
.on(Port.tls())
.in(SystemName.main)
@@ -334,11 +338,11 @@ public class EndpointTest {
var tests2 = Map.of(
// With non-default instance and default cluster
"i2.a2.t2.us-north-1.prod",
- Endpoint.of(instance2).target(EndpointId.defaultId(), ClusterSpec.Id.from("default"), List.of(zone2)).on(Port.tls()).in(SystemName.main),
+ defaultFactory.of(instance2).target(EndpointId.defaultId(), ClusterSpec.Id.from("default"), List.of(zone2)).on(Port.tls()).in(SystemName.main),
// With non-default instance and cluster
"c2.i2.a2.t2.us-north-1.prod",
- Endpoint.of(instance2).target(EndpointId.of("ignored2"), ClusterSpec.Id.from("c2"), List.of(zone2)).on(Port.tls()).in(SystemName.main)
+ defaultFactory.of(instance2).target(EndpointId.of("ignored2"), ClusterSpec.Id.from("c2"), List.of(zone2)).on(Port.tls()).in(SystemName.main)
);
tests1.forEach((expected, endpoint) -> assertEquals(expected, endpoint.upstreamName(zone)));
tests2.forEach((expected, endpoint) -> assertEquals(expected, endpoint.upstreamName(zone2)));
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/certificate/EndpointCertificatesTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/certificate/EndpointCertificatesTest.java
index b06b4eb0cfa..6be6aa84319 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/certificate/EndpointCertificatesTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/certificate/EndpointCertificatesTest.java
@@ -4,6 +4,7 @@ package com.yahoo.vespa.hosted.controller.certificate;
import com.yahoo.config.application.api.DeploymentSpec;
import com.yahoo.config.application.api.xml.DeploymentSpecXmlReader;
import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.CloudName;
import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.InstanceName;
import com.yahoo.config.provision.RegionName;
@@ -25,6 +26,7 @@ import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCe
import com.yahoo.vespa.hosted.controller.application.pkg.ApplicationPackage;
import com.yahoo.vespa.hosted.controller.deployment.ApplicationPackageBuilder;
import com.yahoo.vespa.hosted.controller.integration.SecretStoreMock;
+import com.yahoo.vespa.hosted.controller.integration.ZoneApiMock;
import com.yahoo.vespa.hosted.controller.persistence.CuratorDb;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -136,9 +138,15 @@ public class EndpointCertificatesTest {
assertEquals(expectedSans, endpointCertificateMetadata.get().requestedDnsSans());
}
+ private ControllerTester publicTester() {
+ ControllerTester publicTester = new ControllerTester(SystemName.Public);
+ publicTester.zoneRegistry().setZones(tester.zoneRegistry().zones().all().zones());
+ return publicTester;
+ }
+
@Test
void provisions_new_certificate_in_public_prod() {
- ControllerTester tester = new ControllerTester(SystemName.Public);
+ ControllerTester tester = publicTester();
EndpointCertificateValidatorImpl endpointCertificateValidator = new EndpointCertificateValidatorImpl(secretStore, clock);
EndpointCertificates endpointCertificates = new EndpointCertificates(tester.controller(), endpointCertificateMock, endpointCertificateValidator);
List<String> expectedSans = List.of(
@@ -238,6 +246,9 @@ public class EndpointCertificatesTest {
Instance instance = new Instance(ApplicationId.from("t1", "a1", "default"), Tags.empty());
ZoneId zone1 = ZoneId.from(Environment.prod, RegionName.from("aws-us-east-1c"));
ZoneId zone2 = ZoneId.from(Environment.prod, RegionName.from("aws-us-west-2a"));
+ ControllerTester tester = publicTester();
+ tester.zoneRegistry().addZones(ZoneApiMock.newBuilder().with(CloudName.DEFAULT).with(zone1).build(),
+ ZoneApiMock.newBuilder().with(CloudName.AWS).with(zone2).build());
ApplicationPackage applicationPackage = new ApplicationPackageBuilder()
.instances("beta,main")
.region(zone1.region())
@@ -251,15 +262,14 @@ public class EndpointCertificatesTest {
InstanceName.from("main"), 6),
zone2.region().value(), Map.of(InstanceName.from("main"), 2)))
.build();
- ControllerTester tester = new ControllerTester(SystemName.Public);
EndpointCertificateValidatorImpl endpointCertificateValidator = new EndpointCertificateValidatorImpl(secretStore, clock);
EndpointCertificates endpointCertificates = new EndpointCertificates(tester.controller(), endpointCertificateMock, endpointCertificateValidator);
List<String> expectedSans = List.of(
"vlfms2wpoa4nyrka2s5lktucypjtxkqhv.internal.vespa-app.cloud",
"a1.t1.g.vespa-app.cloud",
"*.a1.t1.g.vespa-app.cloud",
- "a1.t1.aws-us-west-2a.r.vespa-app.cloud",
- "*.a1.t1.aws-us-west-2a.r.vespa-app.cloud",
+ "a1.t1.r.vespa-app.cloud",
+ "*.a1.t1.r.vespa-app.cloud",
"a1.t1.aws-us-east-1c.r.vespa-app.cloud",
"*.a1.t1.aws-us-east-1c.r.vespa-app.cloud",
"a1.t1.aws-us-east-1c.z.vespa-app.cloud",
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/TestConfigSerializerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/TestConfigSerializerTest.java
index 6493eafcde5..ba05cdf2fd5 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/TestConfigSerializerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/TestConfigSerializerTest.java
@@ -3,6 +3,7 @@ package com.yahoo.vespa.hosted.controller.deployment;
import com.yahoo.component.Version;
import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.CloudName;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.SystemName;
import com.yahoo.config.provision.zone.ZoneId;
@@ -10,6 +11,7 @@ import com.yahoo.slime.SlimeUtils;
import com.yahoo.vespa.hosted.controller.api.identifiers.DeploymentId;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.RevisionId;
import com.yahoo.vespa.hosted.controller.application.Endpoint;
+import com.yahoo.vespa.hosted.controller.application.Endpoint.EndpointFactory;
import com.yahoo.vespa.hosted.controller.application.EndpointId;
import org.junit.jupiter.api.Test;
@@ -31,22 +33,23 @@ public class TestConfigSerializerTest {
@Test
void testConfig() throws IOException {
ZoneId zone = DeploymentContext.systemTest.zone();
- byte[] json = new TestConfigSerializer(SystemName.PublicCd).configJson(instanceId,
- DeploymentContext.systemTest,
- true,
- Version.fromString("1.2.3"),
- RevisionId.forProduction(321),
- Instant.ofEpochMilli(222),
- Map.of(zone, List.of(Endpoint.of(ApplicationId.defaultId())
- .target(EndpointId.of("ai"), ClusterSpec.Id.from("qrs"),
- List.of(new DeploymentId(ApplicationId.defaultId(),
- ZoneId.defaultId())))
- .on(Endpoint.Port.tls())
- .in(SystemName.main))),
- Map.of(zone, List.of("facts")));
+ byte[] json = new TestConfigSerializer(SystemName.PublicCd)
+ .configJson(instanceId,
+ DeploymentContext.systemTest,
+ true,
+ Version.fromString("1.2.3"),
+ RevisionId.forProduction(321),
+ Instant.ofEpochMilli(222),
+ Map.of(zone, List.of(new EndpointFactory(__ -> CloudName.DEFAULT).of(ApplicationId.defaultId())
+ .target(EndpointId.of("ai"), ClusterSpec.Id.from("qrs"),
+ List.of(new DeploymentId(ApplicationId.defaultId(),
+ ZoneId.defaultId())))
+ .on(Endpoint.Port.tls())
+ .in(SystemName.main))),
+ Map.of(zone, List.of("facts")));
byte[] expected = Files.readAllBytes(Paths.get("src/test/resources/testConfig.json"));
assertEquals(new String(SlimeUtils.toJsonBytes(SlimeUtils.jsonToSlime(expected))),
- new String(json));
+ new String(json));
}
}