diff options
author | Martin Polden <mpolden@mpolden.no> | 2019-05-23 15:16:43 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-05-23 15:16:43 +0200 |
commit | d51ea3aa7294ca6aaa6f57e32409425ff22d4487 (patch) | |
tree | 735ccd482d61a723f42ddae908f3e2264a0c53f6 /node-repository | |
parent | dfcece099428543644322172f91689d1f76423b0 (diff) | |
parent | d477bae695aa88e5ce2359b92204aa70a1303c95 (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')
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()); + } +} |