aboutsummaryrefslogtreecommitdiffstats
path: root/node-repository/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'node-repository/src/main')
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/Node.java106
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocatableResources.java2
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/LoadBalancerInstance.java29
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/LoadBalancerServiceMock.java1
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/SharedLoadBalancerService.java1
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDb.java10
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/LoadBalancerSerializer.java11
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/NodeSerializer.java17
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/LoadBalancersResponse.java3
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodePatcher.java14
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesResponse.java15
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/WireguardResponse.java19
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockHostProvisioner.java6
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java9
14 files changed, 128 insertions, 115 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/Node.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/Node.java
index 24159b88a9b..d5e891a33c7 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/Node.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/Node.java
@@ -10,7 +10,7 @@ import com.yahoo.config.provision.Flavor;
import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.NodeType;
import com.yahoo.config.provision.TenantName;
-import com.yahoo.config.provision.WireguardKey;
+import com.yahoo.config.provision.WireguardKeyWithTimestamp;
import com.yahoo.config.provision.Zone;
import com.yahoo.vespa.hosted.provision.lb.LoadBalancers;
import com.yahoo.vespa.hosted.provision.node.Agent;
@@ -64,8 +64,7 @@ public final class Node implements Nodelike {
private final CloudAccount cloudAccount;
/** Only set for configservers and exclave nodes */
- private final Optional<WireguardKey> wireguardPubKey;
- private final Optional<Instant> wireguardKeyTimestamp;
+ private final Optional<WireguardKeyWithTimestamp> wireguardPubKey;
/** Record of the last event of each type happening to this node */
private final History history;
@@ -96,8 +95,8 @@ public final class Node implements Nodelike {
NodeType type, Reports reports, Optional<String> modelName, Optional<TenantName> reservedTo,
Optional<ApplicationId> exclusiveToApplicationId, Optional<Duration> hostTTL, Optional<Instant> hostEmptyAt,
Optional<ClusterSpec.Type> exclusiveToClusterType, Optional<String> switchHostname,
- List<TrustStoreItem> trustStoreItems, CloudAccount cloudAccount, Optional<WireguardKey> wireguardPubKey,
- Optional<Instant> wireguardKeyTimestamp) {
+ List<TrustStoreItem> trustStoreItems, CloudAccount cloudAccount,
+ Optional<WireguardKeyWithTimestamp> wireguardPubKey) {
this.id = Objects.requireNonNull(id, "A node must have an ID");
this.extraId = Objects.requireNonNull(extraId, "Extra ID cannot be null");
this.hostname = requireNonEmptyString(hostname, "A node must have a hostname");
@@ -120,7 +119,6 @@ public final class Node implements Nodelike {
this.trustStoreItems = Objects.requireNonNull(trustStoreItems).stream().distinct().toList();
this.cloudAccount = Objects.requireNonNull(cloudAccount);
this.wireguardPubKey = Objects.requireNonNull(wireguardPubKey);
- this.wireguardKeyTimestamp = Objects.requireNonNull(wireguardKeyTimestamp);
if (state == State.active)
requireNonEmpty(ipConfig.primary(), "Active node " + hostname + " must have at least one valid IP address");
@@ -264,15 +262,10 @@ public final class Node implements Nodelike {
}
/** Returns the wireguard public key of this node. Only relevant for enclave nodes. */
- public Optional<WireguardKey> wireguardPubKey() {
+ public Optional<WireguardKeyWithTimestamp> wireguardPubKey() {
return wireguardPubKey;
}
- /** Returns the timestamp of the wireguard key of this node. Only relevant for enclave nodes. */
- public Optional<Instant> wireguardKeyTimestamp() {
- return wireguardKeyTimestamp;
- }
-
/**
* Returns a copy of this where wantToFail is set to true and history is updated to reflect this.
*/
@@ -367,16 +360,14 @@ public final class Node implements Nodelike {
public Node with(Status status) {
return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, type,
reports, modelName, reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt,
- exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey,
- wireguardKeyTimestamp);
+ exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey);
}
/** Returns a node with the type assigned to the given value */
public Node with(NodeType type) {
return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history, type,
reports, modelName, reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt,
- exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey,
- wireguardKeyTimestamp);
+ exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey);
}
/** Returns a node with the flavor assigned to the given value */
@@ -385,40 +376,35 @@ public final class Node implements Nodelike {
History updateHistory = history.with(new History.Event(History.Event.Type.resized, agent, instant));
return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, updateHistory, type,
reports, modelName, reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt,
- exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey,
- wireguardKeyTimestamp);
+ exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey);
}
/** Returns a copy of this with the reboot generation set to generation */
public Node withReboot(Generation generation) {
return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status.withReboot(generation), state, allocation,
history, type, reports, modelName, reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt,
- exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey,
- wireguardKeyTimestamp);
+ exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey);
}
/** Returns a copy of this with given id set */
public Node withId(String id) {
return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation,
history, type, reports, modelName, reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt,
- exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey,
- wireguardKeyTimestamp);
+ exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey);
}
/** Returns a copy of this with model name set to given value */
public Node withModelName(String modelName) {
return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history,
type, reports, Optional.of(modelName), reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt,
- exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey,
- wireguardKeyTimestamp);
+ exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey);
}
/** Returns a copy of this with model name cleared */
public Node withoutModelName() {
return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history,
type, reports, Optional.empty(), reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt,
- exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey,
- wireguardKeyTimestamp);
+ exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey);
}
/** Returns a copy of this with a history record saying it was detected to be down at this instant */
@@ -460,24 +446,21 @@ public final class Node implements Nodelike {
public Node with(Allocation allocation) {
return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, Optional.of(allocation), history,
type, reports, modelName, reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt,
- exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey,
- wireguardKeyTimestamp);
+ exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey);
}
/** Returns a copy of this node with IP config set to the given value. */
public Node with(IP.Config ipConfig) {
return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history,
type, reports, modelName, reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt,
- exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey,
- wireguardKeyTimestamp);
+ exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey);
}
/** Returns a copy of this node with the parent hostname assigned to the given value. */
public Node withParentHostname(String parentHostname) {
return new Node(id, extraId, ipConfig, hostname, Optional.of(parentHostname), flavor, status, state, allocation,
history, type, reports, modelName, reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt,
- exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey,
- wireguardKeyTimestamp);
+ exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey);
}
public Node withReservedTo(TenantName tenant) {
@@ -485,73 +468,59 @@ public final class Node implements Nodelike {
throw new IllegalArgumentException("Only host nodes can be reserved, " + hostname + " has type " + type);
return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history,
type, reports, modelName, Optional.of(tenant), exclusiveToApplicationId, hostTTL, hostEmptyAt,
- exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey,
- wireguardKeyTimestamp);
+ exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey);
}
/** Returns a copy of this node which is not reserved to a tenant */
public Node withoutReservedTo() {
return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history,
type, reports, modelName, Optional.empty(), exclusiveToApplicationId, hostTTL, hostEmptyAt,
- exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey,
- wireguardKeyTimestamp);
+ exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey);
}
public Node withExclusiveToApplicationId(ApplicationId exclusiveTo) {
return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history,
type, reports, modelName, reservedTo, Optional.ofNullable(exclusiveTo), hostTTL, hostEmptyAt,
- exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey,
- wireguardKeyTimestamp);
+ exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey);
}
public Node withExtraId(Optional<String> extraId) {
return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history,
type, reports, modelName, reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt,
- exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey,
- wireguardKeyTimestamp);
+ exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey);
}
public Node withHostTTL(Duration hostTTL) {
return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history,
type, reports, modelName, reservedTo, exclusiveToApplicationId, Optional.ofNullable(hostTTL), hostEmptyAt,
- exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey,
- wireguardKeyTimestamp);
+ exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey);
}
public Node withHostEmptyAt(Instant hostEmptyAt) {
return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history,
type, reports, modelName, reservedTo, exclusiveToApplicationId, hostTTL, Optional.ofNullable(hostEmptyAt),
- exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey,
- wireguardKeyTimestamp);
+ exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey);
}
public Node withExclusiveToClusterType(ClusterSpec.Type exclusiveTo) {
return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history,
type, reports, modelName, reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt,
- Optional.ofNullable(exclusiveTo), switchHostname, trustStoreItems, cloudAccount, wireguardPubKey,
- wireguardKeyTimestamp);
+ Optional.ofNullable(exclusiveTo), switchHostname, trustStoreItems, cloudAccount, wireguardPubKey);
}
- public Node withWireguardPubkey(WireguardKey wireguardPubkey) {
+ public Node withWireguardPubkey(WireguardKeyWithTimestamp wireguardPubkey) {
return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history,
type, reports, modelName, reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt,
- exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, Optional.ofNullable(wireguardPubkey),
- wireguardKeyTimestamp);
- }
-
- public Node withWireguardKeyTimestamp(Instant wireguardKeyTimestamp) {
- return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history,
- type, reports, modelName, reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt,
- exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey,
- Optional.ofNullable(wireguardKeyTimestamp));
+ exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount,
+ Optional.ofNullable(wireguardPubkey));
}
/** Returns a copy of this node with switch hostname set to given value */
public Node withSwitchHostname(String switchHostname) {
return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history,
type, reports, modelName, reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt,
- exclusiveToClusterType, Optional.ofNullable(switchHostname), trustStoreItems, cloudAccount, wireguardPubKey,
- wireguardKeyTimestamp);
+ exclusiveToClusterType, Optional.ofNullable(switchHostname), trustStoreItems, cloudAccount,
+ wireguardPubKey);
}
/** Returns a copy of this node with switch hostname unset */
@@ -604,22 +573,19 @@ public final class Node implements Nodelike {
public Node with(History history) {
return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history,
type, reports, modelName, reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt,
- exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey,
- wireguardKeyTimestamp);
+ exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey);
}
public Node with(Reports reports) {
return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history,
type, reports, modelName, reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt,
- exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey,
- wireguardKeyTimestamp);
+ exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey);
}
public Node with(List<TrustStoreItem> trustStoreItems) {
return new Node(id, extraId, ipConfig, hostname, parentHostname, flavor, status, state, allocation, history,
type, reports, modelName, reservedTo, exclusiveToApplicationId, hostTTL, hostEmptyAt,
- exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey,
- wireguardKeyTimestamp);
+ exclusiveToClusterType, switchHostname, trustStoreItems, cloudAccount, wireguardPubKey);
}
private static Optional<String> requireNonEmptyString(Optional<String> value, String message) {
@@ -767,8 +733,7 @@ public final class Node implements Nodelike {
private History history;
private List<TrustStoreItem> trustStoreItems;
private CloudAccount cloudAccount = CloudAccount.empty;
- private WireguardKey wireguardPubKey;
- private Instant wireguardKeyTimestamp;
+ private WireguardKeyWithTimestamp wireguardPubKey;
private Builder(String id, String hostname, Flavor flavor, State state, NodeType type) {
this.id = id;
@@ -858,16 +823,11 @@ public final class Node implements Nodelike {
return this;
}
- public Builder wireguardPubKey(WireguardKey wireguardPubKey) {
+ public Builder wireguardKey(WireguardKeyWithTimestamp wireguardPubKey) {
this.wireguardPubKey = wireguardPubKey;
return this;
}
- public Builder wireguardKeyTimestamp(Instant wireguardKeyTimestamp) {
- this.wireguardKeyTimestamp = wireguardKeyTimestamp;
- return this;
- }
-
public Node build() {
return new Node(id, Optional.empty(), Optional.ofNullable(ipConfig).orElse(IP.Config.EMPTY), hostname, Optional.ofNullable(parentHostname),
flavor, Optional.ofNullable(status).orElseGet(Status::initial), state, Optional.ofNullable(allocation),
@@ -875,7 +835,7 @@ public final class Node implements Nodelike {
Optional.ofNullable(modelName), Optional.ofNullable(reservedTo), Optional.ofNullable(exclusiveToApplicationId),
Optional.ofNullable(hostTTL), Optional.ofNullable(hostEmptyAt), Optional.ofNullable(exclusiveToClusterType),
Optional.ofNullable(switchHostname), Optional.ofNullable(trustStoreItems).orElseGet(List::of), cloudAccount,
- Optional.ofNullable(wireguardPubKey), Optional.ofNullable(wireguardKeyTimestamp));
+ Optional.ofNullable(wireguardPubKey));
}
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocatableResources.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocatableResources.java
index 8069c9c089b..286ec2451f8 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocatableResources.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocatableResources.java
@@ -160,7 +160,7 @@ public class AllocatableResources {
for (Node node : nodes) {
sum = sum.add(nodeRepository.resourcesCalculator().realResourcesOf(node, nodeRepository).justNumbers());
}
- return nodes.get(0).allocation().get().requestedResources().justNonNumbers()
+ return nodes.get(0).allocation().get().requestedResources()
.withVcpu(sum.vcpu() / nodes.size())
.withMemoryGb(sum.memoryGb() / nodes.size())
.withDiskGb(sum.diskGb() / nodes.size())
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 e228d31384c..f42d1ce9bd3 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
@@ -21,7 +21,8 @@ import java.util.Set;
public class LoadBalancerInstance {
private final Optional<DomainName> hostname;
- private final Optional<String> ipAddress;
+ private final Optional<String> ip4Address;
+ private final Optional<String> ip6Address;
private final Optional<DnsZone> dnsZone;
private final Set<Integer> ports;
private final Set<String> networks;
@@ -30,11 +31,12 @@ public class LoadBalancerInstance {
private final List<PrivateServiceId> serviceIds;
private final CloudAccount cloudAccount;
- public LoadBalancerInstance(Optional<DomainName> hostname, Optional<String> ipAddress,
+ public LoadBalancerInstance(Optional<DomainName> hostname, Optional<String> ip4Address, Optional<String> ip6Address,
Optional<DnsZone> dnsZone, Set<Integer> ports, Set<String> networks, Set<Real> reals,
ZoneEndpoint settings, List<PrivateServiceId> serviceIds, CloudAccount cloudAccount) {
this.hostname = Objects.requireNonNull(hostname, "hostname must be non-null");
- this.ipAddress = Objects.requireNonNull(ipAddress, "ip must be non-null");
+ this.ip4Address = Objects.requireNonNull(ip4Address, "ip4Address must be non-null");
+ this.ip6Address = Objects.requireNonNull(ip6Address, "ip6Address 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"));
@@ -43,9 +45,9 @@ public class LoadBalancerInstance {
this.serviceIds = List.copyOf(Objects.requireNonNull(serviceIds, "private service id 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>")));
+ if (hostname.isEmpty() == ip4Address.isEmpty()) {
+ throw new IllegalArgumentException("Exactly 1 of hostname=%s and ip4Address=%s must be set".formatted(
+ hostname.map(DomainName::value).orElse("<empty>"), ip4Address.orElse("<empty>")));
}
}
@@ -54,9 +56,14 @@ public class LoadBalancerInstance {
return hostname;
}
- /** IP address of this (public) load balancer */
- public Optional<String> ipAddress() {
- return ipAddress;
+ /** IPv4 address of this (public) load balancer */
+ public Optional<String> ip4Address() {
+ return ip4Address;
+ }
+
+ /** IPv6 address of this (public) load balancer */
+ public Optional<String> ip6Address() {
+ return ip6Address;
}
/** ID of the DNS zone associated with this */
@@ -114,7 +121,7 @@ public class LoadBalancerInstance {
public LoadBalancerInstance with(Set<Real> reals, ZoneEndpoint settings, Optional<PrivateServiceId> serviceId) {
List<PrivateServiceId> ids = new ArrayList<>(serviceIds);
serviceId.filter(id -> ! ids.contains(id)).ifPresent(ids::add);
- return new LoadBalancerInstance(hostname, ipAddress, dnsZone, ports, networks,
+ return new LoadBalancerInstance(hostname, ip4Address, ip6Address, dnsZone, ports, networks,
reals, settings, ids,
cloudAccount);
}
@@ -123,7 +130,7 @@ public class LoadBalancerInstance {
public LoadBalancerInstance withServiceIds(List<PrivateServiceId> serviceIds) {
List<PrivateServiceId> ids = new ArrayList<>(serviceIds);
for (PrivateServiceId id : this.serviceIds) if ( ! ids.contains(id)) ids.add(id);
- return new LoadBalancerInstance(hostname, ipAddress, dnsZone, ports, networks, reals, settings, ids, cloudAccount);
+ return new LoadBalancerInstance(hostname, ip4Address, ip6Address, dnsZone, ports, networks, reals, settings, ids, cloudAccount);
}
}
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 a79766a577d..c79ccc2aece 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
@@ -57,6 +57,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 e49d1b302cf..073662b39fe 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
@@ -45,6 +45,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/CuratorDb.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDb.java
index 3c3868bfeb8..e4e08e5a15c 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDb.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDb.java
@@ -47,6 +47,7 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
+import java.util.stream.Stream;
import static com.yahoo.stream.CustomCollectors.toLinkedMap;
import static java.util.stream.Collectors.collectingAndThen;
@@ -222,7 +223,7 @@ public class CuratorDb {
node.type(), node.reports(), node.modelName(), node.reservedTo(),
node.exclusiveToApplicationId(), node.hostTTL(), node.hostEmptyAt(),
node.exclusiveToClusterType(), node.switchHostname(), node.trustedCertificates(),
- node.cloudAccount(), node.wireguardPubKey(), node.wireguardKeyTimestamp());
+ node.cloudAccount(), node.wireguardPubKey());
curatorTransaction.add(createOrSet(nodePath(newNode), nodeSerializer.toJson(newNode)));
writtenNodes.add(newNode);
}
@@ -456,7 +457,12 @@ public class CuratorDb {
transaction.onCommitted(() -> {
for (var lb : loadBalancers) {
if (lb.state() == fromState) continue;
- Optional<String> target = lb.instance().flatMap(instance -> instance.hostname().map(DomainName::value).or(instance::ipAddress));
+ Optional<String> target = lb.instance()
+ .flatMap(instance -> instance.hostname()
+ .map(DomainName::value)
+ .or(() -> Optional.of(Stream.concat(instance.ip4Address().stream(),
+ instance.ip6Address().stream())
+ .collect(Collectors.joining(",")))));
if (fromState == null) {
log.log(Level.INFO, () -> "Creating " + lb.id() + target.map(t -> " (" + t + ")").orElse("") +
" in " + lb.state());
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 b85d96c6b54..d329676f842 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
@@ -45,6 +45,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 lbIp6AddressField = "ip6Address";
private static final String stateField = "state";
private static final String changedAtField = "changedAt";
private static final String dnsZoneField = "dnsZone";
@@ -69,7 +70,8 @@ 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::ip4Address).ifPresent(ip -> root.setString(lbIpAddressField, ip));
+ loadBalancer.instance().flatMap(LoadBalancerInstance::ip6Address).ifPresent(ip -> root.setString(lbIp6AddressField, 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()));
@@ -123,7 +125,8 @@ 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<String> ip4Address = optionalString(object.field(lbIpAddressField), Function.identity()).filter(s -> !s.isEmpty());
+ Optional<String> ip6Address = optionalString(object.field(lbIp6AddressField), 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);
@@ -131,9 +134,9 @@ public class LoadBalancerSerializer {
object.field(serviceIdsField).traverse((ArrayTraverser) (__, serviceIdObject) -> serviceIds.add(PrivateServiceId.of(serviceIdObject.asString())));
if (serviceIds.isEmpty()) serviceId.ifPresent(serviceIds::add); // TODO: remove after winter vacation '23
CloudAccount cloudAccount = optionalString(object.field(cloudAccountField), CloudAccount::from).orElse(CloudAccount.empty);
- Optional<LoadBalancerInstance> instance = hostname.isEmpty() && ipAddress.isEmpty()
+ Optional<LoadBalancerInstance> instance = hostname.isEmpty() && ip4Address.isEmpty() && ip6Address.isEmpty()
? Optional.empty()
- : Optional.of(new LoadBalancerInstance(hostname, ipAddress, dnsZone, ports, networks, reals, settings, serviceIds, cloudAccount));
+ : Optional.of(new LoadBalancerInstance(hostname, ip4Address, ip6Address, dnsZone, ports, networks, reals, settings, serviceIds, cloudAccount));
return new LoadBalancer(LoadBalancerId.fromSerializedForm(object.field(idField).asString()),
instance,
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/NodeSerializer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/NodeSerializer.java
index 870e678a250..73531d650d5 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/NodeSerializer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/NodeSerializer.java
@@ -16,6 +16,7 @@ import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.NodeType;
import com.yahoo.config.provision.TenantName;
import com.yahoo.config.provision.WireguardKey;
+import com.yahoo.config.provision.WireguardKeyWithTimestamp;
import com.yahoo.config.provision.host.FlavorOverrides;
import com.yahoo.config.provision.serialization.NetworkPortsSerializer;
import com.yahoo.slime.ArrayTraverser;
@@ -188,8 +189,10 @@ public class NodeSerializer {
if (!node.cloudAccount().isUnspecified()) {
object.setString(cloudAccountKey, node.cloudAccount().value());
}
- node.wireguardPubKey().ifPresent(pubKey -> object.setString(wireguardPubKeyKey, pubKey.value()));
- node.wireguardKeyTimestamp().ifPresent(timestamp -> object.setLong(wireguardKeyTimestampKey, timestamp.toEpochMilli()));
+ node.wireguardPubKey().ifPresent(pubKey -> {
+ object.setString(wireguardPubKeyKey, pubKey.key().value());
+ object.setLong(wireguardKeyTimestampKey, pubKey.timestamp().toEpochMilli());
+ });
}
private void toSlime(Flavor flavor, Cursor object) {
@@ -284,8 +287,7 @@ public class NodeSerializer {
SlimeUtils.optionalString(object.field(switchHostnameKey)),
trustedCertificatesFromSlime(object),
SlimeUtils.optionalString(object.field(cloudAccountKey)).map(CloudAccount::from).orElse(CloudAccount.empty),
- SlimeUtils.optionalString(object.field(wireguardPubKeyKey)).map(WireguardKey::from),
- SlimeUtils.optionalInstant(object.field(wireguardKeyTimestampKey)));
+ wireguardKeyWithTimestampFromSlime(object.field(wireguardPubKeyKey), object.field(wireguardKeyTimestampKey)));
}
private Status statusFromSlime(Inspector object) {
@@ -397,6 +399,13 @@ public class NodeSerializer {
.toList();
}
+ private Optional<WireguardKeyWithTimestamp> wireguardKeyWithTimestampFromSlime(Inspector keyObject, Inspector timestampObject) {
+ if ( ! keyObject.valid()) return Optional.empty();
+ return SlimeUtils.optionalString(keyObject).map(
+ key -> new WireguardKeyWithTimestamp(WireguardKey.from(key),
+ SlimeUtils.optionalInstant(timestampObject).orElse(null)));
+ }
+
// ----------------- Enum <-> string mappings ----------------------------------------
/** Returns the event type, or null if this event type should be ignored */
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 09f947503f6..20aa7d8181e 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
@@ -57,7 +57,8 @@ public class LoadBalancersResponse extends SlimeJsonResponse {
lbObject.setString("instance", lb.id().application().instance().value());
lbObject.setString("cluster", lb.id().cluster().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::ip4Address).ifPresent(ip -> lbObject.setString("ipAddress", ip));
+ lb.instance().flatMap(LoadBalancerInstance::ip6Address).ifPresent(ip -> lbObject.setString("ip6Address", ip));
lb.instance().flatMap(LoadBalancerInstance::dnsZone).ifPresent(dnsZone -> lbObject.setString("dnsZone", dnsZone.id()));
Cursor networkArray = lbObject.setArray("networks");
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodePatcher.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodePatcher.java
index 9f1ab3dc3d5..cad034e01aa 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodePatcher.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodePatcher.java
@@ -11,6 +11,7 @@ import com.yahoo.config.provision.NodeFlavors;
import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.TenantName;
import com.yahoo.config.provision.WireguardKey;
+import com.yahoo.config.provision.WireguardKeyWithTimestamp;
import com.yahoo.slime.Cursor;
import com.yahoo.slime.Inspector;
import com.yahoo.slime.ObjectTraverser;
@@ -108,7 +109,8 @@ public class NodePatcher {
"reports",
"trustStore",
"vespaVersion",
- "wireguardPubkey"));
+ "wireguardPubkey", // TODO wg: remove when all nodes use new key+timestamp format
+ "wireguard"));
if (!disallowedFields.isEmpty()) {
throw new IllegalArgumentException("Patching fields not supported: " + disallowedFields);
}
@@ -271,9 +273,13 @@ public class NodePatcher {
return value.type() == Type.NIX ? node.withoutSwitchHostname() : node.withSwitchHostname(value.asString());
case "trustStore":
return nodeWithTrustStore(node, value);
- case "wireguardPubkey":
- return node.withWireguardPubkey(SlimeUtils.optionalString(value).map(WireguardKey::new).orElse(null))
- .withWireguardKeyTimestamp(clock.instant());
+ case "wireguard":
+ // This is where we set the key timestamp.
+ var key = SlimeUtils.optionalString(value.field("key")).map(WireguardKey::new).orElse(null);
+ return node.withWireguardPubkey(new WireguardKeyWithTimestamp(key, clock.instant()));
+ case "wireguardPubkey": // TODO wg: remove when all nodes use new key+timestamp format
+ var oldKey = SlimeUtils.optionalString(value).map(WireguardKey::new).orElse(null);
+ return node.withWireguardPubkey(new WireguardKeyWithTimestamp(oldKey, clock.instant()));
default:
throw new IllegalArgumentException("Could not apply field '" + name + "' on a node: No such modifiable field");
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesResponse.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesResponse.java
index a8f526544d7..05bb0a27d69 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesResponse.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesResponse.java
@@ -8,6 +8,7 @@ import com.yahoo.config.provision.ClusterMembership;
import com.yahoo.config.provision.DockerImage;
import com.yahoo.config.provision.HostName;
import com.yahoo.config.provision.NodeResources;
+import com.yahoo.config.provision.WireguardKeyWithTimestamp;
import com.yahoo.config.provision.serialization.NetworkPortsSerializer;
import com.yahoo.container.jdisc.HttpRequest;
import com.yahoo.restapi.SlimeJsonResponse;
@@ -192,8 +193,13 @@ class NodesResponse extends SlimeJsonResponse {
if (!node.cloudAccount().isUnspecified()) {
object.setString("cloudAccount", node.cloudAccount().value());
}
- node.wireguardPubKey().ifPresent(key -> object.setString("wireguardPubkey", key.value()));
- node.wireguardKeyTimestamp().ifPresent(timestamp -> object.setLong("wireguardKeyTimestamp", timestamp.toEpochMilli()));
+ node.wireguardPubKey().ifPresent(key -> toSlime(key, object.setObject("wireguard")));
+
+ // TODO wg: remove when all nodes have upgraded to new key+timestamp format
+ node.wireguardPubKey().ifPresent(key -> {
+ object.setString("wireguardPubkey", key.key().value());
+ object.setLong("wireguardKeyTimestamp", key.timestamp().toEpochMilli());
+ });
}
private Version resolveVersionFlag(StringFlag flag, Node node, Allocation allocation) {
@@ -237,6 +243,11 @@ class NodesResponse extends SlimeJsonResponse {
}
}
+ static void toSlime(WireguardKeyWithTimestamp keyWithTimestamp, Cursor object) {
+ object.setString("key", keyWithTimestamp.key().value());
+ object.setLong("timestamp", keyWithTimestamp.timestamp().toEpochMilli());
+ }
+
private Optional<DockerImage> currentContainerImage(Node node) {
if (node.status().containerImage().isPresent()) {
return node.status().containerImage();
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/WireguardResponse.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/WireguardResponse.java
index 16e85dfa48a..e29c4f1b87a 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/WireguardResponse.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/WireguardResponse.java
@@ -1,7 +1,7 @@
package com.yahoo.vespa.hosted.provision.restapi;
import com.yahoo.config.provision.NodeType;
-import com.yahoo.config.provision.WireguardKey;
+import com.yahoo.config.provision.WireguardKeyWithTimestamp;
import com.yahoo.restapi.SlimeJsonResponse;
import com.yahoo.slime.Cursor;
import com.yahoo.vespa.hosted.provision.Node;
@@ -10,9 +10,9 @@ import com.yahoo.vespa.hosted.provision.NodeRepository;
import com.yahoo.vespa.hosted.provision.node.IP;
import java.net.InetAddress;
-import java.time.Instant;
import java.util.List;
-import java.util.Optional;
+
+import static com.yahoo.vespa.hosted.provision.restapi.NodesResponse.toSlime;
/**
* A response containing the wireguard peer config for each configserver that has a public key.
@@ -36,17 +36,20 @@ public class WireguardResponse extends SlimeJsonResponse {
.toList();
if (ipAddresses.isEmpty()) continue;
- addConfigserver(cfgArray.addObject(), cfg.hostname(), cfg.wireguardPubKey().get(),
- cfg.wireguardKeyTimestamp(), ipAddresses);
+ addConfigserver(cfgArray.addObject(), cfg.hostname(), cfg.wireguardPubKey().get(), ipAddresses);
}
}
- private void addConfigserver(Cursor cfgEntry, String hostname, WireguardKey key, Optional<Instant> keyTimestamp,
+ private void addConfigserver(Cursor cfgEntry, String hostname, WireguardKeyWithTimestamp keyWithTimestamp,
List<String> ipAddresses) {
cfgEntry.setString("hostname", hostname);
- cfgEntry.setString("wireguardPubkey", key.value());
- cfgEntry.setLong("wireguardKeyTimestamp", keyTimestamp.orElse(Instant.EPOCH).toEpochMilli());
+
+ // TODO wg: remove when all nodes are using new key+timestamp format
+ cfgEntry.setString("wireguardPubkey", keyWithTimestamp.key().value());
+ cfgEntry.setLong("wireguardKeyTimestamp", keyWithTimestamp.timestamp().toEpochMilli());
+
NodesResponse.ipAddressesToSlime(ipAddresses, cfgEntry.setArray("ipAddresses"));
+ toSlime(keyWithTimestamp, cfgEntry.setObject("wireguard"));
}
private static boolean isPublicIp(String ipAddress) {
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockHostProvisioner.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockHostProvisioner.java
index 5cdb08d6fc6..a72c2fb0b9c 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockHostProvisioner.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockHostProvisioner.java
@@ -79,7 +79,7 @@ public class MockHostProvisioner implements HostProvisioner {
if (hostFlavor == null)
hostFlavor = flavors.stream()
.filter(f -> request.sharing() == HostSharing.exclusive ? compatible(f, request.resources())
- : f.resources().satisfies(request.resources()))
+ : satisfies(f, request.resources()))
.filter(f -> realHostResourcesWithinLimits.test(f.resources()))
.findFirst()
.orElseThrow(() -> new NodeAllocationException("No host flavor matches " + request.resources(), true));
@@ -223,6 +223,10 @@ public class MockHostProvisioner implements HostProvisioner {
return flavor.resources().compatibleWith(resourcesToVerify);
}
+ public boolean satisfies(Flavor flavor, NodeResources resources) {
+ return flavor.resources().satisfies(resources);
+ }
+
private List<HostName> createHostnames(NodeType hostType, Flavor flavor, int hostIndex) {
long numAddresses = Math.max(2, Math.round(flavor.resources().bandwidthGbps()));
return IntStream.range(1, (int) numAddresses)
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java
index 72225763381..2fb549acc11 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java
@@ -21,6 +21,7 @@ import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.NodeType;
import com.yahoo.config.provision.TenantName;
import com.yahoo.config.provision.WireguardKey;
+import com.yahoo.config.provision.WireguardKeyWithTimestamp;
import com.yahoo.config.provision.Zone;
import com.yahoo.config.provision.ZoneEndpoint;
import com.yahoo.config.provision.ZoneEndpoint.AccessType;
@@ -161,8 +162,8 @@ public class MockNodeRepository extends NodeRepository {
// Emulate host in tenant account
nodes.add(Node.create("dockerhost2", ipConfig(101, 1, 3), "dockerhost2.yahoo.com",
flavors.getFlavorOrThrow("large"), NodeType.host)
- .wireguardPubKey(WireguardKey.from("000011112222333344445555666677778888999900c="))
- .wireguardKeyTimestamp(Instant.ofEpochMilli(123L))
+ .wireguardKey(new WireguardKeyWithTimestamp(WireguardKey.from("000011112222333344445555666677778888999900c="),
+ Instant.ofEpochMilli(123L)))
.cloudAccount(tenantAccount).build());
nodes.add(Node.create("dockerhost3", ipConfig(102, 1, 3), "dockerhost3.yahoo.com",
flavors.getFlavorOrThrow("large"), NodeType.host).cloudAccount(defaultCloudAccount).build());
@@ -176,8 +177,8 @@ public class MockNodeRepository extends NodeRepository {
// Config servers
nodes.add(Node.create("cfg1", ipConfig(201), "cfg1.yahoo.com", flavors.getFlavorOrThrow("default"), NodeType.config)
.cloudAccount(defaultCloudAccount)
- .wireguardPubKey(WireguardKey.from("lololololololololololololololololololololoo="))
- .wireguardKeyTimestamp(Instant.ofEpochMilli(456L))
+ .wireguardKey(new WireguardKeyWithTimestamp(WireguardKey.from("lololololololololololololololololololololoo="),
+ Instant.ofEpochMilli(456L)))
.build());
nodes.add(Node.create("cfg2", ipConfig(202), "cfg2.yahoo.com", flavors.getFlavorOrThrow("default"), NodeType.config)
.cloudAccount(defaultCloudAccount)