diff options
Diffstat (limited to 'node-repository/src/main/java/com')
3 files changed, 99 insertions, 46 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/filter/CloudAccountFilter.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/filter/CloudAccountFilter.java new file mode 100644 index 00000000000..c7a4f50ab7c --- /dev/null +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/filter/CloudAccountFilter.java @@ -0,0 +1,29 @@ +package com.yahoo.vespa.hosted.provision.node.filter; + +import com.yahoo.config.provision.CloudAccount; +import com.yahoo.vespa.hosted.provision.Node; + +import java.util.Collection; +import java.util.Objects; +import java.util.function.Predicate; + +/** + * Filters nodes based on their cloud account. + * + * @author gjoranv + */ +public class CloudAccountFilter { + + private CloudAccountFilter() { } + + /** Creates a node filter which removes the nodes from the given cloud accounts */ + public static Predicate<Node> from(Collection<CloudAccount> unwantedAccounts, boolean enabled) { + Objects.requireNonNull(unwantedAccounts, "unwantedAccounts cannot be null"); + return node -> { + if (unwantedAccounts.isEmpty()) return true; + if (! enabled) return true; + return ! unwantedAccounts.contains(node.cloudAccount()); + }; + } + +} diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/ContainerConfig.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/ContainerConfig.java index 024f071abb1..f0f85b6523f 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/ContainerConfig.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/ContainerConfig.java @@ -1,6 +1,8 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.hosted.provision.testutils; +import com.yahoo.config.provision.CloudAccount; + /** * For running NodeRepository API with some mocked data. * This is used by both NodeAdmin and NodeRepository tests. @@ -9,38 +11,43 @@ package com.yahoo.vespa.hosted.provision.testutils; */ public class ContainerConfig { - public static String servicesXmlV2(int port) { - return "<container version='1.0'>\n" + - " <config name=\"container.handler.threadpool\">\n" + - " <maxthreads>20</maxthreads>\n" + - " </config>\n" + - " <accesslog type='disabled'/>\n" + - " <component id='com.yahoo.test.ManualClock'/>\n" + - " <component id='com.yahoo.vespa.curator.mock.MockCurator'/>\n" + - " <component id='com.yahoo.vespa.hosted.provision.testutils.OrchestratorMock'/>\n" + - " <component id='com.yahoo.vespa.hosted.provision.testutils.MockDeployer'/>\n" + - " <component id='com.yahoo.vespa.hosted.provision.testutils.MockInfraDeployer'/>\n" + - " <component id='com.yahoo.vespa.hosted.provision.testutils.MockProvisioner'/>\n" + - " <component id='com.yahoo.vespa.hosted.provision.testutils.ServiceMonitorStub'/>\n" + - " <component id='com.yahoo.vespa.hosted.provision.testutils.MockDuperModel'/>\n" + - " <component id='com.yahoo.vespa.hosted.provision.testutils.MockNodeFlavors'/>\n" + - " <component id='com.yahoo.vespa.hosted.provision.autoscale.QuestMetricsDb'/>\n" + - " <component id='com.yahoo.vespa.hosted.provision.testutils.MockMetricsFetcher'/>\n" + - " <component id='com.yahoo.vespa.hosted.provision.testutils.MockNodeRepository'/>\n" + - " <component id='com.yahoo.vespa.hosted.provision.testutils.MockProvisionServiceProvider'/>\n" + - " <component id='com.yahoo.vespa.hosted.provision.maintenance.NodeRepositoryMaintenance'/>\n" + - " <component id='com.yahoo.vespa.flags.InMemoryFlagSource'/>\n" + - " <component id='com.yahoo.config.provision.Zone'/>\n" + - " <handler id='com.yahoo.vespa.hosted.provision.restapi.NodesV2ApiHandler'>\n" + - " <binding>http://*/nodes/v2*</binding>\n" + - " </handler>\n" + - " <handler id='com.yahoo.vespa.hosted.provision.restapi.LoadBalancersV1ApiHandler'>\n" + - " <binding>http://*/loadbalancers/v1*</binding>\n" + - " </handler>\n" + - " <http>\n" + - " <server id='myServer' port='" + port + "'/>\n" + - " </http>\n" + - "</container>"; + public static String servicesXmlV2(int port, CloudAccount cloudAccount) { + return """ + <container version='1.0'> + <config name="container.handler.threadpool"> + <maxthreads>20</maxthreads> + </config> + <config name="config.provisioning.cloud"> + <account>%s</account> + </config> + <accesslog type='disabled'/> + <component id='com.yahoo.test.ManualClock'/> + <component id='com.yahoo.vespa.curator.mock.MockCurator'/> + <component id='com.yahoo.vespa.hosted.provision.testutils.OrchestratorMock'/> + <component id='com.yahoo.vespa.hosted.provision.testutils.MockDeployer'/> + <component id='com.yahoo.vespa.hosted.provision.testutils.MockInfraDeployer'/> + <component id='com.yahoo.vespa.hosted.provision.testutils.MockProvisioner'/> + <component id='com.yahoo.vespa.hosted.provision.testutils.ServiceMonitorStub'/> + <component id='com.yahoo.vespa.hosted.provision.testutils.MockDuperModel'/> + <component id='com.yahoo.vespa.hosted.provision.testutils.MockNodeFlavors'/> + <component id='com.yahoo.vespa.hosted.provision.autoscale.QuestMetricsDb'/> + <component id='com.yahoo.vespa.hosted.provision.testutils.MockMetricsFetcher'/> + <component id='com.yahoo.vespa.hosted.provision.testutils.MockNodeRepository'/> + <component id='com.yahoo.vespa.hosted.provision.testutils.MockProvisionServiceProvider'/> + <component id='com.yahoo.vespa.hosted.provision.maintenance.NodeRepositoryMaintenance'/> + <component id='com.yahoo.vespa.flags.InMemoryFlagSource'/> + <component id='com.yahoo.config.provision.Zone'/> + <handler id='com.yahoo.vespa.hosted.provision.restapi.NodesV2ApiHandler'> + <binding>http://*/nodes/v2*</binding> + </handler> + <handler id='com.yahoo.vespa.hosted.provision.restapi.LoadBalancersV1ApiHandler'> + <binding>http://*/loadbalancers/v1*</binding> + </handler> + <http> + <server id='myServer' port='%s'/> + </http> + </container> + """.formatted(cloudAccount.value(), port); } } diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java index dccfa830a8d..a19e48cfa6b 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java @@ -7,6 +7,7 @@ import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.ApplicationName; import com.yahoo.config.provision.ApplicationTransaction; import com.yahoo.config.provision.Capacity; +import com.yahoo.config.provision.CloudAccount; import com.yahoo.config.provision.ClusterResources; import com.yahoo.config.provision.ClusterSpec; import com.yahoo.config.provision.DockerImage; @@ -34,6 +35,7 @@ import com.yahoo.vespa.hosted.provision.node.Status; import com.yahoo.vespa.hosted.provision.provisioning.EmptyProvisionServiceProvider; import com.yahoo.vespa.hosted.provision.provisioning.NodeRepositoryProvisioner; +import javax.inject.Inject; import java.time.Clock; import java.time.Instant; import java.time.ZoneId; @@ -56,20 +58,23 @@ import static com.yahoo.config.provision.NodeResources.StorageType.remote; * Instantiated by DI. */ public class MockNodeRepository extends NodeRepository { + public static final CloudAccount tenantAccount = CloudAccount.from("777888999000"); private final NodeFlavors flavors; + private final CloudAccount defaultCloudAccount; /** * Constructor * * @param flavors flavors to have in node repo */ - public MockNodeRepository(MockCurator curator, NodeFlavors flavors) { + @Inject + public MockNodeRepository(MockCurator curator, NodeFlavors flavors, Zone zone) { super(flavors, new EmptyProvisionServiceProvider(), curator, Clock.fixed(Instant.ofEpochMilli(123), ZoneId.of("Z")), - Zone.defaultZone(), + zone, new MockNameResolver().mockAnyLookup(), DockerImage.fromString("docker-registry.domain.tld:8080/dist/vespa"), Optional.empty(), @@ -79,6 +84,7 @@ public class MockNodeRepository extends NodeRepository { true, 0, 1000); this.flavors = flavors; + defaultCloudAccount = zone.cloud().account(); curator.setZooKeeperEnsembleConnectionSpec("cfg1:1234,cfg2:1234,cfg3:1234"); populate(); @@ -89,14 +95,19 @@ public class MockNodeRepository extends NodeRepository { List<Node> nodes = new ArrayList<>(); // Regular nodes - nodes.add(Node.create("node1", ipConfig(1), "host1.yahoo.com", resources(2, 8, 50, 1, fast, local), NodeType.tenant).build()); - nodes.add(Node.create("node2", ipConfig(2), "host2.yahoo.com", resources(2, 8, 50, 1, fast, local), NodeType.tenant).build()); - nodes.add(Node.create("node3", ipConfig(3), "host3.yahoo.com", resources(0.5, 48, 500, 1, fast, local), NodeType.tenant).build()); + nodes.add(Node.create("node1", ipConfig(1), "host1.yahoo.com", resources(2, 8, 50, 1, fast, local), NodeType.tenant) + .cloudAccount(defaultCloudAccount).build()); + nodes.add(Node.create("node2", ipConfig(2), "host2.yahoo.com", resources(2, 8, 50, 1, fast, local), NodeType.tenant) + .cloudAccount(defaultCloudAccount).build()); + // Emulate node in tenant account + nodes.add(Node.create("node3", ipConfig(3), "host3.yahoo.com", resources(0.5, 48, 500, 1, fast, local), NodeType.tenant) + .cloudAccount(tenantAccount).build()); Node node4 = Node.create("node4", ipConfig(4), "host4.yahoo.com", resources(1, 4, 100, 1, fast, local), NodeType.tenant) .parentHostname("dockerhost1.yahoo.com") .status(Status.initial() .withVespaVersion(new Version("6.41.0")) .withContainerImage(DockerImage.fromString("docker-registry.domain.tld:8080/dist/vespa:6.41.0"))) + .cloudAccount(defaultCloudAccount) .build(); nodes.add(node4); @@ -105,12 +116,15 @@ public class MockNodeRepository extends NodeRepository { .status(Status.initial() .withVespaVersion(new Version("1.2.3")) .withContainerImage(DockerImage.fromString("docker-registry.domain.tld:8080/dist/vespa:1.2.3"))) + .cloudAccount(defaultCloudAccount) .build(); nodes.add(node5); - nodes.add(Node.create("node6", ipConfig(6), "host6.yahoo.com", resources(2, 8, 50, 1, fast, local), NodeType.tenant).build()); - Node node7 = Node.create("node7", ipConfig(7), "host7.yahoo.com", resources(2, 8, 50, 1, fast, local), NodeType.tenant).build(); + nodes.add(Node.create("node6", ipConfig(6), "host6.yahoo.com", resources(2, 8, 50, 1, fast, local), NodeType.tenant) + .cloudAccount(defaultCloudAccount).build()); + Node node7 = Node.create("node7", ipConfig(7), "host7.yahoo.com", resources(2, 8, 50, 1, fast, local), NodeType.tenant) + .cloudAccount(defaultCloudAccount).build(); nodes.add(node7); // 8, 9, 11 and 12 are added by web service calls @@ -119,26 +133,29 @@ public class MockNodeRepository extends NodeRepository { .status(Status.initial() .withVespaVersion(Version.fromString("5.104.142")) .withContainerImage(DockerImage.fromString("docker-registry.domain.tld:8080/dist/vespa:5.104.142"))) + .cloudAccount(defaultCloudAccount) .build(); nodes.add(node10); Node node55 = Node.create("node55", ipConfig(55), "host55.yahoo.com", resources(2, 8, 50, 1, fast, local), NodeType.tenant) - .status(Status.initial().withWantToRetire(true, true, false)).build(); + .status(Status.initial().withWantToRetire(true, true, false)) + .cloudAccount(defaultCloudAccount).build(); nodes.add(node55); /* Setup docker hosts (two of these will be reserved for spares */ nodes.add(Node.create("dockerhost1", ipConfig(100, 1, 3), "dockerhost1.yahoo.com", - flavors.getFlavorOrThrow("large"), NodeType.host).build()); + flavors.getFlavorOrThrow("large"), NodeType.host).cloudAccount(defaultCloudAccount).build()); + // Emulate host in tenant account nodes.add(Node.create("dockerhost2", ipConfig(101, 1, 3), "dockerhost2.yahoo.com", - flavors.getFlavorOrThrow("large"), NodeType.host).build()); + flavors.getFlavorOrThrow("large"), NodeType.host).cloudAccount(tenantAccount).build()); nodes.add(Node.create("dockerhost3", ipConfig(102, 1, 3), "dockerhost3.yahoo.com", - flavors.getFlavorOrThrow("large"), NodeType.host).build()); + flavors.getFlavorOrThrow("large"), NodeType.host).cloudAccount(defaultCloudAccount).build()); nodes.add(Node.create("dockerhost4", ipConfig(103, 1, 3), "dockerhost4.yahoo.com", - flavors.getFlavorOrThrow("large"), NodeType.host).build()); + flavors.getFlavorOrThrow("large"), NodeType.host).cloudAccount(defaultCloudAccount).build()); nodes.add(Node.create("dockerhost5", ipConfig(104, 1, 3), "dockerhost5.yahoo.com", - flavors.getFlavorOrThrow("large"), NodeType.host).build()); + flavors.getFlavorOrThrow("large"), NodeType.host).cloudAccount(defaultCloudAccount).build()); nodes.add(Node.create("dockerhost6", ipConfig(105, 1, 3), "dockerhost6.yahoo.com", - flavors.getFlavorOrThrow("arm64"), NodeType.host).build()); + flavors.getFlavorOrThrow("arm64"), NodeType.host).cloudAccount(defaultCloudAccount).build()); // Config servers nodes.add(Node.create("cfg1", ipConfig(201), "cfg1.yahoo.com", flavors.getFlavorOrThrow("default"), NodeType.config).build()); |