diff --git a/gravitee-apim-integration-tests/src/test/java/io/gravitee/apim/integration/tests/secrets/api/v4/KubernetesHttpProxyHeaderSecretTest.java b/gravitee-apim-integration-tests/src/test/java/io/gravitee/apim/integration/tests/secrets/api/v4/KubernetesHttpProxyHeaderSecretTest.java index 99b421c08e2..572f732c459 100644 --- a/gravitee-apim-integration-tests/src/test/java/io/gravitee/apim/integration/tests/secrets/api/v4/KubernetesHttpProxyHeaderSecretTest.java +++ b/gravitee-apim-integration-tests/src/test/java/io/gravitee/apim/integration/tests/secrets/api/v4/KubernetesHttpProxyHeaderSecretTest.java @@ -52,10 +52,9 @@ import java.util.Set; import java.util.UUID; import java.util.concurrent.TimeUnit; -import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.DisplayNameGeneration; import org.junit.jupiter.api.DisplayNameGenerator; -import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.testcontainers.k3s.K3sContainer; @@ -64,133 +63,107 @@ * @author GraviteeSource Team */ @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) -public class KubernetesHttpProxyHeaderSecretTest { +@GatewayTest +class KubernetesHttpProxyHeaderSecretTest extends AbstractGatewayTest { - abstract static class AbstractKubernetesApiTest extends AbstractGatewayTest { + static Path kubeConfigFile; + static K3sContainer k3sServer; + final String apiKey = UUID.randomUUID().toString(); - Path kubeConfigFile; - K3sContainer k3sServer; - - @AfterEach - void cleanup() throws IOException { - k3sServer.close(); - Files.delete(kubeConfigFile); - } - - @Override - public void configureGateway(GatewayConfigurationBuilder configurationBuilder) { - try { - kubeConfigFile = - Files.createTempDirectory(KubernetesHttpProxyHeaderSecretTest.class.getSimpleName()).resolve("kube_config.yml"); - configurationBuilder.setYamlProperty("api.secrets.providers[0].plugin", "kubernetes"); - configurationBuilder.setYamlProperty("api.secrets.providers[0].configuration.enabled", true); - configurationBuilder.setYamlProperty("api.secrets.providers[0].configuration.kubeConfigFile", kubeConfigFile.toString()); - - setupAdditionalProperties(configurationBuilder); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public void configureEntrypoints(Map> entrypoints) { - entrypoints.putIfAbsent("http-proxy", EntrypointBuilder.build("http-proxy", HttpProxyEntrypointConnectorFactory.class)); - } - - @Override - public void configureEndpoints(Map> endpoints) { - endpoints.putIfAbsent("http-proxy", EndpointBuilder.build("http-proxy", HttpProxyEndpointConnectorFactory.class)); - } - - @Override - public void configureSecretProviders( - Set, ? extends SecretManagerConfiguration>> secretProviderPlugins - ) throws Exception { - secretProviderPlugins.add( - SecretProviderBuilder.build(KubernetesSecretProvider.PLUGIN_ID, KubernetesSecretProviderFactory.class, K8sConfig.class) - ); - startK3s(); - createSecrets(); - } - - @Override - public void configureServices(Set>> services) { - super.configureServices(services); - services.add(SecretsService.class); - } - - abstract void createSecrets() throws IOException, InterruptedException; + @AfterAll + static void cleanup() throws IOException { + k3sServer.close(); + Files.delete(kubeConfigFile); + } - final void startK3s() throws IOException { + // not call by JUnit, as needs to be started before API is deployed + static void startK3s() throws IOException { + if (k3sServer == null) { k3sServer = KubernetesHelper.getK3sServer(); k3sServer.start(); // write config so the secret provider can pick it up Files.writeString(kubeConfigFile, k3sServer.getKubeConfigYaml()); } - - protected void setupAdditionalProperties(GatewayConfigurationBuilder configurationBuilder) { - // no op by default - } } - abstract static class AbstractApiKeyStaticSecretRefTest extends AbstractKubernetesApiTest { - - protected final String apiKey = UUID.randomUUID().toString(); + @Override + public void configureSecretProviders( + Set, ? extends SecretManagerConfiguration>> secretProviderPlugins + ) throws Exception { + secretProviderPlugins.add( + SecretProviderBuilder.build(KubernetesSecretProvider.PLUGIN_ID, KubernetesSecretProviderFactory.class, K8sConfig.class) + ); + startK3s(); + createSecrets(); + } - @Override - void createSecrets() throws IOException, InterruptedException { - KubernetesHelper.createSecret(k3sServer, "default", "test", Map.of("api-key", this.apiKey)); + @Override + public void configureGateway(GatewayConfigurationBuilder configurationBuilder) { + try { + kubeConfigFile = + Files.createTempDirectory(KubernetesHttpProxyHeaderSecretTest.class.getSimpleName()).resolve("kube_config.yml"); + configurationBuilder.setYamlProperty("api.secrets.providers[0].plugin", "kubernetes"); + configurationBuilder.setYamlProperty("api.secrets.providers[0].configuration.enabled", true); + configurationBuilder.setYamlProperty("api.secrets.providers[0].configuration.kubeConfigFile", kubeConfigFile.toString()); + } catch (IOException e) { + throw new RuntimeException(e); } + } - protected void callAndAssert(HttpClient httpClient) { - wiremock.stubFor(get("/endpoint").willReturn(ok("response from backend"))); - - httpClient - .rxRequest(HttpMethod.GET, "/test") - .flatMap(HttpClientRequest::rxSend) - .flatMap(response -> { - // just asserting we get a response (hence no SSL errors), no need for an API. - assertThat(response.statusCode()).isEqualTo(200); - return response.body(); - }) - .test() - .awaitDone(10, TimeUnit.SECONDS) - .assertComplete(); - - wiremock.verify(1, getRequestedFor(urlPathEqualTo("/endpoint")).withHeader("Authorization", equalTo("ApiKey ".concat(apiKey)))); - } + @Override + public void configureEntrypoints(Map> entrypoints) { + entrypoints.putIfAbsent("http-proxy", EntrypointBuilder.build("http-proxy", HttpProxyEntrypointConnectorFactory.class)); + } + + @Override + public void configureEndpoints(Map> endpoints) { + endpoints.putIfAbsent("http-proxy", EndpointBuilder.build("http-proxy", HttpProxyEndpointConnectorFactory.class)); } - @Nested - @GatewayTest - class StaticSecretRef extends AbstractApiKeyStaticSecretRefTest { + @Override + public void configureServices(Set>> services) { + super.configureServices(services); + services.add(SecretsService.class); + } - @Test - @DeployApi("/apis/v4/http/secrets/k8s/api-static-ref.json") - void should_call_api_with_k8s_api_key_from_static_ref(HttpClient httpClient) { - callAndAssert(httpClient); - } + // @Override + void createSecrets() throws IOException, InterruptedException { + KubernetesHelper.createSecret(k3sServer, "default", "test", Map.of("api-key", this.apiKey)); } - @Nested - @GatewayTest - class StaticSecretRefELKey extends AbstractApiKeyStaticSecretRefTest { + protected void callAndAssert(HttpClient httpClient) { + wiremock.stubFor(get("/endpoint").willReturn(ok("response from backend"))); + + httpClient + .rxRequest(HttpMethod.GET, "/test") + .flatMap(HttpClientRequest::rxSend) + .flatMap(response -> { + // just asserting we get a response (hence no SSL errors), no need for an API. + assertThat(response.statusCode()).isEqualTo(200); + return response.body(); + }) + .test() + .awaitDone(10, TimeUnit.SECONDS) + .assertComplete(); + + wiremock.verify(1, getRequestedFor(urlPathEqualTo("/endpoint")).withHeader("Authorization", equalTo("ApiKey ".concat(apiKey)))); + } - @Test - @DeployApi("/apis/v4/http/secrets/k8s/api-el-key-ref.json") - void should_call_api_with_k8s_api_key_from_static_ref_and_el_key(HttpClient httpClient) { - callAndAssert(httpClient); - } + @Test + @DeployApi("/apis/v4/http/secrets/k8s/api-static-ref.json") + void should_call_api_with_k8s_api_key_from_static_ref(HttpClient httpClient) { + callAndAssert(httpClient); } - @Nested - @GatewayTest - class StaticSecretRefELURI extends AbstractApiKeyStaticSecretRefTest { + @Test + @DeployApi("/apis/v4/http/secrets/k8s/api-el-key-ref.json") + void should_call_api_with_k8s_api_key_from_static_ref_and_el_key(HttpClient httpClient) { + callAndAssert(httpClient); + } - @Test - @DeployApi("/apis/v4/http/secrets/k8s/api-el-ref.json") - void should_call_api_with_k8s_api_key_el_ref(HttpClient httpClient) { - callAndAssert(httpClient); - } + @Test + @DeployApi("/apis/v4/http/secrets/k8s/api-el-ref.json") + void should_call_api_with_k8s_api_key_el_ref(HttpClient httpClient) { + callAndAssert(httpClient); } } diff --git a/gravitee-apim-integration-tests/src/test/java/io/gravitee/apim/integration/tests/secrets/conf/KubernetesSecretProviderIntegrationTest.java b/gravitee-apim-integration-tests/src/test/java/io/gravitee/apim/integration/tests/secrets/conf/KubernetesSecretProviderIntegrationTest.java index 3c3b9cd46d5..2c5dab82c5a 100644 --- a/gravitee-apim-integration-tests/src/test/java/io/gravitee/apim/integration/tests/secrets/conf/KubernetesSecretProviderIntegrationTest.java +++ b/gravitee-apim-integration-tests/src/test/java/io/gravitee/apim/integration/tests/secrets/conf/KubernetesSecretProviderIntegrationTest.java @@ -55,10 +55,9 @@ import java.time.Duration; import java.util.Map; import java.util.Set; -import java.util.UUID; import java.util.concurrent.TimeUnit; import javax.net.ssl.SSLHandshakeException; -import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.DisplayNameGeneration; import org.junit.jupiter.api.DisplayNameGenerator; @@ -131,61 +130,51 @@ class KubernetesSecretProviderIntegrationTest { -----END PRIVATE KEY----- """; - abstract static class AbstractKubernetesTest extends AbstractGatewayTest { + static Path kubeConfigFile; + static K3sContainer k3sServer; + + @BeforeAll + static void startK3s() throws IOException { + k3sServer = KubernetesHelper.getK3sServer(); + k3sServer.start(); + // write config so the secret provider can pick it up + kubeConfigFile = + Files.createTempDirectory(KubernetesSecretProviderIntegrationTest.class.getSimpleName()).resolve("kube_config.yml"); + Files.writeString(kubeConfigFile, k3sServer.getKubeConfigYaml()); + } - Path kubeConfigFile; - K3sContainer k3sServer; + @AfterAll + static void cleanup() throws IOException { + k3sServer.close(); + Files.delete(kubeConfigFile); + } - @AfterEach - void cleanup() throws IOException { - k3sServer.close(); - Files.delete(kubeConfigFile); - } + abstract static class AbstractKubernetesTest extends AbstractGatewayTest { @Override public void configureGateway(GatewayConfigurationBuilder configurationBuilder) { - try { - kubeConfigFile = - Files.createTempDirectory(KubernetesSecretProviderIntegrationTest.class.getSimpleName()).resolve("kube_config.yml"); - // this allows to test if the plugin can be configured with or the other method -D... or gravitee.yml - if (useSystemProperties()) { - configurationBuilder.setSystemProperty("secrets.kubernetes.enabled", true); - configurationBuilder.setSystemProperty("secrets.kubernetes.kubeConfigFile", kubeConfigFile.toString()); - } else { - configurationBuilder.setYamlProperty("secrets.kubernetes.enabled", true); - configurationBuilder.setYamlProperty("secrets.kubernetes.kubeConfigFile", kubeConfigFile.toString()); - } - setupAdditionalProperties(configurationBuilder); - } catch (IOException e) { - throw new RuntimeException(e); + // this allows to test if the plugin can be configured with or the other method -D... or gravitee.yml + if (useSystemProperties()) { + configurationBuilder.setSystemProperty("secrets.kubernetes.enabled", true); + configurationBuilder.setSystemProperty("secrets.kubernetes.kubeConfigFile", kubeConfigFile.toString()); + } else { + configurationBuilder.setYamlProperty("secrets.kubernetes.enabled", true); + configurationBuilder.setYamlProperty("secrets.kubernetes.kubeConfigFile", kubeConfigFile.toString()); } + setupAdditionalProperties(configurationBuilder); } @Override public void configureSecretProviders( Set, ? extends SecretManagerConfiguration>> secretProviderPlugins ) throws Exception { - addPlugin(secretProviderPlugins); - startK3s(); - createSecrets(); - } - - abstract void createSecrets() throws IOException, InterruptedException; - - void addPlugin( - Set, ? extends SecretManagerConfiguration>> secretProviderPlugins - ) { secretProviderPlugins.add( SecretProviderBuilder.build(KubernetesSecretProvider.PLUGIN_ID, KubernetesSecretProviderFactory.class, K8sConfig.class) ); + createSecrets(); } - final void startK3s() throws IOException { - k3sServer = KubernetesHelper.getK3sServer(); - k3sServer.start(); - // write config so the secret provider can pick it up - Files.writeString(kubeConfigFile, k3sServer.getKubeConfigYaml()); - } + abstract void createSecrets() throws IOException, InterruptedException; abstract void setupAdditionalProperties(GatewayConfigurationBuilder configurationBuilder); @@ -196,93 +185,89 @@ boolean useSystemProperties() { @Nested @GatewayTest - class DefaultNamespace extends AbstractKubernetesTest { - - String password1 = UUID.randomUUID().toString(); - String password2 = UUID.randomUUID().toString(); + class SimplePropertiesSystemProps extends AbstractKubernetesTest { @Override - public void setupAdditionalProperties(GatewayConfigurationBuilder configurationBuilder) { - configurationBuilder - .setYamlProperty("test", "secret://kubernetes/test:password") - .setYamlProperty("foo", "secret://kubernetes/foo:password"); + boolean useSystemProperties() { + return true; } @Override void createSecrets() throws IOException, InterruptedException { - KubernetesHelper.createSecret(k3sServer, "default", "test", Map.of("password", password1)); - KubernetesHelper.createSecret(k3sServer, "default", "foo", Map.of("password", password2)); + KubernetesHelper.createSecret(k3sServer, "default", "simple", Map.of("password", "simplepwd")); + } + + @Override + void setupAdditionalProperties(GatewayConfigurationBuilder configurationBuilder) { + // setting secret refs to yaml as it is not supported in system props + configurationBuilder.setYamlProperty("simple", "secret://kubernetes/simple:password"); } @Test - void should_be_able_to_resolve_secret() { + void should_be_able_to_resolve_secret_default_ns() { Environment environment = getBean(Environment.class); - assertThat(environment.getProperty("test")).isEqualTo(password1); - assertThat(environment.getProperty("foo")).isEqualTo(password2); + assertThat(environment.getProperty("simple")).isEqualTo("simplepwd"); } } @Nested @GatewayTest - class DefaultNamespaceUsingSystemProps extends AbstractKubernetesTest { - - String password1 = UUID.randomUUID().toString(); - String password2 = UUID.randomUUID().toString(); + class SimplePropertiesYaml extends AbstractKubernetesTest { @Override - boolean useSystemProperties() { - return true; + public void createSecrets() throws IOException, InterruptedException { + KubernetesHelper.createNamespace(k3sServer, "nondefaultns"); + KubernetesHelper.createSecret(k3sServer, "nondefaultns", "bar", Map.of("password", "nonDefaultNSBar")); + KubernetesHelper.createSecret(k3sServer, "default", "bar", Map.of("password", "bar")); + KubernetesHelper.createSecret(k3sServer, "default", "foo", Map.of("password", "foo")); + KubernetesHelper.createSecret(k3sServer, "default", "watched", Map.of("password", "watched")); } @Override void setupAdditionalProperties(GatewayConfigurationBuilder configurationBuilder) { // setting secret refs to yaml as it is not supported in system props configurationBuilder - .setYamlProperty("test", "secret://kubernetes/test:password") - .setYamlProperty("foo", "secret://kubernetes/foo:password"); + .setYamlProperty("barNonDefault", "secret://kubernetes/bar:password?namespace=nondefaultns") + .setYamlProperty("bar", "secret://kubernetes/bar:password") + .setYamlProperty("foo", "secret://kubernetes/foo:password") + .setYamlProperty("watched", "secret://kubernetes/watched:password?watch"); } - @Override - public void createSecrets() throws IOException, InterruptedException { - KubernetesHelper.createSecret(k3sServer, "default", "test", Map.of("password", password1)); - KubernetesHelper.createSecret(k3sServer, "default", "foo", Map.of("password", password2)); + // occurs after Gateway has started, otherwise it won't start + @BeforeAll + void setupBadSecrets() { + final GraviteeYamlPropertySource graviteeProperties = getGraviteeYamlProperties(); + if (graviteeProperties != null) { + graviteeProperties.getSource().put("missing", "secret://kubernetes/missing:pass"); + graviteeProperties.getSource().put("missing2", "secret://kubernetes/missing:pass?namespace=nondefaultns"); + graviteeProperties.getSource().put("no_plugin", "secret://foo/test:pass"); + } } @Test - void should_be_able_to_resolve_secret() { + void should_resolve_secrets() throws IOException, InterruptedException { Environment environment = getBean(Environment.class); - assertThat(environment.getProperty("test")).isEqualTo(password1); - assertThat(environment.getProperty("foo")).isEqualTo(password2); - } - } + assertThat(environment.getProperty("barNonDefault")).isEqualTo("nonDefaultNSBar"); + assertThat(environment.getProperty("bar")).isEqualTo("bar"); + assertThat(environment.getProperty("foo")).isEqualTo("foo"); + assertThat(environment.getProperty("watched")).isEqualTo("watched"); - @Nested - @GatewayTest - class NonDefaultNamespace extends AbstractKubernetesTest { - - String password1 = UUID.randomUUID().toString(); - String password2 = UUID.randomUUID().toString(); - - @Override - void setupAdditionalProperties(GatewayConfigurationBuilder configurationBuilder) { - configurationBuilder - .setYamlProperty("test", "secret://kubernetes/test:password?namespace=test") - .setYamlProperty("foo", "secret://kubernetes/foo:password"); - } - - @Override - public void createSecrets() throws IOException, InterruptedException { - KubernetesHelper.createNamespace(k3sServer, "test"); - KubernetesHelper.createSecret(k3sServer, "test", "test", Map.of("password", password1)); - // create one more to make sure we don't get the right one by chance - KubernetesHelper.createSecret(k3sServer, "default", "foo", Map.of("password", password2)); + KubernetesHelper.updateSecret(k3sServer, "default", "watched", Map.of("password", "okiamchanged"), false); + await() + .atMost(Duration.ofSeconds(2)) + .untilAsserted(() -> assertThat(environment.getProperty("watchIt")).isEqualTo("okiamchanged")); } @Test - void should_be_able_to_resolve_secret() { - Environment environment = getBean(Environment.class); - assertThat(environment.getProperty("test")).isEqualTo(password1); - assertThat(environment.getProperty("foo")).isEqualTo(password2); + void should_fail_resolve_secrets() { + final Environment environment = getBean(Environment.class); + assertThatCode(() -> environment.getProperty("missing")) + .isInstanceOf(SecretManagerException.class) + .hasMessageContaining("secret not found"); + assertThatCode(() -> environment.getProperty("missing2")) + .isInstanceOf(SecretManagerException.class) + .hasMessageContaining("secret not found"); + assertThat(environment.getProperty("no_plugin")).isEqualTo("secret://foo/test:pass"); // not recognized as a secret does not return value } } @@ -297,7 +282,7 @@ boolean useSystemProperties() { @Override void setupAdditionalProperties(GatewayConfigurationBuilder configurationBuilder) { - configurationBuilder.httpSecured(true).httpSslKeystoreType("pem").httpSslSecret("secret://kubernetes/tls-test"); + configurationBuilder.httpSecured(true).httpSslKeystoreType("pem").httpSslSecret("secret://kubernetes/tls-test-default"); } @Override @@ -307,7 +292,7 @@ protected void configureHttpClient(HttpClientOptions options) { @Override public void createSecrets() throws IOException, InterruptedException { - KubernetesHelper.createSecret(k3sServer, "default", "tls-test", Map.of("tls.crt", CERT, "tls.key", KEY), true); + KubernetesHelper.createSecret(k3sServer, "default", "tls-test-default", Map.of("tls.crt", CERT, "tls.key", KEY), true); } @Test @@ -341,7 +326,7 @@ void setupAdditionalProperties(GatewayConfigurationBuilder configurationBuilder) configurationBuilder .httpSecured(true) .httpSslKeystoreType("pem") - .httpSslSecret("secret://kubernetes/tls-test?resolveBeforeWatch=false"); + .httpSslSecret("secret://kubernetes/tls-test-late?resolveBeforeWatch=false"); } @Override @@ -351,7 +336,7 @@ protected void configureHttpClient(HttpClientOptions options) { @Override public void createSecrets() throws IOException, InterruptedException { - KubernetesHelper.createSecret(k3sServer, "default", "tls-test", Map.of("tls.crt", CERT, "tls.key", KEY), true); + KubernetesHelper.createSecret(k3sServer, "default", "tls-test-late", Map.of("tls.crt", CERT, "tls.key", KEY), true); } @Test @@ -380,7 +365,7 @@ class TLSWithCustomKeyMapAndNamespace extends AbstractKubernetesTest { void setupAdditionalProperties(GatewayConfigurationBuilder configurationBuilder) { configurationBuilder .httpSecured(true) - .httpSslSecret("secret://kubernetes/tls-test?namespace=test&keymap=certificate:cert&keymap=private_key:key") + .httpSslSecret("secret://kubernetes/tls-test-custom?namespace=test&keymap=certificate:cert&keymap=private_key:key") .httpSslKeystoreType("pem"); } @@ -392,7 +377,7 @@ protected void configureHttpClient(HttpClientOptions options) { @Override public void createSecrets() throws IOException, InterruptedException { KubernetesHelper.createNamespace(k3sServer, "test"); - KubernetesHelper.createSecret(k3sServer, "test", "tls-test", Map.of("cert", CERT, "key", KEY)); + KubernetesHelper.createSecret(k3sServer, "test", "tls-test-custom", Map.of("cert", CERT, "key", KEY)); } @Test @@ -411,31 +396,6 @@ void should_be_able_to_call_on_https(HttpClient httpClient) { } } - @Nested - @GatewayTest - class WatchProperty extends AbstractKubernetesTest { - - @Override - void setupAdditionalProperties(GatewayConfigurationBuilder configurationBuilder) { - configurationBuilder.setYamlProperty("test", "secret://kubernetes/test:password?watch"); - } - - @Override - void createSecrets() throws IOException, InterruptedException { - KubernetesHelper.createSecret(k3sServer, "default", "test", Map.of("password", "changeme")); - } - - @Test - void should_be_able_to_watch_secret() throws IOException, InterruptedException { - Environment environment = getBean(Environment.class); - assertThat(environment.getProperty("test")).isEqualTo("changeme"); - KubernetesHelper.updateSecret(k3sServer, "default", "test", Map.of("password", "okiamchanged"), false); - await() - .atMost(Duration.ofSeconds(2)) - .untilAsserted(() -> assertThat(environment.getProperty("test")).isEqualTo("okiamchanged")); - } - } - @Nested @GatewayTest class WatchCert extends AbstractKubernetesTest { @@ -573,41 +533,4 @@ void should_be_able_to_call_on_https_then_not(HttpClient httpClient) throws IOEx ); } } - - @Nested - @GatewayTest - class Errors extends AbstractKubernetesTest { - - @Override - void createSecrets() { - // no op - } - - @Override - public void setupAdditionalProperties(GatewayConfigurationBuilder configurationBuilder) { - // We can't add invalid secret here unless the gateway will fail to start. - } - - @BeforeAll - void setupAdditionalSecrets() { - final GraviteeYamlPropertySource graviteeProperties = getGraviteeYamlProperties(); - if (graviteeProperties != null) { - graviteeProperties.getSource().put("missing", "secret://kubernetes/test:pass"); - graviteeProperties.getSource().put("missing2", "secret://kubernetes/test:pass?namespace=test"); - graviteeProperties.getSource().put("no_plugin", "secret://foo/test:pass"); - } - } - - @Test - void should_fail_resolve_secret() { - final Environment environment = getBean(Environment.class); - assertThatCode(() -> environment.getProperty("missing")) - .isInstanceOf(SecretManagerException.class) - .hasMessageContaining("secret not found"); - assertThatCode(() -> environment.getProperty("missing2")) - .isInstanceOf(SecretManagerException.class) - .hasMessageContaining("secret not found"); - assertThat(environment.getProperty("no_plugin")).isEqualTo("secret://foo/test:pass"); // not recognized as a secret does not return value - } - } }