diff options
author | Martin Polden <mpolden@mpolden.no> | 2023-10-12 10:50:20 +0200 |
---|---|---|
committer | Martin Polden <mpolden@mpolden.no> | 2023-10-16 11:26:48 +0200 |
commit | 6147ead5d4c2bb1417dda046203daec66843b8e0 (patch) | |
tree | 4c8867e929618932dafaec0cc15ecc72f8542448 | |
parent | 90c59bfc313263a238c464b21221d1ede8bf997a (diff) |
Read endpoint-config flag
5 files changed, 28 insertions, 42 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 51e20d0017c..f9798fb2559 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 @@ -14,9 +14,9 @@ import com.yahoo.config.provision.zone.AuthMethod; import com.yahoo.config.provision.zone.RoutingMethod; import com.yahoo.config.provision.zone.ZoneApi; import com.yahoo.config.provision.zone.ZoneId; -import com.yahoo.vespa.flags.BooleanFlag; import com.yahoo.vespa.flags.FetchVector; import com.yahoo.vespa.flags.Flags; +import com.yahoo.vespa.flags.StringFlag; import com.yahoo.vespa.hosted.controller.api.identifiers.DeploymentId; import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificate; import com.yahoo.vespa.hosted.controller.api.integration.dns.Record; @@ -82,8 +82,7 @@ public class RoutingController { private final Controller controller; private final RoutingPolicies routingPolicies; private final RotationRepository rotationRepository; - private final BooleanFlag generatedEndpoints; - private final BooleanFlag legacyEndpoints; + private final StringFlag endpointConfig; public RoutingController(Controller controller, RotationsConfig rotationsConfig) { this.controller = Objects.requireNonNull(controller, "controller must be non-null"); @@ -91,8 +90,7 @@ public class RoutingController { this.rotationRepository = new RotationRepository(Objects.requireNonNull(rotationsConfig, "rotationsConfig must be non-null"), controller.applications(), controller.curator()); - this.generatedEndpoints = Flags.RANDOMIZED_ENDPOINT_NAMES.bindTo(controller.flagSource()); - this.legacyEndpoints = Flags.LEGACY_ENDPOINTS.bindTo(controller.flagSource()); + this.endpointConfig = Flags.ENDPOINT_CONFIG.bindTo(controller.flagSource()); } /** Create a routing context for given deployment */ @@ -124,15 +122,17 @@ public class RoutingController { /** Returns the endpoint config to use for given instance */ public EndpointConfig endpointConfig(ApplicationId instance) { - // TODO(mpolden): Switch to reading endpoint-config flag - if (legacyEndpointsEnabled(instance)) { - if (generatedEndpointsEnabled(instance)) { - return EndpointConfig.combined; - } else { - return EndpointConfig.legacy; - } - } - return EndpointConfig.generated; + String flagValue = endpointConfig.with(FetchVector.Dimension.TENANT_ID, instance.tenant().value()) + .with(FetchVector.Dimension.APPLICATION_ID, TenantAndApplicationId.from(instance).serialized()) + .with(FetchVector.Dimension.INSTANCE_ID, instance.serializedForm()) + .value(); + return switch (flagValue) { + case "legacy" -> EndpointConfig.legacy; + case "combined" -> EndpointConfig.combined; + case "generated" -> EndpointConfig.generated; + default -> throw new IllegalArgumentException("Invalid endpoint-config flag value: '" + flagValue + "', must be " + + "'legacy', 'combined' or 'generated'"); + }; } /** Prepares and returns the endpoints relevant for given deployment */ @@ -600,20 +600,6 @@ public class RoutingController { return Collections.unmodifiableList(routingMethods); } - private boolean generatedEndpointsEnabled(ApplicationId instance) { - return generatedEndpoints.with(FetchVector.Dimension.INSTANCE_ID, instance.serializedForm()) - .with(FetchVector.Dimension.TENANT_ID, instance.tenant().value()) - .with(FetchVector.Dimension.APPLICATION_ID, TenantAndApplicationId.from(instance).serialized()) - .value(); - } - - private boolean legacyEndpointsEnabled(ApplicationId instance) { - return legacyEndpoints.with(FetchVector.Dimension.INSTANCE_ID, instance.serializedForm()) - .with(FetchVector.Dimension.TENANT_ID, instance.tenant().value()) - .with(FetchVector.Dimension.APPLICATION_ID, TenantAndApplicationId.from(instance).serialized()) - .value(); - } - private static void requireGeneratedEndpoints(GeneratedEndpointList generatedEndpoints, boolean declared) { if (generatedEndpoints.asList().stream().anyMatch(ge -> ge.declared() != declared)) { throw new IllegalStateException("All generated endpoints require declared=" + declared + 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 7faaee95abb..378b92d37ce 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 @@ -303,8 +303,7 @@ public class EndpointCertificatesTest { @Test public void assign_certificate_from_pool() { - tester.flagSource().withBooleanFlag(Flags.RANDOMIZED_ENDPOINT_NAMES.id(), true); - tester.flagSource().withBooleanFlag(Flags.LEGACY_ENDPOINTS.id(), false); + setEndpointConfig(tester, EndpointConfig.generated); try { addCertificateToPool("bad0f00d", UnassignedCertificate.State.requested, tester); endpointCertificates.get(new DeploymentId(instance, prodZone), DeploymentSpec.empty, lock); @@ -340,7 +339,7 @@ public class EndpointCertificatesTest { @Test public void certificate_migration() { - // An application is initially deployed with legacy config + // An application is initially deployed with legacy config (the default) ZoneId zone1 = ZoneId.from(Environment.prod, RegionName.from("aws-us-east-1c")); ApplicationPackage applicationPackage = new ApplicationPackageBuilder().region(zone1.region()) .build(); @@ -408,8 +407,7 @@ public class EndpointCertificatesTest { devCert0.requestedDnsSans()); // Application switches to combined config - tester.flagSource().withBooleanFlag(Flags.RANDOMIZED_ENDPOINT_NAMES.id(), true); - tester.flagSource().withBooleanFlag(Flags.LEGACY_ENDPOINTS.id(), true); + setEndpointConfig(tester, EndpointConfig.combined); tester.clock().advance(Duration.ofHours(1)); assertEquals(certificate.withLastRequested(tester.clock().instant().getEpochSecond()), endpointCertificates.get(deployment0, applicationPackage.deploymentSpec(), lock), @@ -420,7 +418,7 @@ public class EndpointCertificatesTest { "Certificate is not assigned at application level"); // Application switches to generated config - tester.flagSource().withBooleanFlag(Flags.LEGACY_ENDPOINTS.id(), false); + setEndpointConfig(tester, EndpointConfig.generated); tester.clock().advance(Duration.ofHours(1)); assertEquals(certificate.withLastRequested(tester.clock().instant().getEpochSecond()), endpointCertificates.get(deployment0, applicationPackage.deploymentSpec(), lock), @@ -451,8 +449,7 @@ public class EndpointCertificatesTest { assertEquals(poolCertId1, prodCertificate.generatedId().get()); // Application switches back to legacy config - tester.flagSource().withBooleanFlag(Flags.RANDOMIZED_ENDPOINT_NAMES.id(), false); - tester.flagSource().withBooleanFlag(Flags.LEGACY_ENDPOINTS.id(), true); + setEndpointConfig(tester, EndpointConfig.legacy); EndpointCertificate reissuedCertificate = endpointCertificates.get(deployment0, applicationPackage.deploymentSpec(), lock); assertEquals(certificate.requestedDnsSans(), reissuedCertificate.requestedDnsSans()); assertTrue(tester.curator().readAssignedCertificate(deployment0.applicationId()).isPresent(), "Certificate is assigned at instance level again"); @@ -460,6 +457,10 @@ public class EndpointCertificatesTest { "Certificate is still assigned at application level"); // Not removed because the assumption is that the application will eventually migrate back } + private void setEndpointConfig(ControllerTester tester, EndpointConfig config) { + tester.flagSource().withStringFlag(Flags.ENDPOINT_CONFIG.id(), config.name()); + } + private void addCertificateToPool(String id, UnassignedCertificate.State state, ControllerTester tester) { EndpointCertificate cert = new EndpointCertificate(testKeyName, testCertName, 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 f551a99829e..fe9e9b28655 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 @@ -26,6 +26,7 @@ import com.yahoo.vespa.hosted.controller.deployment.ApplicationPackageBuilder; import com.yahoo.vespa.hosted.controller.deployment.DeploymentContext; import com.yahoo.vespa.hosted.controller.deployment.DeploymentTester; import com.yahoo.vespa.hosted.controller.integration.SecretStoreMock; +import com.yahoo.vespa.hosted.controller.routing.EndpointConfig; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; @@ -262,9 +263,8 @@ public class EndpointCertificateMaintainerTest { } private void prepareCertificatePool(int numCertificates) { - ((InMemoryFlagSource)tester.controller().flagSource()).withIntFlag(PermanentFlags.CERT_POOL_SIZE.id(), numCertificates); - ((InMemoryFlagSource)tester.controller().flagSource()).withBooleanFlag(Flags.RANDOMIZED_ENDPOINT_NAMES.id(), true); - ((InMemoryFlagSource)tester.controller().flagSource()).withBooleanFlag(Flags.LEGACY_ENDPOINTS.id(), false); + ((InMemoryFlagSource) tester.controller().flagSource()).withIntFlag(PermanentFlags.CERT_POOL_SIZE.id(), numCertificates); + ((InMemoryFlagSource) tester.controller().flagSource()).withStringFlag(Flags.ENDPOINT_CONFIG.id(), EndpointConfig.generated.name()); // Provision certificates for (int i = 0; i < numCertificates; i++) { 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 a10bfd46b0c..a7fa2852992 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 @@ -1516,8 +1516,7 @@ public class RoutingPoliciesTest { } public RoutingPoliciesTester setEndpointConfig(EndpointConfig config) { - tester.controllerTester().flagSource().withBooleanFlag(Flags.LEGACY_ENDPOINTS.id(), config.supportsLegacy()); - tester.controllerTester().flagSource().withBooleanFlag(Flags.RANDOMIZED_ENDPOINT_NAMES.id(), config.supportsGenerated()); + tester.controllerTester().flagSource().withStringFlag(Flags.ENDPOINT_CONFIG.id(), config.name()); return this; } diff --git a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java index 56cd06d3b35..d7073ebc0eb 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java +++ b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java @@ -434,7 +434,7 @@ public class Flags { List.of("mpolden", "tokle"), "2023-10-06", "2024-02-01", "Set the endpoint config to use for an application. Must be 'legacy', 'combined' or 'generated'. See EndpointConfig for further details", "Takes effect on next deployment through controller", - APPLICATION_ID); + TENANT_ID, APPLICATION_ID, INSTANCE_ID); /** WARNING: public for testing: All flags should be defined in {@link Flags}. */ public static UnboundBooleanFlag defineFeatureFlag(String flagId, boolean defaultValue, List<String> owners, |