Pass ApiClient to SharedInformer (#903)
* Pass ApiClient to SharedInformer. Fixes #885
This commit is contained in:
@@ -31,6 +31,12 @@ public final class KubernetesClientUtils {
|
||||
private KubernetesClientUtils() {
|
||||
}
|
||||
|
||||
public static ApiClient createApiClientForInformerClient() {
|
||||
ApiClient apiClient = kubernetesApiClient();
|
||||
apiClient.setReadTimeout(0);
|
||||
return apiClient;
|
||||
}
|
||||
|
||||
public static ApiClient kubernetesApiClient() {
|
||||
try {
|
||||
// Assume we are running in a cluster
|
||||
|
||||
@@ -16,20 +16,16 @@
|
||||
|
||||
package org.springframework.cloud.kubernetes.client.config.reload;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
|
||||
import io.kubernetes.client.informer.ResourceEventHandler;
|
||||
import io.kubernetes.client.informer.SharedIndexInformer;
|
||||
import io.kubernetes.client.informer.SharedInformerFactory;
|
||||
import io.kubernetes.client.openapi.ApiClient;
|
||||
import io.kubernetes.client.openapi.apis.CoreV1Api;
|
||||
import io.kubernetes.client.openapi.models.V1ConfigMap;
|
||||
import io.kubernetes.client.openapi.models.V1ConfigMapList;
|
||||
import io.kubernetes.client.util.CallGeneratorParams;
|
||||
import okhttp3.OkHttpClient;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
@@ -42,7 +38,7 @@ import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationC
|
||||
import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationUpdateStrategy;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
|
||||
import static org.springframework.cloud.kubernetes.client.KubernetesClientUtils.kubernetesApiClient;
|
||||
import static org.springframework.cloud.kubernetes.client.KubernetesClientUtils.createApiClientForInformerClient;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
@@ -69,7 +65,7 @@ public class KubernetesClientEventBasedConfigMapChangeDetector extends Configura
|
||||
super(environment, properties, strategy);
|
||||
this.propertySourceLocator = propertySourceLocator;
|
||||
this.coreV1Api = coreV1Api;
|
||||
this.factory = new SharedInformerFactory();
|
||||
this.factory = new SharedInformerFactory(createApiClientForInformerClient());
|
||||
this.kubernetesClientProperties = kubernetesClientProperties;
|
||||
}
|
||||
|
||||
@@ -80,7 +76,12 @@ public class KubernetesClientEventBasedConfigMapChangeDetector extends Configura
|
||||
super(environment, properties, strategy);
|
||||
this.propertySourceLocator = propertySourceLocator;
|
||||
this.coreV1Api = coreV1Api;
|
||||
this.factory = new SharedInformerFactory();
|
||||
// We need to pass an APIClient to the SharedInformerFactory because if we use the default
|
||||
// constructor it will use the configured default APIClient but that may not contain
|
||||
// an APIClient configured within the cluster and does not contain the necessary
|
||||
// certificate authorities for the cluster. This results in SSL errors.
|
||||
// See https://github.com/spring-cloud/spring-cloud-kubernetes/issues/885
|
||||
this.factory = new SharedInformerFactory(createApiClientForInformerClient());
|
||||
this.kubernetesNamespaceProvider = kubernetesNamespaceProvider;
|
||||
}
|
||||
|
||||
@@ -92,16 +93,7 @@ public class KubernetesClientEventBasedConfigMapChangeDetector extends Configura
|
||||
super(environment, properties, strategy);
|
||||
this.propertySourceLocator = propertySourceLocator;
|
||||
this.kubernetesClientProperties = kubernetesClientProperties;
|
||||
try {
|
||||
ApiClient apiClient = kubernetesApiClient();
|
||||
OkHttpClient httpClient = apiClient.getHttpClient().newBuilder().readTimeout(0, TimeUnit.SECONDS).build();
|
||||
apiClient.setHttpClient(httpClient);
|
||||
this.coreV1Api = new CoreV1Api(apiClient);
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.error("Failed to create Kubernetes API client. Event based ConfigMap monitoring will not work", e);
|
||||
}
|
||||
this.factory = new SharedInformerFactory();
|
||||
this.factory = new SharedInformerFactory(createApiClientForInformerClient());
|
||||
}
|
||||
|
||||
private String getNamespace() {
|
||||
|
||||
@@ -16,19 +16,15 @@
|
||||
|
||||
package org.springframework.cloud.kubernetes.client.config.reload;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import io.kubernetes.client.informer.ResourceEventHandler;
|
||||
import io.kubernetes.client.informer.SharedIndexInformer;
|
||||
import io.kubernetes.client.informer.SharedInformerFactory;
|
||||
import io.kubernetes.client.openapi.ApiClient;
|
||||
import io.kubernetes.client.openapi.apis.CoreV1Api;
|
||||
import io.kubernetes.client.openapi.models.V1Secret;
|
||||
import io.kubernetes.client.openapi.models.V1SecretList;
|
||||
import io.kubernetes.client.util.CallGeneratorParams;
|
||||
import okhttp3.OkHttpClient;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
@@ -41,7 +37,7 @@ import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationC
|
||||
import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationUpdateStrategy;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
|
||||
import static org.springframework.cloud.kubernetes.client.KubernetesClientUtils.kubernetesApiClient;
|
||||
import static org.springframework.cloud.kubernetes.client.KubernetesClientUtils.createApiClientForInformerClient;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
@@ -67,7 +63,7 @@ public class KubernetesClientEventBasedSecretsChangeDetector extends Configurati
|
||||
KubernetesClientProperties kubernetesClientProperties) {
|
||||
super(environment, properties, strategy);
|
||||
this.propertySourceLocator = propertySourceLocator;
|
||||
this.factory = new SharedInformerFactory();
|
||||
this.factory = new SharedInformerFactory(createApiClientForInformerClient());
|
||||
this.coreV1Api = coreV1Api;
|
||||
this.kubernetesClientProperties = kubernetesClientProperties;
|
||||
}
|
||||
@@ -78,7 +74,12 @@ public class KubernetesClientEventBasedSecretsChangeDetector extends Configurati
|
||||
KubernetesNamespaceProvider kubernetesNamespaceProvider) {
|
||||
super(environment, properties, strategy);
|
||||
this.propertySourceLocator = propertySourceLocator;
|
||||
this.factory = new SharedInformerFactory();
|
||||
// We need to pass an APIClient to the SharedInformerFactory because if we use the default
|
||||
// constructor it will use the configured default APIClient but that may not contain
|
||||
// an APIClient configured within the cluster and does not contain the necessary
|
||||
// certificate authorities for the cluster. This results in SSL errors.
|
||||
// See https://github.com/spring-cloud/spring-cloud-kubernetes/issues/885
|
||||
this.factory = new SharedInformerFactory(createApiClientForInformerClient());
|
||||
this.coreV1Api = coreV1Api;
|
||||
this.kubernetesNamespaceProvider = kubernetesNamespaceProvider;
|
||||
}
|
||||
@@ -90,17 +91,8 @@ public class KubernetesClientEventBasedSecretsChangeDetector extends Configurati
|
||||
KubernetesClientProperties kubernetesClientProperties) {
|
||||
super(environment, properties, strategy);
|
||||
this.propertySourceLocator = propertySourceLocator;
|
||||
this.factory = new SharedInformerFactory();
|
||||
this.factory = new SharedInformerFactory(createApiClientForInformerClient());
|
||||
this.kubernetesClientProperties = kubernetesClientProperties;
|
||||
try {
|
||||
ApiClient apiClient = kubernetesApiClient();
|
||||
OkHttpClient httpClient = apiClient.getHttpClient().newBuilder().readTimeout(0, TimeUnit.SECONDS).build();
|
||||
apiClient.setHttpClient(httpClient);
|
||||
this.coreV1Api = new CoreV1Api(apiClient);
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.error("Failed to create Kubernetes API client. Event based ConfigMap monitoring will not work", e);
|
||||
}
|
||||
}
|
||||
|
||||
private String getNamespace() {
|
||||
|
||||
@@ -207,15 +207,14 @@ public class KubernetesClientConfigReloadAutoConfigurationTest {
|
||||
return properties;
|
||||
}
|
||||
|
||||
@ConditionalOnMissingBean(ApiClient.class)
|
||||
@Bean
|
||||
ApiClient apiClient() {
|
||||
ApiClient apiClient = new ClientBuilder().setBasePath(wireMockServer.baseUrl()).build();
|
||||
apiClient.setDebugging(true);
|
||||
apiClient.setReadTimeout(0);
|
||||
return apiClient;
|
||||
}
|
||||
|
||||
@ConditionalOnMissingBean(CoreV1Api.class)
|
||||
@Bean
|
||||
CoreV1Api coreApi(ApiClient apiClient) {
|
||||
return new CoreV1Api(apiClient);
|
||||
|
||||
@@ -30,9 +30,9 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@SpringBootTest(classes = TestApplication.class,
|
||||
properties = { "spring.application.name=testapp", "spring.cloud.kubernetes.client.namespace=testns",
|
||||
"spring.cloud.kubernetes.client.trustCerts=true", "spring.cloud.kubernetes.config.namespace=testns",
|
||||
"spring.cloud.kubernetes.secrets.enableApi=true" })
|
||||
properties = { "spring.application.name=testapp", "spring.cloud.kubernetes.client.namespace=testns",
|
||||
"spring.cloud.kubernetes.client.trustCerts=true", "spring.cloud.kubernetes.config.namespace=testns",
|
||||
"spring.cloud.kubernetes.secrets.enableApi=true" })
|
||||
public class CoreTestClientViaSystemProperties {
|
||||
|
||||
@Autowired
|
||||
|
||||
@@ -63,6 +63,31 @@
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>skaffold</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<image>
|
||||
<name>${env.IMAGE}</name>
|
||||
</image>
|
||||
<goal>build-image</goal>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>build-image</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>imagename</id>
|
||||
<activation>
|
||||
|
||||
@@ -6,7 +6,7 @@ build:
|
||||
artifacts:
|
||||
- image: springcloud/spring-cloud-kubernetes-client-config-it
|
||||
custom:
|
||||
buildCommand: "../../mvnw clean install"
|
||||
buildCommand: "../../mvnw clean install -Pskaffold"
|
||||
dependencies:
|
||||
paths:
|
||||
- src
|
||||
|
||||
Reference in New Issue
Block a user