aboutsummaryrefslogtreecommitdiffstats
path: root/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisioner.java
diff options
context:
space:
mode:
Diffstat (limited to 'node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisioner.java')
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisioner.java36
1 files changed, 23 insertions, 13 deletions
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 a62edec52e4..b2fc3127670 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
@@ -48,6 +48,8 @@ import java.util.stream.Collectors;
// 1) (new) -> reserved -> active
// 2) active | reserved -> inactive
// 3) inactive -> active | (removed)
+// 4) active | reserved | inactive -> removable
+// 5) removable -> (removed)
public class LoadBalancerProvisioner {
private static final Logger log = Logger.getLogger(LoadBalancerProvisioner.class.getName());
@@ -161,7 +163,7 @@ public class LoadBalancerProvisioner {
return db.readLoadBalancerIds().stream()
.filter(id -> id.application().tenant().equals(tenant) &&
id.application().application().equals(application))
- .collect(Collectors.toUnmodifiableList());
+ .toList();
}
/** Require that load balancer IDs do not clash. This prevents name clashing when compacting endpoint DNS names */
@@ -190,9 +192,14 @@ public class LoadBalancerProvisioner {
newLoadBalancer = loadBalancer.get().with(instance);
fromState = newLoadBalancer.state();
}
- // Always store load balancer so that LoadBalancerExpirer can expire partially provisioned load balancers
+ if (!inAccount(cloudAccount, newLoadBalancer)) {
+ // We have a load balancer, but in the wrong account. Load balancer must be removed before we can
+ // provision a new one in the wanted account
+ newLoadBalancer = newLoadBalancer.with(LoadBalancer.State.removable, now);
+ }
+ // Always store the load balancer. LoadBalancerExpirer will remove unwanted ones
db.writeLoadBalancer(newLoadBalancer, fromState);
- requireInstance(id, instance);
+ requireInstance(id, instance, cloudAccount);
}
private void activate(ApplicationTransaction transaction, ClusterSpec.Id cluster, NodeList nodes) {
@@ -206,7 +213,7 @@ public class LoadBalancerProvisioner {
LoadBalancer.State state = instance.isPresent() ? LoadBalancer.State.active : loadBalancer.get().state();
LoadBalancer newLoadBalancer = loadBalancer.get().with(instance).with(state, now);
db.writeLoadBalancers(List.of(newLoadBalancer), loadBalancer.get().state(), transaction.nested());
- requireInstance(id, instance);
+ requireInstance(id, instance, loadBalancer.get().instance().get().cloudAccount());
}
/** Provision or reconfigure a load balancer instance, if necessary */
@@ -276,6 +283,11 @@ public class LoadBalancerProvisioner {
return ids;
}
+ /** Returns whether load balancer is provisioned in given account */
+ private static boolean inAccount(Optional<CloudAccount> cloudAccount, LoadBalancer loadBalancer) {
+ return loadBalancer.instance().isEmpty() || loadBalancer.instance().get().cloudAccount().equals(cloudAccount);
+ }
+
/** Returns whether load balancer has given reals */
private static boolean hasReals(Optional<LoadBalancer> loadBalancer, Set<Real> reals) {
if (loadBalancer.isEmpty()) return false;
@@ -293,21 +305,19 @@ public class LoadBalancerProvisioner {
Set<String> reachable = new LinkedHashSet<>(node.ipConfig().primary());
// Remove addresses unreachable by the load balancer service
switch (service.protocol()) {
- case ipv4:
- reachable.removeIf(IP::isV6);
- break;
- case ipv6:
- reachable.removeIf(IP::isV4);
- break;
+ case ipv4 -> reachable.removeIf(IP::isV6);
+ case ipv6 -> reachable.removeIf(IP::isV4);
}
return reachable;
}
- private static void requireInstance(LoadBalancerId id, Optional<LoadBalancerInstance> instance) {
+ private static void requireInstance(LoadBalancerId id, Optional<LoadBalancerInstance> instance, Optional<CloudAccount> cloudAccount) {
if (instance.isEmpty()) {
// Signal that load balancer is not ready yet
- throw new LoadBalancerServiceException("Could not (re)configure " + id + ". The operation will be retried on next deployment",
- null);
+ throw new LoadBalancerServiceException("Could not (re)configure " + id + ". The operation will be retried on next deployment");
+ }
+ if (!instance.get().cloudAccount().equals(cloudAccount)) {
+ throw new LoadBalancerServiceException("Could not (re)configure " + id + " due to change in cloud account. The operation will be retried on next deployment");
}
}