diff options
author | jonmv <venstad@gmail.com> | 2023-02-09 09:51:00 +0100 |
---|---|---|
committer | jonmv <venstad@gmail.com> | 2023-02-09 09:51:00 +0100 |
commit | e401e627a6bb1594067ce3ee4e3ae72c88dfc092 (patch) | |
tree | f3fe10a65bf6468b8e6b1cc31fe869506b494bf7 /node-repository | |
parent | 9606e4b949454ed95368f988a5830ec6537a9a22 (diff) |
Allow additional IP address for private service LB
Diffstat (limited to 'node-repository')
6 files changed, 81 insertions, 51 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/LoadBalancerInstance.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/LoadBalancerInstance.java index ee8ecbada7f..13934b5941f 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/LoadBalancerInstance.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/LoadBalancerInstance.java @@ -20,6 +20,7 @@ public class LoadBalancerInstance { private final Optional<DomainName> hostname; private final Optional<String> ipAddress; + private final Optional<String> privateServiceIpAddress; private final Optional<DnsZone> dnsZone; private final Set<Integer> ports; private final Set<String> networks; @@ -28,11 +29,12 @@ public class LoadBalancerInstance { private final Optional<PrivateServiceId> serviceId; private final CloudAccount cloudAccount; - public LoadBalancerInstance(Optional<DomainName> hostname, Optional<String> ipAddress, Optional<DnsZone> dnsZone, - Set<Integer> ports, Set<String> networks, Set<Real> reals, ZoneEndpoint settings, - Optional<PrivateServiceId> serviceId, CloudAccount cloudAccount) { + public LoadBalancerInstance(Optional<DomainName> hostname, Optional<String> ipAddress, Optional<String> privateServiceIpAddress, + Optional<DnsZone> dnsZone, Set<Integer> ports, Set<String> networks, Set<Real> reals, + ZoneEndpoint settings, Optional<PrivateServiceId> serviceId, CloudAccount cloudAccount) { this.hostname = Objects.requireNonNull(hostname, "hostname must be non-null"); this.ipAddress = Objects.requireNonNull(ipAddress, "ip must be non-null"); + this.privateServiceIpAddress = Objects.requireNonNull(privateServiceIpAddress, "private service ip must be non-null"); this.dnsZone = Objects.requireNonNull(dnsZone, "dnsZone must be non-null"); this.ports = ImmutableSortedSet.copyOf(requirePorts(ports)); this.networks = ImmutableSortedSet.copyOf(Objects.requireNonNull(networks, "networks must be non-null")); @@ -52,11 +54,16 @@ public class LoadBalancerInstance { return hostname; } - /** IP address of this load balancer */ + /** IP address of this (public) load balancer */ public Optional<String> ipAddress() { return ipAddress; } + /** IP address of this (private) load balancer */ + public Optional<String> privateServiceIpAddress() { + return ipAddress; + } + /** ID of the DNS zone associated with this */ public Optional<DnsZone> dnsZone() { return dnsZone; @@ -92,15 +99,6 @@ public class LoadBalancerInstance { return cloudAccount; } - /** Returns a copy of this with reals set to given reals */ - public LoadBalancerInstance withReals(Set<Real> reals) { - return new LoadBalancerInstance(hostname, ipAddress, dnsZone, ports, networks, reals, settings, serviceId, cloudAccount); - } - - public LoadBalancerInstance withSettings(ZoneEndpoint settings) { - return new LoadBalancerInstance(hostname, ipAddress, dnsZone, ports, networks, reals, settings, serviceId, cloudAccount); - } - private static Set<Integer> requirePorts(Set<Integer> ports) { Objects.requireNonNull(ports, "ports must be non-null"); if (ports.isEmpty()) { diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/LoadBalancerServiceMock.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/LoadBalancerServiceMock.java index 2649ddc37aa..3ef1af2cac1 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/LoadBalancerServiceMock.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/LoadBalancerServiceMock.java @@ -55,6 +55,7 @@ public class LoadBalancerServiceMock implements LoadBalancerService { var instance = new LoadBalancerInstance( Optional.of(DomainName.of("lb-" + spec.application().toShortString() + "-" + spec.cluster().value())), Optional.empty(), + Optional.empty(), Optional.of(new DnsZone("zone-id-1")), Collections.singleton(4443), ImmutableSet.of("10.2.3.0/24", "10.4.5.0/24"), @@ -77,6 +78,7 @@ public class LoadBalancerServiceMock implements LoadBalancerService { var instance = new LoadBalancerInstance( Optional.of(DomainName.of("lb-" + spec.application().toShortString() + "-" + spec.cluster().value())), Optional.empty(), + Optional.empty(), Optional.of(new DnsZone("zone-id-1")), Collections.singleton(4443), ImmutableSet.of("10.2.3.0/24", "10.4.5.0/24"), 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 index 15120a66d8a..37e94ea88de 100644 --- 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 @@ -42,6 +42,7 @@ public class SharedLoadBalancerService implements LoadBalancerService { return new LoadBalancerInstance(Optional.of(DomainName.of(vipHostname)), Optional.empty(), Optional.empty(), + Optional.empty(), Set.of(4443), Set.of(), spec.reals(), diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/LoadBalancerSerializer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/LoadBalancerSerializer.java index 6bac1dab3dd..f9a79402d63 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/LoadBalancerSerializer.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/LoadBalancerSerializer.java @@ -43,6 +43,7 @@ public class LoadBalancerSerializer { private static final String idField = "id"; private static final String hostnameField = "hostname"; private static final String lbIpAddressField = "ipAddress"; + private static final String lbPrivateServiceIpAddressField = "psipAddress"; private static final String stateField = "state"; private static final String changedAtField = "changedAt"; private static final String dnsZoneField = "dnsZone"; @@ -67,6 +68,7 @@ public class LoadBalancerSerializer { root.setString(idField, loadBalancer.id().serializedForm()); loadBalancer.instance().flatMap(LoadBalancerInstance::hostname).ifPresent(hostname -> root.setString(hostnameField, hostname.value())); loadBalancer.instance().flatMap(LoadBalancerInstance::ipAddress).ifPresent(ip -> root.setString(lbIpAddressField, ip)); + loadBalancer.instance().flatMap(LoadBalancerInstance::privateServiceIpAddress).ifPresent(ip -> root.setString(lbPrivateServiceIpAddressField, ip)); root.setString(stateField, asString(loadBalancer.state())); root.setLong(changedAtField, loadBalancer.changedAt().toEpochMilli()); loadBalancer.instance().flatMap(LoadBalancerInstance::dnsZone).ifPresent(dnsZone -> root.setString(dnsZoneField, dnsZone.id())); @@ -117,12 +119,13 @@ public class LoadBalancerSerializer { Optional<DomainName> hostname = optionalString(object.field(hostnameField), Function.identity()).filter(s -> !s.isEmpty()).map(DomainName::of); Optional<String> ipAddress = optionalString(object.field(lbIpAddressField), Function.identity()).filter(s -> !s.isEmpty()); + Optional<String> privateServiceIpAddress = optionalString(object.field(lbPrivateServiceIpAddressField), Function.identity()).filter(s -> !s.isEmpty()); Optional<DnsZone> dnsZone = optionalString(object.field(dnsZoneField), DnsZone::new); ZoneEndpoint settings = zoneEndpoint(object.field(settingsField)); Optional<PrivateServiceId> serviceId = optionalString(object.field(serviceIdField), PrivateServiceId::of); CloudAccount cloudAccount = optionalString(object.field(cloudAccountField), CloudAccount::from).orElse(CloudAccount.empty); Optional<LoadBalancerInstance> instance = hostname.isEmpty() && ipAddress.isEmpty() ? Optional.empty() : - Optional.of(new LoadBalancerInstance(hostname, ipAddress, dnsZone, ports, networks, reals, settings, serviceId, cloudAccount)); + Optional.of(new LoadBalancerInstance(hostname, ipAddress, privateServiceIpAddress, dnsZone, ports, networks, reals, settings, serviceId, cloudAccount)); return new LoadBalancer(LoadBalancerId.fromSerializedForm(object.field(idField).asString()), instance, diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisioner.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisioner.java index 4cdcda9fd6a..c0a036b3080 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisioner.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisioner.java @@ -280,13 +280,6 @@ public class LoadBalancerProvisioner { return Optional.empty(); } - /** Returns the nodes allocated to the given load balanced cluster */ - private NodeList nodesOf(ClusterSpec.Id loadBalancedCluster, ApplicationId application) { - NodeList nodes = nodeRepository.nodes().list(Node.State.reserved, Node.State.active) - .owner(application); - return loadBalancedClustersOf(nodes).getOrDefault(loadBalancedCluster, NodeList.of()); - } - /** Returns the load balanced clusters of given application and their nodes */ private Map<ClusterSpec.Id, NodeList> loadBalancedClustersOf(NodeList nodes) { if (nodes.stream().anyMatch(node -> node.type() == NodeType.config)) { diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/LoadBalancerSerializerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/LoadBalancerSerializerTest.java index 16e82e116e1..2111dea262d 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/LoadBalancerSerializerTest.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/LoadBalancerSerializerTest.java @@ -20,6 +20,7 @@ import org.junit.Test; import java.time.Instant; import java.util.List; import java.util.Optional; +import java.util.Set; import static java.time.temporal.ChronoUnit.MILLIS; import static org.junit.Assert.assertEquals; @@ -35,37 +36,69 @@ public class LoadBalancerSerializerTest { @Test public void test_serialization() { var now = Instant.now(); - var loadBalancer = new LoadBalancer(loadBalancerId, - Optional.of(new LoadBalancerInstance( - Optional.of(DomainName.of("lb-host")), - Optional.empty(), - Optional.of(new DnsZone("zone-id-1")), - ImmutableSet.of(4080, 4443), - ImmutableSet.of("10.2.3.4/24"), - ImmutableSet.of(new Real(DomainName.of("real-1"), - "127.0.0.1", - 4080), - new Real(DomainName.of("real-2"), - "127.0.0.2", - 4080)), - new ZoneEndpoint(false, true, List.of(new AllowedUrn(AccessType.awsPrivateLink, "123"))), - Optional.of(PrivateServiceId.of("foo")), - CloudAccount.from("012345678912"))), - LoadBalancer.State.active, - now); + { + var loadBalancer = new LoadBalancer(loadBalancerId, + Optional.of(new LoadBalancerInstance( + Optional.of(DomainName.of("lb-host")), + Optional.empty(), + Optional.empty(), + Optional.of(new DnsZone("zone-id-1")), + Set.of(4080, 4443), + Set.of("10.2.3.4/24"), + Set.of(new Real(DomainName.of("real-1"), + "127.0.0.1", + 4080), + new Real(DomainName.of("real-2"), + "127.0.0.2", + 4080)), + new ZoneEndpoint(false, true, List.of(new AllowedUrn(AccessType.awsPrivateLink, "123"))), + Optional.of(PrivateServiceId.of("foo")), + CloudAccount.from("012345678912"))), + LoadBalancer.State.active, + now); - var serialized = LoadBalancerSerializer.fromJson(LoadBalancerSerializer.toJson(loadBalancer)); - assertEquals(loadBalancer.id(), serialized.id()); - assertEquals(loadBalancer.instance().get().hostname(), serialized.instance().get().hostname()); - assertEquals(loadBalancer.instance().get().dnsZone(), serialized.instance().get().dnsZone()); - assertEquals(loadBalancer.instance().get().ports(), serialized.instance().get().ports()); - assertEquals(loadBalancer.instance().get().networks(), serialized.instance().get().networks()); - assertEquals(loadBalancer.state(), serialized.state()); - assertEquals(loadBalancer.changedAt().truncatedTo(MILLIS), serialized.changedAt()); - assertEquals(loadBalancer.instance().get().reals(), serialized.instance().get().reals()); - assertEquals(loadBalancer.instance().get().settings(), serialized.instance().get().settings()); - assertEquals(loadBalancer.instance().get().serviceId(), serialized.instance().get().serviceId()); - assertEquals(loadBalancer.instance().get().cloudAccount(), serialized.instance().get().cloudAccount()); + var serialized = LoadBalancerSerializer.fromJson(LoadBalancerSerializer.toJson(loadBalancer)); + assertEquals(loadBalancer.id(), serialized.id()); + assertEquals(loadBalancer.instance().get().hostname(), serialized.instance().get().hostname()); + assertEquals(loadBalancer.instance().get().dnsZone(), serialized.instance().get().dnsZone()); + assertEquals(loadBalancer.instance().get().ports(), serialized.instance().get().ports()); + assertEquals(loadBalancer.instance().get().networks(), serialized.instance().get().networks()); + assertEquals(loadBalancer.state(), serialized.state()); + assertEquals(loadBalancer.changedAt().truncatedTo(MILLIS), serialized.changedAt()); + assertEquals(loadBalancer.instance().get().reals(), serialized.instance().get().reals()); + assertEquals(loadBalancer.instance().get().settings(), serialized.instance().get().settings()); + assertEquals(loadBalancer.instance().get().serviceId(), serialized.instance().get().serviceId()); + assertEquals(loadBalancer.instance().get().cloudAccount(), serialized.instance().get().cloudAccount()); + } + { + var loadBalancer = new LoadBalancer(loadBalancerId, + Optional.of(new LoadBalancerInstance( + Optional.empty(), + Optional.of("1.2.3.4"), + Optional.of("4.3.2.1"), + Optional.of(new DnsZone("zone-id-1")), + Set.of(4443), + Set.of("10.2.3.4/24", "12.3.2.1/30"), + Set.of(), + new ZoneEndpoint(true, false, List.of()), + Optional.empty(), + CloudAccount.from("012345678912"))), + LoadBalancer.State.active, + now); + + var serialized = LoadBalancerSerializer.fromJson(LoadBalancerSerializer.toJson(loadBalancer)); + assertEquals(loadBalancer.id(), serialized.id()); + assertEquals(loadBalancer.instance().get().hostname(), serialized.instance().get().hostname()); + assertEquals(loadBalancer.instance().get().dnsZone(), serialized.instance().get().dnsZone()); + assertEquals(loadBalancer.instance().get().ports(), serialized.instance().get().ports()); + assertEquals(loadBalancer.instance().get().networks(), serialized.instance().get().networks()); + assertEquals(loadBalancer.state(), serialized.state()); + assertEquals(loadBalancer.changedAt().truncatedTo(MILLIS), serialized.changedAt()); + assertEquals(loadBalancer.instance().get().reals(), serialized.instance().get().reals()); + assertEquals(loadBalancer.instance().get().settings(), serialized.instance().get().settings()); + assertEquals(loadBalancer.instance().get().serviceId(), serialized.instance().get().serviceId()); + assertEquals(loadBalancer.instance().get().cloudAccount(), serialized.instance().get().cloudAccount()); + } } @Test |