diff options
author | Martin Polden <mpolden@mpolden.no> | 2023-09-04 13:05:41 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-04 13:05:41 +0200 |
commit | c3ee6199624f99eb695a0d397b800a0fd6ab326d (patch) | |
tree | 0f463ba7c0f9c7f940189af9e5b9c39a77e8e7d6 | |
parent | 147e88e2c4cc6a5b389f721c0216880de9455d14 (diff) | |
parent | a7b91304a577d856828e6088342dc3b2cf162b9c (diff) |
Merge pull request #28374 from vespa-engine/mpolden/set-auth-method
Add auth method to ApplicationClusterEndpoint
6 files changed, 146 insertions, 72 deletions
diff --git a/config-model-api/src/main/java/com/yahoo/config/model/api/ApplicationClusterEndpoint.java b/config-model-api/src/main/java/com/yahoo/config/model/api/ApplicationClusterEndpoint.java index b7969267328..e70b0f1a599 100644 --- a/config-model-api/src/main/java/com/yahoo/config/model/api/ApplicationClusterEndpoint.java +++ b/config-model-api/src/main/java/com/yahoo/config/model/api/ApplicationClusterEndpoint.java @@ -18,21 +18,6 @@ import java.util.stream.Stream; * @author mortent */ public class ApplicationClusterEndpoint { - @Override - public String toString() { - return "ApplicationClusterEndpoint{" + - "dnsName=" + dnsName + - ", scope=" + scope + - ", routingMethod=" + routingMethod + - ", weight=" + weight + - ", hostNames=" + hostNames + - ", clusterId='" + clusterId + "'" + - '}'; - } - - public enum Scope {application, global, zone} - - public enum RoutingMethod {shared, sharedLayer4, exclusive} private final DnsName dnsName; private final Scope scope; @@ -40,14 +25,16 @@ public class ApplicationClusterEndpoint { private final int weight; private final List<String> hostNames; private final String clusterId; + private final AuthMethod authMethod; - private ApplicationClusterEndpoint(DnsName dnsName, Scope scope, RoutingMethod routingMethod, int weight, List<String> hostNames, String clusterId) { - this.dnsName = dnsName; - this.scope = scope; - this.routingMethod = routingMethod; + private ApplicationClusterEndpoint(DnsName dnsName, Scope scope, RoutingMethod routingMethod, int weight, List<String> hostNames, String clusterId, AuthMethod authMethod) { + this.dnsName = Objects.requireNonNull(dnsName); + this.scope = Objects.requireNonNull(scope); + this.routingMethod = Objects.requireNonNull(routingMethod); this.weight = weight; - this.hostNames = List.copyOf(hostNames); - this.clusterId = clusterId; + this.hostNames = List.copyOf(Objects.requireNonNull(hostNames)); + this.clusterId = Objects.requireNonNull(clusterId); + this.authMethod = Objects.requireNonNull(authMethod); } public DnsName dnsName() { @@ -74,10 +61,33 @@ public class ApplicationClusterEndpoint { return clusterId; } + public AuthMethod authMethod() { + return authMethod; + } + + @Override + public String toString() { + return "ApplicationClusterEndpoint{" + + "dnsName=" + dnsName + + ", scope=" + scope + + ", routingMethod=" + routingMethod + + ", weight=" + weight + + ", hostNames=" + hostNames + + ", clusterId='" + clusterId + '\'' + + ", authMethod=" + authMethod + + '}'; + } + public static Builder builder() { return new Builder(); } + public enum Scope { application, global, zone } + + public enum RoutingMethod { shared, sharedLayer4, exclusive } + + public enum AuthMethod { mtls, token } + public static class Builder { private DnsName dnsName; @@ -86,6 +96,7 @@ public class ApplicationClusterEndpoint { private int weigth = 1; private List<String> hosts; private String clusterId; + private AuthMethod authMethod; public Builder dnsName(DnsName name) { this.dnsName = name; @@ -132,9 +143,15 @@ public class ApplicationClusterEndpoint { return this; } + public Builder authMethod(AuthMethod authMethod) { + this.authMethod = authMethod; + return this; + } + public ApplicationClusterEndpoint build() { - return new ApplicationClusterEndpoint(dnsName, scope, routingMethod, weigth, hosts, clusterId); + return new ApplicationClusterEndpoint(dnsName, scope, routingMethod, weigth, hosts, clusterId, authMethod); } + } public static class DnsName implements Comparable<DnsName> { diff --git a/config-model-api/src/main/java/com/yahoo/config/model/api/ContainerEndpoint.java b/config-model-api/src/main/java/com/yahoo/config/model/api/ContainerEndpoint.java index 78da750fb5b..de06ddd549a 100644 --- a/config-model-api/src/main/java/com/yahoo/config/model/api/ContainerEndpoint.java +++ b/config-model-api/src/main/java/com/yahoo/config/model/api/ContainerEndpoint.java @@ -3,9 +3,7 @@ package com.yahoo.config.model.api; import java.util.List; import java.util.Objects; -import java.util.Optional; import java.util.OptionalInt; -import java.util.OptionalLong; /** * ContainerEndpoint tracks the service names that a Container Cluster should be @@ -21,6 +19,7 @@ public class ContainerEndpoint { private final List<String> names; private final OptionalInt weight; private final ApplicationClusterEndpoint.RoutingMethod routingMethod; + private final ApplicationClusterEndpoint.AuthMethod authMethod; public ContainerEndpoint(String clusterId, ApplicationClusterEndpoint.Scope scope, List<String> names) { this(clusterId, scope, names, OptionalInt.empty()); @@ -31,11 +30,16 @@ public class ContainerEndpoint { } public ContainerEndpoint(String clusterId, ApplicationClusterEndpoint.Scope scope, List<String> names, OptionalInt weight, ApplicationClusterEndpoint.RoutingMethod routingMethod) { + this(clusterId, scope, names, weight, routingMethod, ApplicationClusterEndpoint.AuthMethod.mtls); + } + + public ContainerEndpoint(String clusterId, ApplicationClusterEndpoint.Scope scope, List<String> names, OptionalInt weight, ApplicationClusterEndpoint.RoutingMethod routingMethod, ApplicationClusterEndpoint.AuthMethod authMethod) { this.clusterId = Objects.requireNonNull(clusterId); this.scope = Objects.requireNonNull(scope); this.names = List.copyOf(Objects.requireNonNull(names)); - this.weight = weight; - this.routingMethod = routingMethod; + this.weight = Objects.requireNonNull(weight); + this.routingMethod = Objects.requireNonNull(routingMethod); + this.authMethod = Objects.requireNonNull(authMethod); } public String clusterId() { @@ -58,6 +62,10 @@ public class ContainerEndpoint { return routingMethod; } + public ApplicationClusterEndpoint.AuthMethod authMethod() { + return authMethod; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -67,16 +75,17 @@ public class ContainerEndpoint { Objects.equals(scope, that.scope) && Objects.equals(names, that.names) && Objects.equals(weight, that.weight) && - Objects.equals(routingMethod, that.routingMethod); + Objects.equals(routingMethod, that.routingMethod) && + Objects.equals(authMethod, that.authMethod); } @Override public int hashCode() { - return Objects.hash(clusterId, names, scope, weight, routingMethod); + return Objects.hash(clusterId, names, scope, weight, routingMethod, authMethod); } @Override public String toString() { - return String.format("container endpoint %s -> %s [scope=%s, weight=%s, routingMetod=%s]", clusterId, names, scope, weight, routingMethod); + return String.format("container endpoint %s -> %s [scope=%s, weight=%s, routingMethod=%s, authMethod=%s]", clusterId, names, scope, weight, routingMethod, authMethod); } } diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java index 584207caeac..07983c7c85a 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java @@ -39,6 +39,7 @@ import com.yahoo.vespa.model.container.component.Handler; import com.yahoo.vespa.model.container.component.SystemBindingPattern; import com.yahoo.vespa.model.container.configserver.ConfigserverCluster; import com.yahoo.vespa.model.utils.FileSender; + import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -48,7 +49,6 @@ import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; -import static com.yahoo.config.model.api.ApplicationClusterEndpoint.RoutingMethod.sharedLayer4; import static com.yahoo.vespa.model.container.docproc.DocprocChains.DOCUMENT_TYPE_MANAGER_CLASS; /** @@ -98,7 +98,7 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat private Integer memoryPercentage = null; - private List<ApplicationClusterEndpoint> endpointList = List.of(); + private List<ApplicationClusterEndpoint> endpoints = List.of(); public ApplicationContainerCluster(TreeConfigProducer<?> parent, String configSubId, String clusterId, DeployState deployState) { super(parent, configSubId, clusterId, deployState, true, 10); @@ -132,7 +132,7 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat super.doPrepare(deployState); addAndSendApplicationBundles(deployState); sendUserConfiguredFiles(deployState); - createEndpointList(deployState); + createEndpoints(deployState); } private void addAndSendApplicationBundles(DeployState deployState) { @@ -198,7 +198,7 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat } /** Create list of endpoints, these will be consumed later by LbServicesProducer */ - private void createEndpointList(DeployState deployState) { + private void createEndpoints(DeployState deployState) { if (!deployState.isHosted()) return; if (deployState.getProperties().applicationId().instance().isTester()) return; List<ApplicationClusterEndpoint> endpoints = new ArrayList<>(); @@ -224,25 +224,26 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat .dnsName(l4Name) .hosts(hosts) .clusterId(getName()) + .authMethod(ApplicationClusterEndpoint.AuthMethod.mtls) .build()); } } // Include all endpoints provided by controller endpointsFromController.stream() - .filter(ce -> ce.clusterId().equals(getName())) - .filter(ce -> ce.routingMethod() == sharedLayer4) - .forEach(ce -> ce.names().forEach( - name -> endpoints.add(ApplicationClusterEndpoint.builder() - .scope(ce.scope()) - .weight(Long.valueOf(ce.weight().orElse(1)).intValue()) // Default to weight=1 if not set - .routingMethod(ce.routingMethod()) - .dnsName(ApplicationClusterEndpoint.DnsName.from(name)) - .hosts(hosts) - .clusterId(getName()) - .build()) - )); - endpointList = List.copyOf(endpoints); + .filter(ce -> ce.clusterId().equals(getName())) + .forEach(ce -> ce.names().forEach( + name -> endpoints.add(ApplicationClusterEndpoint.builder() + .scope(ce.scope()) + .weight(ce.weight().orElse(1)) // Default to weight=1 if not set + .routingMethod(ce.routingMethod()) + .dnsName(ApplicationClusterEndpoint.DnsName.from(name)) + .hosts(hosts) + .clusterId(getName()) + .authMethod(ce.authMethod()) + .build()) + )); + this.endpoints = List.copyOf(endpoints); } @Override @@ -364,7 +365,7 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat @Override public List<ApplicationClusterEndpoint> endpoints() { - return endpointList; + return endpoints; } @Override diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java index 2562e1e3124..894fc55c014 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java @@ -439,7 +439,6 @@ public class ContainerClusterTest { cluster.doPrepare(state); List<ApplicationClusterEndpoint> endpoints = cluster.endpoints(); - assertNames(List.of(), endpoints.stream().filter(e -> e.routingMethod() == shared).toList()); assertNames(expectedSharedL4Names, endpoints.stream().filter(e -> e.routingMethod() == sharedLayer4).toList()); List<ContainerEndpoint> endpointsWithWeight = diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointSerializer.java b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointSerializer.java index b813d56b345..33f47bbc154 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointSerializer.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointSerializer.java @@ -11,6 +11,7 @@ import com.yahoo.slime.SlimeUtils; import java.util.ArrayList; import java.util.List; +import java.util.OptionalInt; /** * Contains all methods for de-/serializing ContainerEndpoints to/from JSON. @@ -32,48 +33,48 @@ public class ContainerEndpointSerializer { private static final String namesField = "names"; private static final String weightField = "weight"; private static final String routingMethodField = "routingMethod"; + private static final String authMethodField = "authMethod"; private ContainerEndpointSerializer() {} public static ContainerEndpoint endpointFromSlime(Inspector inspector) { - final var clusterId = inspector.field(clusterIdField).asString(); - final var scope = inspector.field(scopeField).asString(); - final var namesInspector = inspector.field(namesField); - final var weight = SlimeUtils.optionalInteger(inspector.field(weightField)); + String clusterId = inspector.field(clusterIdField).asString(); + String scope = inspector.field(scopeField).asString(); + Inspector namesInspector = inspector.field(namesField); + OptionalInt weight = SlimeUtils.optionalInteger(inspector.field(weightField)); // assign default routingmethod. Remove when 7.507 is latest version - // Cannot be used before all endpoints are assigned explicit routingmethod (from controller) - final var routingMethod = SlimeUtils.optionalString(inspector.field(routingMethodField)).orElse(ApplicationClusterEndpoint.RoutingMethod.sharedLayer4.name()); + // Cannot be used before all endpoints are assigned explicit routing method (from controller) + ApplicationClusterEndpoint.RoutingMethod routingMethod = SlimeUtils.optionalString(inspector.field(routingMethodField)) + .map(ContainerEndpointSerializer::routingMethodFrom) + .orElse(ApplicationClusterEndpoint.RoutingMethod.sharedLayer4); + ApplicationClusterEndpoint.AuthMethod authMethod = SlimeUtils.optionalString(inspector.field(authMethodField)) + .map(ContainerEndpointSerializer::authMethodFrom) + .orElse(ApplicationClusterEndpoint.AuthMethod.mtls); if (clusterId.isEmpty()) { throw new IllegalStateException("'clusterId' missing on serialized ContainerEndpoint"); } - if (scope.isEmpty()) { throw new IllegalStateException("'scope' missing on serialized ContainerEndpoint"); } - - if (! namesInspector.valid()) { + if (!namesInspector.valid()) { throw new IllegalStateException("'names' missing on serialized ContainerEndpoint"); } - if(routingMethod.isEmpty()) { - throw new IllegalStateException("'routingMethod' missing on serialized ContainerEndpoint"); - } - - final var names = new ArrayList<String>(); + List<String> names = new ArrayList<>(); namesInspector.traverse((ArrayTraverser) (idx, nameInspector) -> { final var containerName = nameInspector.asString(); names.add(containerName); }); - return new ContainerEndpoint(clusterId, ApplicationClusterEndpoint.Scope.valueOf(scope), names, weight, - ApplicationClusterEndpoint.RoutingMethod.valueOf(routingMethod)); + return new ContainerEndpoint(clusterId, scopeFrom(scope), names, weight, routingMethod, authMethod); } public static List<ContainerEndpoint> endpointListFromSlime(Slime slime) { final var inspector = slime.get(); return endpointListFromSlime(inspector); } + public static List<ContainerEndpoint> endpointListFromSlime(Inspector inspector) { final var endpoints = new ArrayList<ContainerEndpoint>(); @@ -88,11 +89,12 @@ public class ContainerEndpointSerializer { public static void endpointToSlime(Cursor cursor, ContainerEndpoint endpoint) { cursor.setString(clusterIdField, endpoint.clusterId()); - cursor.setString(scopeField, endpoint.scope().name()); + cursor.setString(scopeField, asString(endpoint.scope())); endpoint.weight().ifPresent(w -> cursor.setLong(weightField, w)); final var namesInspector = cursor.setArray(namesField); endpoint.names().forEach(namesInspector::addString); - cursor.setString(routingMethodField, endpoint.routingMethod().name()); + cursor.setString(routingMethodField, asString(endpoint.routingMethod())); + cursor.setString(authMethodField, asString(endpoint.authMethod())); } public static Slime endpointListToSlime(List<ContainerEndpoint> endpoints) { @@ -107,4 +109,53 @@ public class ContainerEndpointSerializer { return slime; } + private static ApplicationClusterEndpoint.RoutingMethod routingMethodFrom(String s) { + return switch (s) { + case "shared" -> ApplicationClusterEndpoint.RoutingMethod.shared; + case "sharedLayer4" -> ApplicationClusterEndpoint.RoutingMethod.sharedLayer4; + case "exclusive" -> ApplicationClusterEndpoint.RoutingMethod.exclusive; + default -> throw new IllegalArgumentException("Unknown routing method '" + s + "'"); + }; + } + + private static ApplicationClusterEndpoint.AuthMethod authMethodFrom(String s) { + return switch (s) { + case "mtls" -> ApplicationClusterEndpoint.AuthMethod.mtls; + case "token" -> ApplicationClusterEndpoint.AuthMethod.token; + default -> throw new IllegalArgumentException("Unknown auth method '" + s + "'"); + }; + } + + private static ApplicationClusterEndpoint.Scope scopeFrom(String s) { + return switch (s) { + case "global" -> ApplicationClusterEndpoint.Scope.global; + case "application" -> ApplicationClusterEndpoint.Scope.application; + case "zone" -> ApplicationClusterEndpoint.Scope.zone; + default -> throw new IllegalArgumentException("Unknown scope '" + s + "'"); + }; + } + + private static String asString(ApplicationClusterEndpoint.RoutingMethod routingMethod) { + return switch (routingMethod) { + case shared -> "shared"; + case sharedLayer4 -> "sharedLayer4"; + case exclusive -> "exclusive"; + }; + } + + private static String asString(ApplicationClusterEndpoint.AuthMethod authMethod) { + return switch (authMethod) { + case mtls -> "mtls"; + case token -> "token"; + }; + } + + private static String asString(ApplicationClusterEndpoint.Scope scope) { + return switch (scope) { + case global -> "global"; + case application -> "application"; + case zone -> "zone"; + }; + } + } diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointSerializerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointSerializerTest.java index c8f31697c5e..5e7fe64f998 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointSerializerTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointSerializerTest.java @@ -8,7 +8,6 @@ import org.junit.Test; import java.util.List; import java.util.OptionalInt; -import java.util.OptionalLong; import static org.junit.Assert.assertEquals; @@ -46,11 +45,9 @@ public class ContainerEndpointSerializerTest { @Test public void writeReadEndpoints() { - final var endpoints = List.of(new ContainerEndpoint("foo", ApplicationClusterEndpoint.Scope.global, List.of("a", "b"), OptionalInt.of(3), ApplicationClusterEndpoint.RoutingMethod.shared)); - final var serialized = ContainerEndpointSerializer.endpointListToSlime(endpoints); - final var deserialized = ContainerEndpointSerializer.endpointListFromSlime(serialized); - - assertEquals(endpoints, deserialized); + List<ContainerEndpoint> endpoints = List.of(new ContainerEndpoint("foo", ApplicationClusterEndpoint.Scope.global, List.of("a", "b"), OptionalInt.of(3), + ApplicationClusterEndpoint.RoutingMethod.shared, ApplicationClusterEndpoint.AuthMethod.token)); + assertEquals(endpoints, ContainerEndpointSerializer.endpointListFromSlime(ContainerEndpointSerializer.endpointListToSlime(endpoints))); } } |