Skip to content

docs: migration to 4.4 #1950

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 21, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions docs/_data/sidebar.yml
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@
url: /docs/glossary
- title: Features
url: /docs/features
- title: Dependent Resource Feature
- title: Dependent Resources
url: /docs/dependent-resources
- title: Workflows
url: /docs/workflows
@@ -26,4 +26,8 @@
- title: Migrating from v2 to v3
url: /docs/v3-migration
- title: Migrating from v3 to v3.1
url: /docs/v3-1-migration
url: /docs/v3-1-migration
- title: Migrating from v4.2 to v4.3
url: /docs/v4-3-migration
- title: Migrating from v4.3 to v4.4
url: /docs/v4-4-migration
76 changes: 76 additions & 0 deletions docs/documentation/v4-4-migration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
---
title: Migrating from v4.3 to v4.4
description: Migrating from v4.3 to v4.4
layout: docs
permalink: /docs/v4-4-migration
---

# Migrating from v4.3 to v4.4

## API changes

### ConfigurationService

We have simplified how to deal with the Kubernetes client. Previous versions provided direct
access to underlying aspects of the client's configuration or serialization mechanism. However,
the link between these aspects wasn't as explicit as it should have been. Moreover, the Fabric8
client framework has also revised their serialization architecture in the 6.7 version (see [this
fabric8 pull request](https://github.com/fabric8io/kubernetes-client/pull/4662) for a discussion of
that change), moving from statically configured serialization to a per-client configuration
(though it's still possible to share serialization mechanism between client instances). As a
consequence, we made the following changes to the `ConfigurationService` API:

- Replaced `getClientConfiguration` and `getObjectMapper` methods by a new `getKubernetesClient`
method: instead of providing the configuration and mapper, you now provide a client instance
configured according to your needs and the SDK will extract the needed information from it

If you had previously configured a custom configuration or `ObjectMapper`, it is now recommended
that you do so when creating your client instance, as follows, usually using
`ConfigurationServiceOverrider.withKubernetesClient`:

```java

class Example {

public static void main(String[] args) {
Config config; // your configuration
ObjectMapper mapper; // your mapper
final var operator = new Operator(overrider -> overrider.withKubernetesClient(
new KubernetesClientBuilder()
.withConfig(config)
.withKubernetesSerialization(new KubernetesSerialization(mapper, true))
.build()
));
}
}
```

Consequently, it is now recommended to get the client instance from the `ConfigurationService`.

### Operator

It is now recommended to configure your Operator instance by using a
`ConfigurationServiceOverrider` when creating it. This allows you to change the default
configuration values as needed. In particular, instead of passing a Kubernetes client instance
explicitly to the Operator constructor, it is now recommended to provide that value using
`ConfigurationServiceOverrider.withKubernetesClient` as shown above.

## Using Server-Side Apply in Dependent Resources

From this version by
default [Dependent Resources](https://javaoperatorsdk.io/docs/dependent-resources) use
[Server Side Apply (SSA)](https://kubernetes.io/docs/reference/using-api/server-side-apply/) to
create and
update Kubernetes resources. A
new [default matching](https://github.com/java-operator-sdk/java-operator-sdk/blob/e95f9c8a8b8a8561c9a735e60fc5d82b7758df8e/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResource.java#L163-L163)
algorithm is provided for `KubernetesDependentResource` that is based on `managedFields` of SSA. For
details
see [SSABasedGenericKubernetesResourceMatcher](https://github.com/java-operator-sdk/java-operator-sdk/blob/e95f9c8a8b8a8561c9a735e60fc5d82b7758df8e/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/SSABasedGenericKubernetesResourceMatcher.java)

Since those features are hard to completely test, we provided feature flags to revert to the
legacy behavior if needed,
see those
in [ConfigurationService](https://github.com/java-operator-sdk/java-operator-sdk/blob/e95f9c8a8b8a8561c9a735e60fc5d82b7758df8e/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java#L268-L289)

Note that it is possible to override the related methods/behavior on class level when extending
the `KubernetesDependentResource`.
Original file line number Diff line number Diff line change
@@ -67,16 +67,13 @@ public Operator(Consumer<ConfigurationServiceOverrider> overrider) {
}

/**
* Note that Operator by default closes the client on stop, this can be changed using
* {@link ConfigurationService}
*
* @param client client to use to all Kubernetes related operations
* @param overrider a {@link ConfigurationServiceOverrider} consumer used to override the default
* {@link ConfigurationService} values
* @deprecated Use {@link Operator#Operator(Consumer)} instead, passing your custom client with
* {@link ConfigurationServiceOverrider#withKubernetesClient(KubernetesClient)}
*/
@Deprecated
@Deprecated(since = "4.4.0")
public Operator(KubernetesClient client, Consumer<ConfigurationServiceOverrider> overrider) {
this(initConfigurationService(client, overrider));
}
Original file line number Diff line number Diff line change
@@ -42,9 +42,12 @@ public interface ConfigurationService {


/**
* Used to clone custom resources. It is strongly suggested that implementors override this method
* since the default implementation creates a new {@link Cloner} instance each time this method is
* called.
* Used to clone custom resources.
*
* <p>
* <em>NOTE:</em> It is strongly suggested that implementors override this method since the
* default implementation creates a new {@link Cloner} instance each time this method is called.
* </p>
*
* @return the configured {@link Cloner}
*/
@@ -57,6 +60,32 @@ public <R extends HasMetadata> R clone(R object) {
};
}

/**
* Provides the fully configured {@link KubernetesClient} to use for controllers to the target
* cluster. Note that this client only needs to be able to connect to the cluster, the SDK will
* take care of creating the required connections to watch the target resources (in particular,
* you do not need to worry about setting the namespace information in most cases).
*
* <p>
* Previous versions of this class provided direct access to the serialization mechanism (via
* {@link com.fasterxml.jackson.databind.ObjectMapper}) or the client's configuration. This was
* somewhat confusing, in particular with respect to changes made in the Fabric8 client
* serialization architecture made in 6.7. The proper way to configure these aspects is now to
* configure the Kubernetes client accordingly and the SDK will extract the information it needs
* from this instance. The recommended way to do so is to create your operator with
* {@link io.javaoperatorsdk.operator.Operator#Operator(Consumer)}, passing your custom instance
* with {@link ConfigurationServiceOverrider#withKubernetesClient(KubernetesClient)}.
* </p>
*
* <p>
* <em>NOTE:</em> It is strongly suggested that implementors override this method since the
* default implementation creates a new {@link KubernetesClient} instance each time this method is
* called.
* </p>
*
* @return the configured {@link KubernetesClient}
* @since 4.4.0
*/
default KubernetesClient getKubernetesClient() {
return new KubernetesClientBuilder()
.withConfig(new ConfigBuilder(Config.autoConfigure(null))
@@ -242,6 +271,25 @@ default ResourceClassResolver getResourceClassResolver() {
return new DefaultResourceClassResolver();
}

/**
* Creates a new {@link ConfigurationService} instance used to configure an
* {@link io.javaoperatorsdk.operator.Operator} instance, starting from the specified base
* configuration and overriding specific aspects according to the provided
* {@link ConfigurationServiceOverrider} instance.
*
* <p>
* <em>NOTE:</em> This overriding mechanism should only be used <strong>before</strong> creating
* your Operator instance as the configuration service is set at creation time and cannot be
* subsequently changed. As a result, overriding values this way after the Operator has been
* configured will not take effect.
* </p>
*
* @param baseConfiguration the {@link ConfigurationService} to start from
* @param overrider the {@link ConfigurationServiceOverrider} used to change the values provided
* by the base configuration
* @return a new {@link ConfigurationService} starting from the configuration provided as base but
* with overridden values.
*/
static ConfigurationService newOverriddenConfigurationService(
ConfigurationService baseConfiguration,
Consumer<ConfigurationServiceOverrider> overrider) {
@@ -253,6 +301,25 @@ static ConfigurationService newOverriddenConfigurationService(
return baseConfiguration;
}

/**
* Creates a new {@link ConfigurationService} instance used to configure an
* {@link io.javaoperatorsdk.operator.Operator} instance, starting from the default configuration
* and overriding specific aspects according to the provided {@link ConfigurationServiceOverrider}
* instance.
*
* <p>
* <em>NOTE:</em> This overriding mechanism should only be used <strong>before</strong> creating
* your Operator instance as the configuration service is set at creation time and cannot be
* subsequently changed. As a result, overriding values this way after the Operator has been
* configured will not take effect.
* </p>
*
* @param overrider the {@link ConfigurationServiceOverrider} used to change the values provided
* by the default configuration
* @return a new {@link ConfigurationService} overriding the default values with the ones provided
* by the specified {@link ConfigurationServiceOverrider}
* @since 4.4.0
*/
static ConfigurationService newOverriddenConfigurationService(
Consumer<ConfigurationServiceOverrider> overrider) {
return newOverriddenConfigurationService(new BaseConfigurationService(), overrider);
@@ -269,6 +336,8 @@ default ExecutorServiceManager getExecutorServiceManager() {
* <a href="https://kubernetes.io/docs/reference/using-api/server-side-apply/">Server-Side
* Apply</a> (SSA) by default. Note that the legacy approach, and this setting, might be removed
* in the future.
*
* @since 4.4.0
*/
default boolean ssaBasedCreateUpdateForDependentResources() {
return true;
@@ -280,6 +349,8 @@ default boolean ssaBasedCreateUpdateForDependentResources() {
* Dependent Resources which is quite complex. As a consequence, we introduced this setting to
* allow folks to revert to the previous matching algorithm if needed. Note, however, that the
* legacy algorithm, and this setting, might be removed in the future.
*
* @since 4.4.0
*/
default boolean ssaBasedDefaultMatchingForDependentResources() {
return true;
Original file line number Diff line number Diff line change
@@ -105,6 +105,13 @@ public ConfigurationServiceOverrider withWorkflowExecutorService(
return this;
}

/**
* Replaces the default {@link KubernetesClient} instance by the specified one. This is the
* preferred mechanism to configure which client will be used to access the cluster.
*
* @param client the fully configured client to use for cluster access
* @return this {@link ConfigurationServiceOverrider} for chained customization
*/
public ConfigurationServiceOverrider withKubernetesClient(KubernetesClient client) {
this.client = client;
return this;