diff options
author | jonmv <venstad@gmail.com> | 2022-11-18 15:30:01 +0100 |
---|---|---|
committer | jonmv <venstad@gmail.com> | 2022-11-24 17:11:07 +0100 |
commit | 5a97752f3261905015a50ad15062173e6438ff96 (patch) | |
tree | 121eed2895060f7321308b7c8e3236b6043417e7 /config-model/src | |
parent | 22e91538da2029211bd9d640ec9e34e2fb3a8410 (diff) |
Read load-balancer allowed URNs from container xml, wire to provisioner
Diffstat (limited to 'config-model/src')
5 files changed, 92 insertions, 3 deletions
diff --git a/config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java b/config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java index 1c93ce4bd6d..d2fd6d8cfc4 100644 --- a/config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java +++ b/config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java @@ -25,6 +25,7 @@ import java.util.ListIterator; import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.TreeSet; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -67,6 +68,7 @@ public class InMemoryProvisioner implements HostProvisioner { private final boolean alwaysReturnOneNode; private Provisioned provisioned = new Provisioned(); + private final Set<ClusterSpec> clusters = new TreeSet<>(Comparator.comparing(cluster -> cluster.id().value())); private Environment environment = Environment.prod; @@ -146,6 +148,7 @@ public class InMemoryProvisioner implements HostProvisioner { @Override public List<HostSpec> prepare(ClusterSpec cluster, Capacity requested, ProvisionLogger logger) { provisioned.add(cluster.id(), requested); + clusters.add(cluster); if (environment == Environment.dev) { requested = requested.withLimits(requested.minResources().withNodes(1), requested.maxResources().withNodes(1)); @@ -197,6 +200,7 @@ public class InMemoryProvisioner implements HostProvisioner { /** Create a new provisioned instance to record provision requests to this and returns it */ public Provisioned startProvisionedRecording() { provisioned = new Provisioned(); + clusters.clear(); return provisioned; } @@ -287,4 +291,7 @@ public class InMemoryProvisioner implements HostProvisioner { return 0; } } + + public Set<ClusterSpec> provisionedClusters() { return clusters; } + } diff --git a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecification.java b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecification.java index b46f474aa7c..a31e3fcce71 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecification.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecification.java @@ -11,6 +11,7 @@ import com.yahoo.config.provision.ClusterMembership; import com.yahoo.config.provision.ClusterResources; import com.yahoo.config.provision.ClusterSpec; import com.yahoo.config.provision.DockerImage; +import com.yahoo.config.provision.LoadBalancerSettings; import com.yahoo.config.provision.NodeResources; import com.yahoo.text.XML; import com.yahoo.vespa.model.HostResource; @@ -255,6 +256,15 @@ public class NodesSpecification { ClusterSpec.Id clusterId, DeployLogger logger, boolean stateful) { + return provision(hostSystem, clusterType, clusterId, LoadBalancerSettings.empty, logger, stateful); + } + + public Map<HostResource, ClusterMembership> provision(HostSystem hostSystem, + ClusterSpec.Type clusterType, + ClusterSpec.Id clusterId, + LoadBalancerSettings loadBalancerSettings, + DeployLogger logger, + boolean stateful) { if (combinedId.isPresent()) clusterType = ClusterSpec.Type.combined; ClusterSpec cluster = ClusterSpec.request(clusterType, clusterId) @@ -262,6 +272,7 @@ public class NodesSpecification { .exclusive(exclusive) .combinedId(combinedId.map(ClusterSpec.Id::from)) .dockerImageRepository(dockerImageRepo) + .loadBalancerSettings(loadBalancerSettings) .stateful(stateful) .build(); return hostSystem.allocateHosts(cluster, Capacity.from(min, max, required, canFail, cloudAccount), logger); diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java index 5dc937fe585..03c9335bbc4 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java @@ -27,6 +27,7 @@ import com.yahoo.config.provision.ClusterMembership; import com.yahoo.config.provision.ClusterResources; import com.yahoo.config.provision.ClusterSpec; import com.yahoo.config.provision.HostName; +import com.yahoo.config.provision.LoadBalancerSettings; import com.yahoo.config.provision.NodeResources; import com.yahoo.config.provision.NodeType; import com.yahoo.config.provision.Zone; @@ -734,6 +735,13 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { } } + private LoadBalancerSettings loadBalancerSettings(Element loadBalancerElement) { + List<String> allowedUrnElements = XML.getChildren(XML.getChild(loadBalancerElement, "private-access"), + "allowed-urn") + .stream().map(XML::getValue).toList(); + return new LoadBalancerSettings(allowedUrnElements); + } + private static Map<String, String> getEnvironmentVariables(Element environmentVariables) { var map = new LinkedHashMap<String, String>(); if (environmentVariables != null) { @@ -745,7 +753,8 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { return map; } - private List<ApplicationContainer> createNodes(ApplicationContainerCluster cluster, Element containerElement, Element nodesElement, ConfigModelContext context) { + private List<ApplicationContainer> createNodes(ApplicationContainerCluster cluster, Element containerElement, + Element nodesElement, ConfigModelContext context) { if (nodesElement.hasAttribute("type")) // internal use for hosted system infrastructure nodes return createNodesFromNodeType(cluster, nodesElement, context); else if (nodesElement.hasAttribute("of")) {// hosted node spec referencing a content cluster @@ -818,9 +827,11 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { private List<ApplicationContainer> createNodesFromNodeCount(ApplicationContainerCluster cluster, Element containerElement, Element nodesElement, ConfigModelContext context) { NodesSpecification nodesSpecification = NodesSpecification.from(new ModelElement(nodesElement), context); + LoadBalancerSettings loadBalancerSettings = loadBalancerSettings(XML.getChild(containerElement, "load-balancer")); Map<HostResource, ClusterMembership> hosts = nodesSpecification.provision(cluster.getRoot().hostSystem(), ClusterSpec.Type.container, - ClusterSpec.Id.from(cluster.getName()), + ClusterSpec.Id.from(cluster.getName()), + loadBalancerSettings, log, getZooKeeper(containerElement) != null); return createNodesFromHosts(hosts, cluster, context.getDeployState()); diff --git a/config-model/src/main/resources/schema/containercluster.rnc b/config-model/src/main/resources/schema/containercluster.rnc index 1d31435dad1..8cd7071462e 100644 --- a/config-model/src/main/resources/schema/containercluster.rnc +++ b/config-model/src/main/resources/schema/containercluster.rnc @@ -6,7 +6,8 @@ ContainerCluster = element container { ContainerServices & DocumentBinding* & NodesOfContainerCluster? & - ClientAuthorize? + ClientAuthorize? & + LoadBalancer? } ContainerServices = @@ -255,6 +256,14 @@ NodesOfContainerCluster = element nodes { ) } +LoadBalancer = element load-balancer { + element private-access { + element allow-urn { + xsd:string + }* + }? +} + #DOCUMENT BINDINGS: diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTest.java index 251c18dbdd6..fafd4bb1ff5 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTest.java @@ -197,6 +197,57 @@ public class ContainerModelBuilderTest extends ContainerModelBuilderTestBase { } @Test + void load_balancers_can_be_set() throws IOException, SAXException { + // No load-balancer or nodes elements + verifyAllowedUrns(""); + + // No load-balancer element + verifyAllowedUrns("<nodes count='2' />"); + + // No nodes element + verifyAllowedUrns(""" + <load-balancer> + <private-access> + <allowed-urn>foo</allowed-urn> + <allowed-urn>bar</allowed-urn> + </private-access> + </load-balancer> + """); + + // Both load-balancer and nodes + verifyAllowedUrns(""" + <load-balancer> + <private-access> + <allowed-urn>foo</allowed-urn> + <allowed-urn>bar</allowed-urn> + </private-access> + </load-balancer> + <nodes count='2' /> + """, + "foo", "bar"); + } + + private void verifyAllowedUrns(String containerXml, String... expectedAllowedUrns) throws IOException, SAXException { + String servicesXml = """ + <container id='default' version='1.0'> + %s + </container> + """.formatted(containerXml); + ApplicationPackage applicationPackage = new MockApplicationPackage.Builder().withServices(servicesXml).build(); + InMemoryProvisioner provisioner = new InMemoryProvisioner(true, false, "host1.yahoo.com", "host2.yahoo.com"); + VespaModel model = new VespaModel(new NullConfigModelRegistry(), new DeployState.Builder() + .modelHostProvisioner(provisioner) + .provisioned(provisioner.startProvisionedRecording()) + .applicationPackage(applicationPackage) + .properties(new TestProperties().setMultitenant(true).setHostedVespa(true)) + .build()); + assertEquals(2, model.hostSystem().getHosts().size()); + assertEquals(1, provisioner.provisionedClusters().size()); + assertEquals(List.of(expectedAllowedUrns), + provisioner.provisionedClusters().iterator().next().loadBalancerSettings().allowedUrns()); + } + + @Test void builtin_handlers_get_default_threadpool() { createBasicContainerModel(); |