diff options
author | Martin Polden <mpolden@mpolden.no> | 2023-07-05 15:38:25 +0200 |
---|---|---|
committer | Martin Polden <mpolden@mpolden.no> | 2023-07-06 13:56:42 +0200 |
commit | e5b89c6a148d80cfef77baa52e383b642648e194 (patch) | |
tree | 5b3a2286703f2a1e63eacedc43c986534043ecf3 /controller-server/src/main/java | |
parent | bd7356f18947ba1b08ef43e82e74018e664c0893 (diff) |
EndpointCertificateMetadata -> EndpointCertificate
Diffstat (limited to 'controller-server/src/main/java')
11 files changed, 104 insertions, 108 deletions
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 fdb27ba49a3..54dcfa46188 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 @@ -33,7 +33,7 @@ import com.yahoo.vespa.hosted.controller.api.identifiers.InstanceId; import com.yahoo.vespa.hosted.controller.api.integration.billing.BillingController; import com.yahoo.vespa.hosted.controller.api.integration.billing.Plan; import com.yahoo.vespa.hosted.controller.api.integration.billing.Quota; -import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificateMetadata; +import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificate; import com.yahoo.vespa.hosted.controller.api.integration.configserver.ApplicationReindexing; import com.yahoo.vespa.hosted.controller.api.integration.configserver.ConfigServer; import com.yahoo.vespa.hosted.controller.api.integration.configserver.ContainerEndpoint; @@ -525,9 +525,9 @@ public class ApplicationController { containerEndpoints = controller.routing().of(deployment).prepare(application); } // Release application lock while doing the deployment, which is a lengthy task. - Supplier<Optional<EndpointCertificateMetadata>> endpointCertificateMetadata = () -> { + Supplier<Optional<EndpointCertificate>> endpointCertificate = () -> { try (Mutex lock = lock(applicationId)) { - Optional<EndpointCertificateMetadata> data = endpointCertificates.getMetadata(instance, zone, applicationPackage.truncatedPackage().deploymentSpec()); + Optional<EndpointCertificate> data = endpointCertificates.get(instance, zone, applicationPackage.truncatedPackage().deploymentSpec()); data.ifPresent(e -> deployLogger.accept("Using CA signed certificate version %s".formatted(e.version()))); return data; } @@ -535,7 +535,7 @@ public class ApplicationController { // Carry out deployment without holding the application lock. DeploymentDataAndResult dataAndResult = deploy(job.application(), applicationPackage, zone, platform, containerEndpoints, - endpointCertificateMetadata, run.isDryRun(), run.testerCertificate()); + endpointCertificate, run.isDryRun(), run.testerCertificate()); // Record the quota usage for this application @@ -649,7 +649,7 @@ public class ApplicationController { private record DeploymentDataAndResult(DeploymentData data, DeploymentResult result) {} private DeploymentDataAndResult deploy(ApplicationId application, ApplicationPackageStream applicationPackage, ZoneId zone, Version platform, Set<ContainerEndpoint> endpoints, - Supplier<Optional<EndpointCertificateMetadata>> endpointCertificateMetadata, + Supplier<Optional<EndpointCertificate>> endpointCertificate, boolean dryRun, Optional<X509Certificate> testerCertificate) { DeploymentId deployment = new DeploymentId(application, zone); // Routing and metadata may have changed, so we need to refresh state after deployment, even if deployment fails. @@ -684,16 +684,16 @@ public class ApplicationController { } Supplier<Optional<CloudAccount>> cloudAccount = () -> decideCloudAccountOf(deployment, applicationPackage.truncatedPackage().deploymentSpec()); List<DataplaneTokenVersions> dataplaneTokenVersions = controller.dataplaneTokenService().listTokens(application.tenant()); - Supplier<Optional<EndpointCertificateMetadata>> endpointCertificateMetadataWrapper = () -> { - Optional<EndpointCertificateMetadata> data = endpointCertificateMetadata.get(); + Supplier<Optional<EndpointCertificate>> endpointCertificateWrapper = () -> { + Optional<EndpointCertificate> data = endpointCertificate.get(); // TODO(mpolden): Pass these endpoints to config server as part of the deploy call. This will let the // application know which endpoints are mTLS and which are token-based - data.flatMap(EndpointCertificateMetadata::randomizedId) + data.flatMap(EndpointCertificate::randomizedId) .ifPresent(applicationPart -> generatedEndpoints.addAll(controller.routing().generateEndpoints(applicationPart, deployment.applicationId()))); return data; }; DeploymentData deploymentData = new DeploymentData(application, zone, applicationPackage::zipStream, platform, - endpoints, endpointCertificateMetadataWrapper, dockerImageRepo, domain, + endpoints, endpointCertificateWrapper, dockerImageRepo, domain, deploymentQuota, tenantSecretStores, operatorCertificates, cloudAccount, dataplaneTokenVersions, dryRun); ConfigServer.PreparedApplication preparedApplication = configServer.deploy(deploymentData); diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/pkg/ApplicationPackage.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/pkg/ApplicationPackage.java index 3ebaebf680a..3ec79b03ee8 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/pkg/ApplicationPackage.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/pkg/ApplicationPackage.java @@ -163,7 +163,7 @@ public class ApplicationPackage { deploymentFile, DeploymentSpec.empty.xmlForm().getBytes(UTF_8)))); } - /** Returns a zip containing meta data about deployments of this package by the given job. */ + /** Returns a zip containing metadata about deployments of this package by the given job. */ public byte[] metaDataZip() { return cacheZip(); } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/certificate/AssignedCertificate.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/certificate/AssignedCertificate.java index 0c8c64827fb..7d3bcf8bdaa 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/certificate/AssignedCertificate.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/certificate/AssignedCertificate.java @@ -2,7 +2,7 @@ package com.yahoo.vespa.hosted.controller.certificate; import com.yahoo.config.provision.InstanceName; -import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificateMetadata; +import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificate; import com.yahoo.vespa.hosted.controller.application.TenantAndApplicationId; import java.util.Optional; @@ -15,9 +15,9 @@ import java.util.Optional; */ public record AssignedCertificate(TenantAndApplicationId application, Optional<InstanceName> instance, - EndpointCertificateMetadata certificate) { + EndpointCertificate certificate) { - public AssignedCertificate with(EndpointCertificateMetadata certificate) { + public AssignedCertificate with(EndpointCertificate certificate) { return new AssignedCertificate(application, instance, certificate); } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/certificate/EndpointCertificates.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/certificate/EndpointCertificates.java index 13703c25f15..5d0ee7b74c5 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/certificate/EndpointCertificates.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/certificate/EndpointCertificates.java @@ -17,7 +17,7 @@ import com.yahoo.vespa.flags.StringFlag; import com.yahoo.vespa.hosted.controller.Controller; import com.yahoo.vespa.hosted.controller.Instance; import com.yahoo.vespa.hosted.controller.api.identifiers.DeploymentId; -import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificateMetadata; +import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificate; import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificateProvider; import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificateValidator; import com.yahoo.vespa.hosted.controller.api.integration.secrets.GcpSecretStore; @@ -39,7 +39,7 @@ import java.util.stream.Collectors; import static com.yahoo.vespa.hosted.controller.certificate.UnassignedCertificate.*; /** - * Looks up stored endpoint certificate metadata, provisions new certificates if none is found, + * Looks up stored endpoint certificate, provisions new certificates if none is found, * and re-provisions the certificate if the deploying-to zone is not covered. * * See also {@link com.yahoo.vespa.hosted.controller.maintenance.EndpointCertificateMaintainer}, which handles @@ -73,45 +73,44 @@ public class EndpointCertificates { this.certificateValidator = certificateValidator; } - /** Returns certificate metadata for endpoints of given instance and zone */ - public Optional<EndpointCertificateMetadata> getMetadata(Instance instance, ZoneId zone, DeploymentSpec deploymentSpec) { + /** Returns a suitable certificate for endpoints of given instance and zone */ + public Optional<EndpointCertificate> get(Instance instance, ZoneId zone, DeploymentSpec deploymentSpec) { Instant start = clock.instant(); - Optional<EndpointCertificateMetadata> metadata = getOrProvision(instance, zone, deploymentSpec); + Optional<EndpointCertificate> cert = getOrProvision(instance, zone, deploymentSpec); Duration duration = Duration.between(start, clock.instant()); if (duration.toSeconds() > 30) - log.log(Level.INFO, Text.format("Getting endpoint certificate metadata for %s took %d seconds!", instance.id().serializedForm(), duration.toSeconds())); + log.log(Level.INFO, Text.format("Getting endpoint certificate for %s took %d seconds!", instance.id().serializedForm(), duration.toSeconds())); if (controller.zoneRegistry().zones().all().in(CloudName.GCP).ids().contains(zone)) { // Until CKMS is available from GCP - if (metadata.isPresent()) { - // Validate metadata before copying cert to GCP. This will ensure we don't bug out on the first deployment, but will take more time - certificateValidator.validate(metadata.get(), instance.id().serializedForm(), zone, controller.routing().certificateDnsNames(new DeploymentId(instance.id(), zone), deploymentSpec)); - var m = metadata.get(); + if (cert.isPresent()) { + // Validate before copying cert to GCP. This will ensure we don't bug out on the first deployment, but will take more time + certificateValidator.validate(cert.get(), instance.id().serializedForm(), zone, controller.routing().certificateDnsNames(new DeploymentId(instance.id(), zone), deploymentSpec)); GcpSecretStore gcpSecretStore = controller.serviceRegistry().gcpSecretStore(); - String mangledCertName = "endpointCert_" + m.certName().replace('.', '_') + "-v" + m.version(); // Google cloud does not accept dots in secrets, but they accept underscores - String mangledKeyName = "endpointCert_" + m.keyName().replace('.', '_') + "-v" + m.version(); // Google cloud does not accept dots in secrets, but they accept underscores + String mangledCertName = "endpointCert_" + cert.get().certName().replace('.', '_') + "-v" + cert.get().version(); // Google cloud does not accept dots in secrets, but they accept underscores + String mangledKeyName = "endpointCert_" + cert.get().keyName().replace('.', '_') + "-v" + cert.get().version(); // Google cloud does not accept dots in secrets, but they accept underscores if (gcpSecretStore.getLatestSecretVersion(mangledCertName) == null) { gcpSecretStore.setSecret(mangledCertName, Optional.of(GCP_CERTIFICATE_EXPIRY_TIME), "endpoint-cert-accessor"); gcpSecretStore.addSecretVersion(mangledCertName, - controller.secretStore().getSecret(m.certName(), m.version())); + controller.secretStore().getSecret(cert.get().certName(), cert.get().version())); } if (gcpSecretStore.getLatestSecretVersion(mangledKeyName) == null) { gcpSecretStore.setSecret(mangledKeyName, Optional.of(GCP_CERTIFICATE_EXPIRY_TIME), "endpoint-cert-accessor"); gcpSecretStore.addSecretVersion(mangledKeyName, - controller.secretStore().getSecret(m.keyName(), m.version())); + controller.secretStore().getSecret(cert.get().keyName(), cert.get().version())); } - return Optional.of(m.withVersion(1).withKeyName(mangledKeyName).withCertName(mangledCertName)); + return Optional.of(cert.get().withVersion(1).withKeyName(mangledKeyName).withCertName(mangledCertName)); } } - return metadata; + return cert; } - private EndpointCertificateMetadata assignFromPool(Instance instance, ZoneId zone) { + private EndpointCertificate assignFromPool(Instance instance, ZoneId zone) { // Assign certificate per instance only in manually deployed environments. In other environments, we share the // certificate because application endpoints can span instances Optional<InstanceName> instanceName = zone.environment().isManuallyDeployed() ? Optional.of(instance.name()) : Optional.empty(); @@ -139,7 +138,7 @@ public class EndpointCertificates { } } - private Optional<EndpointCertificateMetadata> getOrProvision(Instance instance, ZoneId zone, DeploymentSpec deploymentSpec) { + private Optional<EndpointCertificate> getOrProvision(Instance instance, ZoneId zone, DeploymentSpec deploymentSpec) { if (useRandomizedCert.with(FetchVector.Dimension.APPLICATION_ID, instance.id().serializedForm()).value()) { return Optional.of(assignFromPool(instance, zone)); } @@ -147,12 +146,12 @@ public class EndpointCertificates { DeploymentId deployment = new DeploymentId(instance.id(), zone); if (assignedCertificate.isEmpty()) { - var provisionedCertificateMetadata = provisionEndpointCertificate(deployment, Optional.empty(), deploymentSpec); + var provisionedCertificate = provisionEndpointCertificate(deployment, Optional.empty(), deploymentSpec); // We do not verify the certificate if one has never existed before - because we do not want to // wait for it to be available before we deploy. This allows the config server to start // provisioning nodes ASAP, and the risk is small for a new deployment. - curator.writeAssignedCertificate(new AssignedCertificate(TenantAndApplicationId.from(instance.id()), Optional.of(instance.id().instance()), provisionedCertificateMetadata)); - return Optional.of(provisionedCertificateMetadata); + curator.writeAssignedCertificate(new AssignedCertificate(TenantAndApplicationId.from(instance.id()), Optional.of(instance.id().instance()), provisionedCertificate)); + return Optional.of(provisionedCertificate); } else { AssignedCertificate updated = assignedCertificate.get().with(assignedCertificate.get().certificate().withLastRequested(clock.instant().getEpochSecond())); curator.writeAssignedCertificate(updated); @@ -160,28 +159,28 @@ public class EndpointCertificates { // Re-provision certificate if it is missing SANs for the zone we are deploying to // Skip this validation for now if the cert has a randomized id - Optional<EndpointCertificateMetadata> currentCertificateMetadata = assignedCertificate.map(AssignedCertificate::certificate); - var requiredSansForZone = currentCertificateMetadata.get().randomizedId().isEmpty() ? + Optional<EndpointCertificate> currentCertificate = assignedCertificate.map(AssignedCertificate::certificate); + var requiredSansForZone = currentCertificate.get().randomizedId().isEmpty() ? controller.routing().certificateDnsNames(deployment, deploymentSpec) : List.<String>of(); - if (!currentCertificateMetadata.get().requestedDnsSans().containsAll(requiredSansForZone)) { - var reprovisionedCertificateMetadata = - provisionEndpointCertificate(deployment, currentCertificateMetadata, deploymentSpec) - .withRootRequestId(currentCertificateMetadata.get().rootRequestId()); // We're required to keep the original request ID - curator.writeAssignedCertificate(assignedCertificate.get().with(reprovisionedCertificateMetadata)); + if (!currentCertificate.get().requestedDnsSans().containsAll(requiredSansForZone)) { + var reprovisionedCertificate = + provisionEndpointCertificate(deployment, currentCertificate, deploymentSpec) + .withRootRequestId(currentCertificate.get().rootRequestId()); // We're required to keep the original request ID + curator.writeAssignedCertificate(assignedCertificate.get().with(reprovisionedCertificate)); // Verification is unlikely to succeed in this case, as certificate must be available first - controller will retry - certificateValidator.validate(reprovisionedCertificateMetadata, instance.id().serializedForm(), zone, requiredSansForZone); - return Optional.of(reprovisionedCertificateMetadata); + certificateValidator.validate(reprovisionedCertificate, instance.id().serializedForm(), zone, requiredSansForZone); + return Optional.of(reprovisionedCertificate); } - certificateValidator.validate(currentCertificateMetadata.get(), instance.id().serializedForm(), zone, requiredSansForZone); - return currentCertificateMetadata; + certificateValidator.validate(currentCertificate.get(), instance.id().serializedForm(), zone, requiredSansForZone); + return currentCertificate; } - private EndpointCertificateMetadata provisionEndpointCertificate(DeploymentId deployment, - Optional<EndpointCertificateMetadata> currentMetadata, - DeploymentSpec deploymentSpec) { + private EndpointCertificate provisionEndpointCertificate(DeploymentId deployment, + Optional<EndpointCertificate> currentCert, + DeploymentSpec deploymentSpec) { List<ZoneId> zonesInSystem = controller.zoneRegistry().zones().controllerUpgraded().ids(); Set<ZoneId> requiredZones = new LinkedHashSet<>(); requiredZones.add(deployment.zoneId()); @@ -201,7 +200,7 @@ public class EndpointCertificates { .collect(Collectors.toCollection(LinkedHashSet::new)); // Preserve any currently present names that are still valid - List<String> currentNames = currentMetadata.map(EndpointCertificateMetadata::requestedDnsSans) + List<String> currentNames = currentCert.map(EndpointCertificate::requestedDnsSans) .orElseGet(List::of); zonesInSystem.stream() .map(zone -> controller.routing().certificateDnsNames(new DeploymentId(deployment.applicationId(), zone), deploymentSpec)) @@ -213,10 +212,10 @@ public class EndpointCertificates { boolean useAlternativeProvider = useAlternateCertProvider.with(FetchVector.Dimension.APPLICATION_ID, deployment.applicationId().serializedForm()).value(); String keyPrefix = deployment.applicationId().toFullString(); var t0 = Instant.now(); - EndpointCertificateMetadata endpointCertificateMetadata = certificateProvider.requestCaSignedCertificate(keyPrefix, List.copyOf(requiredNames), currentMetadata, algo, useAlternativeProvider); + EndpointCertificate endpointCertificate = certificateProvider.requestCaSignedCertificate(keyPrefix, List.copyOf(requiredNames), currentCert, algo, useAlternativeProvider); var t1 = Instant.now(); log.log(Level.INFO, String.format("Endpoint certificate request for application %s returned after %s", deployment.applicationId().serializedForm(), Duration.between(t0, t1))); - return endpointCertificateMetadata; + return endpointCertificate; } } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/certificate/UnassignedCertificate.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/certificate/UnassignedCertificate.java index 2fbff02ffa9..3a8580b7eb5 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/certificate/UnassignedCertificate.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/certificate/UnassignedCertificate.java @@ -1,6 +1,6 @@ package com.yahoo.vespa.hosted.controller.certificate; -import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificateMetadata; +import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificate; /** * An unassigned certificate, which exists in a pre-provisioned pool of certificates. Once assigned to an application, @@ -11,7 +11,7 @@ import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCe * * @author andreer */ -public record UnassignedCertificate(EndpointCertificateMetadata certificate, UnassignedCertificate.State state) { +public record UnassignedCertificate(EndpointCertificate certificate, UnassignedCertificate.State state) { public UnassignedCertificate { if (certificate.randomizedId().isEmpty()) { diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/CertificatePoolMaintainer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/CertificatePoolMaintainer.java index 46d19b627cc..9e2933f60fd 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/CertificatePoolMaintainer.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/CertificatePoolMaintainer.java @@ -12,7 +12,7 @@ import com.yahoo.vespa.flags.IntFlag; import com.yahoo.vespa.flags.PermanentFlags; import com.yahoo.vespa.flags.StringFlag; import com.yahoo.vespa.hosted.controller.Controller; -import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificateMetadata; +import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificate; import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificateProvider; import com.yahoo.vespa.hosted.controller.application.Endpoint; import com.yahoo.vespa.hosted.controller.application.GeneratedEndpoint; @@ -103,13 +103,13 @@ public class CertificatePoolMaintainer extends ControllerMaintainer { curator.readAssignedCertificates().stream() .map(AssignedCertificate::certificate) - .map(EndpointCertificateMetadata::randomizedId) + .map(EndpointCertificate::randomizedId) .forEach(id -> id.ifPresent(existingNames::add)); String id = generateRandomId(); while (existingNames.contains(id)) id = generateRandomId(); - EndpointCertificateMetadata f = endpointCertificateProvider.requestCaSignedCertificate( + EndpointCertificate f = endpointCertificateProvider.requestCaSignedCertificate( "preprovisioned.%s".formatted(id), List.of( "*.%s.z%s".formatted(id, dnsSuffix), @@ -119,7 +119,7 @@ public class CertificatePoolMaintainer extends ControllerMaintainer { Optional.empty(), endpointCertificateAlgo.value(), useAlternateCertProvider.value()) - .withRandomizedId(id); + .withRandomizedId(id); UnassignedCertificate certificate = new UnassignedCertificate(f, UnassignedCertificate.State.requested); curator.writeUnassignedCertificate(certificate); diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/EndpointCertificateMaintainer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/EndpointCertificateMaintainer.java index 935d562a8c2..e8e48bfccee 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/EndpointCertificateMaintainer.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/EndpointCertificateMaintainer.java @@ -11,8 +11,8 @@ import com.yahoo.transaction.Mutex; import com.yahoo.transaction.NestedTransaction; import com.yahoo.vespa.hosted.controller.Application; import com.yahoo.vespa.hosted.controller.Controller; +import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificate; import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificateDetails; -import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificateMetadata; import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificateProvider; import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificateRequestMetadata; import com.yahoo.vespa.hosted.controller.certificate.UnassignedCertificate; @@ -156,7 +156,7 @@ public class EndpointCertificateMaintainer extends ControllerMaintainer { }); } - private OptionalInt latestVersionInSecretStore(EndpointCertificateMetadata originalCertificateMetadata) { + private OptionalInt latestVersionInSecretStore(EndpointCertificate originalCertificateMetadata) { try { var certVersions = new HashSet<>(secretStore.listSecretVersions(originalCertificateMetadata.certName())); var keyVersions = new HashSet<>(secretStore.listSecretVersions(originalCertificateMetadata.keyName())); @@ -169,7 +169,7 @@ public class EndpointCertificateMaintainer extends ControllerMaintainer { private void deleteUnusedCertificates() { var oneMonthAgo = clock.instant().minus(30, ChronoUnit.DAYS); curator.readAssignedCertificates().forEach(assignedCertificate -> { - EndpointCertificateMetadata certificate = assignedCertificate.certificate(); + EndpointCertificate certificate = assignedCertificate.certificate(); var lastRequested = Instant.ofEpochSecond(certificate.lastRequested()); if (lastRequested.isBefore(oneMonthAgo) && hasNoDeployments(assignedCertificate.application())) { try (Mutex lock = lock(assignedCertificate.application())) { @@ -200,11 +200,11 @@ public class EndpointCertificateMaintainer extends ControllerMaintainer { } private void deleteOrReportUnmanagedCertificates() { - List<EndpointCertificateRequestMetadata> endpointCertificateMetadata = endpointCertificateProvider.listCertificates(); + List<EndpointCertificateRequestMetadata> requests = endpointCertificateProvider.listCertificates(); List<AssignedCertificate> assignedCertificates = curator.readAssignedCertificates(); List<String> leafRequestIds = assignedCertificates.stream().map(AssignedCertificate::certificate).flatMap(m -> m.leafRequestId().stream()).toList(); - List<String> rootRequestIds = assignedCertificates.stream().map(AssignedCertificate::certificate).map(EndpointCertificateMetadata::rootRequestId).toList(); + List<String> rootRequestIds = assignedCertificates.stream().map(AssignedCertificate::certificate).map(EndpointCertificate::rootRequestId).toList(); List<UnassignedCertificate> unassignedCertificates = curator.readUnassignedCertificates(); List<String> certPoolRootIds = unassignedCertificates.stream().map(p -> p.certificate().leafRequestId()).flatMap(Optional::stream).toList(); List<String> certPoolLeafIds = unassignedCertificates.stream().map(p -> p.certificate().rootRequestId()).toList(); @@ -215,21 +215,21 @@ public class EndpointCertificateMaintainer extends ControllerMaintainer { managedIds.addAll(certPoolRootIds); managedIds.addAll(certPoolLeafIds); - for (var providerCertificateMetadata : endpointCertificateMetadata) { - if (!managedIds.contains(providerCertificateMetadata.requestId())) { + for (var request : requests) { + if (!managedIds.contains(request.requestId())) { // It could just be a refresh we're not aware of yet. See if it matches the cert/keyname of any known cert - EndpointCertificateDetails unknownCertDetails = endpointCertificateProvider.certificateDetails(providerCertificateMetadata.requestId()); + EndpointCertificateDetails unknownCertDetails = endpointCertificateProvider.certificateDetails(request.requestId()); boolean matchFound = false; for (AssignedCertificate assignedCertificate : assignedCertificates) { - if (assignedCertificate.certificate().certName().equals(unknownCertDetails.cert_key_keyname())) { + if (assignedCertificate.certificate().certName().equals(unknownCertDetails.certKeyKeyname())) { matchFound = true; try (Mutex lock = lock(assignedCertificate.application())) { if (unchanged(assignedCertificate, lock)) { log.log(Level.INFO, "Cert for app " + asString(assignedCertificate.application(), assignedCertificate.instance()) - + " has a new leafRequestId " + unknownCertDetails.request_id() + ", updating in ZK"); + + " has a new leafRequestId " + unknownCertDetails.requestId() + ", updating in ZK"); try (NestedTransaction transaction = new NestedTransaction()) { - EndpointCertificateMetadata updated = assignedCertificate.certificate().withLeafRequestId(Optional.of(unknownCertDetails.request_id())); + EndpointCertificate updated = assignedCertificate.certificate().withLeafRequestId(Optional.of(unknownCertDetails.requestId())); curator.writeAssignedCertificate(assignedCertificate.with(updated), transaction); transaction.commit(); } @@ -241,11 +241,11 @@ public class EndpointCertificateMaintainer extends ControllerMaintainer { if (!matchFound) { // The certificate is not known - however it could be in the process of being requested by us or another controller. // So we only delete if it was requested more than 7 days ago. - if (Instant.parse(providerCertificateMetadata.createTime()).isBefore(Instant.now().minus(7, ChronoUnit.DAYS))) { + if (Instant.parse(request.createTime()).isBefore(Instant.now().minus(7, ChronoUnit.DAYS))) { log.log(Level.INFO, String.format("Deleting unmaintained certificate with request_id %s and SANs %s", - providerCertificateMetadata.requestId(), - providerCertificateMetadata.dnsNames().stream().map(d -> d.dnsName).collect(Collectors.joining(", ")))); - endpointCertificateProvider.deleteCertificate(providerCertificateMetadata.requestId()); + request.requestId(), + request.dnsNames().stream().map(d -> d.dnsName).collect(Collectors.joining(", ")))); + endpointCertificateProvider.deleteCertificate(request.requestId()); } } } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/CuratorDb.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/CuratorDb.java index 942d3167f7a..968befcd0a7 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/CuratorDb.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/CuratorDb.java @@ -619,7 +619,7 @@ public class CuratorDb { Path path = endpointCertificatePath(certificate.application(), certificate.instance()); curator.create(path); CuratorOperation operation = CuratorOperations.setData(path.getAbsolute(), - asJson(EndpointCertificateMetadataSerializer.toSlime(certificate.certificate()))); + asJson(EndpointCertificateSerializer.toSlime(certificate.certificate()))); transaction.add(CuratorTransaction.from(operation, curator)); } @@ -634,7 +634,7 @@ public class CuratorDb { public Optional<AssignedCertificate> readAssignedCertificate(TenantAndApplicationId application, Optional<InstanceName> instance) { return readSlime(endpointCertificatePath(application, instance)).map(Slime::get) - .map(EndpointCertificateMetadataSerializer::fromSlime) + .map(EndpointCertificateSerializer::fromSlime) .map(cert -> new AssignedCertificate(application, instance, cert)); } 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/EndpointCertificateSerializer.java index 822efcc7163..fae9ea1e0e3 100644 --- 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/EndpointCertificateSerializer.java @@ -6,20 +6,17 @@ import com.yahoo.slime.Inspector; import com.yahoo.slime.Slime; import com.yahoo.slime.SlimeUtils; import com.yahoo.slime.Type; -import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificateMetadata; +import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificate; import java.util.Optional; import java.util.stream.IntStream; /** - * (de)serializes endpoint certificate metadata - * <p> - * A copy of package com.yahoo.vespa.config.server.tenant.EndpointCertificateMetadata, - * but with additional fields as we need to store some more information in the controller. + * Serializer for {@link EndpointCertificate}. * * @author andreer */ -public class EndpointCertificateMetadataSerializer { +public class EndpointCertificateSerializer { // 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 @@ -40,33 +37,33 @@ public class EndpointCertificateMetadataSerializer { private final static String lastRefreshedField = "lastRefreshed"; private final static String randomizedIdField = "randomizedId"; - public static Slime toSlime(EndpointCertificateMetadata metadata) { + public static Slime toSlime(EndpointCertificate cert) { Slime slime = new Slime(); Cursor object = slime.setObject(); - toSlime(metadata, object); + toSlime(cert, object); return slime; } - public static void toSlime(EndpointCertificateMetadata metadata, Cursor object) { - object.setString(keyNameField, metadata.keyName()); - object.setString(certNameField, metadata.certName()); - object.setLong(versionField, metadata.version()); - object.setLong(lastRequestedField, metadata.lastRequested()); - object.setString(rootRequestIdField, metadata.rootRequestId()); - metadata.leafRequestId().ifPresent(leafRequestId -> object.setString(leafRequestIdField, leafRequestId)); + public static void toSlime(EndpointCertificate cert, Cursor object) { + object.setString(keyNameField, cert.keyName()); + object.setString(certNameField, cert.certName()); + object.setLong(versionField, cert.version()); + object.setLong(lastRequestedField, cert.lastRequested()); + object.setString(rootRequestIdField, cert.rootRequestId()); + cert.leafRequestId().ifPresent(leafRequestId -> object.setString(leafRequestIdField, leafRequestId)); var cursor = object.setArray(requestedDnsSansField); - metadata.requestedDnsSans().forEach(cursor::addString); - object.setString(issuerField, metadata.issuer()); - metadata.expiry().ifPresent(expiry -> object.setLong(expiryField, expiry)); - metadata.lastRefreshed().ifPresent(refreshTime -> object.setLong(lastRefreshedField, refreshTime)); - metadata.randomizedId().ifPresent(randomizedId -> object.setString(randomizedIdField, randomizedId)); + cert.requestedDnsSans().forEach(cursor::addString); + object.setString(issuerField, cert.issuer()); + cert.expiry().ifPresent(expiry -> object.setLong(expiryField, expiry)); + cert.lastRefreshed().ifPresent(refreshTime -> object.setLong(lastRefreshedField, refreshTime)); + cert.randomizedId().ifPresent(randomizedId -> object.setString(randomizedIdField, randomizedId)); } - public static EndpointCertificateMetadata fromSlime(Inspector inspector) { + public static EndpointCertificate fromSlime(Inspector inspector) { if (inspector.type() != Type.OBJECT) - throw new IllegalArgumentException("Unknown format encountered for endpoint certificate metadata!"); + throw new IllegalArgumentException("Invalid format encountered for endpoint certificate"); - return new EndpointCertificateMetadata( + return new EndpointCertificate( inspector.field(keyNameField).asString(), inspector.field(certNameField).asString(), Math.toIntExact(inspector.field(versionField).asLong()), @@ -87,7 +84,7 @@ public class EndpointCertificateMetadataSerializer { Optional.empty()); } - public static EndpointCertificateMetadata fromJsonString(String zkData) { + public static EndpointCertificate fromJsonString(String zkData) { return fromSlime(SlimeUtils.jsonToSlime(zkData).get()); } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/UnassignedCertificateSerializer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/UnassignedCertificateSerializer.java index 87778f1792f..2f8a0ea585c 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/UnassignedCertificateSerializer.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/UnassignedCertificateSerializer.java @@ -3,7 +3,7 @@ package com.yahoo.vespa.hosted.controller.persistence; import com.yahoo.slime.Cursor; import com.yahoo.slime.Slime; -import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificateMetadata; +import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificate; import com.yahoo.vespa.hosted.controller.certificate.UnassignedCertificate; /** @@ -18,14 +18,14 @@ public class UnassignedCertificateSerializer { Slime slime = new Slime(); Cursor root = slime.setObject(); root.setString(stateKey, unassignedCertificate.state().name()); - EndpointCertificateMetadataSerializer.toSlime(unassignedCertificate.certificate(), root.setObject(certificateKey)); + EndpointCertificateSerializer.toSlime(unassignedCertificate.certificate(), root.setObject(certificateKey)); return slime; } public UnassignedCertificate fromSlime(Slime slime) { Cursor root = slime.get(); UnassignedCertificate.State state = UnassignedCertificate.State.valueOf(root.field(stateKey).asString()); - EndpointCertificateMetadata certificate = EndpointCertificateMetadataSerializer.fromSlime(root.field(certificateKey)); + EndpointCertificate certificate = EndpointCertificateSerializer.fromSlime(root.field(certificateKey)); return new UnassignedCertificate(certificate, state); } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/certificate/EndpointCertificatesHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/certificate/EndpointCertificatesHandler.java index 3980ef87613..c25b4e7e369 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/certificate/EndpointCertificatesHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/certificate/EndpointCertificatesHandler.java @@ -13,13 +13,13 @@ import com.yahoo.vespa.flags.PermanentFlags; import com.yahoo.vespa.flags.StringFlag; import com.yahoo.vespa.hosted.controller.Controller; import com.yahoo.vespa.hosted.controller.api.integration.ServiceRegistry; -import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificateMetadata; +import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificate; import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificateProvider; import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificateRequestMetadata; import com.yahoo.vespa.hosted.controller.application.TenantAndApplicationId; import com.yahoo.vespa.hosted.controller.certificate.AssignedCertificate; import com.yahoo.vespa.hosted.controller.persistence.CuratorDb; -import com.yahoo.vespa.hosted.controller.persistence.EndpointCertificateMetadataSerializer; +import com.yahoo.vespa.hosted.controller.persistence.EndpointCertificateSerializer; import java.util.List; import java.util.Optional; @@ -60,9 +60,9 @@ public class EndpointCertificatesHandler extends ThreadedHttpRequestHandler { } public HttpResponse listEndpointCertificates() { - List<EndpointCertificateRequestMetadata> endpointCertificateMetadata = endpointCertificateProvider.listCertificates(); + List<EndpointCertificateRequestMetadata> request = endpointCertificateProvider.listCertificates(); - String requestsWithNames = endpointCertificateMetadata.stream() + String requestsWithNames = request.stream() .map(metadata -> metadata.requestId() + " : " + String.join(", ", metadata.dnsNames().stream() .map(dnsNameStatus -> dnsNameStatus.dnsName) @@ -85,16 +85,16 @@ public class EndpointCertificatesHandler extends ThreadedHttpRequestHandler { boolean useAlternativeProvider = useAlternateCertProvider.with(FetchVector.Dimension.APPLICATION_ID, applicationId.serializedForm()).value(); String keyPrefix = applicationId.toFullString(); - EndpointCertificateMetadata reRequestedMetadata = endpointCertificateProvider.requestCaSignedCertificate( + EndpointCertificate cert = endpointCertificateProvider.requestCaSignedCertificate( keyPrefix, assignedCertificate.certificate().requestedDnsSans(), ignoreExistingMetadata ? Optional.empty() : Optional.of(assignedCertificate.certificate()), algo, useAlternativeProvider); - curator.writeAssignedCertificate(assignedCertificate.with(reRequestedMetadata)); + curator.writeAssignedCertificate(assignedCertificate.with(cert)); - return new StringResponse(EndpointCertificateMetadataSerializer.toSlime(reRequestedMetadata).toString()); + return new StringResponse(EndpointCertificateSerializer.toSlime(cert).toString()); } } } |