aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMorten Tokle <mortent@verizonmedia.com>2019-07-30 13:34:25 +0200
committerMorten Tokle <mortent@verizonmedia.com>2019-07-30 13:50:52 +0200
commitc054c04cce7d2ba1b8daefe11e74308598a4b5f5 (patch)
treedb0b161dd49db296a327b50f286fa3282d4d84ec
parentb53df1fcba1dae72a6e78c7892bc7b51408d4348 (diff)
Validate that config server is allowed to launch Athenz service
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java28
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/impl/AthenzFacade.java5
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/mock/AthenzDbMock.java13
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/mock/ZmsClientMock.java6
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java3
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/InternalDeploymentTester.java10
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerControllerTester.java4
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java60
8 files changed, 116 insertions, 13 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 65ef270ffd5..cb449f01286 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
@@ -13,7 +13,9 @@ import com.yahoo.config.provision.RegionName;
import com.yahoo.config.provision.TenantName;
import com.yahoo.config.provision.zone.ZoneId;
import com.yahoo.vespa.athenz.api.AthenzDomain;
+import com.yahoo.vespa.athenz.api.AthenzIdentity;
import com.yahoo.vespa.athenz.api.AthenzPrincipal;
+import com.yahoo.vespa.athenz.api.AthenzService;
import com.yahoo.vespa.athenz.api.AthenzUser;
import com.yahoo.vespa.curator.Lock;
import com.yahoo.vespa.flags.BooleanFlag;
@@ -853,14 +855,17 @@ public class ApplicationController {
/**
* Verifies that the application can be deployed to the tenant, following these rules:
*
- * 1. If the principal is given, verify that the principal is tenant admin or admin of the tenant domain
- * 2. If the principal is not given, verify that the Athenz domain of the tenant equals Athenz domain given in deployment.xml
+ * 1. Verify that the Athenz service can be launched by the config server
+ * 2. If the principal is given, verify that the principal is tenant admin or admin of the tenant domain
+ * 3. If the principal is not given, verify that the Athenz domain of the tenant equals Athenz domain given in deployment.xml
*
* @param tenantName Tenant where application should be deployed
* @param applicationPackage Application package
* @param deployer Principal initiating the deployment, possibly empty
*/
public void verifyApplicationIdentityConfiguration(TenantName tenantName, ApplicationPackage applicationPackage, Optional<Principal> deployer) {
+ verifyAllowedLaunchAthenzService(applicationPackage.deploymentSpec());
+
applicationPackage.deploymentSpec().athenzDomain().ifPresent(identityDomain -> {
Tenant tenant = controller.tenants().require(tenantName);
deployer.filter(AthenzPrincipal.class::isInstance)
@@ -886,6 +891,25 @@ public class ApplicationController {
});
}
+ /*
+ * Verifies that the configured athenz service (if any) can be launched.
+ */
+ private void verifyAllowedLaunchAthenzService(DeploymentSpec deploymentSpec) {
+ deploymentSpec.athenzDomain().ifPresent(athenzDomain -> {
+ controller.zoneRegistry().zones().reachable().ids()
+ .forEach(zone -> {
+ AthenzIdentity configServerAthenzIdentity = controller.zoneRegistry().getConfigServerAthenzIdentity(zone);
+ deploymentSpec.athenzService(zone.environment(), zone.region())
+ .map(service -> new AthenzService(athenzDomain.value(), service.value()))
+ .ifPresent(service -> {
+ boolean allowedToLaunch = ((AthenzFacade) accessControl).canLaunch(configServerAthenzIdentity, service);
+ if (!allowedToLaunch)
+ throw new IllegalArgumentException("Not allowed to launch Athenz service " + service.getFullName());
+ });
+ });
+ });
+ }
+
/** Returns the latest known version within the given major. */
private Optional<Version> lastCompatibleVersion(int targetMajorVersion) {
return controller.versionStatus().versions().stream()
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/impl/AthenzFacade.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/impl/AthenzFacade.java
index 75b7e137998..9257855eb6c 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/impl/AthenzFacade.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/impl/AthenzFacade.java
@@ -11,6 +11,7 @@ import com.yahoo.vespa.athenz.api.AthenzIdentity;
import com.yahoo.vespa.athenz.api.AthenzPrincipal;
import com.yahoo.vespa.athenz.api.AthenzResourceName;
import com.yahoo.vespa.athenz.api.AthenzRole;
+import com.yahoo.vespa.athenz.api.AthenzService;
import com.yahoo.vespa.athenz.api.OktaAccessToken;
import com.yahoo.vespa.athenz.client.zms.RoleAction;
import com.yahoo.vespa.athenz.client.zms.ZmsClient;
@@ -192,6 +193,10 @@ public class AthenzFacade implements AccessControl {
return hasAccess("modify", service.getDomain().getName() + ":hosted-vespa", identity);
}
+ public boolean canLaunch(AthenzIdentity principal, AthenzService service) {
+ return hasAccess("launch", service.getDomain().getName() + ":service."+service.getName(), principal);
+ }
+
/**
* Used when creating tenancies. As there are no tenancy policies at this point,
* we cannot use {@link #hasTenantAdminAccess(AthenzIdentity, AthenzDomain)}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/mock/AthenzDbMock.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/mock/AthenzDbMock.java
index a11426b9a23..4d9296ea18d 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/mock/AthenzDbMock.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/mock/AthenzDbMock.java
@@ -26,6 +26,10 @@ public class AthenzDbMock {
return this;
}
+ public Domain getOrCreateDomain(AthenzDomain domain) {
+ return domains.computeIfAbsent(domain, Domain::new);
+ }
+
public AthenzDbMock addHostedOperator(AthenzIdentity athenzIdentity) {
hostedOperators.add(athenzIdentity);
return this;
@@ -37,6 +41,7 @@ public class AthenzDbMock {
public final Set<AthenzIdentity> admins = new HashSet<>();
public final Set<AthenzIdentity> tenantAdmins = new HashSet<>();
public final Map<ApplicationId, Application> applications = new HashMap<>();
+ public final Map<String, Service> services = new HashMap<>();
public boolean isVespaTenant = false;
public Domain(AthenzDomain name) {
@@ -78,4 +83,12 @@ public class AthenzDbMock {
}
}
+ public static class Service {
+
+ public final boolean allowLaunch;
+
+ public Service(boolean allowLaunch) {
+ this.allowLaunch = allowLaunch;
+ }
+ }
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/mock/ZmsClientMock.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/mock/ZmsClientMock.java
index 37926d944b7..01f77795c4b 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/mock/ZmsClientMock.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/mock/ZmsClientMock.java
@@ -107,6 +107,12 @@ public class ZmsClientMock implements ZmsClient {
return false;
}
return false;
+ } else if ("launch".equals(action)){
+ AthenzDbMock.Domain domain = getDomainOrThrow(resource.getDomain(), false);
+ String serviceName = resource.getEntityName().replace("service.","");
+ if(!domain.services.containsKey(serviceName)) return false;
+ AthenzDbMock.Service service = domain.services.get(serviceName);
+ return service.allowLaunch;
}
return false;
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java
index d5935c752d9..40936dd8a68 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java
@@ -248,8 +248,7 @@ public final class ControllerTester {
public AthenzDomain createDomainWithAdmin(String domainName, AthenzUser user) {
AthenzDomain domain = new AthenzDomain(domainName);
- athenzDb.addDomain(new AthenzDbMock.Domain(domain));
- athenzDb.domains.get(domain).admin(user);
+ athenzDb.getOrCreateDomain(domain).admin(user);
return domain;
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/InternalDeploymentTester.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/InternalDeploymentTester.java
index 6725e05dd6d..46e991a135a 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/InternalDeploymentTester.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/InternalDeploymentTester.java
@@ -19,6 +19,7 @@ import com.yahoo.vespa.hosted.controller.api.integration.stubs.MockTesterCloud;
import com.yahoo.config.provision.zone.ZoneId;
import com.yahoo.vespa.hosted.controller.application.ApplicationPackage;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.ApplicationVersion;
+import com.yahoo.vespa.hosted.controller.athenz.mock.AthenzDbMock;
import com.yahoo.vespa.hosted.controller.integration.ConfigServerMock;
import com.yahoo.vespa.hosted.controller.integration.RoutingGeneratorMock;
import com.yahoo.vespa.hosted.controller.maintenance.JobControl;
@@ -39,8 +40,11 @@ import static org.junit.Assert.assertTrue;
public class InternalDeploymentTester {
+ private static final String ATHENZ_DOMAIN = "domain";
+ private static final String ATHENZ_SERVICE = "service";
+
public static final ApplicationPackage applicationPackage = new ApplicationPackageBuilder()
- .athenzIdentity(AthenzDomain.from("domain"), AthenzService.from("service"))
+ .athenzIdentity(AthenzDomain.from(ATHENZ_DOMAIN), AthenzService.from(ATHENZ_SERVICE))
.upgradePolicy("default")
.region("us-central-1")
.parallel("us-west-1", "us-east-3")
@@ -84,6 +88,10 @@ public class InternalDeploymentTester {
Logger.getLogger(InternalStepRunner.class.getName()).setLevel(LogLevel.DEBUG);
Logger.getLogger("").setLevel(LogLevel.DEBUG);
tester.controllerTester().configureDefaultLogHandler(handler -> handler.setLevel(LogLevel.DEBUG));
+
+ // Mock Athenz domain to allow launch of service
+ AthenzDbMock.Domain domain = tester.controllerTester().athenzDb().getOrCreateDomain(new com.yahoo.vespa.athenz.api.AthenzDomain(ATHENZ_DOMAIN));
+ domain.services.put(ATHENZ_SERVICE, new AthenzDbMock.Service(true));
}
/**
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerControllerTester.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerControllerTester.java
index 427428a3a94..54fe575a365 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerControllerTester.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerControllerTester.java
@@ -31,7 +31,6 @@ import com.yahoo.vespa.hosted.controller.integration.ArtifactRepositoryMock;
import com.yahoo.vespa.hosted.controller.maintenance.JobControl;
import com.yahoo.vespa.hosted.controller.maintenance.Upgrader;
import com.yahoo.vespa.hosted.controller.persistence.CuratorDb;
-import com.yahoo.vespa.hosted.controller.persistence.MockCuratorDb;
import com.yahoo.vespa.hosted.controller.security.AthenzCredentials;
import com.yahoo.vespa.hosted.controller.security.AthenzTenantSpec;
@@ -159,10 +158,9 @@ public class ContainerControllerTester {
AthenzClientFactoryMock mock = (AthenzClientFactoryMock) containerTester.container().components()
.getComponent(AthenzClientFactoryMock.class.getName());
AthenzDomain athensDomain = new AthenzDomain(domainName);
- AthenzDbMock.Domain domain = new AthenzDbMock.Domain(athensDomain);
+ AthenzDbMock.Domain domain = mock.getSetup().getOrCreateDomain(athensDomain);
domain.markAsVespaTenant();
domain.admin(new AthenzUser(userName));
- mock.getSetup().addDomain(domain);
return athensDomain;
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
index 5087d5f83ad..8db820f6c83 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
@@ -28,10 +28,10 @@ import com.yahoo.vespa.hosted.controller.api.identifiers.Property;
import com.yahoo.vespa.hosted.controller.api.identifiers.PropertyId;
import com.yahoo.vespa.hosted.controller.api.identifiers.ScrewdriverId;
import com.yahoo.vespa.hosted.controller.api.identifiers.UserId;
-import com.yahoo.vespa.hosted.controller.api.integration.metrics.MetricsService.ApplicationMetrics;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.ConfigServerException;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.ApplicationVersion;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.JobType;
+import com.yahoo.vespa.hosted.controller.api.integration.metrics.MetricsService.ApplicationMetrics;
import com.yahoo.vespa.hosted.controller.api.integration.organization.Contact;
import com.yahoo.vespa.hosted.controller.api.integration.organization.IssueId;
import com.yahoo.vespa.hosted.controller.api.integration.organization.MockContactRetriever;
@@ -562,6 +562,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
.athenzIdentity(com.yahoo.config.provision.AthenzDomain.from(ATHENZ_TENANT_DOMAIN_2.getName()), AthenzService.from("service"))
.region("us-west-1")
.build();
+ configureAthenzIdentity(new com.yahoo.vespa.athenz.api.AthenzService(ATHENZ_TENANT_DOMAIN_2, "service"), true);
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/submit", POST)
.screwdriverIdentity(SCREWDRIVER_ID)
.data(createApplicationSubmissionData(packageWithServiceForWrongDomain)),
@@ -573,6 +574,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
.athenzIdentity(com.yahoo.config.provision.AthenzDomain.from(ATHENZ_TENANT_DOMAIN.getName()), AthenzService.from("service"))
.region("us-west-1")
.build();
+ configureAthenzIdentity(new com.yahoo.vespa.athenz.api.AthenzService(ATHENZ_TENANT_DOMAIN, "service"), true);
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/submit", POST)
.screwdriverIdentity(SCREWDRIVER_ID)
.data(createApplicationSubmissionData(packageWithService)),
@@ -1127,12 +1129,13 @@ public class ApplicationApiTest extends ControllerContainerTest {
public void deployment_fails_on_illegal_domain_in_deployment_spec() {
ApplicationPackage applicationPackage = new ApplicationPackageBuilder()
.upgradePolicy("default")
- .athenzIdentity(com.yahoo.config.provision.AthenzDomain.from("invalid.domain"), com.yahoo.config.provision.AthenzService.from("service"))
+ .athenzIdentity(com.yahoo.config.provision.AthenzDomain.from("another.domain"), com.yahoo.config.provision.AthenzService.from("service"))
.environment(Environment.prod)
.region("us-west-1")
.build();
long screwdriverProjectId = 123;
createAthenzDomainWithAdmin(ATHENZ_TENANT_DOMAIN, USER_ID);
+ configureAthenzIdentity(new com.yahoo.vespa.athenz.api.AthenzService(new AthenzDomain("another.domain"), "service"), true);
Application application = controllerTester.createApplication(ATHENZ_TENANT_DOMAIN.getName(), "tenant1", "application1", "default");
ScrewdriverId screwdriverId = new ScrewdriverId(Long.toString(screwdriverProjectId));
@@ -1147,7 +1150,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/test/region/us-east-1/instance/default/", POST)
.data(createApplicationDeployData(applicationPackage, false))
.screwdriverIdentity(screwdriverId),
- "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Athenz domain in deployment.xml: [invalid.domain] must match tenant domain: [domain1]\"}",
+ "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Athenz domain in deployment.xml: [another.domain] must match tenant domain: [domain1]\"}",
400);
}
@@ -1164,6 +1167,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
ScrewdriverId screwdriverId = new ScrewdriverId(Long.toString(screwdriverProjectId));
createAthenzDomainWithAdmin(ATHENZ_TENANT_DOMAIN, USER_ID);
+ configureAthenzIdentity(new com.yahoo.vespa.athenz.api.AthenzService(ATHENZ_TENANT_DOMAIN, "service"), true);
Application application = controllerTester.createApplication(ATHENZ_TENANT_DOMAIN.getName(), "tenant1", "application1", "default");
controllerTester.authorize(ATHENZ_TENANT_DOMAIN, screwdriverId, ApplicationAction.deploy, application);
@@ -1188,6 +1192,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
UserId tenantAdmin = new UserId("tenant-admin");
UserId userId = new UserId("new-user");
createAthenzDomainWithAdmin(ATHENZ_TENANT_DOMAIN, tenantAdmin);
+ configureAthenzIdentity(new com.yahoo.vespa.athenz.api.AthenzService(ATHENZ_TENANT_DOMAIN, "service"), true);
// Create tenant
// PUT (create) the authenticated user
@@ -1222,6 +1227,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
tester.computeVersionStatus();
UserId tenantAdmin = new UserId("new_user");
createAthenzDomainWithAdmin(ATHENZ_TENANT_DOMAIN, tenantAdmin);
+ configureAthenzIdentity(new com.yahoo.vespa.athenz.api.AthenzService(ATHENZ_TENANT_DOMAIN, "service"), true);
// Create tenant
// PUT (create) the authenticated user
@@ -1247,6 +1253,39 @@ public class ApplicationApiTest extends ControllerContainerTest {
}
@Test
+ public void deployment_fails_when_athenz_service_cannot_be_launched() {
+ ApplicationPackage applicationPackage = new ApplicationPackageBuilder()
+ .upgradePolicy("default")
+ .athenzIdentity(com.yahoo.config.provision.AthenzDomain.from("domain1"), com.yahoo.config.provision.AthenzService.from("service"))
+ .environment(Environment.prod)
+ .region("us-west-1")
+ .build();
+ long screwdriverProjectId = 123;
+ ScrewdriverId screwdriverId = new ScrewdriverId(Long.toString(screwdriverProjectId));
+
+ createAthenzDomainWithAdmin(ATHENZ_TENANT_DOMAIN, USER_ID);
+ configureAthenzIdentity(new com.yahoo.vespa.athenz.api.AthenzService(ATHENZ_TENANT_DOMAIN, "service"), false);
+
+ Application application = controllerTester.createApplication(ATHENZ_TENANT_DOMAIN.getName(), "tenant1", "application1", "default");
+ controllerTester.authorize(ATHENZ_TENANT_DOMAIN, screwdriverId, ApplicationAction.deploy, application);
+
+ // Allow systemtest to succeed by notifying completion of system test
+ controllerTester.jobCompletion(JobType.component)
+ .application(application.id())
+ .projectId(screwdriverProjectId)
+ .uploadArtifact(applicationPackage)
+ .submit();
+
+ String expectedResult="{\"error-code\":\"BAD_REQUEST\",\"message\":\"Not allowed to launch Athenz service domain1.service\"}";
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/test/region/us-east-1/instance/default/", POST)
+ .data(createApplicationDeployData(applicationPackage, false))
+ .screwdriverIdentity(screwdriverId),
+ expectedResult,
+ 400);
+
+ }
+
+ @Test
public void redeployment_succeeds_when_not_specifying_versions_or_application_package() {
// Setup
addUserToHostedOperatorRole(HostedAthenzIdentities.from(HOSTED_VESPA_OPERATOR));
@@ -1262,6 +1301,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
ScrewdriverId screwdriverId = new ScrewdriverId(Long.toString(screwdriverProjectId));
createAthenzDomainWithAdmin(ATHENZ_TENANT_DOMAIN, USER_ID);
+ configureAthenzIdentity(new com.yahoo.vespa.athenz.api.AthenzService(ATHENZ_TENANT_DOMAIN, "service"), true);
Application application = controllerTester.createApplication(ATHENZ_TENANT_DOMAIN.getName(), "tenant1", "application1", "default");
controllerTester.authorize(ATHENZ_TENANT_DOMAIN, screwdriverId, ApplicationAction.deploy, application);
@@ -1476,13 +1516,23 @@ public class ApplicationApiTest extends ControllerContainerTest {
private void createAthenzDomainWithAdmin(AthenzDomain domain, UserId userId) {
AthenzClientFactoryMock mock = (AthenzClientFactoryMock) container.components()
.getComponent(AthenzClientFactoryMock.class.getName());
- AthenzDbMock.Domain domainMock = new AthenzDbMock.Domain(domain);
+ AthenzDbMock.Domain domainMock = mock.getSetup().getOrCreateDomain(domain);
domainMock.markAsVespaTenant();
domainMock.admin(AthenzUser.fromUserId(userId.id()));
- mock.getSetup().addDomain(domainMock);
}
/**
+ * Mock athenz service identity configuration. Simulates that configserver is allowed to launch a service
+ */
+ private void configureAthenzIdentity(com.yahoo.vespa.athenz.api.AthenzService service, boolean allowLaunch) {
+ AthenzClientFactoryMock mock = (AthenzClientFactoryMock) container.components()
+ .getComponent(AthenzClientFactoryMock.class.getName());
+ AthenzDbMock.Domain domainMock = mock.getSetup().domains.computeIfAbsent(service.getDomain(), AthenzDbMock.Domain::new);
+ domainMock.services.put(service.getName(), new AthenzDbMock.Service(allowLaunch));
+ }
+
+
+ /**
* In production this happens outside hosted Vespa, so there is no API for it and we need to reach down into the
* mock setup to replicate the action.
*/