diff options
author | gjoranv <gjoranv@gmail.com> | 2023-02-17 17:17:30 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-02-17 17:17:30 +0100 |
commit | 083f5276f8b40c51e523b2a5ac00d5a1f40515b7 (patch) | |
tree | c7f31693769c0fc9b7677142c1fa328cd7ab2ed1 | |
parent | 14138b2cab436ee2529aa96d7df94cb0094b0a22 (diff) | |
parent | 4a5cc6bd7968e6dbe1fee0c9c30fdb97fd07a29a (diff) |
Merge pull request #26090 from vespa-engine/exclave-nodes-from-node-repo
Exclave nodes from node repo
12 files changed, 154 insertions, 57 deletions
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/NodeRepository.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/NodeRepository.java index b423eb5dbdf..f543416115b 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/NodeRepository.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/NodeRepository.java @@ -1,7 +1,7 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.hosted.node.admin.configserver.noderepository; -import com.yahoo.vespa.hosted.node.admin.wireguard.ConfigserverPeer; +import com.yahoo.vespa.hosted.node.admin.wireguard.WireguardPeer; import java.util.List; import java.util.Map; @@ -24,7 +24,9 @@ public interface NodeRepository { Map<String, Acl> getAcls(String hostname); - List<ConfigserverPeer> getConfigserverPeers(); + List<WireguardPeer> getExclavePeers(); + + List<WireguardPeer> getConfigserverPeers(); void updateNodeAttributes(String hostName, NodeAttributes nodeAttributes); diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/RealNodeRepository.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/RealNodeRepository.java index e092cc15145..1befb543201 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/RealNodeRepository.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/RealNodeRepository.java @@ -18,7 +18,7 @@ import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.bindings.Ge import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.bindings.GetWireguardResponse; import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.bindings.NodeRepositoryNode; import com.yahoo.vespa.hosted.node.admin.task.util.network.VersionedIpAddress; -import com.yahoo.vespa.hosted.node.admin.wireguard.ConfigserverPeer; +import com.yahoo.vespa.hosted.node.admin.wireguard.WireguardPeer; import java.net.URI; import java.time.Instant; @@ -130,12 +130,22 @@ public class RealNodeRepository implements NodeRepository { } @Override - public List<ConfigserverPeer> getConfigserverPeers() { - GetWireguardResponse nodeResponse = configServerApi.get("/nodes/v2/wireguard", - GetWireguardResponse.class); - return nodeResponse.configservers.stream() + public List<WireguardPeer> getExclavePeers() { + String path = "/nodes/v2/node/?recursive=true&enclave=true"; + final GetNodesResponse response = configServerApi.get(path, GetNodesResponse.class); + + return response.nodes.stream() + .map(RealNodeRepository::createTenantPeer) + .sorted() + .toList(); + } + + @Override + public List<WireguardPeer> getConfigserverPeers() { + GetWireguardResponse response = configServerApi.get("/nodes/v2/wireguard", GetWireguardResponse.class); + return response.configservers.stream() .map(RealNodeRepository::createConfigserverPeer) - .sorted(Comparator.comparing(ConfigserverPeer::hostname)) + .sorted(Comparator.comparing(WireguardPeer::hostname)) .toList(); } @@ -340,10 +350,16 @@ public class RealNodeRepository implements NodeRepository { return node; } - private static ConfigserverPeer createConfigserverPeer(GetWireguardResponse.Configserver configServer) { - return new ConfigserverPeer(HostName.of(configServer.hostname), - configServer.ipAddresses.stream().map(VersionedIpAddress::from).toList(), - configServer.wireguardKey()); + private static WireguardPeer createTenantPeer(NodeRepositoryNode node) { + return new WireguardPeer(HostName.of(node.hostname), + node.ipAddresses.stream().map(VersionedIpAddress::from).toList(), + node.wireguardKey()); + } + + private static WireguardPeer createConfigserverPeer(GetWireguardResponse.Configserver configServer) { + return new WireguardPeer(HostName.of(configServer.hostname), + configServer.ipAddresses.stream().map(VersionedIpAddress::from).toList(), + configServer.wireguardKey()); } } diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/bindings/NodeRepositoryNode.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/bindings/NodeRepositoryNode.java index eb7ceab6021..1c6cb5224de 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/bindings/NodeRepositoryNode.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/bindings/NodeRepositoryNode.java @@ -5,9 +5,11 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.JsonNode; +import com.yahoo.config.provision.WireguardKey; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; /** @@ -94,6 +96,10 @@ public class NodeRepositoryNode { @JsonInclude(JsonInclude.Include.NON_EMPTY) public String wireguardPubkey; + public Optional<WireguardKey> wireguardKey() { + return (wireguardPubkey == null || wireguardPubkey.isEmpty()) ? Optional.empty() : Optional.of(new WireguardKey(wireguardPubkey)); + } + @JsonProperty("reports") public Map<String, JsonNode> reports = null; diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/network/VersionedIpAddress.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/network/VersionedIpAddress.java index 987a8909142..4e11b050d38 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/network/VersionedIpAddress.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/network/VersionedIpAddress.java @@ -9,7 +9,7 @@ import java.net.InetAddress; /** * @author gjoranv */ -public class VersionedIpAddress { +public class VersionedIpAddress implements Comparable<VersionedIpAddress> { private final InetAddress address; private final IPVersion version; @@ -46,4 +46,10 @@ public class VersionedIpAddress { } } + @Override + public int compareTo(VersionedIpAddress o) { + int version = version().compareTo(o.version()); + return (version != 0) ? version : asString().compareTo(o.asString()); + } + } diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/wireguard/ConfigserverPeer.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/wireguard/ConfigserverPeer.java deleted file mode 100644 index 63ddc2f3dd2..00000000000 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/wireguard/ConfigserverPeer.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.yahoo.vespa.hosted.node.admin.wireguard; - -import com.yahoo.config.provision.HostName; -import com.yahoo.config.provision.WireguardKey; -import com.yahoo.vespa.hosted.node.admin.task.util.network.VersionedIpAddress; - -import java.util.List; -import java.util.Optional; - -/** - * @author gjoranv - */ -public record ConfigserverPeer(HostName hostname, - List<VersionedIpAddress> ipAddresses, - Optional<WireguardKey> publicKey) { - - public ConfigserverPeer { - if (ipAddresses.isEmpty()) throw new IllegalArgumentException("No IP addresses for configserver " + hostname.value()); - ipAddresses = List.copyOf(ipAddresses); - } - -} diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/wireguard/WireguardPeer.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/wireguard/WireguardPeer.java new file mode 100644 index 00000000000..f3ee8f0eb7f --- /dev/null +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/wireguard/WireguardPeer.java @@ -0,0 +1,29 @@ +package com.yahoo.vespa.hosted.node.admin.wireguard; + +import com.yahoo.config.provision.HostName; +import com.yahoo.config.provision.WireguardKey; +import com.yahoo.vespa.hosted.node.admin.task.util.network.VersionedIpAddress; + +import java.util.List; +import java.util.Optional; + +/** + * A wireguard peer. + * + * @author gjoranv + */ +public record WireguardPeer(HostName hostname, + List<VersionedIpAddress> ipAddresses, + Optional<WireguardKey> publicKey) implements Comparable<WireguardPeer> { + + public WireguardPeer { + if (ipAddresses.isEmpty()) throw new IllegalArgumentException("No IP addresses for peer node " + hostname.value()); + ipAddresses = ipAddresses.stream().sorted().toList(); + } + + @Override + public int compareTo(WireguardPeer o) { + return hostname.value().compareTo(o.hostname.value()); + } + +} diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/RealNodeRepositoryTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/RealNodeRepositoryTest.java index 9c33db0355f..96a0a46a3ff 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/RealNodeRepositoryTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/RealNodeRepositoryTest.java @@ -12,7 +12,7 @@ import com.yahoo.config.provision.host.FlavorOverrides; import com.yahoo.vespa.hosted.node.admin.configserver.ConfigServerApi; import com.yahoo.vespa.hosted.node.admin.configserver.ConfigServerApiImpl; import com.yahoo.vespa.hosted.node.admin.task.util.network.VersionedIpAddress; -import com.yahoo.vespa.hosted.node.admin.wireguard.ConfigserverPeer; +import com.yahoo.vespa.hosted.node.admin.wireguard.WireguardPeer; import com.yahoo.vespa.hosted.provision.restapi.NodesV2ApiHandler; import com.yahoo.vespa.hosted.provision.testutils.ContainerConfig; import org.junit.jupiter.api.AfterEach; @@ -199,24 +199,41 @@ public class RealNodeRepositoryTest { } @Test - void wireguard_peer_config_for_configservers_can_be_retrieved() { - List<ConfigserverPeer> cfgPeers = nodeRepositoryApi.getConfigserverPeers(); + void wireguard_peer_config_can_be_retrieved_for_configservers_and_exclave_nodes() { + + //// Configservers //// + + List<WireguardPeer> cfgPeers = nodeRepositoryApi.getConfigserverPeers(); assertEquals(2, cfgPeers.size()); - var cfg1 = cfgPeers.get(0); - assertEquals("cfg1.yahoo.com", cfg1.hostname().value()); - assertEquals(2, cfg1.ipAddresses().size()); - assertIp(cfg1.ipAddresses().get(0), "127.0.201.1", 4); - assertIp(cfg1.ipAddresses().get(1), "::201:1", 6); - assertEquals("lololololololololololololololololololololoo=", cfg1.publicKey().get().value()); + assertWireguardPeer(cfgPeers.get(0), "cfg1.yahoo.com", + "::201:1", "127.0.201.1", + "lololololololololololololololololololololoo="); + + assertWireguardPeer(cfgPeers.get(1), "cfg2.yahoo.com", + "::202:1", "127.0.202.1", + "olololololololololololololololololololololo="); + + //// Exclave nodes //// - var cfg2 = cfgPeers.get(1); - assertEquals("cfg2.yahoo.com", cfg2.hostname().value()); - assertEquals(2, cfg1.ipAddresses().size()); - assertIp(cfg2.ipAddresses().get(0), "127.0.202.1", 4); - assertIp(cfg2.ipAddresses().get(1), "::202:1", 6); - assertEquals("olololololololololololololololololololololo=", cfg2.publicKey().get().value()); + List<WireguardPeer> exclavePeers = nodeRepositoryApi.getExclavePeers(); + assertEquals(2, exclavePeers.size()); + + assertWireguardPeer(exclavePeers.get(0), "dockerhost2.yahoo.com", + "::101:1", "127.0.101.1", + "000011112222333344445555666677778888999900c="); + + assertWireguardPeer(exclavePeers.get(1), "host3.yahoo.com", + "::3:1", "127.0.3.1", + "333344445555666677778888999900001111222211c="); + } + private void assertWireguardPeer(WireguardPeer peer, String hostname, String ipv6, String ipv4, String publicKey) { + assertEquals(hostname, peer.hostname().value()); + assertEquals(2, peer.ipAddresses().size()); + assertIp(peer.ipAddresses().get(0), ipv6, 6); + assertIp(peer.ipAddresses().get(1), ipv4, 4); + assertEquals(publicKey, peer.publicKey().get().value()); } private void assertIp(VersionedIpAddress ip, String expectedIp, int expectedVersion) { diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integration/NodeRepoMock.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integration/NodeRepoMock.java index 06729083494..3dab2f1e776 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integration/NodeRepoMock.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integration/NodeRepoMock.java @@ -8,14 +8,13 @@ import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeAttribu import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeRepository; import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeSpec; import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeState; -import com.yahoo.vespa.hosted.node.admin.wireguard.ConfigserverPeer; +import com.yahoo.vespa.hosted.node.admin.wireguard.WireguardPeer; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; -import java.util.stream.Collectors; /** * Mock with some simple logic @@ -48,7 +47,12 @@ public class NodeRepoMock implements NodeRepository { } @Override - public List<ConfigserverPeer> getConfigserverPeers() { + public List<WireguardPeer> getExclavePeers() { + throw new UnsupportedOperationException(); + } + + @Override + public List<WireguardPeer> getConfigserverPeers() { throw new UnsupportedOperationException(); } diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/wireguard/WireguardPeerTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/wireguard/WireguardPeerTest.java new file mode 100644 index 00000000000..3264c9aa190 --- /dev/null +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/wireguard/WireguardPeerTest.java @@ -0,0 +1,34 @@ +package com.yahoo.vespa.hosted.node.admin.wireguard; + +import com.yahoo.config.provision.HostName; +import com.yahoo.vespa.hosted.node.admin.task.util.network.VersionedIpAddress; +import org.junit.jupiter.api.Test; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * @author gjoranv + */ +public class WireguardPeerTest { + + @Test + void peers_are_sorted_by_hostname_ascending() { + List<WireguardPeer> peers = Stream.of( + peer("b"), + peer("a"), + peer("c") + ).sorted().toList(); + + assertEquals("a", peers.get(0).hostname().value()); + assertEquals("b", peers.get(1).hostname().value()); + assertEquals("c", peers.get(2).hostname().value()); + } + + private static WireguardPeer peer(String hostname) { + return new WireguardPeer(HostName.of(hostname), List.of(VersionedIpAddress.from("::1:1")), Optional.empty()); + } +} 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 d27bd3aea4a..3caefcdc69e 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 @@ -110,7 +110,8 @@ public class MockNodeRepository extends NodeRepository { .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()); + .wireguardPubKey(WireguardKey.from("333344445555666677778888999900001111222211c=")) + .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() @@ -156,7 +157,9 @@ public class MockNodeRepository extends NodeRepository { 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).cloudAccount(tenantAccount).build()); + flavors.getFlavorOrThrow("large"), NodeType.host) + .wireguardPubKey(WireguardKey.from("000011112222333344445555666677778888999900c=")) + .cloudAccount(tenantAccount).build()); nodes.add(Node.create("dockerhost3", ipConfig(102, 1, 3), "dockerhost3.yahoo.com", flavors.getFlavorOrThrow("large"), NodeType.host).cloudAccount(defaultCloudAccount).build()); nodes.add(Node.create("dockerhost4", ipConfig(103, 1, 3), "dockerhost4.yahoo.com", diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node2.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node2.json index b39aba199b7..f7e02261065 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node2.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node2.json @@ -98,5 +98,6 @@ "::101:3", "::101:4" ], - "cloudAccount": "777888999000" + "cloudAccount": "777888999000", + "wireguardPubkey":"000011112222333344445555666677778888999900c=" } diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node3.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node3.json index 1c560c2f95b..aa45de1f3dd 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node3.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node3.json @@ -50,5 +50,6 @@ "::3:1" ], "additionalIpAddresses": [], - "cloudAccount": "777888999000" + "cloudAccount": "777888999000", + "wireguardPubkey":"333344445555666677778888999900001111222211c=" } |