aboutsummaryrefslogtreecommitdiffstats
path: root/configserver
diff options
context:
space:
mode:
authorMorten Tokle <mortent@verizonmedia.com>2022-05-11 12:03:24 +0200
committerGitHub <noreply@github.com>2022-05-11 12:03:24 +0200
commit5da68e17038c1b9e2e78a0278a281630018bcb1f (patch)
treea020c370a396e2491f80fc2ff4be9317032f60cc /configserver
parentd2273e5d5f0f61ad5f85b261d68025f3a91a000e (diff)
parentab7156b0f092dc312304167904f3a0e8c1f8c172 (diff)
Merge pull request #22539 from vespa-engine/mpolden/deploy-cloud-account
Add cloud account to model
Diffstat (limited to 'configserver')
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java11
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ActivatedModelsBuilder.java4
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/session/PrepareParams.java50
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionPreparer.java12
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionZooKeeperClient.java18
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/tenant/CloudAccountSerializer.java29
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/ModelContextImplTest.java3
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/session/PrepareParamsTest.java9
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/session/SessionPreparerTest.java21
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/tenant/CloudAccountSerializerTest.java22
10 files changed, 149 insertions, 30 deletions
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java
index 249e5931f08..c357b598c2e 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java
@@ -19,6 +19,7 @@ import com.yahoo.config.model.api.Reindexing;
import com.yahoo.config.model.api.TenantSecretStore;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.AthenzDomain;
+import com.yahoo.config.provision.CloudAccount;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.DockerImage;
import com.yahoo.config.provision.TenantName;
@@ -364,6 +365,7 @@ public class ModelContextImpl implements ModelContext {
private final List<String> tlsCiphersOverride;
private final List<String> zoneDnsSuffixes;
private final List<String> environmentVariables;
+ private final Optional<CloudAccount> cloudAccount;
public Properties(ApplicationId applicationId,
Version nodeVespaVersion,
@@ -378,7 +380,8 @@ public class ModelContextImpl implements ModelContext {
Optional<Quota> maybeQuota,
List<TenantSecretStore> tenantSecretStores,
SecretStore secretStore,
- List<X509Certificate> operatorCertificates) {
+ List<X509Certificate> operatorCertificates,
+ Optional<CloudAccount> cloudAccount) {
this.featureFlags = new FeatureFlags(flagSource, applicationId, nodeVespaVersion);
this.applicationId = applicationId;
this.multitenant = configserverConfig.multitenant() || configserverConfig.hostedVespa() || Boolean.getBoolean("multitenant");
@@ -406,6 +409,7 @@ public class ModelContextImpl implements ModelContext {
this.zoneDnsSuffixes = configserverConfig.zoneDnsSuffixes();
this.environmentVariables = PermanentFlags.ENVIRONMENT_VARIABLES.bindTo(flagSource)
.with(FetchVector.Dimension.APPLICATION_ID, applicationId.serializedForm()).value();
+ this.cloudAccount = cloudAccount;
}
@Override public ModelContext.FeatureFlags featureFlags() { return featureFlags; }
@@ -490,6 +494,11 @@ public class ModelContextImpl implements ModelContext {
@Override
public List<String> environmentVariables() { return environmentVariables; }
+ @Override
+ public Optional<CloudAccount> cloudAccount() {
+ return cloudAccount;
+ }
+
}
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ActivatedModelsBuilder.java b/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ActivatedModelsBuilder.java
index b581688d571..468dda605c6 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ActivatedModelsBuilder.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ActivatedModelsBuilder.java
@@ -11,7 +11,6 @@ import com.yahoo.config.model.api.ModelContext;
import com.yahoo.config.model.api.ModelFactory;
import com.yahoo.config.model.api.Provisioned;
import com.yahoo.config.model.application.provider.MockFileRegistry;
-import com.yahoo.config.provision.AllocatedHosts;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.DockerImage;
import com.yahoo.config.provision.TenantName;
@@ -160,7 +159,8 @@ public class ActivatedModelsBuilder extends ModelsBuilder<Application> {
zkClient.readQuota(),
zkClient.readTenantSecretStores(),
secretStore,
- zkClient.readOperatorCertificates());
+ zkClient.readOperatorCertificates(),
+ zkClient.readCloudAccount());
}
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/session/PrepareParams.java b/configserver/src/main/java/com/yahoo/vespa/config/server/session/PrepareParams.java
index e75a01fb8dd..175b6f6457f 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/session/PrepareParams.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/session/PrepareParams.java
@@ -1,35 +1,31 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.config.server.session;
-import com.google.common.collect.ImmutableList;
import com.yahoo.component.Version;
-import com.yahoo.config.model.api.ApplicationRoles;
import com.yahoo.config.model.api.ContainerEndpoint;
import com.yahoo.config.model.api.EndpointCertificateMetadata;
import com.yahoo.config.model.api.Quota;
+import com.yahoo.config.model.api.TenantSecretStore;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.AthenzDomain;
+import com.yahoo.config.provision.CloudAccount;
import com.yahoo.config.provision.DockerImage;
import com.yahoo.config.provision.TenantName;
import com.yahoo.container.jdisc.HttpRequest;
import com.yahoo.security.X509CertificateUtils;
-import com.yahoo.slime.ArrayTraverser;
import com.yahoo.slime.Inspector;
import com.yahoo.slime.Slime;
import com.yahoo.slime.SlimeUtils;
import com.yahoo.vespa.config.server.TimeoutBudget;
-import com.yahoo.config.model.api.TenantSecretStore;
import com.yahoo.vespa.config.server.http.SessionHandler;
+import com.yahoo.vespa.config.server.tenant.CloudAccountSerializer;
import com.yahoo.vespa.config.server.tenant.ContainerEndpointSerializer;
import com.yahoo.vespa.config.server.tenant.EndpointCertificateMetadataSerializer;
import com.yahoo.vespa.config.server.tenant.TenantSecretStoreSerializer;
-import org.eclipse.jetty.util.ssl.X509;
import java.security.cert.X509Certificate;
import java.time.Clock;
import java.time.Duration;
-import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@@ -58,6 +54,7 @@ public final class PrepareParams {
static final String FORCE_PARAM_NAME = "force";
static final String WAIT_FOR_RESOURCES_IN_PREPARE = "waitForResourcesInPrepare";
static final String OPERATOR_CERTIFICATES = "operatorCertificates";
+ static final String CLOUD_ACCOUNT = "cloudAccount";
private final ApplicationId applicationId;
private final TimeoutBudget timeoutBudget;
@@ -75,6 +72,7 @@ public final class PrepareParams {
private final Optional<Quota> quota;
private final List<TenantSecretStore> tenantSecretStores;
private final List<X509Certificate> operatorCertificates;
+ private final Optional<CloudAccount> cloudAccount;
private PrepareParams(ApplicationId applicationId, TimeoutBudget timeoutBudget, boolean ignoreValidationErrors,
boolean dryRun, boolean verbose, boolean isBootstrap, Optional<Version> vespaVersion,
@@ -82,7 +80,8 @@ public final class PrepareParams {
Optional<EndpointCertificateMetadata> endpointCertificateMetadata,
Optional<DockerImage> dockerImageRepository, Optional<AthenzDomain> athenzDomain,
Optional<Quota> quota, List<TenantSecretStore> tenantSecretStores,
- boolean force, boolean waitForResourcesInPrepare, List<X509Certificate> operatorCertificates) {
+ boolean force, boolean waitForResourcesInPrepare, List<X509Certificate> operatorCertificates,
+ Optional<CloudAccount> cloudAccount) {
this.timeoutBudget = timeoutBudget;
this.applicationId = Objects.requireNonNull(applicationId);
this.ignoreValidationErrors = ignoreValidationErrors;
@@ -99,6 +98,7 @@ public final class PrepareParams {
this.force = force;
this.waitForResourcesInPrepare = waitForResourcesInPrepare;
this.operatorCertificates = operatorCertificates;
+ this.cloudAccount = Objects.requireNonNull(cloudAccount);
}
public static class Builder {
@@ -116,10 +116,10 @@ public final class PrepareParams {
private Optional<EndpointCertificateMetadata> endpointCertificateMetadata = Optional.empty();
private Optional<DockerImage> dockerImageRepository = Optional.empty();
private Optional<AthenzDomain> athenzDomain = Optional.empty();
- private Optional<ApplicationRoles> applicationRoles = Optional.empty();
private Optional<Quota> quota = Optional.empty();
private List<TenantSecretStore> tenantSecretStores = List.of();
private List<X509Certificate> operatorCertificates = List.of();
+ private Optional<CloudAccount> cloudAccount = Optional.empty();
public Builder() { }
@@ -213,11 +213,6 @@ public final class PrepareParams {
return this;
}
- public Builder applicationRoles(ApplicationRoles applicationRoles) {
- this.applicationRoles = Optional.ofNullable(applicationRoles);
- return this;
- }
-
public Builder quota(Quota quota) {
this.quota = Optional.ofNullable(quota);
return this;
@@ -252,18 +247,24 @@ public final class PrepareParams {
return this;
}
- public Builder withOperatorCertificates(List<X509Certificate> operatorCertificates) {
+ public Builder operatorCertificates(List<X509Certificate> operatorCertificates) {
this.operatorCertificates = List.copyOf(operatorCertificates);
return this;
}
+ public Builder cloudAccount(CloudAccount cloudAccount) {
+ this.cloudAccount = Optional.ofNullable(cloudAccount);
+ return this;
+ }
+
public PrepareParams build() {
return new PrepareParams(applicationId, timeoutBudget, ignoreValidationErrors, dryRun,
verbose, isBootstrap, vespaVersion, containerEndpoints,
endpointCertificateMetadata, dockerImageRepository, athenzDomain,
quota, tenantSecretStores, force, waitForResourcesInPrepare,
- operatorCertificates);
+ operatorCertificates, cloudAccount);
}
+
}
public static PrepareParams fromHttpRequest(HttpRequest request, TenantName tenant, Duration barrierTimeout) {
@@ -295,7 +296,7 @@ public final class PrepareParams {
.timeoutBudget(SessionHandler.getTimeoutBudget(getTimeout(params, barrierTimeout)))
.applicationId(createApplicationId(params, tenant))
.vespaVersion(SlimeUtils.optionalString(params.field(VESPA_VERSION_PARAM_NAME)).orElse(null))
- .containerEndpointList(deserialize(params.field(CONTAINER_ENDPOINTS_PARAM_NAME), ContainerEndpointSerializer::endpointListFromSlime, Collections.emptyList()))
+ .containerEndpointList(deserialize(params.field(CONTAINER_ENDPOINTS_PARAM_NAME), ContainerEndpointSerializer::endpointListFromSlime, List.of()))
.endpointCertificateMetadata(deserialize(params.field(ENDPOINT_CERTIFICATE_METADATA_PARAM_NAME), EndpointCertificateMetadataSerializer::fromSlime))
.dockerImageRepository(SlimeUtils.optionalString(params.field(DOCKER_IMAGE_REPOSITORY)).orElse(null))
.athenzDomain(SlimeUtils.optionalString(params.field(ATHENZ_DOMAIN)).orElse(null))
@@ -303,13 +304,15 @@ public final class PrepareParams {
.tenantSecretStores(deserialize(params.field(TENANT_SECRET_STORES_PARAM_NAME), TenantSecretStoreSerializer::listFromSlime, List.of()))
.force(booleanValue(params, FORCE_PARAM_NAME))
.waitForResourcesInPrepare(booleanValue(params, WAIT_FOR_RESOURCES_IN_PREPARE))
- .withOperatorCertificates(deserialize(params.field(OPERATOR_CERTIFICATES), PrepareParams::readOperatorCertificates, Collections.emptyList()))
+ .operatorCertificates(deserialize(params.field(OPERATOR_CERTIFICATES), PrepareParams::readOperatorCertificates, List.of()))
+ .cloudAccount(deserialize(params.field(CLOUD_ACCOUNT), CloudAccountSerializer::fromSlime, null))
.build();
}
private static <T> T deserialize(Inspector field, Function<Inspector, T> mapper) {
return deserialize(field, mapper, null);
}
+
private static <T> T deserialize(Inspector field, Function<Inspector, T> mapper, T defaultValue) {
return field.valid()
? mapper.apply(field)
@@ -318,13 +321,11 @@ public final class PrepareParams {
private static boolean booleanValue(Inspector inspector, String fieldName) {
Inspector field = inspector.field(fieldName);
- return field.valid()
- ? field.asBool()
- : false;
+ return field.valid() && field.asBool();
}
private static Duration getTimeout(Inspector params, Duration defaultTimeout) {
- if(params.field("timeout").valid()) {
+ if (params.field("timeout").valid()) {
return Duration.ofSeconds(params.field("timeout").asLong());
} else {
return defaultTimeout;
@@ -419,4 +420,9 @@ public final class PrepareParams {
public List<X509Certificate> operatorCertificates() {
return operatorCertificates;
}
+
+ public Optional<CloudAccount> cloudAccount() {
+ return cloudAccount;
+ }
+
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionPreparer.java b/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionPreparer.java
index 6019f3ff438..4c1da9dc3af 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionPreparer.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionPreparer.java
@@ -20,10 +20,10 @@ import com.yahoo.config.model.api.TenantSecretStore;
import com.yahoo.config.provision.AllocatedHosts;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.AthenzDomain;
+import com.yahoo.config.provision.CloudAccount;
import com.yahoo.config.provision.DockerImage;
import com.yahoo.config.provision.Zone;
import com.yahoo.container.jdisc.secretstore.SecretStore;
-import com.yahoo.lang.SettableOptional;
import com.yahoo.net.HostName;
import com.yahoo.path.Path;
import com.yahoo.vespa.config.server.TimeoutBudget;
@@ -204,7 +204,8 @@ public class SessionPreparer {
params.quota(),
params.tenantSecretStores(),
secretStore,
- params.operatorCertificates());
+ params.operatorCertificates(),
+ params.cloudAccount());
this.fileRegistry = fileDistributionFactory.createFileRegistry(serverDbSessionDir);
this.preparedModelsBuilder = new PreparedModelsBuilder(modelFactoryRegistry,
permanentApplicationPackage,
@@ -281,7 +282,8 @@ public class SessionPreparer {
athenzDomain,
params.quota(),
params.tenantSecretStores(),
- params.operatorCertificates());
+ params.operatorCertificates(),
+ params.cloudAccount());
checkTimeout("write state to zookeeper");
}
@@ -321,7 +323,8 @@ public class SessionPreparer {
Optional<AthenzDomain> athenzDomain,
Optional<Quota> quota,
List<TenantSecretStore> tenantSecretStores,
- List<X509Certificate> operatorCertificates) {
+ List<X509Certificate> operatorCertificates,
+ Optional<CloudAccount> cloudAccount) {
ZooKeeperDeployer zkDeployer = zooKeeperClient.createDeployer(deployLogger);
try {
zkDeployer.deploy(applicationPackage, fileRegistryMap, allocatedHosts);
@@ -334,6 +337,7 @@ public class SessionPreparer {
zooKeeperClient.writeQuota(quota);
zooKeeperClient.writeTenantSecretStores(tenantSecretStores);
zooKeeperClient.writeOperatorCertificates(operatorCertificates);
+ zooKeeperClient.writeCloudAccount(cloudAccount);
} catch (RuntimeException | IOException e) {
zkDeployer.cleanup();
throw new RuntimeException("Error preparing session", e);
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionZooKeeperClient.java b/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionZooKeeperClient.java
index 0b34bd95f8e..de8cbcb4066 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionZooKeeperClient.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionZooKeeperClient.java
@@ -12,6 +12,7 @@ import com.yahoo.config.model.api.TenantSecretStore;
import com.yahoo.config.provision.AllocatedHosts;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.AthenzDomain;
+import com.yahoo.config.provision.CloudAccount;
import com.yahoo.config.provision.DockerImage;
import com.yahoo.config.provision.TenantName;
import com.yahoo.path.Path;
@@ -23,6 +24,7 @@ import com.yahoo.vespa.config.server.deploy.ZooKeeperClient;
import com.yahoo.vespa.config.server.deploy.ZooKeeperDeployer;
import com.yahoo.vespa.config.server.filedistribution.AddFileInterface;
import com.yahoo.vespa.config.server.filedistribution.MockFileManager;
+import com.yahoo.vespa.config.server.tenant.CloudAccountSerializer;
import com.yahoo.vespa.config.server.tenant.OperatorCertificateSerializer;
import com.yahoo.vespa.config.server.tenant.TenantRepository;
import com.yahoo.vespa.config.server.tenant.TenantSecretStoreSerializer;
@@ -63,6 +65,7 @@ public class SessionZooKeeperClient {
private static final String QUOTA_PATH = "quota";
private static final String TENANT_SECRET_STORES_PATH = "tenantSecretStores";
private static final String OPERATOR_CERTIFICATES_PATH = "operatorCertificates";
+ private static final String CLOUD_ACCOUNT_PATH = "cloudAccount";
private final Curator curator;
private final TenantName tenantName;
@@ -208,6 +211,10 @@ public class SessionZooKeeperClient {
return sessionPath.append(OPERATOR_CERTIFICATES_PATH);
}
+ private Path cloudAccountPath() {
+ return sessionPath.append(CLOUD_ACCOUNT_PATH);
+ }
+
public void writeVespaVersion(Version version) {
curator.set(versionPath(), Utf8.toBytes(version.toString()));
}
@@ -309,6 +316,17 @@ public class SessionZooKeeperClient {
.orElse(List.of());
}
+ public void writeCloudAccount(Optional<CloudAccount> cloudAccount) {
+ if (cloudAccount.isPresent()) {
+ byte[] data = uncheck(() -> SlimeUtils.toJsonBytes(CloudAccountSerializer.toSlime(cloudAccount.get())));
+ curator.set(cloudAccountPath(), data);
+ }
+ }
+
+ public Optional<CloudAccount> readCloudAccount() {
+ return curator.getData(cloudAccountPath()).map(SlimeUtils::jsonToSlime).map(slime -> CloudAccountSerializer.fromSlime(slime.get()));
+ }
+
/**
* Create necessary paths atomically for a new session.
*
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/CloudAccountSerializer.java b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/CloudAccountSerializer.java
new file mode 100644
index 00000000000..2478cf6baeb
--- /dev/null
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/CloudAccountSerializer.java
@@ -0,0 +1,29 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.config.server.tenant;
+
+import com.yahoo.config.provision.CloudAccount;
+import com.yahoo.slime.Cursor;
+import com.yahoo.slime.Inspector;
+import com.yahoo.slime.Slime;
+
+/**
+ * @author mpolden
+ */
+public class CloudAccountSerializer {
+
+ private static final String ID_FIELD = "id";
+
+ private CloudAccountSerializer() {}
+
+ public static CloudAccount fromSlime(Inspector object) {
+ return new CloudAccount(object.field(ID_FIELD).asString());
+ }
+
+ public static Slime toSlime(CloudAccount account) {
+ Slime slime = new Slime();
+ Cursor root = slime.setObject();
+ root.setString(ID_FIELD, account.value());
+ return slime;
+ }
+
+}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/ModelContextImplTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/ModelContextImplTest.java
index 41e6fe98441..8848beb3821 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/ModelContextImplTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/ModelContextImplTest.java
@@ -75,7 +75,8 @@ public class ModelContextImplTest {
Optional.empty(),
List.of(),
new SecretStoreProvider().get(),
- List.of()),
+ List.of(),
+ Optional.empty()),
Optional.empty(),
Optional.empty(),
new Version(7),
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/session/PrepareParamsTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/session/PrepareParamsTest.java
index 46c31533598..e5b550fdc1a 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/session/PrepareParamsTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/session/PrepareParamsTest.java
@@ -6,6 +6,7 @@ import com.yahoo.config.model.api.ContainerEndpoint;
import com.yahoo.config.model.api.EndpointCertificateMetadata;
import com.yahoo.config.model.api.TenantSecretStore;
import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.CloudAccount;
import com.yahoo.config.provision.TenantName;
import com.yahoo.container.jdisc.HttpRequest;
@@ -67,6 +68,7 @@ public class PrepareParamsTest {
assertTrue(prepareParams.vespaVersion().isEmpty());
assertTrue(prepareParams.getTimeoutBudget().hasTimeLeft());
assertTrue(prepareParams.containerEndpoints().isEmpty());
+ assertTrue(prepareParams.cloudAccount().isEmpty());
}
@Test
@@ -190,6 +192,13 @@ public class PrepareParamsTest {
assertPrepareParamsEqual(prepareParams, prepareParamsJson);
}
+ @Test
+ public void testCloudAccount() {
+ String json = "{\"cloudAccount\": {\"id\": \"012345678912\"}}";
+ PrepareParams params = PrepareParams.fromJson(json.getBytes(StandardCharsets.UTF_8), TenantName.defaultName(), Duration.ZERO);
+ assertEquals(new CloudAccount("012345678912"), params.cloudAccount().get());
+ }
+
private void assertPrepareParamsEqual(PrepareParams urlParams, PrepareParams jsonParams) {
assertEquals(urlParams.ignoreValidationErrors(), jsonParams.ignoreValidationErrors());
assertEquals(urlParams.isDryRun(), jsonParams.isDryRun());
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/session/SessionPreparerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/session/SessionPreparerTest.java
index 72d7311ed9a..78548dea195 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/session/SessionPreparerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/session/SessionPreparerTest.java
@@ -9,11 +9,13 @@ import com.yahoo.config.application.api.FileRegistry;
import com.yahoo.config.model.api.ApplicationClusterEndpoint;
import com.yahoo.config.model.api.ContainerEndpoint;
import com.yahoo.config.model.api.EndpointCertificateSecrets;
+import com.yahoo.config.model.api.ModelContext;
import com.yahoo.config.model.application.provider.BaseDeployLogger;
import com.yahoo.config.model.application.provider.FilesApplicationPackage;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ApplicationName;
import com.yahoo.config.provision.CertificateNotReadyException;
+import com.yahoo.config.provision.CloudAccount;
import com.yahoo.config.provision.InstanceName;
import com.yahoo.config.provision.TenantName;
import com.yahoo.config.provision.Zone;
@@ -341,6 +343,25 @@ public class SessionPreparerTest {
prepare(new File("src/test/resources/deploy/hosted-app"), params);
}
+ @Test
+ public void require_that_cloud_account_is_written() throws Exception {
+ TestModelFactory modelFactory = new TestModelFactory(version123);
+ preparer = createPreparer(new ModelFactoryRegistry(List.of(modelFactory)), HostProvisionerProvider.empty());
+ ApplicationId applicationId = applicationId("test");
+ CloudAccount expected = new CloudAccount("012345678912");
+ PrepareParams params = new PrepareParams.Builder().applicationId(applicationId)
+ .cloudAccount(expected)
+ .build();
+ prepare(new File("src/test/resources/deploy/hosted-app"), params);
+
+ SessionZooKeeperClient zkClient = createSessionZooKeeperClient();
+ assertEquals(expected, zkClient.readCloudAccount().get());
+
+ ModelContext modelContext = modelFactory.getModelContext();
+ Optional<CloudAccount> accountFromModel = modelContext.properties().cloudAccount();
+ assertEquals(Optional.of(expected), accountFromModel);
+ }
+
private List<ContainerEndpoint> readContainerEndpoints(ApplicationId applicationId) {
Path tenantPath = TenantRepository.getTenantPath(applicationId.tenant());
return new ContainerEndpointsCache(tenantPath, curator).read(applicationId);
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/CloudAccountSerializerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/CloudAccountSerializerTest.java
new file mode 100644
index 00000000000..7989cdcf019
--- /dev/null
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/CloudAccountSerializerTest.java
@@ -0,0 +1,22 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.config.server.tenant;
+
+import com.yahoo.config.provision.CloudAccount;
+import org.junit.Test;
+
+import static com.yahoo.vespa.config.server.tenant.CloudAccountSerializer.fromSlime;
+import static com.yahoo.vespa.config.server.tenant.CloudAccountSerializer.toSlime;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author mpolden
+ */
+public class CloudAccountSerializerTest {
+
+ @Test
+ public void serialization() {
+ CloudAccount account = new CloudAccount("012345678912");
+ assertEquals(account, fromSlime(toSlime(account).get()));
+ }
+
+}