Skip to content

Commit 69bd6e6

Browse files
committed
wip
Signed-off-by: Attila Mészáros <a_meszaros@apple.com> format Signed-off-by: Attila Mészáros <a_meszaros@apple.com> docs Signed-off-by: Attila Mészáros <a_meszaros@apple.com> feat: support to handle different cluster for InformerEventSource Signed-off-by: Attila Mészáros <a_meszaros@apple.com>
1 parent e364774 commit 69bd6e6

File tree

7 files changed

+125
-3
lines changed

7 files changed

+125
-3
lines changed

docs/content/en/docs/features/_index.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,24 @@ parts of reconciliation logic and during the execution of the controller:
606606

607607
For more information about MDC see this [link](https://www.baeldung.com/mdc-in-log4j-2-logback).
608608

609+
## InformerEventSource Multi-Cluster Support
610+
611+
It is possible to handle resources for remote cluster with `InformerEventSource`. To do so,
612+
simply just set a client that connects to a remote cluster:
613+
614+
```java
615+
616+
InformerEventSourceConfiguration<Tomcat> configuration =
617+
InformerEventSourceConfiguration.from(SecondaryResource.class, PrimaryResource.class)
618+
.withKubernetesClient(remoteClusterClient)
619+
.withSecondaryToPrimaryMapper(Mappers.fromDefaultAnnotations());
620+
621+
```
622+
623+
Of course, you will need to specify a `SecondaryToPrimaryMapper`, since the default that
624+
is based on owner references naturally won't work, rather use the one that supports annotations.
625+
626+
609627
## Dynamically Changing Target Namespaces
610628

611629
A controller can be configured to watch a specific set of namespaces in addition of the

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/InformerEventSourceConfiguration.java

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import io.fabric8.kubernetes.api.model.GenericKubernetesResource;
99
import io.fabric8.kubernetes.api.model.HasMetadata;
10+
import io.fabric8.kubernetes.client.KubernetesClient;
1011
import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
1112
import io.javaoperatorsdk.operator.api.config.DefaultResourceConfiguration;
1213
import io.javaoperatorsdk.operator.api.config.ResourceConfiguration;
@@ -74,6 +75,12 @@ default String name() {
7475
return getInformerConfig().getName();
7576
}
7677

78+
/**
79+
* Use of a specific kubernetes client, typically a client connects to a different cluster. Note
80+
* that this is solely for multi cluster support.
81+
*/
82+
KubernetesClient getKubernetesClient();
83+
7784
@SuppressWarnings("unchecked")
7885
@Override
7986
default Class<R> getResourceClass() {
@@ -86,17 +93,20 @@ class DefaultInformerEventSourceConfiguration<R extends HasMetadata> extends
8693
private final PrimaryToSecondaryMapper<?> primaryToSecondaryMapper;
8794
private final SecondaryToPrimaryMapper<R> secondaryToPrimaryMapper;
8895
private final GroupVersionKind groupVersionKind;
96+
private final KubernetesClient kubernetesClient;
8997

9098
protected DefaultInformerEventSourceConfiguration(
9199
Class<R> resourceClass,
92100
GroupVersionKind groupVersionKind,
93101
PrimaryToSecondaryMapper<?> primaryToSecondaryMapper,
94102
SecondaryToPrimaryMapper<R> secondaryToPrimaryMapper,
95-
InformerConfiguration<R> informerConfig) {
103+
InformerConfiguration<R> informerConfig,
104+
KubernetesClient kubernetesClient) {
96105
super(resourceClass, informerConfig);
97106
this.groupVersionKind = groupVersionKind;
98107
this.primaryToSecondaryMapper = primaryToSecondaryMapper;
99108
this.secondaryToPrimaryMapper = secondaryToPrimaryMapper;
109+
this.kubernetesClient = kubernetesClient;
100110
}
101111

102112
@Override
@@ -120,6 +130,11 @@ public Optional<GroupVersionKind> getGroupVersionKind() {
120130
return Optional.ofNullable(groupVersionKind);
121131
}
122132

133+
@Override
134+
public KubernetesClient getKubernetesClient() {
135+
return kubernetesClient;
136+
}
137+
123138
public boolean inheritsNamespacesFromController() {
124139
return InformerEventSourceConfiguration.inheritsNamespacesFromController(getNamespaces());
125140
}
@@ -145,6 +160,7 @@ class Builder<R extends HasMetadata> {
145160
private String name;
146161
private PrimaryToSecondaryMapper<?> primaryToSecondaryMapper;
147162
private SecondaryToPrimaryMapper<R> secondaryToPrimaryMapper;
163+
private KubernetesClient kubernetesClient;
148164

149165
private Builder(Class<R> resourceClass,
150166
Class<? extends HasMetadata> primaryResourceClass) {
@@ -189,6 +205,16 @@ public Builder<R> withSecondaryToPrimaryMapper(
189205
return this;
190206
}
191207

208+
/**
209+
* Use this is case want to create an InformerEventSource that handles resources from different
210+
* cluster.
211+
*/
212+
public Builder<R> withKubernetesClient(
213+
KubernetesClient kubernetesClient) {
214+
this.kubernetesClient = kubernetesClient;
215+
return this;
216+
}
217+
192218
public String getName() {
193219
return name;
194220
}
@@ -229,7 +255,7 @@ public InformerEventSourceConfiguration<R> build() {
229255
Objects.requireNonNullElse(secondaryToPrimaryMapper,
230256
Mappers.fromOwnerReferences(HasMetadata.getApiVersion(primaryResourceClass),
231257
HasMetadata.getKind(primaryResourceClass), false)),
232-
config.buildForInformerEventSource());
258+
config.buildForInformerEventSource(), kubernetesClient);
233259
}
234260
}
235261
}

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/InformerEventSource.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,9 @@ public class InformerEventSource<R extends HasMetadata, P extends HasMetadata>
7878

7979
public InformerEventSource(
8080
InformerEventSourceConfiguration<R> configuration, EventSourceContext<P> context) {
81-
this(configuration, context.getClient(),
81+
this(configuration,
82+
configuration.getKubernetesClient() != null ? configuration.getKubernetesClient()
83+
: context.getClient(),
8284
context.getControllerConfiguration().getConfigurationService()
8385
.parseResourceVersionsForEventFilteringAndCaching());
8486
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package io.javaoperatorsdk.operator.baseapi.informerremotecluster;
2+
3+
import io.fabric8.kubernetes.api.model.Namespaced;
4+
import io.fabric8.kubernetes.client.CustomResource;
5+
import io.fabric8.kubernetes.model.annotation.Group;
6+
import io.fabric8.kubernetes.model.annotation.ShortNames;
7+
import io.fabric8.kubernetes.model.annotation.Version;
8+
9+
@Group("sample.javaoperatorsdk")
10+
@Version("v1")
11+
@ShortNames("irc")
12+
public class InformerRemoteClusterCustomResource
13+
extends CustomResource<Void, InformerRemoteClusterStatus> implements Namespaced {
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package io.javaoperatorsdk.operator.baseapi.informerremotecluster;
2+
3+
import org.junit.jupiter.api.Test;
4+
import org.junit.jupiter.api.extension.RegisterExtension;
5+
6+
import io.javaoperatorsdk.jenvtest.junit.EnableKubeAPIServer;
7+
import io.javaoperatorsdk.operator.baseapi.labelselector.LabelSelectorTestReconciler;
8+
import io.javaoperatorsdk.operator.junit.LocallyRunOperatorExtension;
9+
10+
@EnableKubeAPIServer(apiServerFlags = {"--min-request-timeout", "1"})
11+
public class InformerRemoteClusterIT {
12+
13+
@RegisterExtension
14+
LocallyRunOperatorExtension extension =
15+
LocallyRunOperatorExtension.builder().withReconciler(new LabelSelectorTestReconciler())
16+
.build();
17+
18+
@Test
19+
void testRemoteClusterInformer() {
20+
21+
}
22+
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package io.javaoperatorsdk.operator.baseapi.informerremotecluster;
2+
3+
import java.util.List;
4+
5+
import io.javaoperatorsdk.operator.api.reconciler.Context;
6+
import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration;
7+
import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext;
8+
import io.javaoperatorsdk.operator.api.reconciler.Reconciler;
9+
import io.javaoperatorsdk.operator.api.reconciler.UpdateControl;
10+
import io.javaoperatorsdk.operator.processing.event.source.EventSource;
11+
12+
@ControllerConfiguration
13+
public class InformerRemoteClusterReconciler
14+
implements Reconciler<InformerRemoteClusterCustomResource> {
15+
16+
17+
@Override
18+
public UpdateControl<InformerRemoteClusterCustomResource> reconcile(
19+
InformerRemoteClusterCustomResource resource,
20+
Context<InformerRemoteClusterCustomResource> context) throws Exception {
21+
22+
23+
24+
return UpdateControl.noUpdate();
25+
}
26+
27+
@Override
28+
public List<EventSource<?, InformerRemoteClusterCustomResource>> prepareEventSources(
29+
EventSourceContext<InformerRemoteClusterCustomResource> context) {
30+
return Reconciler.super.prepareEventSources(context);
31+
}
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package io.javaoperatorsdk.operator.baseapi.informerremotecluster;
2+
3+
public class InformerRemoteClusterStatus {
4+
5+
6+
7+
}

0 commit comments

Comments
 (0)