summaryrefslogtreecommitdiffstats
path: root/node-repository
diff options
context:
space:
mode:
authorMartin Polden <mpolden@mpolden.no>2021-06-24 08:56:21 +0200
committerMartin Polden <mpolden@mpolden.no>2021-06-24 08:57:12 +0200
commit684731b4223a6a414f079a5724014695dccfc73f (patch)
tree51b0579cc322c570c4a63d211e20d7772467b099 /node-repository
parent87f276475ffeb2635af6b0a237964c0ca896ee3b (diff)
Add feature flag for deferring host encryption
Diffstat (limited to 'node-repository')
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/HostEncrypter.java26
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/HostEncrypterTest.java20
2 files changed, 43 insertions, 3 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/HostEncrypter.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/HostEncrypter.java
index 6d88e43630a..c93f226603c 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/HostEncrypter.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/HostEncrypter.java
@@ -2,8 +2,11 @@
package com.yahoo.vespa.hosted.provision.maintenance;
import com.yahoo.component.Version;
+import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.NodeType;
import com.yahoo.jdisc.Metric;
+import com.yahoo.vespa.flags.BooleanFlag;
+import com.yahoo.vespa.flags.FetchVector;
import com.yahoo.vespa.flags.Flags;
import com.yahoo.vespa.flags.IntFlag;
import com.yahoo.vespa.hosted.provision.Node;
@@ -20,6 +23,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;
+import java.util.stream.Collectors;
/**
* This maintainer triggers encryption of hosts that have unencrypted disk.
@@ -36,10 +40,12 @@ public class HostEncrypter extends NodeRepositoryMaintainer {
private static final Logger LOG = Logger.getLogger(HostEncrypter.class.getName());
private final IntFlag maxEncryptingHosts;
+ private final BooleanFlag deferHostEncryption;
public HostEncrypter(NodeRepository nodeRepository, Duration interval, Metric metric) {
super(nodeRepository, interval, metric);
this.maxEncryptingHosts = Flags.MAX_ENCRYPTING_HOSTS.bindTo(nodeRepository.flagSource());
+ this.deferHostEncryption = Flags.DEFER_HOST_ENCRYPTION.bindTo(nodeRepository.flagSource());
}
@Override
@@ -48,8 +54,6 @@ public class HostEncrypter extends NodeRepositoryMaintainer {
NodeList allNodes = nodeRepository().nodes().list();
for (var nodeType : NodeType.values()) {
if (!nodeType.isHost()) continue;
- // TODO: Require a minimum number of proxies in Orchestrator. For now skip proxy hosts.
- if (nodeType == NodeType.proxyhost) continue;
if (upgradingVespa(allNodes, nodeType)) continue;
unencryptedHosts(allNodes, nodeType).forEach(host -> encrypt(host, now));
}
@@ -81,9 +85,11 @@ public class HostEncrypter extends NodeRepositoryMaintainer {
NodeList candidates = hostsOfTargetType.state(Node.State.active)
.not().encrypted()
.not().encrypting()
+ .not().matching(host -> deferEncryptionOf(host, allNodes))
// Require an OS version supporting encryption
.matching(node -> node.status().osVersion().current()
- .orElse(Version.emptyVersion).getMajor() >= 8);
+ .orElse(Version.emptyVersion)
+ .getMajor() >= 8);
for (Node host : candidates) {
if (hostsToEncrypt.size() == hostLimit) break;
@@ -106,6 +112,20 @@ public class HostEncrypter extends NodeRepositoryMaintainer {
return Math.max(0, limit - hosts.encrypting().size());
}
+ private boolean deferEncryptionOf(Node host, NodeList allNodes) {
+ // TODO: Require a minimum number of proxies in Orchestrator. For now skip proxy hosts.
+ if (host.type() == NodeType.proxyhost) return true;
+
+ Set<ApplicationId> applicationsOnHost = allNodes.childrenOf(host).stream()
+ .filter(node -> node.allocation().isPresent())
+ .map(node -> node.allocation().get().owner())
+ .collect(Collectors.toSet());
+ return applicationsOnHost.stream()
+ .anyMatch(application -> deferHostEncryption.with(FetchVector.Dimension.APPLICATION_ID,
+ application.serializedForm())
+ .value());
+ }
+
private void encrypt(Node host, Instant now) {
LOG.info("Retiring and encrypting " + host);
nodeRepository().nodes().encrypt(host.hostname(), Agent.HostEncrypter, now);
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/HostEncrypterTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/HostEncrypterTest.java
index 5cae181f87d..f55452acba8 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/HostEncrypterTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/HostEncrypterTest.java
@@ -47,6 +47,26 @@ public class HostEncrypterTest {
}
@Test
+ public void deferred_hosts_are_not_encrypted() {
+ int hostCount = 2;
+ int proxyHostCount = 1;
+ ApplicationId tenantApp = ApplicationId.from("t1", "a1", "i1");
+ provisionHosts(hostCount);
+ deployApplication(tenantApp);
+
+ ApplicationId proxyHostApp = ApplicationId.from("t2", "a2", "i2");
+ List<Node> proxyHosts = tester.makeReadyNodes(proxyHostCount, "default", NodeType.proxyhost, 10);
+ tester.patchNodes(proxyHosts, (host) -> host.with(host.status().withOsVersion(host.status().osVersion().withCurrent(Optional.of(Version.fromString("8.0"))))));
+ tester.prepareAndActivateInfraApplication(proxyHostApp, NodeType.proxyhost);
+
+ tester.flagSource()
+ .withIntFlag(Flags.MAX_ENCRYPTING_HOSTS.id(), hostCount + proxyHostCount)
+ .withBooleanFlag(Flags.DEFER_HOST_ENCRYPTION.id(), true);
+ encrypter.maintain();
+ assertEquals("No hosts are encrypted", 0, tester.nodeRepository().nodes().list().encrypting().size());
+ }
+
+ @Test
public void encrypt_hosts() {
tester.flagSource().withIntFlag(Flags.MAX_ENCRYPTING_HOSTS.id(), 3);
Supplier<NodeList> hosts = () -> tester.nodeRepository().nodes().list().nodeType(NodeType.host);