diff options
author | Valerij Fredriksen <valerijf@yahooinc.com> | 2022-10-05 13:00:28 +0200 |
---|---|---|
committer | Valerij Fredriksen <valerijf@yahooinc.com> | 2022-10-06 12:53:01 +0200 |
commit | 522f279ee81dd86f29fe5db56d600ebba1d3dcfc (patch) | |
tree | 9a1520e313055bc4fb146c32d26589e0c8e5b2a7 /node-repository | |
parent | bbb47ccadb603a84b3a9d4e695aa098ea46a25ad (diff) |
Allow LoadBalancerInstance to specify either IP address or domain name
Diffstat (limited to 'node-repository')
7 files changed, 47 insertions, 17 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 edffa817f64..bdd39061823 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 @@ -17,28 +17,39 @@ import java.util.Set; */ public class LoadBalancerInstance { - private final DomainName hostname; + private final Optional<DomainName> hostname; + private final Optional<String> ipAddress; private final Optional<DnsZone> dnsZone; private final Set<Integer> ports; private final Set<String> networks; private final Set<Real> reals; private final Optional<CloudAccount> cloudAccount; - public LoadBalancerInstance(DomainName hostname, Optional<DnsZone> dnsZone, Set<Integer> ports, Set<String> networks, - Set<Real> reals, Optional<CloudAccount> cloudAccount) { + public LoadBalancerInstance(Optional<DomainName> hostname, Optional<String> ipAddress, Optional<DnsZone> dnsZone, Set<Integer> ports, + Set<String> networks, Set<Real> reals, Optional<CloudAccount> cloudAccount) { this.hostname = Objects.requireNonNull(hostname, "hostname must be non-null"); + this.ipAddress = Objects.requireNonNull(ipAddress, "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")); this.reals = ImmutableSortedSet.copyOf(Objects.requireNonNull(reals, "targets must be non-null")); this.cloudAccount = Objects.requireNonNull(cloudAccount, "cloudAccount must be non-null"); + + if (hostname.isEmpty() == ipAddress.isEmpty()) + throw new IllegalArgumentException("Exactly 1 of hostname=%s and ipAddress=%s must be set".formatted( + hostname.map(DomainName::value).orElse("<empty>"), ipAddress.orElse("<empty>"))); } /** Fully-qualified domain name of this load balancer. This hostname can be used for query and feed */ - public DomainName hostname() { + public Optional<DomainName> hostname() { return hostname; } + /** IP address this load balancer */ + public Optional<String> ipAddress() { + return ipAddress; + } + /** ID of the DNS zone associated with this */ public Optional<DnsZone> dnsZone() { return dnsZone; @@ -66,7 +77,7 @@ public class LoadBalancerInstance { /** Returns a copy of this with reals set to given reals */ public LoadBalancerInstance withReals(Set<Real> reals) { - return new LoadBalancerInstance(hostname, dnsZone, ports, networks, reals, cloudAccount); + return new LoadBalancerInstance(hostname, ipAddress, dnsZone, ports, networks, reals, cloudAccount); } private static Set<Integer> requirePorts(Set<Integer> ports) { 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 df92a6ee44d..ac5330dce12 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,7 +55,8 @@ public class LoadBalancerServiceMock implements LoadBalancerService { throw new IllegalArgumentException("Refusing to remove all reals from load balancer " + id); } var instance = new LoadBalancerInstance( - DomainName.of("lb-" + spec.application().toShortString() + "-" + spec.cluster().value()), + Optional.of(DomainName.of("lb-" + spec.application().toShortString() + "-" + spec.cluster().value())), + 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 3d0cd3ef1e1..c126b3969fa 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 @@ -28,7 +28,8 @@ public class SharedLoadBalancerService implements LoadBalancerService { @Override public LoadBalancerInstance create(LoadBalancerSpec spec, boolean force) { - return new LoadBalancerInstance(DomainName.of(vipHostname), + return new LoadBalancerInstance(Optional.of(DomainName.of(vipHostname)), + Optional.empty(), Optional.empty(), Set.of(4443), Set.of(), 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 83180b2b136..d1e58b0e965 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 @@ -38,6 +38,7 @@ public class LoadBalancerSerializer { private static final String idField = "id"; private static final String hostnameField = "hostname"; + private static final String lbIpAddressField = "ipAdress"; private static final String stateField = "state"; private static final String changedAtField = "changedAt"; private static final String dnsZoneField = "dnsZone"; @@ -53,7 +54,8 @@ public class LoadBalancerSerializer { Cursor root = slime.setObject(); root.setString(idField, loadBalancer.id().serializedForm()); - loadBalancer.instance().ifPresent(instance -> root.setString(hostnameField, instance.hostname().value())); + loadBalancer.instance().flatMap(LoadBalancerInstance::hostname).ifPresent(hostname -> root.setString(hostnameField, hostname.value())); + loadBalancer.instance().flatMap(LoadBalancerInstance::ipAddress).ifPresent(ip -> root.setString(lbIpAddressField, 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())); @@ -94,10 +96,11 @@ public class LoadBalancerSerializer { object.field(networksField).traverse((ArrayTraverser) (i, network) -> networks.add(network.asString())); 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<DnsZone> dnsZone = optionalString(object.field(dnsZoneField), DnsZone::new); Optional<CloudAccount> cloudAccount = optionalString(object.field(cloudAccountField), CloudAccount::new); - Optional<LoadBalancerInstance> instance = hostname.map(h -> new LoadBalancerInstance(h, dnsZone, ports, - networks, reals, cloudAccount)); + Optional<LoadBalancerInstance> instance = hostname.isEmpty() && ipAddress.isEmpty() ? Optional.empty() : + Optional.of(new LoadBalancerInstance(hostname, ipAddress, dnsZone, ports, networks, reals, cloudAccount)); return new LoadBalancer(LoadBalancerId.fromSerializedForm(object.field(idField).asString()), instance, diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/LoadBalancersResponse.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/LoadBalancersResponse.java index 7686a9a4885..13489db9f62 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/LoadBalancersResponse.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/LoadBalancersResponse.java @@ -56,7 +56,8 @@ public class LoadBalancersResponse extends SlimeJsonResponse { lbObject.setString("tenant", lb.id().application().tenant().value()); lbObject.setString("instance", lb.id().application().instance().value()); lbObject.setString("cluster", lb.id().cluster().value()); - lb.instance().ifPresent(instance -> lbObject.setString("hostname", instance.hostname().value())); + lb.instance().flatMap(LoadBalancerInstance::hostname).ifPresent(hostname -> lbObject.setString("hostname", hostname.value())); + lb.instance().flatMap(LoadBalancerInstance::ipAddress).ifPresent(ipAddress -> lbObject.setString("ipAddress", ipAddress)); lb.instance().flatMap(LoadBalancerInstance::dnsZone).ifPresent(dnsZone -> lbObject.setString("dnsZone", dnsZone.id())); Cursor networkArray = lbObject.setArray("networks"); 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 index 825e46865fe..1b5fceecbf9 100644 --- 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 @@ -28,7 +28,7 @@ public class SharedLoadBalancerServiceTest { public void test_create_lb() { var lb = loadBalancerService.create(new LoadBalancerSpec(applicationId, clusterId, reals, Optional.empty()), false); - assertEquals(HostName.of("vip.example.com"), lb.hostname()); + assertEquals(Optional.of(HostName.of("vip.example.com")), lb.hostname()); assertEquals(Optional.empty(), lb.dnsZone()); assertEquals(Set.of(), lb.networks()); assertEquals(Set.of(4443), lb.ports()); 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 ce8fc2e9d03..5bb9b71a223 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 @@ -24,15 +24,16 @@ import static org.junit.Assert.assertEquals; */ public class LoadBalancerSerializerTest { + private static final LoadBalancerId loadBalancerId = new LoadBalancerId( + ApplicationId.from("tenant1", "application1", "default"), ClusterSpec.Id.from("qrs"));; + @Test public void test_serialization() { var now = Instant.now(); - var loadBalancer = new LoadBalancer(new LoadBalancerId(ApplicationId.from("tenant1", - "application1", - "default"), - ClusterSpec.Id.from("qrs")), + var loadBalancer = new LoadBalancer(loadBalancerId, Optional.of(new LoadBalancerInstance( - DomainName.of("lb-host"), + 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"), @@ -58,4 +59,16 @@ public class LoadBalancerSerializerTest { assertEquals(loadBalancer.instance().get().cloudAccount(), serialized.instance().get().cloudAccount()); } + @Test + public void no_instance_serialization() { + var now = Instant.now(); + var loadBalancer = new LoadBalancer(loadBalancerId, Optional.empty(), LoadBalancer.State.reserved, now); + + var serialized = LoadBalancerSerializer.fromJson(LoadBalancerSerializer.toJson(loadBalancer)); + assertEquals(loadBalancer.id(), serialized.id()); + assertEquals(loadBalancer.instance(), serialized.instance()); + assertEquals(loadBalancer.state(), serialized.state()); + assertEquals(loadBalancer.changedAt().truncatedTo(MILLIS), serialized.changedAt()); + } + } |