Merge remote-tracking branch 'origin/main' into simlify-encryption-config-for-aot
This commit is contained in:
@@ -1432,10 +1432,12 @@ NOTE: The `--key` argument is mandatory (despite having a `--` prefix).
|
||||
=== Key Management
|
||||
|
||||
The Config Server can use a symmetric (shared) key or an asymmetric one (RSA key pair).
|
||||
The asymmetric choice is superior in terms of security, but it is often more convenient to use a symmetric key since it is a single property value to configure in the `bootstrap.properties`.
|
||||
The asymmetric choice is superior in terms of security, but it is often more convenient to use a symmetric key since it is a single property value to configure in the `application.properties`.
|
||||
|
||||
To configure a symmetric key, you need to set `encrypt.key` to a secret String (or use the `ENCRYPT_KEY` environment variable to keep it out of plain-text configuration files).
|
||||
|
||||
NOTE: If you include `spring-cloud-starter-bootstrap` on the classpath or set `spring.cloud.bootstrap.enabled=true` as a system property, you will need to set `encrypt.key` in `bootstrap.properties`.
|
||||
|
||||
NOTE: You cannot configure an asymmetric key using `encrypt.key`.
|
||||
|
||||
To configure an asymmetric key use a keystore (e.g. as
|
||||
|
||||
20
pom.xml
20
pom.xml
@@ -30,10 +30,8 @@
|
||||
<spring-cloud-commons.version>4.0.0-SNAPSHOT</spring-cloud-commons.version>
|
||||
<aws-java-sdk.version>2.17.195</aws-java-sdk.version>
|
||||
<google-api-services-iam.version>v1-rev20201112-1.30.10</google-api-services-iam.version>
|
||||
<testcontainers.version>1.16.2</testcontainers.version>
|
||||
<testcontainers.version>1.17.3</testcontainers.version>
|
||||
<wiremock.version>2.31.0</wiremock.version>
|
||||
<micrometer.version>1.10.0-M3</micrometer.version>
|
||||
<micrometer-tracing.version>1.0.0-M6</micrometer-tracing.version>
|
||||
<maven-checkstyle-plugin.failsOnError>true</maven-checkstyle-plugin.failsOnError>
|
||||
<maven-checkstyle-plugin.failsOnViolation>true
|
||||
</maven-checkstyle-plugin.failsOnViolation>
|
||||
@@ -106,23 +104,9 @@
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-bom</artifactId>
|
||||
<version>${micrometer.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-tracing-bom</artifactId>
|
||||
<version>${micrometer-tracing.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.tomakehurst</groupId>
|
||||
<artifactId>wiremock-jre8</artifactId>
|
||||
<artifactId>wiremock-jre8-standalone</artifactId>
|
||||
<version>${wiremock.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
# Auto Configure
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
org.springframework.cloud.config.client.ConfigClientAutoConfiguration
|
||||
# Bootstrap components
|
||||
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
|
||||
org.springframework.cloud.config.client.ConfigServiceBootstrapConfiguration,\
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
org.springframework.cloud.config.client.ConfigClientAutoConfiguration
|
||||
@@ -108,22 +108,16 @@ public class PropertyPathEndpoint implements ApplicationEventPublisherAware {
|
||||
String stem = StringUtils.stripFilenameExtension(StringUtils.getFilename(StringUtils.cleanPath(path)));
|
||||
// TODO: correlate with service registry
|
||||
int index = stem.indexOf("-");
|
||||
while (index >= 0) {
|
||||
String name = stem.substring(0, index);
|
||||
String profile = stem.substring(index + 1);
|
||||
if ("application".equals(name)) {
|
||||
services.add("*:" + profile);
|
||||
}
|
||||
else if (!name.startsWith("application")) {
|
||||
services.add(name + ":" + profile);
|
||||
}
|
||||
index = stem.indexOf("-", index + 1);
|
||||
}
|
||||
String name = stem;
|
||||
if (index > 0) {
|
||||
name = stem.substring(0, index);
|
||||
}
|
||||
// foo.properties is targeted at the foo application,
|
||||
// while application.properties is targeted at all applications
|
||||
if ("application".equals(name)) {
|
||||
services.add("*");
|
||||
}
|
||||
else if (!name.startsWith("application")) {
|
||||
else {
|
||||
services.add(name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
# Autoconfiguration
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
org.springframework.cloud.config.monitor.EnvironmentMonitorAutoConfiguration
|
||||
@@ -0,0 +1 @@
|
||||
org.springframework.cloud.config.monitor.EnvironmentMonitorAutoConfiguration
|
||||
@@ -72,7 +72,7 @@ public class PropertyPathEndpointTests {
|
||||
public void testNotifyAllWithProfile() {
|
||||
assertThat(this.endpoint
|
||||
.notifyByPath(new HttpHeaders(), Collections.singletonMap("path", "application-local.yml")).toString())
|
||||
.isEqualTo("[*:local]");
|
||||
.isEqualTo("[*]");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -92,13 +92,13 @@ public class PropertyPathEndpointTests {
|
||||
@Test
|
||||
public void testNotifyOneWithProfile() {
|
||||
assertThat(this.endpoint.notifyByPath(new HttpHeaders(), Collections.singletonMap("path", "foo-local.yml"))
|
||||
.toString()).isEqualTo("[foo:local, foo-local]");
|
||||
.toString()).isEqualTo("[foo]");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotifyMultiDash() {
|
||||
assertThat(this.endpoint.notifyByPath(new HttpHeaders(), Collections.singletonMap("path", "foo-local-dev.yml"))
|
||||
.toString()).isEqualTo("[foo:local-dev, foo-local:dev, foo-local-dev]");
|
||||
.toString()).isEqualTo("[foo]");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -53,7 +53,8 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
|
||||
// config
|
||||
// server on the classpath we need to set it explicitly
|
||||
properties = { "spring.cloud.config.enabled:true", "", "spring.config.use-legacy-processing=true",
|
||||
"management.security.enabled=false", "management.endpoints.web.exposure.include=*" },
|
||||
"management.security.enabled=false", "management.endpoints.web.exposure.include=*",
|
||||
"management.endpoint.env.show-values=ALWAYS" },
|
||||
webEnvironment = RANDOM_PORT)
|
||||
public class ApplicationBootstrapTests {
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
|
||||
properties = { "spring.cloud.config.enabled:true",
|
||||
// FIXME: configdata why is this needed here?
|
||||
"spring.config.use-legacy-processing=true", "management.security.enabled=false",
|
||||
"management.endpoints.web.exposure.include=*" },
|
||||
"management.endpoints.web.exposure.include=*", "management.endpoint.env.show-values=ALWAYS" },
|
||||
webEnvironment = RANDOM_PORT)
|
||||
public class ApplicationTests {
|
||||
|
||||
|
||||
@@ -42,7 +42,8 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
|
||||
// Normally spring.cloud.config.enabled:true is the default but since we have the
|
||||
// config server on the classpath we need to set it explicitly
|
||||
properties = { "spring.cloud.config.enabled=true", "spring.config.import=configserver:",
|
||||
"management.security.enabled=false", "management.endpoints.web.exposure.include=*" },
|
||||
"management.security.enabled=false", "management.endpoints.web.exposure.include=*",
|
||||
"management.endpoint.env.show-values=ALWAYS" },
|
||||
webEnvironment = RANDOM_PORT)
|
||||
public class ConfigDataIntegrationTests {
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
|
||||
// hence no spring.config.import here and config name change
|
||||
properties = { "spring.application.name=profilesample", "spring.cloud.config.enabled=true",
|
||||
"spring.config.name=orderingtest", "management.security.enabled=false", "spring.profiles.active=dev",
|
||||
"management.endpoints.web.exposure.include=*" },
|
||||
"management.endpoints.web.exposure.include=*", "management.endpoint.env.show-values=ALWAYS" },
|
||||
webEnvironment = RANDOM_PORT)
|
||||
public class ConfigDataOrderingIntegrationTests {
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
|
||||
properties = { "spring.application.name=retryapp", "spring.cloud.config.fail-fast=true",
|
||||
"spring.cloud.config.enabled=true", "spring.config.import=configserver:",
|
||||
"management.security.enabled=false", "management.endpoints.web.exposure.include=*",
|
||||
"logging.level.org.springframework.retry=TRACE" },
|
||||
"logging.level.org.springframework.retry=TRACE", "management.endpoint.env.show-values=ALWAYS" },
|
||||
webEnvironment = RANDOM_PORT)
|
||||
public class ConfigDataRetryIntegrationTests {
|
||||
|
||||
|
||||
@@ -179,7 +179,7 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.tomakehurst</groupId>
|
||||
<artifactId>wiremock-jre8</artifactId>
|
||||
<artifactId>wiremock-jre8-standalone</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
@@ -39,7 +39,7 @@ import org.springframework.util.StringUtils;
|
||||
* Default text encryption auto-configuration.
|
||||
*
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @since 3.1.2
|
||||
* @since 4.0.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@AutoConfigureAfter(RsaEncryptionAutoConfiguration.class)
|
||||
|
||||
@@ -30,7 +30,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.crypto.encrypt.TextEncryptor;
|
||||
|
||||
/**
|
||||
* Auto-configuration for text encryptors and environment encryptors (non-web stuff).
|
||||
* Autoconfiguration for text encryptors and environment encryptors (non-web stuff).
|
||||
* Users can provide beans of the same type as any or all of the beans defined here in
|
||||
* application code to override the default behaviour.
|
||||
*
|
||||
|
||||
@@ -31,10 +31,10 @@ import org.springframework.security.rsa.crypto.RsaAlgorithm;
|
||||
import org.springframework.security.rsa.crypto.RsaSecretEncryptor;
|
||||
|
||||
/**
|
||||
* Auto-configuration for RSA encryption.
|
||||
* Autoconfiguration for RSA encryption.
|
||||
*
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @since 3.1.2
|
||||
* @since 4.0.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnProperty(prefix = "encrypt.key-store", value = "location")
|
||||
|
||||
@@ -130,29 +130,37 @@ public class AwsS3EnvironmentRepository implements EnvironmentRepository, Ordere
|
||||
|
||||
private S3ConfigFile getS3ConfigFile(String keyPrefix) {
|
||||
try {
|
||||
final ResponseInputStream<GetObjectResponse> responseInputStream = s3Client
|
||||
.getObject(GetObjectRequest.builder().bucket(bucketName).key(keyPrefix + ".properties").build());
|
||||
final ResponseInputStream<GetObjectResponse> responseInputStream = getObject(keyPrefix + ".properties");
|
||||
return new PropertyS3ConfigFile(responseInputStream.response().versionId(), responseInputStream);
|
||||
}
|
||||
catch (Exception eProperties) {
|
||||
try {
|
||||
final ResponseInputStream<GetObjectResponse> responseInputStream = s3Client
|
||||
.getObject(GetObjectRequest.builder().bucket(bucketName).key(keyPrefix + ".yml").build());
|
||||
final ResponseInputStream<GetObjectResponse> responseInputStream = getObject(keyPrefix + ".yml");
|
||||
return new YamlS3ConfigFile(responseInputStream.response().versionId(), responseInputStream);
|
||||
}
|
||||
catch (Exception eYaml) {
|
||||
catch (Exception eYml) {
|
||||
try {
|
||||
final ResponseInputStream<GetObjectResponse> responseInputStream = s3Client
|
||||
.getObject(GetObjectRequest.builder().bucket(bucketName).key(keyPrefix + ".json").build());
|
||||
return new JsonS3ConfigFile(responseInputStream.response().versionId(), responseInputStream);
|
||||
final ResponseInputStream<GetObjectResponse> responseInputStream = getObject(keyPrefix + ".yaml");
|
||||
return new YamlS3ConfigFile(responseInputStream.response().versionId(), responseInputStream);
|
||||
}
|
||||
catch (Exception eJson) {
|
||||
return null;
|
||||
catch (Exception eYaml) {
|
||||
try {
|
||||
final ResponseInputStream<GetObjectResponse> responseInputStream = getObject(
|
||||
keyPrefix + ".json");
|
||||
return new JsonS3ConfigFile(responseInputStream.response().versionId(), responseInputStream);
|
||||
}
|
||||
catch (Exception eJson) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ResponseInputStream<GetObjectResponse> getObject(String key) throws Exception {
|
||||
return s3Client.getObject(GetObjectRequest.builder().bucket(bucketName).key(key).build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locations getLocations(String application, String profiles, String label) {
|
||||
String baseLocation = AWS_S3_RESOURCE_SCHEME + bucketName + PATH_SEPARATOR + application;
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.cloud.config.server.environment;
|
||||
|
||||
import io.micrometer.common.docs.KeyName;
|
||||
import io.micrometer.observation.Observation;
|
||||
import io.micrometer.observation.ObservationConvention;
|
||||
import io.micrometer.observation.docs.DocumentedObservation;
|
||||
|
||||
enum DocumentedConfigObservation implements DocumentedObservation {
|
||||
@@ -27,7 +28,7 @@ enum DocumentedConfigObservation implements DocumentedObservation {
|
||||
*/
|
||||
ENVIRONMENT_REPOSITORY {
|
||||
@Override
|
||||
public Class<? extends Observation.ObservationConvention<? extends Observation.Context>> getDefaultConvention() {
|
||||
public Class<? extends ObservationConvention<? extends Observation.Context>> getDefaultConvention() {
|
||||
return ObservationEnvironmentRepositoryObservationConvention.class;
|
||||
}
|
||||
|
||||
@@ -54,7 +55,7 @@ enum DocumentedConfigObservation implements DocumentedObservation {
|
||||
*/
|
||||
ENVIRONMENT_CLASS {
|
||||
@Override
|
||||
public String getKeyName() {
|
||||
public String asString() {
|
||||
return "spring.cloud.config.environment.class";
|
||||
}
|
||||
},
|
||||
@@ -64,7 +65,7 @@ enum DocumentedConfigObservation implements DocumentedObservation {
|
||||
*/
|
||||
PROFILE {
|
||||
@Override
|
||||
public String getKeyName() {
|
||||
public String asString() {
|
||||
return "spring.cloud.config.environment.profile";
|
||||
}
|
||||
},
|
||||
@@ -74,7 +75,7 @@ enum DocumentedConfigObservation implements DocumentedObservation {
|
||||
*/
|
||||
LABEL {
|
||||
@Override
|
||||
public String getKeyName() {
|
||||
public String asString() {
|
||||
return "spring.cloud.config.environment.label";
|
||||
}
|
||||
},
|
||||
@@ -84,7 +85,7 @@ enum DocumentedConfigObservation implements DocumentedObservation {
|
||||
*/
|
||||
APPLICATION {
|
||||
@Override
|
||||
public String getKeyName() {
|
||||
public String asString() {
|
||||
return "spring.cloud.config.environment.application";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,14 +103,12 @@ public class EnvironmentController {
|
||||
this.acceptEmpty = acceptEmpty;
|
||||
}
|
||||
|
||||
@GetMapping(path = "/{name}/{profiles:(?!.*\\b\\.(?:ya?ml|properties|json)\\b).*}",
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@GetMapping(path = "/{name}/{profiles:[^\\.]*}", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public Environment defaultLabel(@PathVariable String name, @PathVariable String profiles) {
|
||||
return getEnvironment(name, profiles, null, false);
|
||||
}
|
||||
|
||||
@GetMapping(path = "/{name}/{profiles:(?!.*\\b\\.(?:ya?ml|properties|json)\\b).*}",
|
||||
produces = EnvironmentMediaType.V2_JSON)
|
||||
@GetMapping(path = "/{name}/{profiles:[^\\.]*}", produces = EnvironmentMediaType.V2_JSON)
|
||||
public Environment defaultLabelIncludeOrigin(@PathVariable String name, @PathVariable String profiles) {
|
||||
return getEnvironment(name, profiles, null, true);
|
||||
}
|
||||
@@ -464,14 +462,14 @@ public class EnvironmentController {
|
||||
}
|
||||
else {
|
||||
switch (this.propertyKey.charAt(this.currentPos)) {
|
||||
case '.':
|
||||
this.valueType = NodeType.MAP;
|
||||
break;
|
||||
case '[':
|
||||
this.valueType = NodeType.ARRAY;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid key: " + this.propertyKey);
|
||||
case '.':
|
||||
this.valueType = NodeType.MAP;
|
||||
break;
|
||||
case '[':
|
||||
this.valueType = NodeType.ARRAY;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid key: " + this.propertyKey);
|
||||
}
|
||||
}
|
||||
return index;
|
||||
|
||||
@@ -32,7 +32,6 @@ import java.util.stream.Collectors;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.eclipse.jgit.transport.http.HttpConnection;
|
||||
import org.eclipse.jgit.transport.http.apache.HttpClientConnection;
|
||||
|
||||
@@ -70,7 +69,16 @@ public class HttpClientConfigurableHttpConnectionFactory implements Configurable
|
||||
|
||||
@Override
|
||||
public HttpConnection create(URL url, Proxy proxy) throws IOException {
|
||||
return new HttpClientConnection(url.toString(), null, lookupHttpClientBuilder(url).build());
|
||||
HttpClientBuilder builder = lookupHttpClientBuilder(url);
|
||||
if (builder != null) {
|
||||
return new HttpClientConnection(url.toString(), null, builder.build());
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* No matching builder found: let jGit handle the creation of the HttpClient
|
||||
*/
|
||||
return new HttpClientConnection(url.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private void addHttpClient(JGitEnvironmentProperties properties) throws GeneralSecurityException {
|
||||
@@ -99,7 +107,7 @@ public class HttpClientConfigurableHttpConnectionFactory implements Configurable
|
||||
|
||||
if (builderMap.isEmpty()) {
|
||||
this.log.warn(String.format("No custom http config found for URL: %s", url));
|
||||
return HttpClients.custom();
|
||||
return null;
|
||||
}
|
||||
if (builderMap.size() > 1) {
|
||||
/*
|
||||
@@ -118,7 +126,7 @@ public class HttpClientConfigurableHttpConnectionFactory implements Configurable
|
||||
"More than one git repo URL template matched URL:"
|
||||
+ " %s, proxy and skipSslValidation config won't be applied. Matched templates: %s",
|
||||
url, builderMap.keySet().stream().collect(Collectors.joining(", "))));
|
||||
return HttpClients.custom();
|
||||
return null;
|
||||
}
|
||||
return new ArrayList<>(builderMap.values()).get(0);
|
||||
}
|
||||
|
||||
@@ -726,7 +726,7 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository
|
||||
}
|
||||
List<Ref> branches = command.call();
|
||||
for (Ref ref : branches) {
|
||||
if (ref.getName().endsWith("/" + label)) {
|
||||
if (ref.getName().equals("refs/heads/" + label) || ref.getName().equals("refs/remotes/origin/" + label)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,6 +270,9 @@ public class NativeEnvironmentRepository implements EnvironmentRepository, Searc
|
||||
locations = new String[] { matcher.group(2) };
|
||||
}
|
||||
}
|
||||
name = name.replace("\\", "/"); // change windows path '\' into '/'
|
||||
name = name.replaceAll("\\[(?=\\w:)", "[/"); // change [D:/path] into
|
||||
// [/D:/path]
|
||||
name = name.replace("applicationConfig: [", "");
|
||||
name = name.replace("file [", "file:");
|
||||
name = name.replace("class path resource [", "classpath:/");
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.cloud.config.server.environment;
|
||||
import io.micrometer.common.KeyValues;
|
||||
import io.micrometer.common.docs.KeyName;
|
||||
import io.micrometer.observation.Observation;
|
||||
import io.micrometer.observation.ObservationConvention;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -29,7 +30,7 @@ import org.springframework.util.StringUtils;
|
||||
* @since 4.0.0
|
||||
*/
|
||||
class ObservationEnvironmentRepositoryObservationConvention
|
||||
implements Observation.ObservationConvention<ObservationEnvironmentRepositoryContext> {
|
||||
implements ObservationConvention<ObservationEnvironmentRepositoryContext> {
|
||||
|
||||
@Override
|
||||
public KeyValues getLowCardinalityKeyValues(ObservationEnvironmentRepositoryContext context) {
|
||||
@@ -46,7 +47,7 @@ class ObservationEnvironmentRepositoryObservationConvention
|
||||
|
||||
private KeyValues appendIfPresent(KeyValues keyValues, KeyName profile, String value) {
|
||||
if (StringUtils.hasText(value)) {
|
||||
keyValues = keyValues.and(profile.of(value));
|
||||
keyValues = keyValues.and(profile.withValue(value));
|
||||
}
|
||||
return keyValues;
|
||||
}
|
||||
|
||||
@@ -46,12 +46,12 @@ public final class VaultKvAccessStrategyFactory {
|
||||
public static VaultKvAccessStrategy forVersion(RestOperations rest, String baseUrl, int version, String pathToKey) {
|
||||
|
||||
switch (version) {
|
||||
case 1:
|
||||
return new V1VaultKvAccessStrategy(baseUrl, rest);
|
||||
case 2:
|
||||
return new V2VaultKvAccessStrategy(baseUrl, pathToKey, rest);
|
||||
default:
|
||||
throw new IllegalArgumentException("No support for given Vault k/v backend version " + version);
|
||||
case 1:
|
||||
return new V1VaultKvAccessStrategy(baseUrl, rest);
|
||||
case 2:
|
||||
return new V2VaultKvAccessStrategy(baseUrl, pathToKey, rest);
|
||||
default:
|
||||
throw new IllegalArgumentException("No support for given Vault k/v backend version " + version);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,16 +32,17 @@ public final class GoogleSecretManagerAccessStrategyFactory {
|
||||
GoogleSecretManagerEnvironmentProperties properties) {
|
||||
|
||||
switch (properties.getVersion()) {
|
||||
case 1:
|
||||
try {
|
||||
return new GoogleSecretManagerV1AccessStrategy(rest, configProvider, properties.getServiceAccount());
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RepositoryException("Cannot create service client", e);
|
||||
}
|
||||
default:
|
||||
throw new IllegalArgumentException(
|
||||
"No support for given Google Secret manager backend version " + properties.getVersion());
|
||||
case 1:
|
||||
try {
|
||||
return new GoogleSecretManagerV1AccessStrategy(rest, configProvider,
|
||||
properties.getServiceAccount());
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RepositoryException("Cannot create service client", e);
|
||||
}
|
||||
default:
|
||||
throw new IllegalArgumentException(
|
||||
"No support for given Google Secret manager backend version " + properties.getVersion());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -50,11 +51,11 @@ public final class GoogleSecretManagerAccessStrategyFactory {
|
||||
GoogleSecretManagerEnvironmentProperties properties, SecretManagerServiceClient client) {
|
||||
|
||||
switch (properties.getVersion()) {
|
||||
case 1:
|
||||
return new GoogleSecretManagerV1AccessStrategy(rest, configProvider, client);
|
||||
default:
|
||||
throw new IllegalArgumentException(
|
||||
"No support for given Google Secret manager backend version " + properties.getVersion());
|
||||
case 1:
|
||||
return new GoogleSecretManagerV1AccessStrategy(rest, configProvider, client);
|
||||
default:
|
||||
throw new IllegalArgumentException(
|
||||
"No support for given Google Secret manager backend version " + properties.getVersion());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -61,12 +61,12 @@ public class SpringVaultEnvironmentRepositoryFactory
|
||||
int version = vaultProperties.getKvVersion();
|
||||
|
||||
switch (version) {
|
||||
case 1:
|
||||
return vaultTemplate.opsForKeyValue(backend, VaultKeyValueOperationsSupport.KeyValueBackend.KV_1);
|
||||
case 2:
|
||||
return vaultTemplate.opsForKeyValue(backend, VaultKeyValueOperationsSupport.KeyValueBackend.KV_2);
|
||||
default:
|
||||
throw new IllegalArgumentException("No support for given Vault k/v backend version " + version);
|
||||
case 1:
|
||||
return vaultTemplate.opsForKeyValue(backend, VaultKeyValueOperationsSupport.KeyValueBackend.KV_1);
|
||||
case 2:
|
||||
return vaultTemplate.opsForKeyValue(backend, VaultKeyValueOperationsSupport.KeyValueBackend.KV_2);
|
||||
default:
|
||||
throw new IllegalArgumentException("No support for given Vault k/v backend version " + version);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,13 @@ public final class HttpClientSupport {
|
||||
httpClientBuilder.setDefaultCredentialsProvider(new SystemDefaultCredentialsProvider());
|
||||
}
|
||||
|
||||
/*
|
||||
* According to https://git.eclipse.org/c/jgit/jgit.git/commit/?id=
|
||||
* e17bfc96f293744cc5c0cef306e100f53d63bb3d jGit does its own redirect handling
|
||||
* and disables HttpClient's redirect handing.
|
||||
*/
|
||||
httpClientBuilder.disableRedirectHandling();
|
||||
|
||||
int timeout = environmentProperties.getTimeout() * 1000;
|
||||
return httpClientBuilder.setSSLContext(sslContextBuilder.build()).setDefaultRequestConfig(
|
||||
RequestConfig.custom().setSocketTimeout(timeout).setConnectTimeout(timeout).build());
|
||||
|
||||
@@ -1,20 +1,11 @@
|
||||
# Bootstrap components
|
||||
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
|
||||
org.springframework.cloud.config.server.bootstrap.ConfigServerBootstrapConfiguration,\
|
||||
org.springframework.cloud.config.server.config.DefaultTextEncryptionAutoConfiguration,\
|
||||
org.springframework.cloud.config.server.config.RsaEncryptionAutoConfiguration,\
|
||||
org.springframework.cloud.config.server.config.EncryptionAutoConfiguration
|
||||
|
||||
# Environment PostProcessor
|
||||
org.springframework.boot.env.EnvironmentPostProcessor=\
|
||||
org.springframework.cloud.config.server.bootstrap.ConfigServerBootstrapApplicationListener
|
||||
|
||||
# Autoconfiguration
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
org.springframework.cloud.config.server.config.ConfigServerAutoConfiguration,\
|
||||
org.springframework.cloud.config.server.config.EncryptionAutoConfiguration,\
|
||||
org.springframework.cloud.config.server.config.DefaultTextEncryptionAutoConfiguration,\
|
||||
org.springframework.cloud.config.server.config.RsaEncryptionAutoConfiguration,\
|
||||
org.springframework.cloud.config.server.config.VaultEncryptionAutoConfiguration
|
||||
org.springframework.boot.diagnostics.FailureAnalyzer=\
|
||||
org.springframework.cloud.config.server.diagnostics.GitUriFailureAnalyzer
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
org.springframework.cloud.config.server.config.ConfigServerAutoConfiguration
|
||||
org.springframework.cloud.config.server.config.EncryptionAutoConfiguration
|
||||
org.springframework.cloud.config.server.config.DefaultTextEncryptionAutoConfiguration
|
||||
org.springframework.cloud.config.server.config.RsaEncryptionAutoConfiguration
|
||||
org.springframework.cloud.config.server.config.VaultEncryptionAutoConfiguration
|
||||
@@ -115,6 +115,15 @@ public class AwsS3EnvironmentRepositoryTests {
|
||||
|
||||
@Test
|
||||
public void findYamlObject() throws UnsupportedEncodingException {
|
||||
setupS3("foo-bar.yaml", yamlContent);
|
||||
|
||||
final Environment env = envRepo.findOne("foo", "bar", null);
|
||||
|
||||
assertExpectedEnvironment(env, "foo", null, null, 1, "bar");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findYmlObject() throws UnsupportedEncodingException {
|
||||
setupS3("foo-bar.yml", yamlContent);
|
||||
|
||||
final Environment env = envRepo.findOne("foo", "bar", null);
|
||||
|
||||
@@ -643,11 +643,11 @@ class EnvironmentControllerTests {
|
||||
|
||||
@Test
|
||||
public void handleEnvironmentException() throws Exception {
|
||||
when(EnvironmentControllerTests.this.repository.findOne(eq("exception"), eq("bad_syntax.ext"), any(),
|
||||
when(EnvironmentControllerTests.this.repository.findOne(eq("exception"), eq("bad_syntax"), any(),
|
||||
eq(false)))
|
||||
.thenThrow(new FailedToConstructEnvironmentException("Cannot construct",
|
||||
new RuntimeException("underlier")));
|
||||
MvcResult result = this.mvc.perform(MockMvcRequestBuilders.get("/exception/bad_syntax.ext"))
|
||||
MvcResult result = this.mvc.perform(MockMvcRequestBuilders.get("/exception/bad_syntax"))
|
||||
.andExpect(MockMvcResultMatchers.status().is(500)).andReturn();
|
||||
assertThat(result.getResponse().getErrorMessage()).isEqualTo("Cannot construct");
|
||||
}
|
||||
|
||||
@@ -198,10 +198,8 @@ public class HttpClientConfigurableHttpConnectionFactoryTest {
|
||||
HttpConnection actualConnection = this.connectionFactory.create(
|
||||
new URL(properties2.getUri().replace("{placeholder1}", "value1").replace("{placeholder2}", "value2")));
|
||||
|
||||
HttpClientBuilder expectedHttpClientBuilder = this.connectionFactory.httpClientBuildersByUri
|
||||
.get(properties2.getUri());
|
||||
HttpClientBuilder actualHttpClientBuilder = getActualHttpClientBuilder(actualConnection);
|
||||
assertThat(actualHttpClientBuilder).isNotSameAs(expectedHttpClientBuilder);
|
||||
HttpClient actualHttpClient = getActualHttpClient(actualConnection);
|
||||
assertThat(actualHttpClient).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -230,6 +230,20 @@ public class JGitEnvironmentRepositoryTests {
|
||||
assertThat(this.repository.getUri()).isEqualTo("git://localhost/foo");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBranchEndsWithTag() throws IOException {
|
||||
String uri = ConfigServerTestUtils.prepareLocalRepo("branch-with-slash-repo");
|
||||
this.repository.setUri(uri);
|
||||
|
||||
// exists branch "feature/foo"
|
||||
Environment environment = this.repository.findOne("bar", "staging", "feature/foo");
|
||||
assertVersion(environment);
|
||||
|
||||
// try tag "foo"
|
||||
environment = this.repository.findOne("bar", "staging", "foo");
|
||||
assertThat(environment.getPropertySources().get(0).getSource().get("key")).isEqualTo("value from tag");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void afterPropertiesSet_CloneOnStartTrue_CloneAndFetchCalled() throws Exception {
|
||||
Git mockGit = mock(Git.class);
|
||||
@@ -744,7 +758,7 @@ public class JGitEnvironmentRepositoryTests {
|
||||
when(checkoutCommand.call()).thenReturn(ref);
|
||||
when(listBranchCommand.call()).thenReturn(Arrays.asList(branch1Ref));
|
||||
when(fetchCommand.call()).thenReturn(fetchResult);
|
||||
when(branch1Ref.getName()).thenReturn("origin/master");
|
||||
when(branch1Ref.getName()).thenReturn("refs/remotes/origin/master");
|
||||
when(status.isClean()).thenReturn(true);
|
||||
|
||||
JGitEnvironmentRepository repo = new JGitEnvironmentRepository(this.environment,
|
||||
@@ -1207,12 +1221,12 @@ public class JGitEnvironmentRepositoryTests {
|
||||
// Mock master branch
|
||||
Ref mockMasterRef = mock(Ref.class);
|
||||
repositoryRefsList.add(mockMasterRef);
|
||||
when(mockMasterRef.getName()).thenReturn("/master");
|
||||
when(mockMasterRef.getName()).thenReturn("refs/remotes/origin/master");
|
||||
|
||||
// Mock release branch.
|
||||
Ref mockReleaseRef = mock(Ref.class);
|
||||
repositoryRefsList.add(mockReleaseRef);
|
||||
when(mockReleaseRef.getName()).thenReturn("/release");
|
||||
when(mockReleaseRef.getName()).thenReturn("refs/remotes/origin/release");
|
||||
|
||||
// Mock calls on list and checkout commands
|
||||
when(mockListBranchCommand.call()).thenReturn(repositoryRefsList);
|
||||
@@ -1261,7 +1275,7 @@ public class JGitEnvironmentRepositoryTests {
|
||||
// Mock master branch
|
||||
Ref mockMasterRef = mock(Ref.class);
|
||||
repositoryRefsList.add(mockMasterRef);
|
||||
when(mockMasterRef.getName()).thenReturn("/master");
|
||||
when(mockMasterRef.getName()).thenReturn("refs/remotes/origin/master");
|
||||
|
||||
// Mock calls on list and checkout commands
|
||||
when(mockListBranchCommand.call()).thenReturn(repositoryRefsList);
|
||||
|
||||
@@ -49,8 +49,8 @@ public class RedisEnvironmentRepositoryIntegrationTests {
|
||||
|
||||
@DynamicPropertySource
|
||||
static void containerProperties(DynamicPropertyRegistry registry) {
|
||||
registry.add("spring.redis.host", redisContainer::getContainerIpAddress);
|
||||
registry.add("spring.redis.port", redisContainer::getFirstMappedPort);
|
||||
registry.add("spring.data.redis.host", redisContainer::getHost);
|
||||
registry.add("spring.data.redis.port", redisContainer::getFirstMappedPort);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -45,7 +45,6 @@ import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.get;
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor;
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.verify;
|
||||
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
|
||||
@@ -77,7 +76,7 @@ public class HttpClientSupportTest {
|
||||
wireMockProxyServer.start();
|
||||
wireMockServer.start();
|
||||
WireMock.configureFor("https", "localhost", wireMockServer.httpsPort());
|
||||
stubFor(get("/test/proxy").willReturn(aResponse().withStatus(200)));
|
||||
wireMockServer.stubFor(get("/test/proxy").willReturn(aResponse().withStatus(200)));
|
||||
|
||||
JGitEnvironmentProperties properties = new JGitEnvironmentProperties();
|
||||
Map<ProxyHostProperties.ProxyForScheme, ProxyHostProperties> proxy = new HashMap<>();
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
key: value from master
|
||||
@@ -0,0 +1 @@
|
||||
master
|
||||
@@ -0,0 +1 @@
|
||||
ref: refs/heads/master
|
||||
@@ -0,0 +1,5 @@
|
||||
[core]
|
||||
repositoryformatversion = 0
|
||||
filemode = true
|
||||
bare = false
|
||||
logallrefupdates = true
|
||||
@@ -0,0 +1 @@
|
||||
Unnamed repository; edit this file 'description' to name the repository.
|
||||
Binary file not shown.
@@ -0,0 +1,3 @@
|
||||
0000000000000000000000000000000000000000 7a9804f8901709bdcf794c553805d5bc5188f821 woshikid <name.kid@gmail.com> 1663579538 +0800 commit (initial): tag
|
||||
7a9804f8901709bdcf794c553805d5bc5188f821 915bd24aaf815120f2755ef4fc66404f5d37b383 woshikid <name.kid@gmail.com> 1663579645 +0800 commit: branch
|
||||
915bd24aaf815120f2755ef4fc66404f5d37b383 08eb9e67a7225c302e3906a63cb9544e619fc804 woshikid <name.kid@gmail.com> 1663579718 +0800 commit: master
|
||||
@@ -0,0 +1 @@
|
||||
0000000000000000000000000000000000000000 915bd24aaf815120f2755ef4fc66404f5d37b383 woshikid <name.kid@gmail.com> 1663579678 +0800 branch: Created from master
|
||||
@@ -0,0 +1,3 @@
|
||||
0000000000000000000000000000000000000000 7a9804f8901709bdcf794c553805d5bc5188f821 woshikid <name.kid@gmail.com> 1663579538 +0800 commit (initial): tag
|
||||
7a9804f8901709bdcf794c553805d5bc5188f821 915bd24aaf815120f2755ef4fc66404f5d37b383 woshikid <name.kid@gmail.com> 1663579645 +0800 commit: branch
|
||||
915bd24aaf815120f2755ef4fc66404f5d37b383 08eb9e67a7225c302e3906a63cb9544e619fc804 woshikid <name.kid@gmail.com> 1663579718 +0800 commit: master
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,2 @@
|
||||
x<01><>A
|
||||
<EFBFBD>0E]<5D><14>J<><4A>LR(<28>U&ql<71><6C>@<40>x}sw<><07><><EFBFBD>j-fv<66>~<7E><>]2SB<53><1C>G<EFBFBD>.EVL.<2E>l<13>L<16>$<18><><EFBFBD><1D>m<EFBFBD><6D><<3C>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
915bd24aaf815120f2755ef4fc66404f5d37b383
|
||||
@@ -0,0 +1 @@
|
||||
08eb9e67a7225c302e3906a63cb9544e619fc804
|
||||
@@ -0,0 +1 @@
|
||||
7a9804f8901709bdcf794c553805d5bc5188f821
|
||||
Reference in New Issue
Block a user