summaryrefslogtreecommitdiffstats
path: root/node-repository
diff options
context:
space:
mode:
authorMartin Polden <mpolden@mpolden.no>2019-05-23 15:16:43 +0200
committerGitHub <noreply@github.com>2019-05-23 15:16:43 +0200
commitd51ea3aa7294ca6aaa6f57e32409425ff22d4487 (patch)
tree735ccd482d61a723f42ddae908f3e2264a0c53f6 /node-repository
parentdfcece099428543644322172f91689d1f76423b0 (diff)
parentd477bae695aa88e5ce2359b92204aa70a1303c95 (diff)
Merge pull request #9509 from vespa-engine/ogronnesby/on-premises-load-balancer-service
Load Balancer Service for use for on-prem Vespa
Diffstat (limited to 'node-repository')
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/SharedLoadBalancerService.java76
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/lb/SharedLoadBalancerServiceTest.java49
2 files changed, 125 insertions, 0 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/SharedLoadBalancerService.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/SharedLoadBalancerService.java
new file mode 100644
index 00000000000..87b7c73386e
--- /dev/null
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/SharedLoadBalancerService.java
@@ -0,0 +1,76 @@
+// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.hosted.provision.lb;
+
+import com.google.inject.Inject;
+import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.ClusterSpec;
+import com.yahoo.config.provision.HostName;
+import com.yahoo.config.provision.NodeType;
+import com.yahoo.vespa.hosted.provision.Node;
+import com.yahoo.vespa.hosted.provision.NodeRepository;
+import com.yahoo.vespa.hosted.provision.node.IP;
+
+import java.util.Comparator;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * This code mimics provisioning load balancers that already exist in the routing layer.
+ * It will just map the load balancer request to the proxy nodes available in the node repository.
+ *
+ * @author ogronnesby
+ */
+public class SharedLoadBalancerService implements LoadBalancerService {
+ private static final Comparator<Node> hostnameComparator = Comparator.comparing(Node::hostname);
+ private final NodeRepository nodeRepository;
+
+ @Inject
+ public SharedLoadBalancerService(NodeRepository nodeRepository) {
+ this.nodeRepository = Objects.requireNonNull(nodeRepository, "Missing nodeRepository value");
+ }
+
+ @Override
+ public LoadBalancerInstance create(ApplicationId application, ClusterSpec.Id cluster, Set<Real> reals) {
+ final var proxyNodes = nodeRepository.getNodes(NodeType.proxy);
+ proxyNodes.sort(hostnameComparator);
+
+ if (proxyNodes.size() == 0) {
+ throw new IllegalStateException("Missing proxy nodes in nodeRepository");
+ }
+
+ final var firstProxyNode = proxyNodes.get(0);
+ final var networkNames = proxyNodes.stream()
+ .flatMap(node -> node.ipAddresses().stream())
+ .map(SharedLoadBalancerService::addNetworKPrefixLength)
+ .collect(Collectors.toSet());
+
+ return new LoadBalancerInstance(
+ HostName.from(firstProxyNode.hostname()),
+ Optional.empty(),
+ Set.of(4080, 4443),
+ networkNames,
+ reals
+ );
+ }
+
+ @Override
+ public void remove(ApplicationId application, ClusterSpec.Id cluster) {
+ // Do nothing, we have no external state to modify
+ }
+
+ @Override
+ public Protocol protocol() {
+ return Protocol.dualstack;
+ }
+
+ private static String addNetworKPrefixLength(String address) {
+ if (IP.isV6(address)) {
+ return address + "/128";
+ }
+ else {
+ return address + "/32";
+ }
+ }
+}
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/lb/SharedLoadBalancerServiceTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/lb/SharedLoadBalancerServiceTest.java
new file mode 100644
index 00000000000..40c307c6bef
--- /dev/null
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/lb/SharedLoadBalancerServiceTest.java
@@ -0,0 +1,49 @@
+// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.hosted.provision.lb;
+
+import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.ClusterSpec;
+import com.yahoo.config.provision.HostName;
+import com.yahoo.config.provision.NodeType;
+import com.yahoo.vespa.hosted.provision.provisioning.ProvisioningTester;
+import org.junit.Test;
+
+import java.util.Optional;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author ogronnesby
+ */
+public class SharedLoadBalancerServiceTest {
+ private final ProvisioningTester tester = new ProvisioningTester.Builder().build();
+ private final SharedLoadBalancerService loadBalancerService = new SharedLoadBalancerService(tester.nodeRepository());
+ private final ApplicationId applicationId = ApplicationId.from("tenant1", "application1", "default");
+ private final ClusterSpec.Id clusterId = ClusterSpec.Id.from("qrs1");
+ private final Set<Real> reals = Set.of(
+ new Real(HostName.from("some.nice.host"), "10.23.56.102"),
+ new Real(HostName.from("some.awful.host"), "10.23.56.103")
+ );
+
+ @Test
+ public void test_create_lb() {
+ tester.makeReadyNodes(2, "default", NodeType.proxy);
+ final var lb = loadBalancerService.create(applicationId, clusterId, reals);
+
+ assertEquals(HostName.from("host-1.yahoo.com"), lb.hostname());
+ assertEquals(Optional.empty(), lb.dnsZone());
+ assertEquals(Set.of("127.0.0.1/32", "127.0.0.2/32", "::1/128", "::2/128"), lb.networks());
+ assertEquals(Set.of(4080, 4443), lb.ports());
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void test_exception_on_missing_proxies() {
+ loadBalancerService.create(applicationId, clusterId, reals);
+ }
+
+ @Test
+ public void test_protocol() {
+ assertEquals(LoadBalancerService.Protocol.dualstack, loadBalancerService.protocol());
+ }
+}