diff options
author | Martin Polden <mpolden@mpolden.no> | 2020-01-20 14:25:10 +0100 |
---|---|---|
committer | Martin Polden <mpolden@mpolden.no> | 2020-01-20 14:26:31 +0100 |
commit | 3d0f3aef927403f6e4ac80b35edc99db2923ed0f (patch) | |
tree | 68bcc3f45d77fb7c9d799d9697279b8fcb0043b8 | |
parent | e57e76ef56dd38731f080aa0477708f547b39307 (diff) |
Support overriding global routing status through deployment.xml
3 files changed, 54 insertions, 10 deletions
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 670cb7bd52a..a2e22cc03d9 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 @@ -77,11 +77,12 @@ public class RoutingPolicies { var loadBalancers = new AllocatedLoadBalancers(application, zone, controller.serviceRegistry().configServer() .getLoadBalancers(application, zone), deploymentSpec); + var inactiveZones = inactiveZones(application, deploymentSpec); try (var lock = db.lockRoutingPolicies()) { removeGlobalDnsUnreferencedBy(loadBalancers, lock); storePoliciesOf(loadBalancers, lock); removePoliciesUnreferencedBy(loadBalancers, lock); - updateGlobalDnsOf(get(loadBalancers.application).values(), lock); + updateGlobalDnsOf(get(loadBalancers.application).values(), inactiveZones, lock); } } @@ -92,7 +93,7 @@ public class RoutingPolicies { controller.clock().instant()))); var allPolicies = db.readRoutingPolicies(); for (var applicationPolicies : allPolicies.values()) { - updateGlobalDnsOf(applicationPolicies.values(), lock); + updateGlobalDnsOf(applicationPolicies.values(), Set.of(), lock); } } } @@ -109,12 +110,12 @@ public class RoutingPolicies { newPolicies.put(policy.id(), newPolicy); } db.writeRoutingPolicies(deployment.applicationId(), newPolicies); - updateGlobalDnsOf(newPolicies.values(), lock); + updateGlobalDnsOf(newPolicies.values(), Set.of(), lock); } } /** Update global DNS record for given policies */ - private void updateGlobalDnsOf(Collection<RoutingPolicy> routingPolicies, @SuppressWarnings("unused") Lock lock) { + private void updateGlobalDnsOf(Collection<RoutingPolicy> routingPolicies, Set<ZoneId> inactiveZones, @SuppressWarnings("unused") Lock lock) { // Create DNS record for each routing ID var routingTable = routingTableFrom(routingPolicies); for (Map.Entry<RoutingId, List<RoutingPolicy>> routeEntry : routingTable.entrySet()) { @@ -124,8 +125,12 @@ public class RoutingPolicies { if (policy.dnsZone().isEmpty()) continue; var target = new AliasTarget(policy.canonicalName(), policy.dnsZone().get(), policy.id().zone()); var zonePolicy = db.readZoneRoutingPolicy(policy.id().zone()); - // Remove target if global routing status is set out, either on zone-level or policy-level - if (anyOut(zonePolicy.globalRouting(), policy.status().globalRouting())) { + // Remove target zone if global routing status is set out at: + // - zone level (ZoneRoutingPolicy) + // - deployment level (RoutingPolicy) + // - application package level (deployment.xml) + if (anyOut(zonePolicy.globalRouting(), policy.status().globalRouting()) || + inactiveZones.contains(policy.id().zone())) { staleTargets.add(target); } else { targets.add(target); @@ -269,4 +274,15 @@ public class RoutingPolicies { } + /** Returns zones where global routing is declared inactive for instance through deploymentSpec */ + private static Set<ZoneId> inactiveZones(ApplicationId instance, DeploymentSpec deploymentSpec) { + var instanceSpec = deploymentSpec.instance(instance.instance()); + if (instanceSpec.isEmpty()) return Set.of(); + return instanceSpec.get().zones().stream() + .filter(zone -> zone.environment().isProduction()) + .filter(zone -> !zone.active()) + .map(zone -> ZoneId.from(zone.environment(), zone.region().get())) + .collect(Collectors.toUnmodifiableSet()); + } + } diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/ApplicationPackageBuilder.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/ApplicationPackageBuilder.java index e4b5e77b377..9b0706d184f 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/ApplicationPackageBuilder.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/ApplicationPackageBuilder.java @@ -101,13 +101,19 @@ public class ApplicationPackageBuilder { } public ApplicationPackageBuilder region(RegionName regionName) { - return region(regionName.value()); + return region(regionName, true); } public ApplicationPackageBuilder region(String regionName) { - environmentBody.append(" <region active='true'>"); - environmentBody.append(regionName); - environmentBody.append("</region>\n"); + return region(RegionName.from(regionName), true); + } + + public ApplicationPackageBuilder region(RegionName regionName, boolean active) { + environmentBody.append(" <region active='") + .append(active) + .append("'>") + .append(regionName.value()) + .append("</region>\n"); return this; } 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 8e0921d8d66..c0420c7b895 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 @@ -396,6 +396,28 @@ public class RoutingPoliciesTest { assertEquals(GlobalRouting.Status.in, policy1.status().globalRouting().status()); assertEquals(GlobalRouting.Agent.tenant, policy1.status().globalRouting().agent()); assertEquals(changedAt.truncatedTo(ChronoUnit.MILLIS), policy1.status().globalRouting().changedAt()); + + // Deployment is set out through a new deployment.xml + var applicationPackage2 = new ApplicationPackageBuilder() + .region(zone1.region()) + .region(zone2.region(), false) + .endpoint("r0", "c0", zone1.region().value(), zone2.region().value()) + .endpoint("r1", "c0", zone1.region().value(), zone2.region().value()) + .build(); + context.submit(applicationPackage2).deploy(); + tester.assertTargets(context.instanceId(), EndpointId.of("r0"), 0, zone1); + tester.assertTargets(context.instanceId(), EndpointId.of("r1"), 0, zone1); + + // ... back in + var applicationPackage3 = new ApplicationPackageBuilder() + .region(zone1.region()) + .region(zone2.region()) + .endpoint("r0", "c0", zone1.region().value(), zone2.region().value()) + .endpoint("r1", "c0", zone1.region().value(), zone2.region().value()) + .build(); + context.submit(applicationPackage3).deploy(); + tester.assertTargets(context.instanceId(), EndpointId.of("r0"), 0, zone1, zone2); + tester.assertTargets(context.instanceId(), EndpointId.of("r1"), 0, zone1, zone2); } @Test |