From 0b2952a11d18168c33b18e862aa24157f3bf06f7 Mon Sep 17 00:00:00 2001 From: Laird Nelson Date: Wed, 13 Sep 2023 11:03:44 -0700 Subject: [PATCH] Introduces OciSecretsMpMetaConfigProvider, which adapts OciSecretsConfigSourceProvider to the MpMetaConfigProvider contract (#7555) Signed-off-by: Laird Nelson --- bom/pom.xml | 2 +- .../oci/oci-secrets-mp-config-source/pom.xml | 106 ++++++++++++++++++ .../OciSecretsMpMetaConfigProvider.java | 96 ++++++++++++++++ .../secrets/mp/configsource/package-info.java | 26 +++++ .../src/main/java/module-info.java | 39 +++++++ .../src/test/java/UsageTest.java | 79 +++++++++++++ .../src/test/java/logging.properties | 19 ++++ .../src/test/resources/mp-meta-config.yaml | 27 +++++ integrations/oci/pom.xml | 1 + 9 files changed, 394 insertions(+), 1 deletion(-) create mode 100644 integrations/oci/oci-secrets-mp-config-source/pom.xml create mode 100644 integrations/oci/oci-secrets-mp-config-source/src/main/java/io/helidon/integrations/oci/secrets/mp/configsource/OciSecretsMpMetaConfigProvider.java create mode 100644 integrations/oci/oci-secrets-mp-config-source/src/main/java/io/helidon/integrations/oci/secrets/mp/configsource/package-info.java create mode 100644 integrations/oci/oci-secrets-mp-config-source/src/main/java/module-info.java create mode 100644 integrations/oci/oci-secrets-mp-config-source/src/test/java/io/helidon/integrations/oci/oci-secrets-mp-config-source/src/test/java/UsageTest.java create mode 100644 integrations/oci/oci-secrets-mp-config-source/src/test/java/logging.properties create mode 100644 integrations/oci/oci-secrets-mp-config-source/src/test/resources/mp-meta-config.yaml diff --git a/bom/pom.xml b/bom/pom.xml index afa910711cb..a5a577f5494 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -914,7 +914,7 @@ io.helidon.integrations.oci - helidon-integrations-oci-secrets-configsource + helidon-integrations-oci-secrets-config-source ${helidon.version} diff --git a/integrations/oci/oci-secrets-mp-config-source/pom.xml b/integrations/oci/oci-secrets-mp-config-source/pom.xml new file mode 100644 index 00000000000..e81dfa09be9 --- /dev/null +++ b/integrations/oci/oci-secrets-mp-config-source/pom.xml @@ -0,0 +1,106 @@ + + + + 4.0.0 + + io.helidon.integrations.oci + helidon-integrations-oci-project + 3.2.3-SNAPSHOT + + helidon-integrations-oci-secrets-mp-config-source + Helidon Integrations OCI Secrets MP Config Source + + + OCI Secrets Retrieval API MPMetaConfigProvider Implementation + + + + + src/test/java/logging.properties + false + + + + + + + + + io.helidon.config + helidon-config + + + io.helidon.config + helidon-config-mp + + + io.helidon.integrations.oci + helidon-integrations-oci-secrets-config-source + + + org.eclipse.microprofile.config + microprofile-config-api + + + + + + org.hamcrest + hamcrest-core + test + + + org.junit.jupiter + junit-jupiter-api + test + + + org.slf4j + slf4j-jdk14 + test + + + + + + + + src/test/resources + true + + mp-meta-config.yaml + + + + + + maven-surefire-plugin + + + ${compartment-ocid} + ${java.util.logging.config.file} + ${lazy} + ${vault-ocid} + + + + + + + diff --git a/integrations/oci/oci-secrets-mp-config-source/src/main/java/io/helidon/integrations/oci/secrets/mp/configsource/OciSecretsMpMetaConfigProvider.java b/integrations/oci/oci-secrets-mp-config-source/src/main/java/io/helidon/integrations/oci/secrets/mp/configsource/OciSecretsMpMetaConfigProvider.java new file mode 100644 index 00000000000..c05707a23f0 --- /dev/null +++ b/integrations/oci/oci-secrets-mp-config-source/src/main/java/io/helidon/integrations/oci/secrets/mp/configsource/OciSecretsMpMetaConfigProvider.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.helidon.integrations.oci.secrets.mp.configsource; + +import java.util.List; +import java.util.Set; + +import io.helidon.config.Config; +import io.helidon.config.mp.MpConfigSources; +import io.helidon.config.mp.spi.MpMetaConfigProvider; +import io.helidon.integrations.oci.secrets.configsource.OciSecretsConfigSourceProvider; + +import org.eclipse.microprofile.config.spi.ConfigSource; + +/** + * An {@link MpMetaConfigProvider} that uses the Oracle Cloud Infrastructure (OCI) Secrets + * Retrieval and Vault APIs + * to provide a {@link ConfigSource} implementation. + * + *

This class adapts the Helidon {@link io.helidon.config.spi.ConfigSource} created by the {@link + * OciSecretsConfigSourceProvider} to the MicroProfile Config contracts. + * + * @see #create(String, Config, String) + * + * @see OciSecretsConfigSourceProvider + */ +public final class OciSecretsMpMetaConfigProvider implements MpMetaConfigProvider { + + private final OciSecretsConfigSourceProvider p; + + /** + * Creates a new {@link OciSecretsMpMetaConfigProvider}. + * + * @deprecated For use by the Helidon Config subsystem only. + */ + @Deprecated // For java.util.ServiceLoader use only. + @SuppressWarnings("deprecation") + public OciSecretsMpMetaConfigProvider() { + super(); + this.p = new OciSecretsConfigSourceProvider(); + } + + /** + * Returns an immutable {@link List} whose sole element is a {@link ConfigSource} implementation backed by the Oracle Cloud Infrastructure (OCI) Secrets + * Retrieval and Vault APIs. + * + * @param type ignored + * + * @param metaConfig a Helidon {@link Config} representing meta-configuration + * + * @param profile a configuration profile; not currently used + * + * @return a single-element immutable {@link List} + */ + @Override + @SuppressWarnings("deprecation") + public List create(String type, Config metaConfig, String profile) { + return List.of(MpConfigSources.create(Config.builder() + .disableEnvironmentVariablesSource() + .disableFilterServices() + .disableMapperServices() + .disableParserServices() + .disableSystemPropertiesSource() + .addSource(this.p.create(type, metaConfig)) + .build())); + } + + /** + * Returns the return value of an invocation of {@link OciSecretsConfigSourceProvider#supported()}. + * + * @return an immutable {@link Set} + */ + @Override + @SuppressWarnings("deprecation") + public Set supportedTypes() { + return this.p.supported(); + } + +} diff --git a/integrations/oci/oci-secrets-mp-config-source/src/main/java/io/helidon/integrations/oci/secrets/mp/configsource/package-info.java b/integrations/oci/oci-secrets-mp-config-source/src/main/java/io/helidon/integrations/oci/secrets/mp/configsource/package-info.java new file mode 100644 index 00000000000..23d08c1da50 --- /dev/null +++ b/integrations/oci/oci-secrets-mp-config-source/src/main/java/io/helidon/integrations/oci/secrets/mp/configsource/package-info.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Provides classes and interfaces for using the Oracle Cloud Infrastructure (OCI) Secrets + * Retrieval and Vault APIs + * as part of a {@linkplain io.helidon.config.mp.spi.MpMetaConfigProvider} implementation. + * + * @see io.helidon.integrations.oci.secrets.mp.configsource.OciSecretsMpMetaConfigProvider + */ +package io.helidon.integrations.oci.secrets.mp.configsource; diff --git a/integrations/oci/oci-secrets-mp-config-source/src/main/java/module-info.java b/integrations/oci/oci-secrets-mp-config-source/src/main/java/module-info.java new file mode 100644 index 00000000000..d977751318b --- /dev/null +++ b/integrations/oci/oci-secrets-mp-config-source/src/main/java/module-info.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Provides packages containing classes and interfaces for Oracle Cloud Infrastructure (OCI) Secrets + * Retrieval and Vault + * API-using {@linkplain org.eclipse.microprofile.config.spi.ConfigSource configuration sources}. + * + * @see io.helidon.integrations.oci.secrets.mp.configsource.OciSecretsMpMetaConfigProvider + */ +@SuppressWarnings({ "requires-automatic", "requires-transitive-automatic" }) +module io.helidon.integrations.oci.secrets.mp.configsource { + + exports io.helidon.integrations.oci.secrets.mp.configsource; + + requires transitive io.helidon.config; + requires transitive io.helidon.config.mp; + requires io.helidon.integrations.oci.secrets.configsource; + requires microprofile.config.api; + + provides io.helidon.config.mp.spi.MpMetaConfigProvider with io.helidon.integrations.oci.secrets.mp.configsource.OciSecretsMpMetaConfigProvider; + +} + diff --git a/integrations/oci/oci-secrets-mp-config-source/src/test/java/io/helidon/integrations/oci/oci-secrets-mp-config-source/src/test/java/UsageTest.java b/integrations/oci/oci-secrets-mp-config-source/src/test/java/io/helidon/integrations/oci/oci-secrets-mp-config-source/src/test/java/UsageTest.java new file mode 100644 index 00000000000..2d8363ed652 --- /dev/null +++ b/integrations/oci/oci-secrets-mp-config-source/src/test/java/io/helidon/integrations/oci/oci-secrets-mp-config-source/src/test/java/UsageTest.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.helidon.integrations.oci.secrets.mp.configsource; + +import java.nio.file.Files; +import java.nio.file.Paths; + +import org.eclipse.microprofile.config.Config; +import org.eclipse.microprofile.config.ConfigProvider; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assumptions.assumeFalse; +import static org.junit.jupiter.api.Assumptions.assumeTrue; + +class UsageTest { + + @Test + void testUsage() { + // Get a Config object. Because src/test/resources/mp-meta-config.yaml exists, and because it will be processed + // according to the Helidon rules, an + // io.helidon.integrations.oci.secrets.mp.configsource.OciSecretsMpMetaConfigProvider will be created and any + // ConfigSources it creates will become part of the assembled Config object. + Config c = ConfigProvider.getConfig(); + + // Make sure non-existent properties don't cause the Vault to get involved. + assertThat(c.getOptionalValue("bogus", String.class).orElse(null), nullValue()); + + // Make sure properties that have nothing to do with the OCI Secrets Retrieval or Vault APIs are handled by some + // other (default) ConfigSource, e.g., System properties, etc. (The OCI Secrets Retrieval API should never be + // consulted for java.home, in other words.) + assertThat(c.getValue("java.home", String.class), is(System.getProperty("java.home"))); + + // Do the rest of this test only if the following assumptions hold. To avoid skipping the rest of this test: + // + // 1. Set up a ${HOME}/.oci/config file following + // https://docs.oracle.com/en-us/iaas/Content/API/Concepts/sdkconfig.htm or similar + // + // 2. Run Maven with all of the following properties: + // + // -Dcompartment-ocid=ocid1.compartment.oci1.iad.123xyz (a valid OCI Compartment OCID) + // -Dvault-ocid=ocid1.vault.oci1.iad.123xyz (a valid OCI Vault OCID) + // -DFrancqueSecret.expectedValue='Some Value' (some value for a secret named FrancqueSecret in that vault) + // + assumeTrue(Files.exists(Paths.get(System.getProperty("user.home"), ".oci", "config"))); // condition 1 + assumeFalse(System.getProperty("compartment-ocid", "").isBlank()); // condition 2 + assumeFalse(System.getProperty("vault-ocid", "").isBlank()); // condition 2 + String expectedValue = System.getProperty("FrancqueSecret.expectedValue", ""); + assumeFalse(expectedValue.isBlank()); // condition 2 + + // + // (Code below this line executes only if the above JUnit assumptions passed. Otherwise control flow stops above.) + // + + // For this test to pass, all of the following must hold: + // + // 1. The vault designated by the vault OCID must hold a secret named FrancqueSecret + // + // 2. The secret named FrancqueSecret must have a value equal to the expected value + assertThat(c.getValue("FrancqueSecret", String.class), is(expectedValue)); + } + +} diff --git a/integrations/oci/oci-secrets-mp-config-source/src/test/java/logging.properties b/integrations/oci/oci-secrets-mp-config-source/src/test/java/logging.properties new file mode 100644 index 00000000000..9587ed14579 --- /dev/null +++ b/integrations/oci/oci-secrets-mp-config-source/src/test/java/logging.properties @@ -0,0 +1,19 @@ +# +# Copyright (c) 2023 Oracle and/or its affiliates. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +com.oracle.bmc.level = SEVERE +handlers = java.util.logging.ConsoleHandler +io.helidon.integrations.oci.secrets.mp.configsource.level = INFO +java.util.logging.ConsoleHandler.level = FINER diff --git a/integrations/oci/oci-secrets-mp-config-source/src/test/resources/mp-meta-config.yaml b/integrations/oci/oci-secrets-mp-config-source/src/test/resources/mp-meta-config.yaml new file mode 100644 index 00000000000..9fa225b8c36 --- /dev/null +++ b/integrations/oci/oci-secrets-mp-config-source/src/test/resources/mp-meta-config.yaml @@ -0,0 +1,27 @@ +# +# Copyright (c) 2023 Oracle and/or its affiliates. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +add-default-sources: false +add-discovered-converters: false +add-discovered-sources: true + +sources: + - type: 'environment-variables' + - type: 'system-properties' + - type: 'oci-secrets' + accept-pattern: '^FrancqueSecret$' + compartment-ocid: '${compartment-ocid}' + lazy: ${lazy} + vault-ocid: '${vault-ocid}' diff --git a/integrations/oci/pom.xml b/integrations/oci/pom.xml index d861f2864b3..50f9707d705 100644 --- a/integrations/oci/pom.xml +++ b/integrations/oci/pom.xml @@ -35,6 +35,7 @@ metrics oci-secrets-config-source + oci-secrets-mp-config-source sdk