summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eriksen <andreer@verizonmedia.com>2020-01-22 15:12:26 +0100
committerGitHub <noreply@github.com>2020-01-22 15:12:26 +0100
commitf2cbfe11060273ea592e1a319c4f877ecac6fea5 (patch)
treeb9e229ca96871abc960b9b158ca55779f251eef5
parent77d1dde0fdf1f5af7a8ad85de5bb464ef01b1c0e (diff)
parentc54f73fdd627f03cd185c48c7e3b580f5cf831bc (diff)
Merge pull request #11893 from vespa-engine/andreer/deploy-with-endpoint-certificate-metadata
andreer/deploy with endpoint certificate metadata
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/tenant/EndpointCertificateMetadataSerializer.java2
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateMetadata.java42
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServer.java4
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java15
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/EndpointCertificateMetadataSerializer.java58
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java4
6 files changed, 114 insertions, 11 deletions
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/EndpointCertificateMetadataSerializer.java b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/EndpointCertificateMetadataSerializer.java
index 6d092aaa18b..f3240a62133 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/EndpointCertificateMetadataSerializer.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/EndpointCertificateMetadataSerializer.java
@@ -45,7 +45,7 @@ public class EndpointCertificateMetadataSerializer {
);
default:
- throw new IllegalArgumentException("Unknown format encountered for TLS secrets metadata!");
+ throw new IllegalArgumentException("Unknown format encountered for endpoint certificate metadata!");
}
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateMetadata.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateMetadata.java
new file mode 100644
index 00000000000..5838c828a3f
--- /dev/null
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateMetadata.java
@@ -0,0 +1,42 @@
+package com.yahoo.vespa.hosted.controller.api.integration.certificates;
+
+/**
+ * This class is used for metadata about an application's endpoint certificate on the controller.
+ * <p>
+ * It is a copy of com.yahoo.config.model.api.EndpointCertificateMetadata, but will soon be extended.
+ *
+ * @author andreer
+ */
+public class EndpointCertificateMetadata {
+
+ private final String keyName;
+ private final String certName;
+ private final int version;
+
+ public EndpointCertificateMetadata(String keyName, String certName, int version) {
+ this.keyName = keyName;
+ this.certName = certName;
+ this.version = version;
+ }
+
+ public String keyName() {
+ return keyName;
+ }
+
+ public String certName() {
+ return certName;
+ }
+
+ public int version() {
+ return version;
+ }
+
+ @Override
+ public String toString() {
+ return "EndpointCertificateMetadata{" +
+ "keyName='" + keyName + '\'' +
+ ", certName='" + certName + '\'' +
+ ", version=" + version +
+ '}';
+ }
+}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServer.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServer.java
index a009f002954..f8f63df40a9 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServer.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServer.java
@@ -10,7 +10,7 @@ import com.yahoo.vespa.hosted.controller.api.application.v4.model.DeployOptions;
import com.yahoo.vespa.hosted.controller.api.application.v4.model.EndpointStatus;
import com.yahoo.vespa.hosted.controller.api.identifiers.DeploymentId;
import com.yahoo.vespa.hosted.controller.api.identifiers.Hostname;
-import com.yahoo.vespa.hosted.controller.api.integration.certificates.ApplicationCertificate;
+import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificateMetadata;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.TesterCloud;
import com.yahoo.vespa.serviceview.bindings.ApplicationView;
@@ -32,7 +32,7 @@ public interface ConfigServer {
}
PreparedApplication deploy(DeploymentId deployment, DeployOptions deployOptions,
- Set<ContainerEndpoint> containerEndpoints, ApplicationCertificate applicationCertificate,
+ Set<ContainerEndpoint> containerEndpoints, Optional<EndpointCertificateMetadata> endpointCertificateMetadata,
byte[] content);
void restart(DeploymentId deployment, Optional<Hostname> hostname);
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java
index 82120f13b75..20c1b0999e6 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java
@@ -28,6 +28,7 @@ import com.yahoo.vespa.hosted.controller.api.identifiers.Hostname;
import com.yahoo.vespa.hosted.controller.api.identifiers.InstanceId;
import com.yahoo.vespa.hosted.controller.api.identifiers.RevisionId;
import com.yahoo.vespa.hosted.controller.api.integration.certificates.ApplicationCertificate;
+import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificateMetadata;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.ConfigServer;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.ConfigServerException;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.ContainerEndpoint;
@@ -59,6 +60,7 @@ import com.yahoo.vespa.hosted.controller.deployment.DeploymentTrigger;
import com.yahoo.vespa.hosted.controller.deployment.Run;
import com.yahoo.vespa.hosted.controller.deployment.Versions;
import com.yahoo.vespa.hosted.controller.dns.NameServiceQueue.Priority;
+import com.yahoo.vespa.hosted.controller.persistence.EndpointCertificateMetadataSerializer;
import com.yahoo.vespa.hosted.controller.routing.RoutingPolicies;
import com.yahoo.vespa.hosted.controller.persistence.CuratorDb;
import com.yahoo.vespa.hosted.controller.rotation.RotationLock;
@@ -359,7 +361,7 @@ public class ApplicationController {
ApplicationVersion applicationVersion;
ApplicationPackage applicationPackage;
Set<ContainerEndpoint> endpoints;
- Optional<ApplicationCertificate> applicationCertificate;
+ Optional<EndpointCertificateMetadata> endpointCertificateMetadata;
try (Lock lock = lock(applicationId)) {
LockedApplication application = new LockedApplication(requireApplication(applicationId), lock);
@@ -397,9 +399,10 @@ public class ApplicationController {
if (controller.zoneRegistry().zones().directlyRouted().ids().contains(zone)) {
// Provisions a new certificate if missing
- applicationCertificate = getApplicationCertificate(application.get().require(instance));
+ endpointCertificateMetadata = getApplicationCertificate(application.get().require(instance))
+ .map(appCert -> EndpointCertificateMetadataSerializer.fromString(appCert.secretsKeyNamePrefix()));
} else {
- applicationCertificate = Optional.empty();
+ endpointCertificateMetadata = Optional.empty();
}
endpoints = registerEndpointsInDns(applicationPackage.deploymentSpec(), application.get().require(instanceId.instance()), zone);
@@ -408,7 +411,7 @@ public class ApplicationController {
// Carry out deployment without holding the application lock.
options = withVersion(platformVersion, options);
ActivateResult result = deploy(instanceId, applicationPackage, zone, options, endpoints,
- applicationCertificate.orElse(null));
+ endpointCertificateMetadata);
lockApplicationOrThrow(applicationId, application ->
store(application.with(instanceId.instance(),
@@ -494,11 +497,11 @@ public class ApplicationController {
private ActivateResult deploy(ApplicationId application, ApplicationPackage applicationPackage,
ZoneId zone, DeployOptions deployOptions, Set<ContainerEndpoint> endpoints,
- ApplicationCertificate applicationCertificate) {
+ Optional<EndpointCertificateMetadata> endpointCertificateMetadata) {
DeploymentId deploymentId = new DeploymentId(application, zone);
try {
ConfigServer.PreparedApplication preparedApplication =
- configServer.deploy(deploymentId, deployOptions, endpoints, applicationCertificate, applicationPackage.zippedContent());
+ configServer.deploy(deploymentId, deployOptions, endpoints, endpointCertificateMetadata, applicationPackage.zippedContent());
return new ActivateResult(new RevisionId(applicationPackage.hash()), preparedApplication.prepareResponse(),
applicationPackage.zippedContent().length);
} finally {
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/EndpointCertificateMetadataSerializer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/EndpointCertificateMetadataSerializer.java
new file mode 100644
index 00000000000..fe684b6c419
--- /dev/null
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/EndpointCertificateMetadataSerializer.java
@@ -0,0 +1,58 @@
+package com.yahoo.vespa.hosted.controller.persistence;
+
+import com.yahoo.slime.Cursor;
+import com.yahoo.slime.Inspector;
+import com.yahoo.slime.Slime;
+import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificateMetadata;
+
+/**
+ * (de)serializes endpoint certificate metadata
+ * <p>
+ * A copy of package com.yahoo.vespa.config.server.tenant.EndpointCertificateMetadata,
+ * but will soon be extended as we need to store some more information in the controller.
+ *
+ * @author andreer
+ */
+public class EndpointCertificateMetadataSerializer {
+
+ // WARNING: Since there are multiple servers in a ZooKeeper cluster and they upgrade one by one
+ // (and rewrite all nodes on startup), changes to the serialized format must be made
+ // such that what is serialized on version N+1 can be read by version N:
+ // - ADDING FIELDS: Always ok
+ // - REMOVING FIELDS: Stop reading the field first. Stop writing it on a later version.
+ // - CHANGING THE FORMAT OF A FIELD: Don't do it bro.
+
+ private final static String keyNameField = "keyName";
+ private final static String certNameField = "certName";
+ private final static String versionField = "version";
+
+ public static void toSlime(EndpointCertificateMetadata metadata, Cursor object) {
+ object.setString(keyNameField, metadata.keyName());
+ object.setString(certNameField, metadata.certName());
+ object.setLong(versionField, metadata.version());
+ }
+
+ public static EndpointCertificateMetadata fromSlime(Inspector inspector) {
+ switch (inspector.type()) {
+ case STRING: // TODO: Remove once all are transmitted and stored as JSON
+ return new EndpointCertificateMetadata(
+ inspector.asString() + "-key",
+ inspector.asString() + "-cert",
+ 0
+ );
+ case OBJECT:
+ return new EndpointCertificateMetadata(
+ inspector.field(keyNameField).asString(),
+ inspector.field(certNameField).asString(),
+ Math.toIntExact(inspector.field(versionField).asLong())
+ );
+
+ default:
+ throw new IllegalArgumentException("Unknown format encountered for endpoint certificate metadata!");
+ }
+ }
+
+ public static EndpointCertificateMetadata fromString(String tlsSecretsKeys) {
+ return fromSlime(new Slime().setString(tlsSecretsKeys));
+ }
+}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java
index fef8ab32d17..66429795878 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java
@@ -18,7 +18,7 @@ import com.yahoo.vespa.hosted.controller.api.identifiers.DeploymentId;
import com.yahoo.vespa.hosted.controller.api.identifiers.Hostname;
import com.yahoo.vespa.hosted.controller.api.identifiers.Identifier;
import com.yahoo.vespa.hosted.controller.api.identifiers.TenantId;
-import com.yahoo.vespa.hosted.controller.api.integration.certificates.ApplicationCertificate;
+import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificateMetadata;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.ConfigServer;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.ContainerEndpoint;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.LoadBalancer;
@@ -287,7 +287,7 @@ public class ConfigServerMock extends AbstractComponent implements ConfigServer
@Override
public PreparedApplication deploy(DeploymentId deployment, DeployOptions deployOptions,
Set<ContainerEndpoint> containerEndpoints,
- ApplicationCertificate applicationCertificate, byte[] content) {
+ Optional<EndpointCertificateMetadata> endpointCertificateMetadata, byte[] content) {
lastPrepareVersion = deployOptions.vespaVersion.map(Version::fromString).orElse(null);
if (prepareException != null) {
RuntimeException prepareException = this.prepareException;