diff options
8 files changed, 121 insertions, 10 deletions
diff --git a/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java b/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java index c1d45c213fb..306f36e7674 100644 --- a/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java +++ b/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java @@ -8,6 +8,7 @@ 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.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.ClusterSpec; @@ -58,6 +59,7 @@ public class TestProperties implements ModelContext.Properties, ModelContext.Fea private int clusterControllerMaxHeapSizeInMb = 256; private int metricsProxyMaxHeapSizeInMb = 256; private int maxActivationInhibitedOutOfSyncGroups = 0; + private List<TenantSecretStore> tenantSecretStores = Collections.emptyList(); @Override public ModelContext.FeatureFlags featureFlags() { return this; } @Override public boolean multitenant() { return multitenant; } @@ -97,6 +99,7 @@ public class TestProperties implements ModelContext.Properties, ModelContext.Fea @Override public int clusterControllerMaxHeapSizeInMb() { return clusterControllerMaxHeapSizeInMb; } @Override public int metricsProxyMaxHeapSizeInMb(ClusterSpec.Type type) { return metricsProxyMaxHeapSizeInMb; } @Override public int maxActivationInhibitedOutOfSyncGroups() { return maxActivationInhibitedOutOfSyncGroups; } + @Override public List<TenantSecretStore> tenantSecretStores() { return tenantSecretStores; } public TestProperties setFeedConcurrency(double feedConcurrency) { this.feedConcurrency = feedConcurrency; @@ -233,6 +236,11 @@ public class TestProperties implements ModelContext.Properties, ModelContext.Fea return this; } + public TestProperties setTenantSecretStores(List<TenantSecretStore> secretStores) { + this.tenantSecretStores = List.copyOf(secretStores); + return this; + } + public static class Spec implements ConfigServerSpec { private final String hostName; diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/CloudSecretStore.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/CloudSecretStore.java index 39f9a627e0c..bf6a0275a94 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/CloudSecretStore.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/CloudSecretStore.java @@ -33,9 +33,9 @@ public class CloudSecretStore extends SimpleComponent implements SecretStoreConf @Override public void getConfig(SecretStoreConfig.Builder builder) { - builder.groups( + builder.awsParameterStores( configList.stream() - .map(config -> new SecretStoreConfig.Groups.Builder() + .map(config -> new SecretStoreConfig.AwsParameterStores.Builder() .name(config.name) .region(config.region) .awsId(config.awsId) diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java index 21aad7a565c..7b3bc498164 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java @@ -281,7 +281,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { store -> store )); - for (Element group : XML.getChildren(secretStoreElement, "group")) { + for (Element group : XML.getChildren(secretStoreElement, "aws-parameter-store")) { String name = group.getAttribute("name"); String region = group.getAttribute("region"); TenantSecretStore secretStore = secretStoresByName.get(name); diff --git a/config-model/src/main/resources/schema/containercluster.rnc b/config-model/src/main/resources/schema/containercluster.rnc index abe7386fa00..9313d91ea55 100644 --- a/config-model/src/main/resources/schema/containercluster.rnc +++ b/config-model/src/main/resources/schema/containercluster.rnc @@ -89,9 +89,12 @@ SecretStore = element secret-store { attribute type { string "oath-ckms" | string "cloud" } & element group { attribute name { string } & - (attribute environment { string "alpha" | string "corp" | string "prod" | string "aws" | string "aws_stage" } | - attribute region { string } ) - } + + attribute environment { string "alpha" | string "corp" | string "prod" | string "aws" | string "aws_stage" } + } * & + element aws-parameter-store { + attribute name { string } & + attribute region { string } + } * } ZooKeeper = element zookeeper { diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTest.java index 92e0b116878..e43b5085528 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTest.java @@ -7,6 +7,7 @@ import com.yahoo.config.application.api.ApplicationPackage; import com.yahoo.config.model.NullConfigModelRegistry; import com.yahoo.config.model.api.ContainerEndpoint; import com.yahoo.config.model.api.EndpointCertificateSecrets; +import com.yahoo.config.model.api.TenantSecretStore; import com.yahoo.config.model.builder.xml.test.DomBuilderTest; import com.yahoo.config.model.deploy.DeployState; import com.yahoo.config.model.deploy.TestProperties; @@ -15,6 +16,7 @@ import com.yahoo.config.model.provision.InMemoryProvisioner; import com.yahoo.config.model.provision.SingleNodeProvisioner; import com.yahoo.config.model.test.MockApplicationPackage; import com.yahoo.config.model.test.MockRoot; +import com.yahoo.config.provision.Cloud; import com.yahoo.config.provision.Environment; import com.yahoo.config.provision.Flavor; import com.yahoo.config.provision.RegionName; @@ -29,6 +31,7 @@ import com.yahoo.container.handler.VipStatusHandler; import com.yahoo.container.handler.metrics.MetricsV2Handler; import com.yahoo.container.handler.observability.ApplicationStatusHandler; import com.yahoo.container.jdisc.JdiscBindingsConfig; +import com.yahoo.container.jdisc.secretstore.SecretStoreConfig; import com.yahoo.container.servlet.ServletConfigConfig; import com.yahoo.container.usability.BindingsOverviewHandler; import com.yahoo.jdisc.http.ConnectorConfig; @@ -715,6 +718,54 @@ public class ContainerModelBuilderTest extends ContainerModelBuilderTestBase { } @Test + public void cloud_secret_store_requires_configured_secret_store() { + Element clusterElem = DomBuilderTest.parse( + "<container version='1.0'>", + " <secret-store type='cloud'>", + " <aws-parameter-store name='store1' region='eu-north-1'/>", + " </secret-store>", + "</container>"); + try { + createModel(root, clusterElem); + fail("secret store not defined"); + } catch (RuntimeException e) { + assertEquals("No configured secret store named store1", e.getMessage()); + } + } + + + @Test + public void cloud_secret_store_can_be_set_up() { + Element clusterElem = DomBuilderTest.parse( + "<container version='1.0'>", + " <secret-store type='cloud'>", + " <aws-parameter-store name='store1' region='eu-north-1'/>", + " </secret-store>", + "</container>"); + + DeployState state = new DeployState.Builder() + .properties( + new TestProperties() + .setHostedVespa(true) + .setTenantSecretStores(List.of(new TenantSecretStore("store1", "1234", "role", Optional.of("externalid"))))) + .zone(new Zone(SystemName.Public, Environment.prod, RegionName.defaultName())) + .build(); + createModel(root, state, null, clusterElem); + + ApplicationContainerCluster container = getContainerCluster("container"); + assertComponentConfigured(container, "com.yahoo.jdisc.cloud.aws.AwsParameterStore"); + CloudSecretStore secretStore = (CloudSecretStore) container.getComponentsMap().get(ComponentId.fromString("com.yahoo.jdisc.cloud.aws.AwsParameterStore")); + + + SecretStoreConfig.Builder configBuilder = new SecretStoreConfig.Builder(); + secretStore.getConfig(configBuilder); + SecretStoreConfig secretStoreConfig = configBuilder.build(); + + assertEquals(1, secretStoreConfig.awsParameterStores().size()); + assertEquals("store1", secretStoreConfig.awsParameterStores().get(0).name()); + } + + @Test public void missing_security_clients_pem_fails_in_public() { Element clusterElem = DomBuilderTest.parse("<container version='1.0' />"); diff --git a/container-disc/abi-spec.json b/container-disc/abi-spec.json index 63f6b241750..735211ff47c 100644 --- a/container-disc/abi-spec.json +++ b/container-disc/abi-spec.json @@ -60,6 +60,43 @@ ], "fields": [] }, + "com.yahoo.container.jdisc.secretstore.SecretStoreConfig$AwsParameterStores$Builder": { + "superClass": "java.lang.Object", + "interfaces": [ + "com.yahoo.config.ConfigBuilder" + ], + "attributes": [ + "public" + ], + "methods": [ + "public void <init>()", + "public void <init>(com.yahoo.container.jdisc.secretstore.SecretStoreConfig$AwsParameterStores)", + "public com.yahoo.container.jdisc.secretstore.SecretStoreConfig$AwsParameterStores$Builder name(java.lang.String)", + "public com.yahoo.container.jdisc.secretstore.SecretStoreConfig$AwsParameterStores$Builder region(java.lang.String)", + "public com.yahoo.container.jdisc.secretstore.SecretStoreConfig$AwsParameterStores$Builder awsId(java.lang.String)", + "public com.yahoo.container.jdisc.secretstore.SecretStoreConfig$AwsParameterStores$Builder role(java.lang.String)", + "public com.yahoo.container.jdisc.secretstore.SecretStoreConfig$AwsParameterStores$Builder externalId(java.lang.String)", + "public com.yahoo.container.jdisc.secretstore.SecretStoreConfig$AwsParameterStores build()" + ], + "fields": [] + }, + "com.yahoo.container.jdisc.secretstore.SecretStoreConfig$AwsParameterStores": { + "superClass": "com.yahoo.config.InnerNode", + "interfaces": [], + "attributes": [ + "public", + "final" + ], + "methods": [ + "public void <init>(com.yahoo.container.jdisc.secretstore.SecretStoreConfig$AwsParameterStores$Builder)", + "public java.lang.String name()", + "public java.lang.String region()", + "public java.lang.String awsId()", + "public java.lang.String role()", + "public java.lang.String externalId()" + ], + "fields": [] + }, "com.yahoo.container.jdisc.secretstore.SecretStoreConfig$Builder": { "superClass": "java.lang.Object", "interfaces": [ @@ -73,6 +110,8 @@ "public void <init>(com.yahoo.container.jdisc.secretstore.SecretStoreConfig)", "public com.yahoo.container.jdisc.secretstore.SecretStoreConfig$Builder groups(com.yahoo.container.jdisc.secretstore.SecretStoreConfig$Groups$Builder)", "public com.yahoo.container.jdisc.secretstore.SecretStoreConfig$Builder groups(java.util.List)", + "public com.yahoo.container.jdisc.secretstore.SecretStoreConfig$Builder awsParameterStores(com.yahoo.container.jdisc.secretstore.SecretStoreConfig$AwsParameterStores$Builder)", + "public com.yahoo.container.jdisc.secretstore.SecretStoreConfig$Builder awsParameterStores(java.util.List)", "public final boolean dispatchGetConfig(com.yahoo.config.ConfigInstance$Producer)", "public final java.lang.String getDefMd5()", "public final java.lang.String getDefName()", @@ -82,7 +121,8 @@ "public com.yahoo.container.jdisc.secretstore.SecretStoreConfig build()" ], "fields": [ - "public java.util.List groups" + "public java.util.List groups", + "public java.util.List awsParameterStores" ] }, "com.yahoo.container.jdisc.secretstore.SecretStoreConfig$Groups$Builder": { @@ -151,7 +191,9 @@ "public static java.lang.String getDefVersion()", "public void <init>(com.yahoo.container.jdisc.secretstore.SecretStoreConfig$Builder)", "public java.util.List groups()", - "public com.yahoo.container.jdisc.secretstore.SecretStoreConfig$Groups groups(int)" + "public com.yahoo.container.jdisc.secretstore.SecretStoreConfig$Groups groups(int)", + "public java.util.List awsParameterStores()", + "public com.yahoo.container.jdisc.secretstore.SecretStoreConfig$AwsParameterStores awsParameterStores(int)" ], "fields": [ "public static final java.lang.String CONFIG_DEF_MD5", diff --git a/container-disc/src/main/resources/configdefinitions/container.jdisc.secretstore.secret-store.def b/container-disc/src/main/resources/configdefinitions/container.jdisc.secretstore.secret-store.def index c3edc10c0bc..67ef4744da8 100644 --- a/container-disc/src/main/resources/configdefinitions/container.jdisc.secretstore.secret-store.def +++ b/container-disc/src/main/resources/configdefinitions/container.jdisc.secretstore.secret-store.def @@ -1,8 +1,15 @@ # Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. namespace=container.jdisc.secretstore +# remove groups after 7.376 is oldest model groups[].name string groups[].region string groups[].awsId string groups[].role string -groups[].externalId string
\ No newline at end of file +groups[].externalId string + +awsParameterStores[].name string +awsParameterStores[].region string +awsParameterStores[].awsId string +awsParameterStores[].role string +awsParameterStores[].externalId string diff --git a/jdisc-cloud-aws/src/main/java/com/yahoo/jdisc/cloud/aws/AwsParameterStore.java b/jdisc-cloud-aws/src/main/java/com/yahoo/jdisc/cloud/aws/AwsParameterStore.java index f2cac68c030..595bb4f6786 100644 --- a/jdisc-cloud-aws/src/main/java/com/yahoo/jdisc/cloud/aws/AwsParameterStore.java +++ b/jdisc-cloud-aws/src/main/java/com/yahoo/jdisc/cloud/aws/AwsParameterStore.java @@ -82,7 +82,7 @@ public class AwsParameterStore extends AbstractComponent implements SecretStore } private static List<AwsSettings> translateConfig(SecretStoreConfig secretStoreConfig) { - return secretStoreConfig.groups() + return secretStoreConfig.awsParameterStores() .stream() .map(config -> new AwsSettings(config.name(), config.role(), config.awsId(), config.externalId(), config.region())) .collect(Collectors.toList()); |