Skip to content

Commit

Permalink
fix (kubernetes-client-api) : Config's autoConfigure should disab…
Browse files Browse the repository at this point in the history
…le auto configuration

`Config`'s autoConfigure field should behave as per expectations. In
order to make auto configuration configurable via builder, we need to
move it after builder initialization is done. Do not autoConfigure in the
default constructor `new Config()`.

Auto configuration would be done in the final constructor annotated with
the sundrio's `@Buildable` annotation. Then merge user provided fields
with autoConfigured values.

Signed-off-by: Rohan Kumar <[email protected]>
  • Loading branch information
rohanKanojia committed Jul 21, 2024
1 parent ad4fcaf commit c1a47c8
Show file tree
Hide file tree
Showing 5 changed files with 520 additions and 94 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#### Bugs
* Fix #6038: Support for Gradle configuration cache
* Fix #6110: VolumeSource (and other file mode fields) in Octal are correctly interpreted
* Fix #6137: `ConfigBuilder.withAutoConfigure` is not working

#### Improvements
* Fix #6008: removing the optional dependency on bouncy castle
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public class Config {
private static final Logger LOGGER = LoggerFactory.getLogger(Config.class);

/**
* Disables auto-configuration based on opinionated defaults in a {@link Config} object in the default constructor
* Disables auto-configuration based on opinionated defaults in a {@link Config} object in the Builder constructor
*/
public static final String KUBERNETES_DISABLE_AUTO_CONFIG_SYSTEM_PROPERTY = "kubernetes.disable.autoConfig";
public static final String KUBERNETES_MASTER_SYSTEM_PROPERTY = "kubernetes.master";
Expand Down Expand Up @@ -151,6 +151,9 @@ public class Config {

private static final String ACCESS_TOKEN = "access-token";
private static final String ID_TOKEN = "id-token";
private static final TlsVersion[] DEFAULT_TLS_VERSIONS_LIST = new TlsVersion[] { TlsVersion.TLS_1_3, TlsVersion.TLS_1_2 };
private static final int DEFAULT_WATCH_RECONNECT_INTERVAL = 1000;
private static final int DEFAULT_CONNECTION_TIMEOUT = 10 * 1000;

private boolean trustCerts;
private boolean disableHostnameVerification;
Expand Down Expand Up @@ -178,7 +181,7 @@ public class Config {
private volatile String autoOAuthToken;
private OAuthTokenProvider oauthTokenProvider;
private long websocketPingInterval = DEFAULT_WEBSOCKET_PING_INTERVAL;
private int connectionTimeout = 10 * 1000;
private int connectionTimeout = DEFAULT_CONNECTION_TIMEOUT;
private int maxConcurrentRequests = DEFAULT_MAX_CONCURRENT_REQUESTS;
private int maxConcurrentRequestsPerHost = DEFAULT_MAX_CONCURRENT_REQUESTS_PER_HOST;

Expand All @@ -190,7 +193,7 @@ public class Config {
/**
* fields not used but needed for builder generation.
*/
private int watchReconnectInterval = 1000;
private int watchReconnectInterval = DEFAULT_WATCH_RECONNECT_INTERVAL;
private int watchReconnectLimit = -1;
private int uploadRequestTimeout = DEFAULT_UPLOAD_REQUEST_TIMEOUT;
private int requestRetryBackoffLimit;
Expand Down Expand Up @@ -218,7 +221,7 @@ public class Config {
private String proxyPassword;
private String[] noProxy;
private String userAgent = "fabric8-kubernetes-client/" + Version.clientVersion();
private TlsVersion[] tlsVersions = new TlsVersion[] { TlsVersion.TLS_1_3, TlsVersion.TLS_1_2 };
private TlsVersion[] tlsVersions = DEFAULT_TLS_VERSIONS_LIST;

private boolean onlyHttpWatches;

Expand All @@ -239,7 +242,7 @@ public class Config {
*/
@Deprecated
public Config() {
this(!disableAutoConfig());
this.autoConfigure = true;
}

private static boolean disableAutoConfig() {
Expand Down Expand Up @@ -336,7 +339,7 @@ public Config(String masterUrl, String apiVersion, String namespace, boolean tru
DEFAULT_UPLOAD_REQUEST_TIMEOUT, false, null, Collections.emptyList());
}

@Buildable(builderPackage = "io.fabric8.kubernetes.api.builder", editableEnabled = false)
@Deprecated
public Config(String masterUrl, String apiVersion, String namespace, boolean trustCerts, boolean disableHostnameVerification,
String caCertFile, String caCertData, String clientCertFile, String clientCertData, String clientKeyFile,
String clientKeyData, String clientKeyAlgo, String clientKeyPassphrase, String username, String password,
Expand All @@ -350,56 +353,198 @@ public Config(String masterUrl, String apiVersion, String namespace, boolean tru
OAuthTokenProvider oauthTokenProvider, Map<String, String> customHeaders, int requestRetryBackoffLimit,
int requestRetryBackoffInterval, int uploadRequestTimeout, boolean onlyHttpWatches, NamedContext currentContext,
List<NamedContext> contexts) {
this.apiVersion = apiVersion;
this.namespace = namespace;
this.trustCerts = trustCerts;
this.disableHostnameVerification = disableHostnameVerification;
this.caCertFile = caCertFile;
this.caCertData = caCertData;
this.clientCertFile = clientCertFile;
this.clientCertData = clientCertData;
this.clientKeyFile = clientKeyFile;
this.clientKeyData = clientKeyData;
this.clientKeyAlgo = clientKeyAlgo;
this.clientKeyPassphrase = clientKeyPassphrase;
this.username = username;
this.password = password;
this.oauthToken = oauthToken;
this.websocketPingInterval = websocketPingInterval;
this.connectionTimeout = connectionTimeout;

this.requestConfig = new RequestConfig(watchReconnectLimit, watchReconnectInterval,
requestTimeout, scaleTimeout, loggingInterval,
requestRetryBackoffLimit, requestRetryBackoffInterval, uploadRequestTimeout);
this.requestConfig.setImpersonateUsername(impersonateUsername);
this.requestConfig.setImpersonateGroups(impersonateGroups);
this.requestConfig.setImpersonateExtras(impersonateExtras);
this(masterUrl, apiVersion, namespace, trustCerts, disableHostnameVerification, caCertFile, caCertData,
clientCertFile, clientCertData, clientKeyFile, clientKeyData, clientKeyAlgo, clientKeyPassphrase, username,
password, oauthToken, autoOAuthToken, watchReconnectInterval, watchReconnectLimit, connectionTimeout, requestTimeout,
scaleTimeout, loggingInterval, maxConcurrentRequests, maxConcurrentRequestsPerHost, http2Disable,
httpProxy, httpsProxy, noProxy, userAgent, tlsVersions, websocketPingInterval, proxyUsername, proxyPassword,
trustStoreFile, trustStorePassphrase, keyStoreFile, keyStorePassphrase, impersonateUsername, impersonateGroups,
impersonateExtras, oauthTokenProvider, customHeaders, requestRetryBackoffLimit, requestRetryBackoffInterval,
uploadRequestTimeout, onlyHttpWatches, currentContext, contexts, false);
}

this.http2Disable = http2Disable;
this.httpProxy = httpProxy;
this.httpsProxy = httpsProxy;
this.noProxy = noProxy;
this.proxyUsername = proxyUsername;
this.proxyPassword = proxyPassword;
this.userAgent = userAgent;
this.tlsVersions = tlsVersions;
this.trustStoreFile = trustStoreFile;
this.trustStorePassphrase = trustStorePassphrase;
this.keyStoreFile = keyStoreFile;
this.keyStorePassphrase = keyStorePassphrase;
this.oauthTokenProvider = oauthTokenProvider;
this.customHeaders = customHeaders;
@Buildable(builderPackage = "io.fabric8.kubernetes.api.builder", editableEnabled = false)
public Config(String masterUrl, String apiVersion, String namespace, boolean trustCerts, boolean disableHostnameVerification,
String caCertFile, String caCertData, String clientCertFile, String clientCertData, String clientKeyFile,
String clientKeyData, String clientKeyAlgo, String clientKeyPassphrase, String username, String password,
String oauthToken, String autoOAuthToken, int watchReconnectInterval, int watchReconnectLimit, int connectionTimeout,
int requestTimeout,
long scaleTimeout, int loggingInterval, int maxConcurrentRequests, int maxConcurrentRequestsPerHost,
boolean http2Disable, String httpProxy, String httpsProxy, String[] noProxy,
String userAgent, TlsVersion[] tlsVersions, long websocketPingInterval, String proxyUsername,
String proxyPassword, String trustStoreFile, String trustStorePassphrase, String keyStoreFile, String keyStorePassphrase,
String impersonateUsername, String[] impersonateGroups, Map<String, List<String>> impersonateExtras,
OAuthTokenProvider oauthTokenProvider, Map<String, String> customHeaders, int requestRetryBackoffLimit,
int requestRetryBackoffInterval, int uploadRequestTimeout, boolean onlyHttpWatches, NamedContext currentContext,
List<NamedContext> contexts, boolean autoConfigure) {
if (autoConfigure && !disableAutoConfig()) {
autoConfigure(this, null);
}
if (Utils.isNotNullOrEmpty(apiVersion)) {
this.apiVersion = apiVersion;
}
if (Utils.isNotNullOrEmpty(namespace)) {
this.namespace = namespace;
}
if (trustCerts) {
this.trustCerts = trustCerts;
}
if (disableHostnameVerification) {
this.disableHostnameVerification = disableHostnameVerification;
}
if (Utils.isNotNullOrEmpty(caCertData)) {
this.caCertData = caCertData;
}
if (Utils.isNotNullOrEmpty(caCertFile)) {
this.caCertFile = caCertFile;
}
if (Utils.isNotNullOrEmpty(clientCertFile)) {
this.clientCertFile = clientCertFile;
}
if (Utils.isNotNullOrEmpty(clientCertData)) {
this.clientCertData = clientCertData;
}
if (Utils.isNotNullOrEmpty(clientKeyFile)) {
this.clientKeyFile = clientKeyFile;
}
if (Utils.isNotNullOrEmpty(clientKeyData)) {
this.clientKeyData = clientKeyData;
}
if (Utils.isNotNullOrEmpty(clientKeyAlgo) && !clientKeyAlgo.equals("RSA")) {
this.clientKeyAlgo = clientKeyAlgo;
}
if (Utils.isNotNullOrEmpty(clientKeyPassphrase) && !clientKeyPassphrase.equals("changeit")) {
this.clientKeyPassphrase = clientKeyPassphrase;
}
if (Utils.isNotNullOrEmpty(username)) {
this.username = username;
}
if (Utils.isNotNullOrEmpty(password)) {
this.password = password;
}
if (Utils.isNotNullOrEmpty(oauthToken)) {
this.oauthToken = oauthToken;
}
if (websocketPingInterval != DEFAULT_WEBSOCKET_PING_INTERVAL) {
this.websocketPingInterval = websocketPingInterval;
}
if (connectionTimeout != DEFAULT_CONNECTION_TIMEOUT) {
this.connectionTimeout = connectionTimeout;
}
if (http2Disable) {
this.http2Disable = http2Disable;
}
if (Utils.isNotNullOrEmpty(httpProxy)) {
this.httpProxy = httpProxy;
}
if (Utils.isNotNullOrEmpty(httpsProxy)) {
this.httpsProxy = httpsProxy;
}
if (Utils.isNotNullOrEmpty(noProxy)) {
this.noProxy = noProxy;
}
if (Utils.isNotNullOrEmpty(proxyUsername)) {
this.proxyUsername = proxyUsername;
}
if (Utils.isNotNullOrEmpty(proxyPassword)) {
this.proxyPassword = proxyPassword;
}
if (Utils.isNotNullOrEmpty(userAgent)) {
this.userAgent = userAgent;
}
if (tlsVersions != null && tlsVersions.length > 0 && !Arrays.equals(tlsVersions, DEFAULT_TLS_VERSIONS_LIST)) {
this.tlsVersions = tlsVersions;
}
if (Utils.isNotNullOrEmpty(trustStoreFile)) {
this.trustStoreFile = trustStoreFile;
}
if (Utils.isNotNullOrEmpty(trustStorePassphrase)) {
this.trustStorePassphrase = trustStorePassphrase;
}
if (Utils.isNotNullOrEmpty(keyStoreFile)) {
this.keyStoreFile = keyStoreFile;
}
if (Utils.isNotNullOrEmpty(keyStorePassphrase)) {
this.keyStorePassphrase = keyStorePassphrase;
}
if (Utils.isNotNull(oauthTokenProvider)) {
this.oauthTokenProvider = oauthTokenProvider;
}
if (Utils.isNotNullOrEmpty(customHeaders)) {
this.customHeaders = customHeaders;
}

//We need to keep this after ssl configuration & masterUrl
//We set the masterUrl because it's needed by ensureHttps
this.masterUrl = masterUrl;
this.masterUrl = ensureEndsWithSlash(ensureHttps(masterUrl, this));
this.maxConcurrentRequests = maxConcurrentRequests;
this.maxConcurrentRequestsPerHost = maxConcurrentRequestsPerHost;
this.autoOAuthToken = autoOAuthToken;
this.onlyHttpWatches = onlyHttpWatches;
this.contexts = contexts;
this.currentContext = currentContext;
if (Utils.isNotNullOrEmpty(masterUrl) && !masterUrl.equals(DEFAULT_MASTER_URL)) {
this.masterUrl = masterUrl;
this.masterUrl = ensureEndsWithSlash(ensureHttps(masterUrl, this));
}
if (maxConcurrentRequests != DEFAULT_MAX_CONCURRENT_REQUESTS) {
this.maxConcurrentRequests = maxConcurrentRequests;
}
if (maxConcurrentRequestsPerHost != DEFAULT_MAX_CONCURRENT_REQUESTS_PER_HOST) {
this.maxConcurrentRequestsPerHost = maxConcurrentRequestsPerHost;
}
if (Utils.isNotNullOrEmpty(autoOAuthToken)) {
this.autoOAuthToken = autoOAuthToken;
}
if (onlyHttpWatches) {
this.onlyHttpWatches = onlyHttpWatches;
}
if (contexts != null && !contexts.isEmpty()) {
this.contexts = contexts;
}
if (currentContext != null) {
this.currentContext = currentContext;
}

RequestConfig autoConfiguredRequestConfig = this.requestConfig;
this.requestConfig = mergeRequestConfig(new RequestConfig(watchReconnectLimit, watchReconnectInterval,
requestTimeout, scaleTimeout, loggingInterval,
requestRetryBackoffLimit, requestRetryBackoffInterval, uploadRequestTimeout), autoConfiguredRequestConfig);
this.requestConfig.setImpersonateUsername(
Optional.ofNullable(impersonateUsername).orElse(autoConfiguredRequestConfig.getImpersonateUsername()));
this.requestConfig.setImpersonateGroups(
Utils.isNotNullOrEmpty(impersonateGroups) ? impersonateGroups : autoConfiguredRequestConfig.getImpersonateGroups());
this.requestConfig.setImpersonateExtras(
Utils.isNotNullOrEmpty(impersonateExtras) ? impersonateExtras : autoConfiguredRequestConfig.getImpersonateExtras());
}

private RequestConfig mergeRequestConfig(RequestConfig userProvidedRequestConfig, RequestConfig autoConfiguredRequestConfig) {
RequestConfigBuilder requestConfigBuilder = new RequestConfigBuilder(userProvidedRequestConfig);
if (userProvidedRequestConfig.getRequestTimeout() == DEFAULT_REQUEST_TIMEOUT
&& autoConfiguredRequestConfig.getRequestTimeout() != DEFAULT_REQUEST_TIMEOUT) {
requestConfigBuilder.withRequestTimeout(autoConfiguredRequestConfig.getRequestTimeout());
}
if (userProvidedRequestConfig.getWatchReconnectLimit() == -1 && autoConfiguredRequestConfig.getWatchReconnectLimit() > 0) {
requestConfigBuilder.withWatchReconnectLimit(autoConfiguredRequestConfig.getWatchReconnectLimit());
}
if (userProvidedRequestConfig.getWatchReconnectInterval() == DEFAULT_WATCH_RECONNECT_INTERVAL
&& autoConfiguredRequestConfig.getWatchReconnectInterval() != DEFAULT_WATCH_RECONNECT_INTERVAL) {
requestConfigBuilder.withWatchReconnectInterval(autoConfiguredRequestConfig.getWatchReconnectInterval());
}
if (userProvidedRequestConfig.getRequestTimeout() == DEFAULT_REQUEST_TIMEOUT
&& autoConfiguredRequestConfig.getRequestTimeout() != DEFAULT_REQUEST_TIMEOUT) {
requestConfigBuilder.withRequestTimeout(autoConfiguredRequestConfig.getRequestTimeout());
}
if (userProvidedRequestConfig.getScaleTimeout() == DEFAULT_SCALE_TIMEOUT
&& autoConfiguredRequestConfig.getScaleTimeout() != DEFAULT_SCALE_TIMEOUT) {
requestConfigBuilder.withScaleTimeout(autoConfiguredRequestConfig.getScaleTimeout());
}
if (userProvidedRequestConfig.getRequestRetryBackoffLimit() == DEFAULT_REQUEST_RETRY_BACKOFFLIMIT
&& autoConfiguredRequestConfig.getRequestRetryBackoffLimit() != DEFAULT_REQUEST_RETRY_BACKOFFLIMIT) {
requestConfigBuilder.withRequestRetryBackoffLimit(autoConfiguredRequestConfig.getRequestRetryBackoffLimit());
}
if (userProvidedRequestConfig.getRequestRetryBackoffInterval() == DEFAULT_REQUEST_RETRY_BACKOFFINTERVAL
&& autoConfiguredRequestConfig.getRequestRetryBackoffInterval() != DEFAULT_REQUEST_RETRY_BACKOFFINTERVAL) {
requestConfigBuilder.withRequestRetryBackoffInterval(autoConfiguredRequestConfig.getRequestRetryBackoffInterval());
}
if (userProvidedRequestConfig.getUploadRequestTimeout() == DEFAULT_UPLOAD_REQUEST_TIMEOUT
&& autoConfiguredRequestConfig.getRequestTimeout() != DEFAULT_UPLOAD_REQUEST_TIMEOUT) {
requestConfigBuilder.withUploadRequestTimeout(autoConfiguredRequestConfig.getUploadRequestTimeout());
}
return requestConfigBuilder.build();
}

public static void configFromSysPropsOrEnvVars(Config config) {
Expand Down
Loading

0 comments on commit c1a47c8

Please sign in to comment.