aboutsummaryrefslogtreecommitdiffstats
path: root/controller-server/src/test
diff options
context:
space:
mode:
authorMartin Polden <mpolden@mpolden.no>2023-07-04 11:57:49 +0200
committerMartin Polden <mpolden@mpolden.no>2023-07-05 12:52:00 +0200
commitd56134d93b7d62f5e96b688185d3d5b64d0bf942 (patch)
treecfb60fe3ef1a99288be9974d0eb65984a6f5d777 /controller-server/src/test
parent8fc733d22134a4645e6b3bb4cdde524cb251f5ae (diff)
Support anonymized endpoints
Diffstat (limited to 'controller-server/src/test')
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java34
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/EndpointTest.java32
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/CertificatePoolMaintainerTest.java14
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/EndpointCertificateMaintainerTest.java3
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/RoutingPolicySerializerTest.java11
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/routing/RoutingPoliciesTest.java169
6 files changed, 176 insertions, 87 deletions
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java
index eabbdd76d5a..d9b95a53a0e 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java
@@ -66,6 +66,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.OptionalLong;
+import java.util.Random;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
@@ -307,11 +308,11 @@ public final class ControllerTester {
}
public TenantName createTenant(String tenantName, Tenant.Type type) {
- switch (type) {
- case athenz: return createTenant(tenantName, "domain" + nextDomainId.getAndIncrement(), nextPropertyId.getAndIncrement());
- case cloud: return createCloudTenant(tenantName);
- default: throw new UnsupportedOperationException();
- }
+ return switch (type) {
+ case athenz -> createTenant(tenantName, "domain" + nextDomainId.getAndIncrement(), nextPropertyId.getAndIncrement());
+ case cloud -> createCloudTenant(tenantName);
+ default -> throw new UnsupportedOperationException();
+ };
}
public TenantName createTenant(String tenantName, String domainName, Long propertyId) {
@@ -347,17 +348,13 @@ public final class ControllerTester {
public Credentials credentialsFor(TenantName tenantName) {
Tenant tenant = controller().tenants().require(tenantName);
- switch (tenant.type()) {
- case athenz:
- return new AthenzCredentials(new AthenzPrincipal(new AthenzUser("user")),
- ((AthenzTenant) tenant).domain(),
- OAuthCredentials.createForTesting("okta-access-token", "okta-identity-token"));
- case cloud:
- return new Credentials(new SimplePrincipal("dev"));
-
- default:
- throw new IllegalArgumentException("Unexpected tenant type '" + tenant.type() + "'");
- }
+ return switch (tenant.type()) {
+ case athenz -> new AthenzCredentials(new AthenzPrincipal(new AthenzUser("user")),
+ ((AthenzTenant) tenant).domain(),
+ OAuthCredentials.createForTesting("okta-access-token", "okta-identity-token"));
+ case cloud -> new Credentials(new SimplePrincipal("dev"));
+ default -> throw new IllegalArgumentException("Unexpected tenant type '" + tenant.type() + "'");
+ };
}
public Application createApplication(ApplicationId id) {
@@ -385,6 +382,7 @@ public final class ControllerTester {
AthenzDbMock athensDb,
ServiceRegistryMock serviceRegistry,
FlagSource flagSource) {
+ Random random = new Random(serviceRegistry.clock().instant().toEpochMilli()); // Seed with clock for test determinism
Controller controller = new Controller(curator,
rotationsConfig,
serviceRegistry.zoneRegistry().system().isPublic() ?
@@ -395,7 +393,9 @@ public final class ControllerTester {
serviceRegistry,
new MetricsMock(), new SecretStoreMock(),
new ControllerConfig.Builder().build(),
- Sleeper.NOOP);
+ Sleeper.NOOP,
+ random,
+ random);
// Calculate initial versions
controller.updateVersionStatus(VersionStatus.compute(controller));
return controller;
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 dc96aa6c62c..23c029845bb 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
@@ -344,4 +344,36 @@ public class EndpointTest {
tests2.forEach((expected, endpoint) -> assertEquals(expected, endpoint.upstreamName(zone2)));
}
+ @Test
+ public void generated_id() {
+ GeneratedEndpoint ge = new GeneratedEndpoint("cafed00d", "deadbeef", Endpoint.AuthMethod.mtls);
+ var deployment = new DeploymentId(instance1, ZoneId.from("prod", "us-north-1"));
+ var tests = Map.of(
+ // Zone endpoint in main, unlike named endpoints, this includes the scope symbol 'z'
+ "cafed00d.deadbeef.z.vespa.oath.cloud",
+ Endpoint.of(instance1).target(ClusterSpec.Id.from("c1"), deployment).generatedEndpoint(ge)
+ .routingMethod(RoutingMethod.sharedLayer4).on(Port.tls()).in(SystemName.main),
+ // Zone endpoint in public
+ "cafed00d.deadbeef.z.vespa-app.cloud",
+ Endpoint.of(instance1).target(ClusterSpec.Id.from("c1"), deployment).generatedEndpoint(ge)
+ .routingMethod(RoutingMethod.exclusive).on(Port.tls()).in(SystemName.Public),
+ // Global endpoint in public
+ "foo.deadbeef.g.vespa-app.cloud",
+ Endpoint.of(instance1).target(EndpointId.of("foo"), ClusterSpec.Id.from("c1"), List.of(deployment))
+ .generatedEndpoint(ge)
+ .routingMethod(RoutingMethod.exclusive).on(Port.tls()).in(SystemName.Public),
+ // Global endpoint in public, with default ID
+ "deadbeef.g.vespa-app.cloud",
+ Endpoint.of(instance1).target(EndpointId.defaultId(), ClusterSpec.Id.from("c1"), List.of(deployment))
+ .generatedEndpoint(ge)
+ .routingMethod(RoutingMethod.exclusive).on(Port.tls()).in(SystemName.Public),
+ // Application endpoint in public
+ "bar.deadbeef.a.vespa-app.cloud",
+ Endpoint.of(TenantAndApplicationId.from(instance1)).targetApplication(EndpointId.of("bar"), deployment)
+ .generatedEndpoint(ge)
+ .routingMethod(RoutingMethod.exclusive).on(Port.tls()).in(SystemName.Public)
+ );
+ tests.forEach((expected, endpoint) -> assertEquals(expected, endpoint.dnsName()));
+ }
+
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/CertificatePoolMaintainerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/CertificatePoolMaintainerTest.java
index f94120241e7..a371677b82b 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/CertificatePoolMaintainerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/CertificatePoolMaintainerTest.java
@@ -10,7 +10,6 @@ import org.junit.jupiter.api.Test;
import java.time.Duration;
import java.util.List;
-import java.util.Random;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -20,7 +19,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
public class CertificatePoolMaintainerTest {
private final ControllerTester tester = new ControllerTester();
- private final CertificatePoolMaintainer maintainer = new CertificatePoolMaintainer(tester.controller(), new MockMetric(), Duration.ofHours(1), new Random(4));
+ private final CertificatePoolMaintainer maintainer = new CertificatePoolMaintainer(tester.controller(), new MockMetric(), Duration.ofHours(1));
@Test
void new_certs_are_requested_until_limit() {
@@ -41,17 +40,18 @@ public class CertificatePoolMaintainerTest {
assertEquals(
List.of(
- new DnsNameStatus("*.c8868d4e.z.vespa.oath.cloud", "done"),
- new DnsNameStatus("*.c8868d4e.g.vespa.oath.cloud", "done"),
- new DnsNameStatus("*.c8868d4e.a.vespa.oath.cloud", "done")
+ new DnsNameStatus("*.f5549014.z.vespa.oath.cloud", "done"),
+ new DnsNameStatus("*.f5549014.g.vespa.oath.cloud", "done"),
+ new DnsNameStatus("*.f5549014.a.vespa.oath.cloud", "done")
), metadata.dnsNames());
- assertEquals("vespa.tls.preprovisioned.c8868d4e-cert", endpointCertificateProvider.certificateDetails(metadata.requestId()).cert_key_keyname());
- assertEquals("vespa.tls.preprovisioned.c8868d4e-key", endpointCertificateProvider.certificateDetails(metadata.requestId()).private_key_keyname());
+ assertEquals("vespa.tls.preprovisioned.f5549014-cert", endpointCertificateProvider.certificateDetails(metadata.requestId()).cert_key_keyname());
+ assertEquals("vespa.tls.preprovisioned.f5549014-key", endpointCertificateProvider.certificateDetails(metadata.requestId()).private_key_keyname());
}
private void assertNumCerts(int n) {
assertEquals(0.0, maintainer.maintain(), 0.0000001);
assertEquals(n, tester.curator().readUnassignedCertificates().size());
}
+
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/EndpointCertificateMaintainerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/EndpointCertificateMaintainerTest.java
index 24eb9f33d33..247ffe1de00 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/EndpointCertificateMaintainerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/EndpointCertificateMaintainerTest.java
@@ -31,7 +31,6 @@ import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Optional;
import java.util.OptionalDouble;
-import java.util.Random;
import java.util.stream.Stream;
import static com.yahoo.vespa.hosted.controller.deployment.DeploymentContext.productionUsWest1;
@@ -49,7 +48,7 @@ public class EndpointCertificateMaintainerTest {
private final ControllerTester tester = new ControllerTester();
private final SecretStoreMock secretStore = (SecretStoreMock) tester.controller().secretStore();
private final EndpointCertificateMaintainer maintainer = new EndpointCertificateMaintainer(tester.controller(), Duration.ofHours(1));
- private final CertificatePoolMaintainer certificatePoolMaintainer = new CertificatePoolMaintainer(tester.controller(), new MockMetric(), Duration.ofHours(1), new Random(4));
+ private final CertificatePoolMaintainer certificatePoolMaintainer = new CertificatePoolMaintainer(tester.controller(), new MockMetric(), Duration.ofHours(1));
private final EndpointCertificateMetadata exampleMetadata = new EndpointCertificateMetadata("keyName", "certName", 0, 0, "root-request-uuid", Optional.of("leaf-request-uuid"), List.of(), "issuer", Optional.empty(), Optional.empty(), Optional.empty());
@Test
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/RoutingPolicySerializerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/RoutingPolicySerializerTest.java
index c1267ad5edf..f685c75bbe3 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/RoutingPolicySerializerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/RoutingPolicySerializerTest.java
@@ -5,7 +5,9 @@ import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.HostName;
import com.yahoo.config.provision.zone.ZoneId;
+import com.yahoo.vespa.hosted.controller.application.Endpoint;
import com.yahoo.vespa.hosted.controller.application.EndpointId;
+import com.yahoo.vespa.hosted.controller.application.GeneratedEndpoint;
import com.yahoo.vespa.hosted.controller.routing.RoutingPolicy;
import com.yahoo.vespa.hosted.controller.routing.RoutingPolicyId;
import com.yahoo.vespa.hosted.controller.routing.RoutingStatus;
@@ -44,7 +46,8 @@ public class RoutingPolicySerializerTest {
Set.of(),
Set.of(),
RoutingStatus.DEFAULT,
- false),
+ false,
+ List.of(new GeneratedEndpoint("deadbeef", "cafed00d", Endpoint.AuthMethod.mtls))),
new RoutingPolicy(id2,
Optional.of(HostName.of("long-and-ugly-name-2")),
Optional.empty(),
@@ -54,7 +57,8 @@ public class RoutingPolicySerializerTest {
new RoutingStatus(RoutingStatus.Value.out,
RoutingStatus.Agent.tenant,
Instant.ofEpochSecond(123)),
- true),
+ true,
+ List.of(new GeneratedEndpoint("cafed00d", "deadbeef", Endpoint.AuthMethod.token))),
new RoutingPolicy(id1,
Optional.empty(),
Optional.of("127.0.0.1"),
@@ -62,7 +66,8 @@ public class RoutingPolicySerializerTest {
instanceEndpoints,
applicationEndpoints,
RoutingStatus.DEFAULT,
- true));
+ true,
+ List.of()));
var serialized = serializer.fromSlime(owner, serializer.toSlime(policies));
assertEquals(policies.size(), serialized.size());
for (Iterator<RoutingPolicy> it1 = policies.iterator(), it2 = serialized.iterator(); it1.hasNext(); ) {
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/routing/RoutingPoliciesTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/routing/RoutingPoliciesTest.java
index 0233db50ac6..783629c8f4a 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/routing/RoutingPoliciesTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/routing/RoutingPoliciesTest.java
@@ -3,7 +3,6 @@ package com.yahoo.vespa.hosted.controller.routing;
import ai.vespa.http.DomainName;
import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Sets;
import com.yahoo.config.application.api.DeploymentSpec;
import com.yahoo.config.application.api.ValidationId;
import com.yahoo.config.provision.ApplicationId;
@@ -20,6 +19,7 @@ import com.yahoo.vespa.flags.Flags;
import com.yahoo.vespa.hosted.controller.ControllerTester;
import com.yahoo.vespa.hosted.controller.Instance;
import com.yahoo.vespa.hosted.controller.api.identifiers.DeploymentId;
+import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificateMetadata;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.LoadBalancer;
import com.yahoo.vespa.hosted.controller.api.integration.dns.Record;
import com.yahoo.vespa.hosted.controller.api.integration.dns.Record.Type;
@@ -32,6 +32,7 @@ import com.yahoo.vespa.hosted.controller.application.EndpointList;
import com.yahoo.vespa.hosted.controller.application.SystemApplication;
import com.yahoo.vespa.hosted.controller.application.TenantAndApplicationId;
import com.yahoo.vespa.hosted.controller.application.pkg.ApplicationPackage;
+import com.yahoo.vespa.hosted.controller.certificate.UnassignedCertificate;
import com.yahoo.vespa.hosted.controller.deployment.ApplicationPackageBuilder;
import com.yahoo.vespa.hosted.controller.deployment.DeploymentContext;
import com.yahoo.vespa.hosted.controller.deployment.DeploymentTester;
@@ -53,7 +54,6 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
-import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -262,11 +262,11 @@ public class RoutingPoliciesTest {
context1.submit(applicationPackage).deferLoadBalancerProvisioningIn(Environment.prod).deploy();
// Deployment creates records and policies for all clusters in all zones
- Set<String> expectedRecords = Set.of(
- "c0.app1.tenant1.us-west-1.vespa.oath.cloud",
- "c1.app1.tenant1.us-west-1.vespa.oath.cloud",
+ List<String> expectedRecords = List.of(
"c0.app1.tenant1.us-central-1.vespa.oath.cloud",
- "c1.app1.tenant1.us-central-1.vespa.oath.cloud"
+ "c0.app1.tenant1.us-west-1.vespa.oath.cloud",
+ "c1.app1.tenant1.us-central-1.vespa.oath.cloud",
+ "c1.app1.tenant1.us-west-1.vespa.oath.cloud"
);
assertEquals(expectedRecords, tester.recordNames());
assertEquals(4, tester.policiesOf(context1.instanceId()).size());
@@ -279,13 +279,13 @@ public class RoutingPoliciesTest {
// Add 1 cluster in each zone and deploy
tester.provisionLoadBalancers(clustersPerZone + 1, context1.instanceId(), sharedRoutingLayer, zone1, zone2);
context1.submit(applicationPackage).deferLoadBalancerProvisioningIn(Environment.prod).deploy();
- expectedRecords = Set.of(
- "c0.app1.tenant1.us-west-1.vespa.oath.cloud",
- "c1.app1.tenant1.us-west-1.vespa.oath.cloud",
- "c2.app1.tenant1.us-west-1.vespa.oath.cloud",
+ expectedRecords = List.of(
"c0.app1.tenant1.us-central-1.vespa.oath.cloud",
+ "c0.app1.tenant1.us-west-1.vespa.oath.cloud",
"c1.app1.tenant1.us-central-1.vespa.oath.cloud",
- "c2.app1.tenant1.us-central-1.vespa.oath.cloud"
+ "c1.app1.tenant1.us-west-1.vespa.oath.cloud",
+ "c2.app1.tenant1.us-central-1.vespa.oath.cloud",
+ "c2.app1.tenant1.us-west-1.vespa.oath.cloud"
);
assertEquals(expectedRecords, tester.recordNames());
assertEquals(6, tester.policiesOf(context1.instanceId()).size());
@@ -293,17 +293,17 @@ public class RoutingPoliciesTest {
// Deploy another application
tester.provisionLoadBalancers(clustersPerZone, context2.instanceId(), sharedRoutingLayer, zone1, zone2);
context2.submit(applicationPackage).deferLoadBalancerProvisioningIn(Environment.prod).deploy();
- expectedRecords = Set.of(
- "c0.app1.tenant1.us-west-1.vespa.oath.cloud",
- "c1.app1.tenant1.us-west-1.vespa.oath.cloud",
- "c2.app1.tenant1.us-west-1.vespa.oath.cloud",
+ expectedRecords = List.of(
"c0.app1.tenant1.us-central-1.vespa.oath.cloud",
- "c1.app1.tenant1.us-central-1.vespa.oath.cloud",
- "c2.app1.tenant1.us-central-1.vespa.oath.cloud",
+ "c0.app1.tenant1.us-west-1.vespa.oath.cloud",
"c0.app2.tenant1.us-central-1.vespa.oath.cloud",
- "c1.app2.tenant1.us-central-1.vespa.oath.cloud",
"c0.app2.tenant1.us-west-1.vespa.oath.cloud",
- "c1.app2.tenant1.us-west-1.vespa.oath.cloud"
+ "c1.app1.tenant1.us-central-1.vespa.oath.cloud",
+ "c1.app1.tenant1.us-west-1.vespa.oath.cloud",
+ "c1.app2.tenant1.us-central-1.vespa.oath.cloud",
+ "c1.app2.tenant1.us-west-1.vespa.oath.cloud",
+ "c2.app1.tenant1.us-central-1.vespa.oath.cloud",
+ "c2.app1.tenant1.us-west-1.vespa.oath.cloud"
);
assertEquals(expectedRecords.stream().sorted().toList(), tester.recordNames().stream().sorted().toList());
assertEquals(4, tester.policiesOf(context2.instanceId()).size());
@@ -311,14 +311,14 @@ public class RoutingPoliciesTest {
// Deploy removes cluster from app1
tester.provisionLoadBalancers(clustersPerZone, context1.instanceId(), sharedRoutingLayer, zone1, zone2);
context1.submit(applicationPackage).deferLoadBalancerProvisioningIn(Environment.prod).deploy();
- expectedRecords = Set.of(
- "c0.app1.tenant1.us-west-1.vespa.oath.cloud",
- "c1.app1.tenant1.us-west-1.vespa.oath.cloud",
+ expectedRecords = List.of(
"c0.app1.tenant1.us-central-1.vespa.oath.cloud",
- "c1.app1.tenant1.us-central-1.vespa.oath.cloud",
+ "c0.app1.tenant1.us-west-1.vespa.oath.cloud",
"c0.app2.tenant1.us-central-1.vespa.oath.cloud",
- "c1.app2.tenant1.us-central-1.vespa.oath.cloud",
"c0.app2.tenant1.us-west-1.vespa.oath.cloud",
+ "c1.app1.tenant1.us-central-1.vespa.oath.cloud",
+ "c1.app1.tenant1.us-west-1.vespa.oath.cloud",
+ "c1.app2.tenant1.us-central-1.vespa.oath.cloud",
"c1.app2.tenant1.us-west-1.vespa.oath.cloud"
);
assertEquals(expectedRecords, tester.recordNames());
@@ -327,11 +327,11 @@ public class RoutingPoliciesTest {
tester.controllerTester().controller().applications().requireInstance(context2.instanceId()).deployments().keySet()
.forEach(zone -> tester.controllerTester().controller().applications().deactivate(context2.instanceId(), zone));
context2.flushDnsUpdates();
- expectedRecords = Set.of(
- "c0.app1.tenant1.us-west-1.vespa.oath.cloud",
- "c1.app1.tenant1.us-west-1.vespa.oath.cloud",
+ expectedRecords = List.of(
"c0.app1.tenant1.us-central-1.vespa.oath.cloud",
- "c1.app1.tenant1.us-central-1.vespa.oath.cloud"
+ "c0.app1.tenant1.us-west-1.vespa.oath.cloud",
+ "c1.app1.tenant1.us-central-1.vespa.oath.cloud",
+ "c1.app1.tenant1.us-west-1.vespa.oath.cloud"
);
assertEquals(expectedRecords, tester.recordNames());
assertTrue(tester.routingPolicies().read(context2.instanceId()).isEmpty(), "Removes stale routing policies " + context2.application());
@@ -350,11 +350,11 @@ public class RoutingPoliciesTest {
context1.submit(applicationPackage).deferLoadBalancerProvisioningIn(Environment.prod).deploy();
// Deployment creates records and policies for all clusters in all zones
- Set<String> expectedRecords = Set.of(
- "c0.app1.tenant1.us-west-1.vespa.oath.cloud",
- "token-c0.app1.tenant1.us-west-1.vespa.oath.cloud",
+ List<String> expectedRecords = List.of(
"c0.app1.tenant1.us-central-1.vespa.oath.cloud",
- "token-c0.app1.tenant1.us-central-1.vespa.oath.cloud"
+ "c0.app1.tenant1.us-west-1.vespa.oath.cloud",
+ "token-c0.app1.tenant1.us-central-1.vespa.oath.cloud",
+ "token-c0.app1.tenant1.us-west-1.vespa.oath.cloud"
);
assertEquals(expectedRecords, tester.recordNames());
assertEquals(2, tester.policiesOf(context1.instanceId()).size());
@@ -367,7 +367,7 @@ public class RoutingPoliciesTest {
tester.provisionLoadBalancers(1, context.instanceId(), true, zone1, zone2);
context.submit(applicationPackage).deferLoadBalancerProvisioningIn(Environment.prod).deploy();
assertEquals(0, tester.controllerTester().controller().curator().readNameServiceQueue().requests().size());
- assertEquals(Set.of(), tester.recordNames());
+ assertEquals(List.of(), tester.recordNames());
assertEquals(2, tester.policiesOf(context.instanceId()).size());
}
@@ -409,15 +409,17 @@ public class RoutingPoliciesTest {
.build();
context.submit(applicationPackage).deferLoadBalancerProvisioningIn(Environment.prod).deploy();
- List<String> expectedRecords = List.of("c0.app1.tenant1.aws-us-east-1c.z.vespa-app.cloud",
- "c0.app1.tenant1.gcp-us-south1-b.z.vespa-app.cloud",
- "c0.app1.tenant1.aws-us-east-1.w.vespa-app.cloud",
- "c0.app1.tenant1.gcp-us-south1.w.vespa-app.cloud",
- "r0.app1.tenant1.g.vespa-app.cloud");
- assertEquals(Set.copyOf(expectedRecords), tester.recordNames());
+ List<String> expectedRecords = List.of(
+ "c0.app1.tenant1.aws-us-east-1.w.vespa-app.cloud",
+ "c0.app1.tenant1.aws-us-east-1c.z.vespa-app.cloud",
+ "c0.app1.tenant1.gcp-us-south1-b.z.vespa-app.cloud",
+ "c0.app1.tenant1.gcp-us-south1.w.vespa-app.cloud",
+ "r0.app1.tenant1.g.vespa-app.cloud"
+ );
+ assertEquals(expectedRecords, tester.recordNames());
- assertEquals(List.of("lb-0--tenant1.app1.default--prod.aws-us-east-1c."), tester.recordDataOf(Record.Type.CNAME, expectedRecords.get(0)));
- assertEquals(List.of("10.0.0.0"), tester.recordDataOf(Record.Type.A, expectedRecords.get(1)));
+ assertEquals(List.of("lb-0--tenant1.app1.default--prod.aws-us-east-1c."), tester.recordDataOf(Record.Type.CNAME, expectedRecords.get(1)));
+ assertEquals(List.of("10.0.0.0"), tester.recordDataOf(Record.Type.A, expectedRecords.get(2)));
assertEquals(List.of("weighted/10.0.0.0/prod.gcp-us-south1-b/1"), tester.recordDataOf(Record.Type.DIRECT, expectedRecords.get(3)));
assertEquals(List.of("latency/c0.app1.tenant1.aws-us-east-1.w.vespa-app.cloud/dns-zone-1/prod.aws-us-east-1c",
"latency/c0.app1.tenant1.gcp-us-south1.w.vespa-app.cloud/ignored/prod.gcp-us-south1-b"),
@@ -443,11 +445,12 @@ public class RoutingPoliciesTest {
tester.assertTargets(context.instanceId(), EndpointId.defaultId(),
ClusterSpec.Id.from("default"), 0,
Map.of(zone1, 1L, zone2, 1L));
- assertEquals(Set.of("app1.tenant1.aws-eu-west-1.w.vespa-app.cloud",
- "app1.tenant1.aws-eu-west-1a.z.vespa-app.cloud",
- "app1.tenant1.aws-us-east-1.w.vespa-app.cloud",
- "app1.tenant1.aws-us-east-1c.z.vespa-app.cloud",
- "app1.tenant1.g.vespa-app.cloud"),
+ assertEquals(List.of("app1.tenant1.aws-eu-west-1.w.vespa-app.cloud",
+ "app1.tenant1.aws-eu-west-1a.z.vespa-app.cloud",
+ "app1.tenant1.aws-us-east-1.w.vespa-app.cloud",
+ "app1.tenant1.aws-us-east-1c.z.vespa-app.cloud",
+ "app1.tenant1.g.vespa-app.cloud"
+ ),
tester.recordNames(),
"Registers expected DNS names");
}
@@ -471,7 +474,7 @@ public class RoutingPoliciesTest {
// Routing policy is created and DNS is updated
assertEquals(1, tester.policiesOf(context.instanceId()).size());
- assertEquals(Set.of("app1.tenant1.us-east-1.dev.vespa.oath.cloud"), tester.recordNames());
+ assertEquals(List.of("app1.tenant1.us-east-1.dev.vespa.oath.cloud"), tester.recordNames());
}
@Test
@@ -482,7 +485,7 @@ public class RoutingPoliciesTest {
context.submit(applicationPackage).deploy();
var zone = ZoneId.from("dev", "us-east-1");
tester.controllerTester().setRoutingMethod(List.of(zone), RoutingMethod.exclusive);
- var prodRecords = Set.of("app1.tenant1.us-central-1.vespa.oath.cloud", "app1.tenant1.us-west-1.vespa.oath.cloud");
+ var prodRecords = List.of("app1.tenant1.us-central-1.vespa.oath.cloud", "app1.tenant1.us-west-1.vespa.oath.cloud");
assertEquals(prodRecords, tester.recordNames());
// Deploy to dev under different instance
@@ -494,7 +497,8 @@ public class RoutingPoliciesTest {
// Routing policy is created and DNS is updated
assertEquals(1, tester.policiesOf(devContext.instanceId()).size());
- assertEquals(Sets.union(prodRecords, Set.of("user.app1.tenant1.us-east-1.dev.vespa.oath.cloud")), tester.recordNames());
+ assertEquals(Stream.concat(prodRecords.stream(), Stream.of("user.app1.tenant1.us-east-1.dev.vespa.oath.cloud")).sorted().toList(),
+ tester.recordNames());
}
@Test
@@ -510,7 +514,7 @@ public class RoutingPoliciesTest {
// Application is deployed
context.submit(applicationPackage).deferLoadBalancerProvisioningIn(Environment.prod).deploy();
- var expectedRecords = Set.of(
+ var expectedRecords = List.of(
"c0.app1.tenant1.us-west-1.vespa.oath.cloud"
);
assertEquals(expectedRecords, tester.recordNames());
@@ -557,8 +561,8 @@ public class RoutingPoliciesTest {
app.deploy();
// TXT records are cleaned up as we go—the last challenge is the last to go here, and we must flush it ourselves.
- assertEquals(Set.of("a.t.aws-us-east-1a.vespa.oath.cloud",
- "challenge--a.t.aws-us-east-1a.vespa.oath.cloud"),
+ assertEquals(List.of("a.t.aws-us-east-1a.vespa.oath.cloud",
+ "challenge--a.t.aws-us-east-1a.vespa.oath.cloud"),
tester.recordNames());
app.flushDnsUpdates();
assertEquals(Set.of(new Record(Type.CNAME,
@@ -773,7 +777,7 @@ public class RoutingPoliciesTest {
tester.routingPolicies().setRoutingStatus(context.deploymentIdIn(zone2), RoutingStatus.Value.out,
RoutingStatus.Agent.tenant);
} catch (IllegalArgumentException e) {
- assertEquals("Cannot deactivate routing for tenant1.app1 in prod.us-central-1 as it's the last remaining active deployment in endpoint https://r0.app1.tenant1.global.vespa.oath.cloud/ [scope=global, legacy=false, routingMethod=exclusive]", e.getMessage());
+ assertEquals("Cannot deactivate routing for tenant1.app1 in prod.us-central-1 as it's the last remaining active deployment in endpoint https://r0.app1.tenant1.global.vespa.oath.cloud/ [scope=global, legacy=false, routingMethod=exclusive, authMethod=mtls]", e.getMessage());
}
context.flushDnsUpdates();
tester.assertTargets(context.instanceId(), EndpointId.of("r0"), 0, zone2);
@@ -841,9 +845,9 @@ public class RoutingPoliciesTest {
// Application endpoints are not created until production jobs run
betaContext.submit(applicationPackage)
.runJob(DeploymentContext.systemTest);
- assertEquals(Set.of("beta.app1.tenant1.us-east-1.test.vespa.oath.cloud"), tester.recordNames());
+ assertEquals(List.of("beta.app1.tenant1.us-east-1.test.vespa.oath.cloud"), tester.recordNames());
betaContext.runJob(DeploymentContext.stagingTest);
- assertEquals(Set.of("beta.app1.tenant1.us-east-3.staging.vespa.oath.cloud"), tester.recordNames());
+ assertEquals(List.of("beta.app1.tenant1.us-east-3.staging.vespa.oath.cloud"), tester.recordNames());
// Deploy both instances
betaContext.completeRollout();
@@ -958,7 +962,7 @@ public class RoutingPoliciesTest {
tester.routingPolicies().setRoutingStatus(mainZone2, RoutingStatus.Value.out, RoutingStatus.Agent.tenant);
fail("Expected exception");
} catch (IllegalArgumentException e) {
- assertEquals("Cannot deactivate routing for tenant1.app1.main in prod.south as it's the last remaining active deployment in endpoint https://a0.app1.tenant1.a.vespa.oath.cloud/ [scope=application, legacy=false, routingMethod=exclusive]",
+ assertEquals("Cannot deactivate routing for tenant1.app1.main in prod.south as it's the last remaining active deployment in endpoint https://a0.app1.tenant1.a.vespa.oath.cloud/ [scope=application, legacy=false, routingMethod=exclusive, authMethod=mtls]",
e.getMessage());
}
@@ -1004,6 +1008,53 @@ public class RoutingPoliciesTest {
"Policies removed");
}
+ @Test
+ public void generated_zone_endpoints() {
+ var tester = new RoutingPoliciesTester(SystemName.Public);
+ var context = tester.newDeploymentContext("tenant1", "app1", "default");
+ tester.controllerTester().flagSource().withBooleanFlag(Flags.RANDOMIZED_ENDPOINT_NAMES.id(), true);
+ addCertificateToPool("cafed00d", UnassignedCertificate.State.ready, tester);
+
+ // Deploy application
+ int clustersPerZone = 1;
+ var zone1 = ZoneId.from("prod", "aws-us-east-1c");
+ var zone2 = ZoneId.from("prod", "aws-eu-west-1a");
+ ApplicationPackage applicationPackage = applicationPackageBuilder().region(zone1.region())
+ .region(zone2.region())
+ .build();
+ tester.provisionLoadBalancers(clustersPerZone, context.instanceId(), zone1, zone2);
+ context.submit(applicationPackage).deferLoadBalancerProvisioningIn(Environment.prod).deploy();
+
+ // Deployment creates generated zone names
+ List<String> expectedRecords = List.of(
+ "a9c8c045.cafed00d.z.vespa-app.cloud",
+ "c0.app1.tenant1.aws-eu-west-1a.z.vespa-app.cloud",
+ "c0.app1.tenant1.aws-us-east-1c.z.vespa-app.cloud",
+ "e144a11b.cafed00d.z.vespa-app.cloud"
+ );
+ assertEquals(expectedRecords, tester.recordNames());
+ assertEquals(2, tester.policiesOf(context.instanceId()).size());
+ for (var zone : List.of(zone1, zone2)) {
+ EndpointList endpoints = tester.controllerTester().controller().routing().readEndpointsOf(context.deploymentIdIn(zone));
+ assertEquals(1, endpoints.generated().size());
+ }
+
+ // Next deployment does not change generated names
+ context.submit(applicationPackage).deferLoadBalancerProvisioningIn(Environment.prod).deploy();
+ assertEquals(expectedRecords, tester.recordNames());
+ }
+
+ private void addCertificateToPool(String id, UnassignedCertificate.State state, RoutingPoliciesTester tester) {
+ EndpointCertificateMetadata cert = new EndpointCertificateMetadata("testKey", "testCert", 1, 0,
+ "request-id",
+ Optional.of("leaf-request-uuid"),
+ List.of("name1", "name2"),
+ "", Optional.empty(),
+ Optional.empty(), Optional.of(id));
+ UnassignedCertificate pooledCert = new UnassignedCertificate(cert, state);
+ tester.controllerTester().controller().curator().writeUnassignedCertificate(pooledCert);
+ }
+
/** Returns an application package builder that satisfies requirements for a directly routed endpoint */
private static ApplicationPackageBuilder applicationPackageBuilder() {
return new ApplicationPackageBuilder().athenzIdentity(AthenzDomain.from("domain"),
@@ -1113,11 +1164,13 @@ public class RoutingPoliciesTest {
return tester.controller().routing().policies().read(instance);
}
- private Set<String> recordNames() {
+ private List<String> recordNames() {
return tester.controllerTester().nameService().records().stream()
.map(Record::name)
.map(RecordName::asString)
- .collect(Collectors.toSet());
+ .distinct()
+ .sorted()
+ .toList();
}
private Set<String> aliasDataOf(String name) {