Refactor spring-cloud-core To Allow For Alternative Implementation (#649)
* Deprecate KubernetesAutoServiceRegistration * Document service registry in kubernetes. Fixes #348 * Refactoring of core to provide an alternate Kubernetes client implementation
This commit is contained in:
1
pom.xml
1
pom.xml
@@ -87,6 +87,7 @@
|
||||
|
||||
<modules>
|
||||
<module>spring-cloud-kubernetes-dependencies</module>
|
||||
<module>spring-cloud-kubernetes-commons</module>
|
||||
<module>spring-cloud-kubernetes-core</module>
|
||||
<module>spring-cloud-kubernetes-config</module>
|
||||
<module>spring-cloud-kubernetes-discovery</module>
|
||||
|
||||
42
spring-cloud-kubernetes-commons/pom.xml
Normal file
42
spring-cloud-kubernetes-commons/pom.xml
Normal file
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-kubernetes</artifactId>
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-cloud-kubernetes-commons</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-autoconfigure</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-actuator-autoconfigure</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.vintage</groupId>
|
||||
<artifactId>junit-vintage-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2013-2020 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.cloud.kubernetes.commons;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
|
||||
import org.springframework.boot.actuate.health.Health;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public abstract class AbstractKubernetesHealthIndicator extends AbstractHealthIndicator {
|
||||
|
||||
/**
|
||||
* Inside key.
|
||||
*/
|
||||
public static final String INSIDE = "inside";
|
||||
|
||||
/**
|
||||
* Namespace key.
|
||||
*/
|
||||
public static final String NAMESPACE = "namespace";
|
||||
|
||||
/**
|
||||
* Pod name key.
|
||||
*/
|
||||
public static final String POD_NAME = "podName";
|
||||
|
||||
/**
|
||||
* Pod IP key.
|
||||
*/
|
||||
public static final String POD_IP = "podIp";
|
||||
|
||||
/**
|
||||
* Service account key.
|
||||
*/
|
||||
public static final String SERVICE_ACCOUNT = "serviceAccount";
|
||||
|
||||
/**
|
||||
* Node name key.
|
||||
*/
|
||||
public static final String NODE_NAME = "nodeName";
|
||||
|
||||
/**
|
||||
* Host IP key.
|
||||
*/
|
||||
public static final String HOST_IP = "hostIp";
|
||||
|
||||
/**
|
||||
* Labels key.
|
||||
*/
|
||||
public static final String LABELS = "labels";
|
||||
|
||||
@Override
|
||||
protected void doHealthCheck(Health.Builder builder) throws Exception {
|
||||
try {
|
||||
builder.withDetails(getDetails());
|
||||
}
|
||||
catch (Exception e) {
|
||||
builder.down(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract Map<String, Object> getDetails() throws Exception;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2013-2020 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.cloud.kubernetes.commons;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.boot.actuate.info.Info;
|
||||
import org.springframework.boot.actuate.info.InfoContributor;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public abstract class AbstractKubernetesInfoContributor implements InfoContributor {
|
||||
|
||||
/**
|
||||
* Kubernetes key.
|
||||
*/
|
||||
public static final String KUBERNETES = "kubernetes";
|
||||
|
||||
/**
|
||||
* Inside key.
|
||||
*/
|
||||
public static final String INSIDE = "inside";
|
||||
|
||||
/**
|
||||
* Namespace key.
|
||||
*/
|
||||
public static final String NAMESPACE = "namespace";
|
||||
|
||||
/**
|
||||
* Pod name key.
|
||||
*/
|
||||
public static final String POD_NAME = "podName";
|
||||
|
||||
/**
|
||||
* Pod IP key.
|
||||
*/
|
||||
public static final String POD_IP = "podIp";
|
||||
|
||||
/**
|
||||
* Service account key.
|
||||
*/
|
||||
public static final String SERVICE_ACCOUNT = "serviceAccount";
|
||||
|
||||
/**
|
||||
* Node name key.
|
||||
*/
|
||||
public static final String NODE_NAME = "nodeName";
|
||||
|
||||
/**
|
||||
* Host IP key.
|
||||
*/
|
||||
public static final String HOST_IP = "hostIp";
|
||||
|
||||
/**
|
||||
* Labels key.
|
||||
*/
|
||||
public static final String LABELS = "labels";
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(AbstractKubernetesInfoContributor.class);
|
||||
|
||||
@Override
|
||||
public void contribute(Info.Builder builder) {
|
||||
try {
|
||||
builder.withDetail(KUBERNETES, getDetails());
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.warn("Failed to get pod details", e);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract Map<String, Object> getDetails();
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2019 the original author or authors.
|
||||
* Copyright 2019-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.kubernetes;
|
||||
package org.springframework.cloud.kubernetes.commons;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
* Copyright 2013-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.kubernetes;
|
||||
package org.springframework.cloud.kubernetes.commons;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2013-2020 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.cloud.kubernetes.commons;
|
||||
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnKubernetesEnabled
|
||||
@EnableConfigurationProperties(KubernetesClientProperties.class)
|
||||
public class KubernetesCommonsAutoConfiguration {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 2013-2020 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.cloud.kubernetes.commons.profile;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.context.config.ConfigFileApplicationListener;
|
||||
import org.springframework.boot.env.EnvironmentPostProcessor;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public abstract class AbstractKubernetesProfileEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered {
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(AbstractKubernetesProfileEnvironmentPostProcessor.class);
|
||||
|
||||
// Before ConfigFileApplicationListener so values there can use these ones
|
||||
private static final int ORDER = ConfigFileApplicationListener.DEFAULT_ORDER - 1;
|
||||
|
||||
/**
|
||||
* Profile name.
|
||||
*/
|
||||
public static final String KUBERNETES_PROFILE = "kubernetes";
|
||||
|
||||
@Override
|
||||
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
|
||||
|
||||
final boolean kubernetesEnabled = environment.getProperty("spring.cloud.kubernetes.enabled", Boolean.class,
|
||||
true);
|
||||
if (!kubernetesEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isInsideKubernetes()) {
|
||||
if (hasKubernetesProfile(environment)) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("'kubernetes' already in list of active profiles");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Adding 'kubernetes' to list of active profiles");
|
||||
}
|
||||
environment.addActiveProfile(KUBERNETES_PROFILE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.warn("Not running inside kubernetes. Skipping 'kubernetes' profile activation.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract boolean isInsideKubernetes();
|
||||
|
||||
private boolean hasKubernetesProfile(Environment environment) {
|
||||
for (String activeProfile : environment.getActiveProfiles()) {
|
||||
if (KUBERNETES_PROFILE.equalsIgnoreCase(activeProfile)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return ORDER;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
org.springframework.cloud.kubernetes.commons.KubernetesCommonsAutoConfiguration
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2013-2020 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 org.springframework.cloud.kubernetes.commons;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE,
|
||||
classes = KubernetesCommonsAutoConfigurationTests.App.class,
|
||||
properties = { "spring.cloud.kubernetes.client.password=mypassword",
|
||||
"spring.cloud.kubernetes.client.proxy-password=myproxypassword" })
|
||||
public class KubernetesCommonsAutoConfigurationTests {
|
||||
|
||||
@Autowired
|
||||
ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void beansAreCreated() {
|
||||
assertThat(context.getBeansOfType(KubernetesClientProperties.class)).hasSize(1);
|
||||
|
||||
KubernetesClientProperties properties = context.getBeansOfType(KubernetesClientProperties.class).values()
|
||||
.stream().findFirst().get();
|
||||
assertThat(properties.getPassword()).isEqualTo("mypassword");
|
||||
assertThat(properties.getProxyPassword()).isEqualTo("myproxypassword");
|
||||
}
|
||||
|
||||
@SpringBootApplication
|
||||
static class App {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,6 +25,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.kubernetes.KubernetesAutoConfiguration;
|
||||
import org.springframework.cloud.kubernetes.commons.KubernetesCommonsAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
@@ -40,7 +41,7 @@ import org.springframework.context.annotation.Import;
|
||||
public class BootstrapConfiguration {
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Import(KubernetesAutoConfiguration.class)
|
||||
@Import({ KubernetesCommonsAutoConfiguration.class, KubernetesAutoConfiguration.class })
|
||||
@EnableConfigurationProperties({ ConfigMapConfigProperties.class, SecretsConfigProperties.class })
|
||||
protected static class KubernetesPropertySourceConfiguration {
|
||||
|
||||
|
||||
@@ -44,6 +44,10 @@
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-kubernetes-commons</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-logging</artifactId>
|
||||
|
||||
@@ -27,9 +27,12 @@ import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
|
||||
import org.springframework.boot.actuate.health.HealthIndicator;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.kubernetes.commons.ConditionalOnKubernetesEnabled;
|
||||
import org.springframework.cloud.kubernetes.commons.KubernetesClientProperties;
|
||||
import org.springframework.cloud.kubernetes.commons.KubernetesCommonsAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@@ -42,7 +45,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnKubernetesEnabled
|
||||
@EnableConfigurationProperties(KubernetesClientProperties.class)
|
||||
@AutoConfigureAfter(KubernetesCommonsAutoConfiguration.class)
|
||||
public class KubernetesAutoConfiguration {
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(KubernetesAutoConfiguration.class);
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
|
||||
package org.springframework.cloud.kubernetes;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import io.fabric8.kubernetes.api.model.Pod;
|
||||
|
||||
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
|
||||
import org.springframework.boot.actuate.health.Health;
|
||||
import org.springframework.cloud.kubernetes.commons.AbstractKubernetesHealthIndicator;
|
||||
|
||||
/**
|
||||
* Kubernetes implementation of {@link AbstractHealthIndicator}.
|
||||
@@ -27,7 +30,7 @@ import org.springframework.boot.actuate.health.Health;
|
||||
* @author Ioannis Canellos
|
||||
* @author Eddú Meléndez
|
||||
*/
|
||||
public class KubernetesHealthIndicator extends AbstractHealthIndicator {
|
||||
public class KubernetesHealthIndicator extends AbstractKubernetesHealthIndicator {
|
||||
|
||||
private PodUtils utils;
|
||||
|
||||
@@ -36,25 +39,23 @@ public class KubernetesHealthIndicator extends AbstractHealthIndicator {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doHealthCheck(Health.Builder builder) throws Exception {
|
||||
try {
|
||||
Pod current = this.utils.currentPod().get();
|
||||
if (current != null) {
|
||||
builder.up().withDetail("inside", true).withDetail("namespace", current.getMetadata().getNamespace())
|
||||
.withDetail("podName", current.getMetadata().getName())
|
||||
.withDetail("podIp", current.getStatus().getPodIP())
|
||||
.withDetail("serviceAccount", current.getSpec().getServiceAccountName())
|
||||
.withDetail("nodeName", current.getSpec().getNodeName())
|
||||
.withDetail("hostIp", current.getStatus().getHostIP())
|
||||
.withDetail("labels", current.getMetadata().getLabels());
|
||||
}
|
||||
else {
|
||||
builder.up().withDetail("inside", false);
|
||||
}
|
||||
protected Map<String, Object> getDetails() throws Exception {
|
||||
Map<String, Object> details = new HashMap<>();
|
||||
Pod current = this.utils.currentPod().get();
|
||||
if (current != null) {
|
||||
details.put(INSIDE, true);
|
||||
details.put(NAMESPACE, current.getMetadata().getNamespace());
|
||||
details.put(POD_NAME, current.getMetadata().getName());
|
||||
details.put(POD_IP, current.getStatus().getPodIP());
|
||||
details.put(SERVICE_ACCOUNT, current.getSpec().getServiceAccountName());
|
||||
details.put(NODE_NAME, current.getSpec().getNodeName());
|
||||
details.put(HOST_IP, current.getStatus().getHostIP());
|
||||
details.put(LABELS, current.getMetadata().getLabels());
|
||||
}
|
||||
catch (Exception e) {
|
||||
builder.down(e);
|
||||
else {
|
||||
details.put(INSIDE, false);
|
||||
}
|
||||
return details;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,20 +20,16 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import io.fabric8.kubernetes.api.model.Pod;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.boot.actuate.info.Info.Builder;
|
||||
import org.springframework.boot.actuate.info.InfoContributor;
|
||||
import org.springframework.cloud.kubernetes.commons.AbstractKubernetesInfoContributor;
|
||||
|
||||
/**
|
||||
* Kubernetes implementation of {@link InfoContributor}.
|
||||
*
|
||||
* @author Mark Anderson
|
||||
*/
|
||||
public class KubernetesInfoContributor implements InfoContributor {
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(KubernetesInfoContributor.class);
|
||||
public class KubernetesInfoContributor extends AbstractKubernetesInfoContributor {
|
||||
|
||||
private PodUtils utils;
|
||||
|
||||
@@ -42,27 +38,20 @@ public class KubernetesInfoContributor implements InfoContributor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contribute(Builder builder) {
|
||||
try {
|
||||
Pod current = this.utils.currentPod().get();
|
||||
Map<String, Object> details = new HashMap<>();
|
||||
if (current != null) {
|
||||
details.put("inside", true);
|
||||
details.put("namespace", current.getMetadata().getNamespace());
|
||||
details.put("podName", current.getMetadata().getName());
|
||||
details.put("podIp", current.getStatus().getPodIP());
|
||||
details.put("serviceAccount", current.getSpec().getServiceAccountName());
|
||||
details.put("nodeName", current.getSpec().getNodeName());
|
||||
details.put("hostIp", current.getStatus().getHostIP());
|
||||
}
|
||||
else {
|
||||
details.put("inside", false);
|
||||
}
|
||||
builder.withDetail("kubernetes", details);
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.warn("Failed to get pod details", e);
|
||||
public Map<String, Object> getDetails() {
|
||||
Pod current = this.utils.currentPod().get();
|
||||
Map<String, Object> details = new HashMap<>();
|
||||
boolean inside = current != null;
|
||||
details.put(INSIDE, inside);
|
||||
if (inside) {
|
||||
details.put(NAMESPACE, current.getMetadata().getNamespace());
|
||||
details.put(POD_NAME, current.getMetadata().getName());
|
||||
details.put(POD_IP, current.getStatus().getPodIP());
|
||||
details.put(SERVICE_ACCOUNT, current.getSpec().getServiceAccountName());
|
||||
details.put(NODE_NAME, current.getSpec().getNodeName());
|
||||
details.put(HOST_IP, current.getStatus().getHostIP());
|
||||
}
|
||||
return details;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,74 +17,18 @@
|
||||
package org.springframework.cloud.kubernetes.profile;
|
||||
|
||||
import io.fabric8.kubernetes.client.DefaultKubernetesClient;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.context.config.ConfigFileApplicationListener;
|
||||
import org.springframework.boot.env.EnvironmentPostProcessor;
|
||||
import org.springframework.cloud.kubernetes.StandardPodUtils;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.cloud.kubernetes.commons.profile.AbstractKubernetesProfileEnvironmentPostProcessor;
|
||||
|
||||
public class KubernetesProfileEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered {
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(KubernetesProfileEnvironmentPostProcessor.class);
|
||||
|
||||
// Before ConfigFileApplicationListener so values there can use these ones
|
||||
private static final int ORDER = ConfigFileApplicationListener.DEFAULT_ORDER - 1;
|
||||
|
||||
private static final String KUBERNETES_PROFILE = "kubernetes";
|
||||
public class KubernetesProfileEnvironmentPostProcessor extends AbstractKubernetesProfileEnvironmentPostProcessor {
|
||||
|
||||
@Override
|
||||
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
|
||||
|
||||
final boolean kubernetesEnabled = environment.getProperty("spring.cloud.kubernetes.enabled", Boolean.class,
|
||||
true);
|
||||
if (!kubernetesEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isInsideKubernetes()) {
|
||||
if (hasKubernetesProfile(environment)) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("'kubernetes' already in list of active profiles");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Adding 'kubernetes' to list of active profiles");
|
||||
}
|
||||
environment.addActiveProfile(KUBERNETES_PROFILE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.warn("Not running inside kubernetes. Skipping 'kubernetes' profile activation.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isInsideKubernetes() {
|
||||
protected boolean isInsideKubernetes() {
|
||||
try (DefaultKubernetesClient client = new DefaultKubernetesClient()) {
|
||||
final StandardPodUtils podUtils = new StandardPodUtils(client);
|
||||
return podUtils.isInsideKubernetes();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasKubernetesProfile(Environment environment) {
|
||||
for (String activeProfile : environment.getActiveProfiles()) {
|
||||
if (KUBERNETES_PROFILE.equalsIgnoreCase(activeProfile)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return ORDER;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.commons.KubernetesClientProperties;
|
||||
import org.springframework.cloud.kubernetes.example.App;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
@@ -64,6 +65,7 @@ public class KubernetesAutoConfigurationTests {
|
||||
assertThat(context.getBeanNamesForType(StandardPodUtils.class)).hasSize(1);
|
||||
assertThat(context.getBeanNamesForType(KubernetesHealthIndicator.class)).hasSize(1);
|
||||
assertThat(context.getBeanNamesForType(KubernetesInfoContributor.class)).hasSize(1);
|
||||
assertThat(context.getBeanNamesForType(KubernetesClientProperties.class)).hasSize(1);
|
||||
|
||||
Config config = context.getBean(Config.class);
|
||||
assertThat(config.getPassword()).isEqualTo("mypassword");
|
||||
|
||||
@@ -87,6 +87,12 @@
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-kubernetes-commons</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-kubernetes-loadbalancer</artifactId>
|
||||
|
||||
@@ -25,8 +25,8 @@ import org.springframework.cloud.client.CommonsClientAutoConfiguration;
|
||||
import org.springframework.cloud.client.ConditionalOnBlockingDiscoveryEnabled;
|
||||
import org.springframework.cloud.client.ConditionalOnDiscoveryEnabled;
|
||||
import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration;
|
||||
import org.springframework.cloud.kubernetes.ConditionalOnKubernetesEnabled;
|
||||
import org.springframework.cloud.kubernetes.KubernetesAutoConfiguration;
|
||||
import org.springframework.cloud.kubernetes.commons.ConditionalOnKubernetesEnabled;
|
||||
import org.springframework.cloud.kubernetes.registry.KubernetesRegistration;
|
||||
import org.springframework.cloud.kubernetes.registry.KubernetesServiceRegistry;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
@@ -30,7 +30,7 @@ import org.springframework.cloud.client.discovery.composite.reactive.ReactiveCom
|
||||
import org.springframework.cloud.client.discovery.health.DiscoveryClientHealthIndicatorProperties;
|
||||
import org.springframework.cloud.client.discovery.health.reactive.ReactiveDiscoveryClientHealthIndicator;
|
||||
import org.springframework.cloud.client.discovery.simple.reactive.SimpleReactiveDiscoveryClientAutoConfiguration;
|
||||
import org.springframework.cloud.kubernetes.ConditionalOnKubernetesEnabled;
|
||||
import org.springframework.cloud.kubernetes.commons.ConditionalOnKubernetesEnabled;
|
||||
import org.springframework.cloud.kubernetes.discovery.ConditionalOnKubernetesDiscoveryEnabled;
|
||||
import org.springframework.cloud.kubernetes.discovery.KubernetesClientServicesFunction;
|
||||
import org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryClientAutoConfiguration;
|
||||
|
||||
@@ -20,8 +20,7 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringBootConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
@@ -46,8 +45,7 @@ public class KubernetesDiscoveryClientAutoConfigurationTests {
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@SpringBootConfiguration
|
||||
@EnableAutoConfiguration
|
||||
@SpringBootApplication
|
||||
protected static class TestConfig {
|
||||
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.cloud.commons.util.UtilAutoConfiguration;
|
||||
import org.springframework.cloud.config.client.ConfigClientProperties;
|
||||
import org.springframework.cloud.config.client.DiscoveryClientConfigServiceBootstrapConfiguration;
|
||||
import org.springframework.cloud.kubernetes.KubernetesAutoConfiguration;
|
||||
import org.springframework.cloud.kubernetes.commons.KubernetesCommonsAutoConfiguration;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -73,12 +73,13 @@ public class KubernetesDiscoveryClientConfigClientBootstrapConfigurationTests {
|
||||
AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext();
|
||||
TestPropertyValues.of(env).applyTo(parent);
|
||||
parent.register(UtilAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class,
|
||||
EnvironmentKnobbler.class, KubernetesDiscoveryClientConfigClientBootstrapConfiguration.class,
|
||||
EnvironmentKnobbler.class, KubernetesCommonsAutoConfiguration.class,
|
||||
KubernetesDiscoveryClientConfigClientBootstrapConfiguration.class,
|
||||
DiscoveryClientConfigServiceBootstrapConfiguration.class, ConfigClientProperties.class);
|
||||
parent.refresh();
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
this.context.setParent(parent);
|
||||
this.context.register(PropertyPlaceholderAutoConfiguration.class, KubernetesAutoConfiguration.class,
|
||||
this.context.register(PropertyPlaceholderAutoConfiguration.class, KubernetesCommonsAutoConfiguration.class,
|
||||
KubernetesDiscoveryClientAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient;
|
||||
import org.springframework.cloud.client.discovery.health.reactive.ReactiveDiscoveryClientHealthIndicator;
|
||||
import org.springframework.cloud.commons.util.UtilAutoConfiguration;
|
||||
import org.springframework.cloud.kubernetes.KubernetesAutoConfiguration;
|
||||
import org.springframework.cloud.kubernetes.commons.KubernetesCommonsAutoConfiguration;
|
||||
import org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryClientAutoConfiguration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -35,8 +36,9 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
*/
|
||||
class KubernetesReactiveDiscoveryClientAutoConfigurationTests {
|
||||
|
||||
private ApplicationContextRunner contextRunner = new ApplicationContextRunner().withConfiguration(
|
||||
AutoConfigurations.of(UtilAutoConfiguration.class, ReactiveCommonsClientAutoConfiguration.class,
|
||||
private ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(UtilAutoConfiguration.class,
|
||||
ReactiveCommonsClientAutoConfiguration.class, KubernetesCommonsAutoConfiguration.class,
|
||||
KubernetesAutoConfiguration.class, KubernetesDiscoveryClientAutoConfiguration.class,
|
||||
KubernetesReactiveDiscoveryClientAutoConfiguration.class));
|
||||
|
||||
|
||||
@@ -31,6 +31,10 @@
|
||||
<name>Spring Cloud Kubernetes :: Starter :: Config</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-kubernetes-commons</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-kubernetes-core</artifactId>
|
||||
|
||||
@@ -31,6 +31,10 @@
|
||||
<name>Spring Cloud Kubernetes :: Starter</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-kubernetes-commons</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-kubernetes-core</artifactId>
|
||||
|
||||
Reference in New Issue
Block a user