aboutsummaryrefslogtreecommitdiffstats
path: root/controller-server
diff options
context:
space:
mode:
authorMartin Polden <mpolden@mpolden.no>2020-06-15 11:36:18 +0200
committerMartin Polden <mpolden@mpolden.no>2020-06-15 13:58:59 +0200
commitf34efe30c2a17ba6fc9b4b80fabd1c612d958bee (patch)
tree788c3fb2efce219b563e0c10e9d0be6891a3c91e /controller-server
parentf23863f6f7698d4fc34392c59977447988a86754 (diff)
Add support for config server routing policy
Diffstat (limited to 'controller-server')
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/RoutingController.java7
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/Endpoint.java30
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/SystemApplication.java18
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/routing/RoutingPolicies.java5
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/routing/RoutingPolicy.java7
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/routing/RoutingPoliciesTest.java13
6 files changed, 70 insertions, 10 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 463ffb58460..c441188b1be 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
@@ -23,6 +23,7 @@ import com.yahoo.vespa.hosted.controller.application.Deployment;
import com.yahoo.vespa.hosted.controller.application.Endpoint;
import com.yahoo.vespa.hosted.controller.application.Endpoint.Port;
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.dns.NameServiceQueue.Priority;
import com.yahoo.vespa.hosted.controller.rotation.RotationLock;
@@ -84,13 +85,14 @@ public class RoutingController {
/** Returns zone-scoped endpoints for given deployment */
public EndpointList endpointsOf(DeploymentId deployment) {
var endpoints = new LinkedHashSet<Endpoint>();
+ boolean isSystemApplication = SystemApplication.matching(deployment.applicationId()).isPresent();
// Avoid reading application more than once per call to this
var application = Suppliers.memoize(() -> controller.applications().requireApplication(TenantAndApplicationId.from(deployment.applicationId())));
for (var policy : routingPolicies.get(deployment).values()) {
if (!policy.status().isActive()) continue;
for (var routingMethod : controller.zoneRegistry().routingMethods(policy.id().zone())) {
- if (routingMethod.isDirect() && !canRouteDirectlyTo(deployment, application.get())) continue;
- endpoints.add(policy.endpointIn(controller.system(), routingMethod));
+ if (routingMethod.isDirect() && !isSystemApplication && !canRouteDirectlyTo(deployment, application.get())) continue;
+ endpoints.add(policy.endpointIn(controller.system(), routingMethod, controller.zoneRegistry()));
}
}
return EndpointList.copyOf(endpoints);
@@ -98,6 +100,7 @@ public class RoutingController {
/** Returns global-scoped endpoints for given instance */
public EndpointList endpointsOf(ApplicationId instance) {
+ if (SystemApplication.matching(instance).isPresent()) return EndpointList.copyOf(List.of());
return endpointsOf(controller.applications().requireApplication(TenantAndApplicationId.from(instance)),
instance.instance());
}
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 ed5add8b98a..f8982c96637 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
@@ -36,20 +36,18 @@ public class Endpoint {
private final RoutingMethod routingMethod;
private final boolean tls;
- private Endpoint(String name, ApplicationId application, List<ZoneId> zones, Scope scope, SystemName system,
- Port port, boolean legacy, RoutingMethod routingMethod) {
+ private Endpoint(String name, URI url, List<ZoneId> zones, Scope scope, Port port, boolean legacy,
+ RoutingMethod routingMethod) {
Objects.requireNonNull(name, "name must be non-null");
- Objects.requireNonNull(application, "application must be non-null");
Objects.requireNonNull(zones, "zones must be non-null");
Objects.requireNonNull(scope, "scope must be non-null");
- Objects.requireNonNull(system, "system must be non-null");
Objects.requireNonNull(port, "port must be non-null");
Objects.requireNonNull(routingMethod, "routingMethod must be non-null");
if (scope == Scope.zone && zones.size() != 1) {
throw new IllegalArgumentException("A single zone must be given for zone-scoped endpoints");
}
this.name = name;
- this.url = createUrl(name, application, zones, scope, system, port, legacy, routingMethod);
+ this.url = url;
this.zones = List.copyOf(zones);
this.scope = scope;
this.legacy = legacy;
@@ -57,6 +55,20 @@ public class Endpoint {
this.tls = port.tls;
}
+ private Endpoint(String name, ApplicationId application, List<ZoneId> zones, Scope scope, SystemName system,
+ Port port, boolean legacy, RoutingMethod routingMethod) {
+ this(name,
+ createUrl(name,
+ Objects.requireNonNull(application, "application must be non-null"),
+ zones,
+ scope,
+ Objects.requireNonNull(system, "system must be non-null"),
+ port,
+ legacy,
+ routingMethod),
+ zones, scope, port, legacy, routingMethod);
+ }
+
/**
* Returns the name of this endpoint (the first component of the DNS name). Depending on the endpoint type, this
* can be one of the following:
@@ -286,6 +298,14 @@ public class Endpoint {
return new EndpointBuilder(application);
}
+ /** Create an endpoint for given system application */
+ public static Endpoint of(SystemApplication systemApplication, ZoneId zone, URI url) {
+ if (!systemApplication.hasEndpoint()) throw new IllegalArgumentException(systemApplication + " has no endpoint");
+ RoutingMethod routingMethod = RoutingMethod.exclusive;
+ Port port = url.getPort() == -1 ? Port.tls() : Port.tls(url.getPort()); // System application endpoints are always TLS
+ return new Endpoint("", url, List.of(zone), Scope.zone, port, false, routingMethod);
+ }
+
public static class EndpointBuilder {
private final ApplicationId application;
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/SystemApplication.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/SystemApplication.java
index 243bca8c027..e1acf867744 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/SystemApplication.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/SystemApplication.java
@@ -8,7 +8,9 @@ import com.yahoo.config.provision.zone.ZoneId;
import com.yahoo.vespa.hosted.controller.Controller;
import com.yahoo.vespa.hosted.controller.api.identifiers.DeploymentId;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.ServiceConvergence;
+import com.yahoo.vespa.hosted.controller.api.integration.zone.ZoneRegistry;
+import java.util.Arrays;
import java.util.List;
import java.util.Optional;
@@ -71,11 +73,27 @@ public enum SystemApplication {
return nodeType.isDockerHost();
}
+ /** Returns whether this has an endpoint */
+ public boolean hasEndpoint() {
+ return this == configServer;
+ }
+
+ /** Returns the endpoint of this, if any */
+ public Optional<Endpoint> endpointIn(ZoneId zone, ZoneRegistry zoneRegistry) {
+ if (!hasEndpoint()) return Optional.empty();
+ return Optional.of(Endpoint.of(this, zone, zoneRegistry.getConfigServerVipUri(zone)));
+ }
+
/** All known system applications */
public static List<SystemApplication> all() {
return List.of(values());
}
+ /** Returns the system application matching given id, if any */
+ public static Optional<SystemApplication> matching(ApplicationId id) {
+ return Arrays.stream(values()).filter(app -> app.id().equals(id)).findFirst();
+ }
+
@Override
public String toString() {
return String.format("system application %s of type %s", id, nodeType);
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 7d7803915be..abd4770ea0d 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
@@ -175,7 +175,8 @@ public class RoutingPolicies {
/** Update zone DNS record for given policy */
private void updateZoneDnsOf(RoutingPolicy policy) {
- var name = RecordName.from(policy.endpointIn(controller.system(), RoutingMethod.exclusive).dnsName());
+ var name = RecordName.from(policy.endpointIn(controller.system(), RoutingMethod.exclusive, controller.zoneRegistry())
+ .dnsName());
var data = RecordData.fqdn(policy.canonicalName().value());
nameUpdaterIn(policy.id().zone()).createCname(name, data);
}
@@ -190,7 +191,7 @@ public class RoutingPolicies {
if (activeIds.contains(policy.id()) ||
!policy.id().zone().equals(allocation.deployment.zoneId())) continue;
- var dnsName = policy.endpointIn(controller.system(), RoutingMethod.exclusive).dnsName();
+ var dnsName = policy.endpointIn(controller.system(), RoutingMethod.exclusive, controller.zoneRegistry()).dnsName();
nameUpdaterIn(allocation.deployment.zoneId()).removeRecords(Record.Type.CNAME, RecordName.from(dnsName));
newPolicies.remove(policy.id());
}
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 37027e8a8c9..c56a5f0bd66 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
@@ -5,9 +5,11 @@ import com.google.common.collect.ImmutableSortedSet;
import com.yahoo.config.provision.HostName;
import com.yahoo.config.provision.SystemName;
import com.yahoo.config.provision.zone.RoutingMethod;
+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.Port;
import com.yahoo.vespa.hosted.controller.application.EndpointId;
+import com.yahoo.vespa.hosted.controller.application.SystemApplication;
import java.util.Objects;
import java.util.Optional;
@@ -68,7 +70,10 @@ public class RoutingPolicy {
}
/** Returns the endpoint of this */
- public Endpoint endpointIn(SystemName system, RoutingMethod routingMethod) {
+ public Endpoint endpointIn(SystemName system, RoutingMethod routingMethod, ZoneRegistry zoneRegistry) {
+ Optional<Endpoint> infraEndpoint = SystemApplication.matching(id.owner())
+ .flatMap(app -> app.endpointIn(id.zone(), zoneRegistry));
+ if (infraEndpoint.isPresent()) return infraEndpoint.get();
return Endpoint.of(id.owner())
.target(id.cluster(), id.zone())
.on(Port.fromRoutingMethod(routingMethod))
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 19e684aa175..56fb7194e4e 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
@@ -32,6 +32,7 @@ import com.yahoo.vespa.hosted.controller.deployment.DeploymentContext;
import com.yahoo.vespa.hosted.controller.deployment.DeploymentTester;
import com.yahoo.vespa.hosted.controller.integration.ServiceRegistryMock;
import com.yahoo.vespa.hosted.controller.integration.ZoneApiMock;
+import com.yahoo.vespa.hosted.controller.maintenance.NameServiceDispatcher;
import com.yahoo.vespa.hosted.rotation.config.RotationsConfig;
import org.junit.Test;
@@ -579,6 +580,18 @@ public class RoutingPoliciesTest {
tester.assertTargets(context.instanceId(), EndpointId.of("r0"), 0, zone1, zone2);
}
+ @Test
+ public void config_server_routing_policy() {
+ var tester = new RoutingPoliciesTester();
+ var app = SystemApplication.configServer.id();
+
+ tester.provisionLoadBalancers(1, app, zone1);
+ tester.routingPolicies().refresh(app, DeploymentSpec.empty, zone1);
+ new NameServiceDispatcher(tester.tester.controller(), Duration.ofDays(1), Integer.MAX_VALUE).run();
+
+ assertEquals(Set.of("cfg.prod.us-west-1.test.vip"), tester.recordNames());
+ }
+
/** Returns an application package builder that satisfies requirements for a directly routed endpoint */
private static ApplicationPackageBuilder applicationPackageBuilder() {
return new ApplicationPackageBuilder()