diff --git a/pom.xml b/pom.xml index 2fcbeae7..f45cce5d 100644 --- a/pom.xml +++ b/pom.xml @@ -87,6 +87,7 @@ spring-cloud-kubernetes-dependencies + spring-cloud-kubernetes-commons spring-cloud-kubernetes-core spring-cloud-kubernetes-config spring-cloud-kubernetes-discovery diff --git a/spring-cloud-kubernetes-commons/pom.xml b/spring-cloud-kubernetes-commons/pom.xml new file mode 100644 index 00000000..b67c8c5f --- /dev/null +++ b/spring-cloud-kubernetes-commons/pom.xml @@ -0,0 +1,42 @@ + + + + org.springframework.cloud + spring-cloud-kubernetes + 2.0.0-SNAPSHOT + + 4.0.0 + + spring-cloud-kubernetes-commons + + + + org.springframework.boot + spring-boot-autoconfigure + + + org.springframework.boot + spring-boot-actuator-autoconfigure + true + + + org.springframework.boot + spring-boot-configuration-processor + true + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.vintage + junit-vintage-engine + test + + + + + diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/AbstractKubernetesHealthIndicator.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/AbstractKubernetesHealthIndicator.java new file mode 100644 index 00000000..d395ad11 --- /dev/null +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/AbstractKubernetesHealthIndicator.java @@ -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 getDetails() throws Exception; + +} diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/AbstractKubernetesInfoContributor.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/AbstractKubernetesInfoContributor.java new file mode 100644 index 00000000..3327f19f --- /dev/null +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/AbstractKubernetesInfoContributor.java @@ -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 getDetails(); + +} diff --git a/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/ConditionalOnKubernetesEnabled.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/ConditionalOnKubernetesEnabled.java similarity index 91% rename from spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/ConditionalOnKubernetesEnabled.java rename to spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/ConditionalOnKubernetesEnabled.java index a9bbcfc2..b88ee4dc 100644 --- a/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/ConditionalOnKubernetesEnabled.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/ConditionalOnKubernetesEnabled.java @@ -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; diff --git a/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesClientProperties.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/KubernetesClientProperties.java similarity index 98% rename from spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesClientProperties.java rename to spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/KubernetesClientProperties.java index d8783e41..b2bfaa6f 100644 --- a/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesClientProperties.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/KubernetesClientProperties.java @@ -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; diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/KubernetesCommonsAutoConfiguration.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/KubernetesCommonsAutoConfiguration.java new file mode 100644 index 00000000..22bc4420 --- /dev/null +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/KubernetesCommonsAutoConfiguration.java @@ -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 { + +} diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/profile/AbstractKubernetesProfileEnvironmentPostProcessor.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/profile/AbstractKubernetesProfileEnvironmentPostProcessor.java new file mode 100644 index 00000000..616c33d1 --- /dev/null +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/profile/AbstractKubernetesProfileEnvironmentPostProcessor.java @@ -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; + } + +} diff --git a/spring-cloud-kubernetes-core/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-kubernetes-commons/src/main/resources/META-INF/additional-spring-configuration-metadata.json similarity index 100% rename from spring-cloud-kubernetes-core/src/main/resources/META-INF/additional-spring-configuration-metadata.json rename to spring-cloud-kubernetes-commons/src/main/resources/META-INF/additional-spring-configuration-metadata.json diff --git a/spring-cloud-kubernetes-commons/src/main/resources/META-INF/spring.factories b/spring-cloud-kubernetes-commons/src/main/resources/META-INF/spring.factories new file mode 100644 index 00000000..85a298fb --- /dev/null +++ b/spring-cloud-kubernetes-commons/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +org.springframework.cloud.kubernetes.commons.KubernetesCommonsAutoConfiguration diff --git a/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/KubernetesCommonsAutoConfigurationTests.java b/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/KubernetesCommonsAutoConfigurationTests.java new file mode 100644 index 00000000..51c73510 --- /dev/null +++ b/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/KubernetesCommonsAutoConfigurationTests.java @@ -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 { + + } + +} diff --git a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/BootstrapConfiguration.java b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/BootstrapConfiguration.java index 4754fecf..dc243f09 100644 --- a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/BootstrapConfiguration.java +++ b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/BootstrapConfiguration.java @@ -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 { diff --git a/spring-cloud-kubernetes-core/pom.xml b/spring-cloud-kubernetes-core/pom.xml index 112105a6..c8980516 100644 --- a/spring-cloud-kubernetes-core/pom.xml +++ b/spring-cloud-kubernetes-core/pom.xml @@ -44,6 +44,10 @@ + + org.springframework.cloud + spring-cloud-kubernetes-commons + org.springframework.boot spring-boot-starter-logging diff --git a/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesAutoConfiguration.java b/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesAutoConfiguration.java index 425e6b0f..67e78455 100644 --- a/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesAutoConfiguration.java +++ b/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesAutoConfiguration.java @@ -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); diff --git a/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesHealthIndicator.java b/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesHealthIndicator.java index 8aef880e..aacf8d9d 100644 --- a/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesHealthIndicator.java +++ b/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesHealthIndicator.java @@ -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 getDetails() throws Exception { + Map 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; } } diff --git a/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesInfoContributor.java b/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesInfoContributor.java index c53e64ac..f35b2ce4 100644 --- a/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesInfoContributor.java +++ b/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesInfoContributor.java @@ -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 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 getDetails() { + Pod current = this.utils.currentPod().get(); + Map 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; } } diff --git a/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/profile/KubernetesProfileEnvironmentPostProcessor.java b/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/profile/KubernetesProfileEnvironmentPostProcessor.java index 8c4070cd..85285ce6 100644 --- a/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/profile/KubernetesProfileEnvironmentPostProcessor.java +++ b/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/profile/KubernetesProfileEnvironmentPostProcessor.java @@ -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; - } - } diff --git a/spring-cloud-kubernetes-core/src/test/java/org/springframework/cloud/kubernetes/KubernetesAutoConfigurationTests.java b/spring-cloud-kubernetes-core/src/test/java/org/springframework/cloud/kubernetes/KubernetesAutoConfigurationTests.java index 2f00210a..a31351c0 100644 --- a/spring-cloud-kubernetes-core/src/test/java/org/springframework/cloud/kubernetes/KubernetesAutoConfigurationTests.java +++ b/spring-cloud-kubernetes-core/src/test/java/org/springframework/cloud/kubernetes/KubernetesAutoConfigurationTests.java @@ -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"); diff --git a/spring-cloud-kubernetes-dependencies/pom.xml b/spring-cloud-kubernetes-dependencies/pom.xml index 6262bc1f..85c996e2 100644 --- a/spring-cloud-kubernetes-dependencies/pom.xml +++ b/spring-cloud-kubernetes-dependencies/pom.xml @@ -87,6 +87,12 @@ ${project.version} + + org.springframework.cloud + spring-cloud-kubernetes-commons + ${project.version} + + org.springframework.cloud spring-cloud-kubernetes-loadbalancer diff --git a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientAutoConfiguration.java b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientAutoConfiguration.java index 6bc15592..e35e61b3 100644 --- a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientAutoConfiguration.java +++ b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientAutoConfiguration.java @@ -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; diff --git a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/reactive/KubernetesReactiveDiscoveryClientAutoConfiguration.java b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/reactive/KubernetesReactiveDiscoveryClientAutoConfiguration.java index 7546c000..d2e19f42 100644 --- a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/reactive/KubernetesReactiveDiscoveryClientAutoConfiguration.java +++ b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/reactive/KubernetesReactiveDiscoveryClientAutoConfiguration.java @@ -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; diff --git a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientAutoConfigurationTests.java b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientAutoConfigurationTests.java index 1bbb4af5..cf46d24a 100644 --- a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientAutoConfigurationTests.java +++ b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientAutoConfigurationTests.java @@ -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 { } diff --git a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientConfigClientBootstrapConfigurationTests.java b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientConfigClientBootstrapConfigurationTests.java index dbf8ce6d..a7ca2da8 100644 --- a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientConfigClientBootstrapConfigurationTests.java +++ b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientConfigClientBootstrapConfigurationTests.java @@ -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(); } diff --git a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/reactive/KubernetesReactiveDiscoveryClientAutoConfigurationTests.java b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/reactive/KubernetesReactiveDiscoveryClientAutoConfigurationTests.java index 338bc737..a1120f90 100644 --- a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/reactive/KubernetesReactiveDiscoveryClientAutoConfigurationTests.java +++ b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/reactive/KubernetesReactiveDiscoveryClientAutoConfigurationTests.java @@ -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)); diff --git a/spring-cloud-starter-kubernetes-config/pom.xml b/spring-cloud-starter-kubernetes-config/pom.xml index 35b167b4..f4755f06 100644 --- a/spring-cloud-starter-kubernetes-config/pom.xml +++ b/spring-cloud-starter-kubernetes-config/pom.xml @@ -31,6 +31,10 @@ Spring Cloud Kubernetes :: Starter :: Config + + org.springframework.cloud + spring-cloud-kubernetes-commons + org.springframework.cloud spring-cloud-kubernetes-core diff --git a/spring-cloud-starter-kubernetes/pom.xml b/spring-cloud-starter-kubernetes/pom.xml index 9b17a860..84aa6373 100644 --- a/spring-cloud-starter-kubernetes/pom.xml +++ b/spring-cloud-starter-kubernetes/pom.xml @@ -31,6 +31,10 @@ Spring Cloud Kubernetes :: Starter + + org.springframework.cloud + spring-cloud-kubernetes-commons + org.springframework.cloud spring-cloud-kubernetes-core