aboutsummaryrefslogtreecommitdiffstats
path: root/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java
diff options
context:
space:
mode:
Diffstat (limited to 'controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java')
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java52
1 files changed, 32 insertions, 20 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 90653d85aed..d7a3d4fb9e5 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
@@ -1,4 +1,4 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.controller;
import com.yahoo.component.Version;
@@ -43,6 +43,7 @@ import com.yahoo.vespa.hosted.controller.api.integration.configserver.Deployment
import com.yahoo.vespa.hosted.controller.api.integration.configserver.Node;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.NodeFilter;
import com.yahoo.vespa.hosted.controller.api.integration.dataplanetoken.DataplaneTokenVersions;
+import com.yahoo.vespa.hosted.controller.api.integration.dataplanetoken.TokenId;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.ApplicationStore;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.ApplicationVersion;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.ArtifactRepository;
@@ -523,7 +524,7 @@ public class ApplicationController {
try (Mutex lock = lock(applicationId)) {
LockedApplication application = new LockedApplication(requireApplication(applicationId), lock);
application.get().revisions().last().map(ApplicationVersion::id).ifPresent(lastRevision::set);
- return prepareEndpoints(deployment, job, application, applicationPackage, deployLogger);
+ return prepareEndpoints(deployment, job, application, applicationPackage, deployLogger, lock);
}
};
@@ -553,38 +554,32 @@ public class ApplicationController {
if (warnings.isEmpty())
controller.notificationsDb().removeNotification(source, Notification.Type.applicationPackage);
else
- controller.notificationsDb().setNotification(source, Notification.Type.applicationPackage, Notification.Level.warning, warnings);
+ controller.notificationsDb().setApplicationPackageNotification(source, warnings);
}
lockApplicationOrThrow(applicationId, application ->
store(application.with(job.application().instance(),
i -> i.withNewDeployment(zone, revision, platform,
clock.instant(), warningsFrom(dataAndResult.result().log()),
- quotaUsage, dataAndResult.data().cloudAccount().orElse(CloudAccount.empty)))));
+ quotaUsage, dataAndResult.data().cloudAccount().orElse(CloudAccount.empty),
+ dataAndResult.data.dataPlaneTokens()))));
return dataAndResult.result();
}
}
private PreparedEndpoints prepareEndpoints(DeploymentId deployment, JobId job, LockedApplication application,
ApplicationPackageStream applicationPackage,
- Consumer<String> deployLogger) {
+ Consumer<String> deployLogger,
+ Mutex applicationLock) {
Instance instance = application.get().require(job.application().instance());
Tags tags = applicationPackage.truncatedPackage().deploymentSpec().instance(instance.name())
.map(DeploymentInstanceSpec::tags)
.orElseGet(Tags::empty);
- Optional<EndpointCertificate> certificate = endpointCertificates.get(instance, deployment.zoneId(), applicationPackage.truncatedPackage().deploymentSpec());
- certificate.ifPresent(e -> deployLogger.accept("Using CA signed certificate version %s".formatted(e.version())));
- BasicServicesXml services;
- try {
- services = applicationPackage.truncatedPackage().services(deployment, tags);
- } catch (Exception e) {
- // If the basic parsing done by the controller fails, we ignore the exception here so that
- // complete parsing errors are propagated from the config server. Otherwise, throwing here
- // will interrupt the request while it's being streamed to the config server
- log.warning("Ignoring failure to parse services.xml for deployment " + deployment +
- " while streaming application package: " + Exceptions.toMessageString(e));
- services = BasicServicesXml.empty;
- }
+ EndpointCertificate certificate = endpointCertificates.get(deployment,
+ applicationPackage.truncatedPackage().deploymentSpec(),
+ applicationLock);
+ deployLogger.accept("Using CA signed certificate version %s".formatted(certificate.version()));
+ BasicServicesXml services = applicationPackage.truncatedPackage().services(deployment, tags);
return controller.routing().of(deployment).prepare(services, certificate, application);
}
@@ -700,12 +695,29 @@ public class ApplicationController {
operatorCertificates = Stream.concat(operatorCertificates.stream(), testerCertificate.stream()).toList();
}
Supplier<Optional<CloudAccount>> cloudAccount = () -> cloudAccountOverride.apply(decideCloudAccountOf(deployment, applicationPackage.truncatedPackage().deploymentSpec()));
- List<DataplaneTokenVersions> dataplaneTokenVersions = controller.dataplaneTokenService().listTokens(application.tenant());
Supplier<DeploymentEndpoints> endpoints = () -> {
if (preparedEndpoints == null) return DeploymentEndpoints.none;
PreparedEndpoints prepared = preparedEndpoints.get();
generatedEndpoints.set(prepared.endpoints().generated());
- return new DeploymentEndpoints(prepared.containerEndpoints(), prepared.certificate());
+ return new DeploymentEndpoints(prepared.containerEndpoints(), Optional.of(prepared.certificate()));
+ };
+ Supplier<List<DataplaneTokenVersions>> dataplaneTokenVersions = () -> {
+ Tags tags = applicationPackage.truncatedPackage().deploymentSpec()
+ .instance(application.instance())
+ .map(DeploymentInstanceSpec::tags)
+ .orElse(Tags.empty());
+ BasicServicesXml services = applicationPackage.truncatedPackage().services(deployment, tags);
+ Set<TokenId> referencedTokens = services.containers().stream()
+ .flatMap(container -> container.dataPlaneTokens().stream())
+ .collect(toSet());
+ List<DataplaneTokenVersions> currentTokens = controller.dataplaneTokenService().listTokens(application.tenant()).stream()
+ .filter(token -> referencedTokens.contains(token.tokenId()))
+ .toList();
+ return Stream.concat(currentTokens.stream(),
+ referencedTokens.stream()
+ .filter(token -> currentTokens.stream().noneMatch(t -> t.tokenId().equals(token)))
+ .map(token -> new DataplaneTokenVersions(token, List.of(), Instant.EPOCH)))
+ .toList();
};
DeploymentData deploymentData = new DeploymentData(application, zone, applicationPackage::zipStream, platform,
endpoints, dockerImageRepo, domain, deploymentQuota, tenantSecretStores, operatorCertificates, cloudAccount, dataplaneTokenVersions, dryRun);