From 92f0a107f640294518d9bbafce30658945d853ed Mon Sep 17 00:00:00 2001 From: Valerij Fredriksen Date: Tue, 26 Mar 2019 13:23:11 +0100 Subject: Use CredentialMaintainer interface --- .../identity/AthenzCredentialsMaintainer.java | 15 ++++++++------- .../maintenance/identity/CredentialsMaintainer.java | 21 +++++++++++++++++++++ .../hosted/node/admin/nodeagent/NodeAgentImpl.java | 12 ++++++------ .../node/admin/nodeagent/NodeAgentImplTest.java | 6 +++--- 4 files changed, 38 insertions(+), 16 deletions(-) create mode 100644 node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/CredentialsMaintainer.java (limited to 'node-admin') diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/AthenzCredentialsMaintainer.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/AthenzCredentialsMaintainer.java index abac16d242e..4fe0f420f05 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/AthenzCredentialsMaintainer.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/AthenzCredentialsMaintainer.java @@ -17,8 +17,8 @@ import com.yahoo.vespa.athenz.identity.ServiceIdentityProvider; import com.yahoo.vespa.athenz.identityprovider.api.EntityBindingsMapper; import com.yahoo.vespa.athenz.identityprovider.api.IdentityDocumentClient; import com.yahoo.vespa.athenz.identityprovider.api.SignedIdentityDocument; -import com.yahoo.vespa.athenz.identityprovider.client.DefaultIdentityDocumentClient; import com.yahoo.vespa.athenz.identityprovider.client.CsrGenerator; +import com.yahoo.vespa.athenz.identityprovider.client.DefaultIdentityDocumentClient; import com.yahoo.vespa.athenz.tls.AthenzIdentityVerifier; import com.yahoo.vespa.athenz.utils.SiaUtils; import com.yahoo.vespa.hosted.dockerapi.ContainerName; @@ -51,7 +51,7 @@ import static java.util.Collections.singleton; * * @author bjorncs */ -public class AthenzCredentialsMaintainer { +public class AthenzCredentialsMaintainer implements CredentialsMaintainer { private static final Logger logger = Logger.getLogger(AthenzCredentialsMaintainer.class.getName()); @@ -89,7 +89,7 @@ public class AthenzCredentialsMaintainer { this.clock = Clock.systemUTC(); } - public void converge(NodeAgentContext context) { + public boolean converge(NodeAgentContext context) { try { context.log(logger, LogLevel.DEBUG, "Checking certificate"); Path containerSiaDirectory = context.pathOnHostFromPathInNode(CONTAINER_SIA_DIRECTORY); @@ -102,7 +102,7 @@ public class AthenzCredentialsMaintainer { Files.createDirectories(certificateFile.getParent()); Files.createDirectories(identityDocumentFile.getParent()); registerIdentity(context, privateKeyFile, certificateFile, identityDocumentFile); - return; + return true; } X509Certificate certificate = readCertificateFromFile(certificateFile); @@ -111,7 +111,7 @@ public class AthenzCredentialsMaintainer { if (isCertificateExpired(expiry, now)) { context.log(logger, "Certificate has expired (expiry=%s)", expiry.toString()); registerIdentity(context, privateKeyFile, certificateFile, identityDocumentFile); - return; + return true; } Duration age = Duration.between(certificate.getNotBefore().toInstant(), now); @@ -121,14 +121,15 @@ public class AthenzCredentialsMaintainer { context.log(logger, LogLevel.WARNING, String.format( "Skipping refresh attempt as last refresh was on %s (less than %s ago)", lastRefreshAttempt.get(context.containerName()).toString(), REFRESH_BACKOFF.toString())); - return; + return false; } else { lastRefreshAttempt.put(context.containerName(), now); refreshIdentity(context, privateKeyFile, certificateFile, identityDocumentFile); - return; + return true; } } context.log(logger, LogLevel.DEBUG, "Certificate is still valid"); + return false; } catch (IOException e) { throw new UncheckedIOException(e); } diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/CredentialsMaintainer.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/CredentialsMaintainer.java new file mode 100644 index 00000000000..58c3585a48f --- /dev/null +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/CredentialsMaintainer.java @@ -0,0 +1,21 @@ +// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.node.admin.maintenance.identity; + +import com.yahoo.vespa.hosted.node.admin.nodeagent.NodeAgentContext; + +/** + * A maintainer that is responsible for providing and refreshing credentials for a container. + * + * @author freva + */ +public interface CredentialsMaintainer { + + /** + * Creates/refreshes credentials for the given NodeAgentContext. Called for every NodeAgent tick. + * @return false if already converged, i.e. was a no-op. + */ + boolean converge(NodeAgentContext context); + + /** Remove any existing credentials. This method is called just before container data is archived. */ + void clearCredentials(NodeAgentContext context); +} diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImpl.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImpl.java index fc4162a0f73..57e504a6ffd 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImpl.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImpl.java @@ -27,7 +27,7 @@ import com.yahoo.vespa.hosted.node.admin.configserver.orchestrator.OrchestratorE import com.yahoo.vespa.hosted.node.admin.docker.DockerOperations; import com.yahoo.vespa.hosted.node.admin.maintenance.StorageMaintainer; import com.yahoo.vespa.hosted.node.admin.maintenance.acl.AclMaintainer; -import com.yahoo.vespa.hosted.node.admin.maintenance.identity.AthenzCredentialsMaintainer; +import com.yahoo.vespa.hosted.node.admin.maintenance.identity.CredentialsMaintainer; import com.yahoo.vespa.hosted.node.admin.nodeadmin.ConvergenceException; import com.yahoo.vespa.hosted.node.admin.util.SecretAgentCheckConfig; @@ -63,7 +63,7 @@ public class NodeAgentImpl implements NodeAgent { private final Orchestrator orchestrator; private final DockerOperations dockerOperations; private final StorageMaintainer storageMaintainer; - private final Optional athenzCredentialsMaintainer; + private final Optional credentialsMaintainer; private final Optional aclMaintainer; private final Optional healthChecker; @@ -105,7 +105,7 @@ public class NodeAgentImpl implements NodeAgent { final DockerOperations dockerOperations, final StorageMaintainer storageMaintainer, final FlagSource flagSource, - final Optional athenzCredentialsMaintainer, + final Optional credentialsMaintainer, final Optional aclMaintainer, final Optional healthChecker) { this.contextSupplier = contextSupplier; @@ -113,7 +113,7 @@ public class NodeAgentImpl implements NodeAgent { this.orchestrator = orchestrator; this.dockerOperations = dockerOperations; this.storageMaintainer = storageMaintainer; - this.athenzCredentialsMaintainer = athenzCredentialsMaintainer; + this.credentialsMaintainer = credentialsMaintainer; this.aclMaintainer = aclMaintainer; this.healthChecker = healthChecker; @@ -443,7 +443,7 @@ public class NodeAgentImpl implements NodeAgent { return; } container = removeContainerIfNeededUpdateContainerState(context, container); - athenzCredentialsMaintainer.ifPresent(maintainer -> maintainer.converge(context)); + credentialsMaintainer.ifPresent(maintainer -> maintainer.converge(context)); if (! container.isPresent()) { containerState = STARTING; startContainer(context); @@ -481,7 +481,7 @@ public class NodeAgentImpl implements NodeAgent { case dirty: removeContainerIfNeededUpdateContainerState(context, container); context.log(logger, "State is " + node.getState() + ", will delete application storage and mark node as ready"); - athenzCredentialsMaintainer.ifPresent(maintainer -> maintainer.clearCredentials(context)); + credentialsMaintainer.ifPresent(maintainer -> maintainer.clearCredentials(context)); storageMaintainer.archiveNodeStorage(context); updateNodeRepoWithCurrentAttributes(context); nodeRepository.setNodeState(context.hostname().value(), NodeState.ready); diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImplTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImplTest.java index 15786f2ed34..dcbbaf792a8 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImplTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImplTest.java @@ -25,7 +25,7 @@ import com.yahoo.vespa.hosted.node.admin.configserver.orchestrator.OrchestratorE import com.yahoo.vespa.hosted.node.admin.docker.DockerOperations; import com.yahoo.vespa.hosted.node.admin.maintenance.StorageMaintainer; import com.yahoo.vespa.hosted.node.admin.maintenance.acl.AclMaintainer; -import com.yahoo.vespa.hosted.node.admin.maintenance.identity.AthenzCredentialsMaintainer; +import com.yahoo.vespa.hosted.node.admin.maintenance.identity.CredentialsMaintainer; import com.yahoo.vespa.hosted.node.admin.nodeadmin.ConvergenceException; import org.junit.Test; import org.mockito.InOrder; @@ -84,7 +84,7 @@ public class NodeAgentImplTest { private final HealthChecker healthChecker = mock(HealthChecker.class); private final ContainerStats emptyContainerStats = new ContainerStats(Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap()); - private final AthenzCredentialsMaintainer athenzCredentialsMaintainer = mock(AthenzCredentialsMaintainer.class); + private final CredentialsMaintainer credentialsMaintainer = mock(CredentialsMaintainer.class); private final InMemoryFlagSource flagSource = new InMemoryFlagSource(); @@ -763,7 +763,7 @@ public class NodeAgentImplTest { doNothing().when(storageMaintainer).writeMetricsConfig(any()); return new NodeAgentImpl(contextSupplier, nodeRepository, orchestrator, dockerOperations, - storageMaintainer, flagSource, Optional.of(athenzCredentialsMaintainer), Optional.of(aclMaintainer), + storageMaintainer, flagSource, Optional.of(credentialsMaintainer), Optional.of(aclMaintainer), Optional.of(healthChecker)); } -- cgit v1.2.3