Skip to content

Commit 30689ce

Browse files
authored
Backport PR#2720 for owls-93995 to release 3.3 (#2743)
* Backport PR#2720 for owls-93995 to release 3.3
1 parent 875687e commit 30689ce

File tree

9 files changed

+111
-76
lines changed

9 files changed

+111
-76
lines changed

integration-tests/src/test/java/oracle/weblogic/kubernetes/ItKubernetesEvents.java

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2020, 2021, Oracle and/or its affiliates.
1+
// Copyright (c) 2020, 2022, Oracle and/or its affiliates.
22
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
33

44
package oracle.weblogic.kubernetes;
@@ -15,6 +15,7 @@
1515
import java.util.Properties;
1616

1717
import io.kubernetes.client.custom.V1Patch;
18+
import io.kubernetes.client.openapi.ApiException;
1819
import io.kubernetes.client.openapi.models.CoreV1Event;
1920
import io.kubernetes.client.openapi.models.V1Container;
2021
import io.kubernetes.client.openapi.models.V1EnvVar;
@@ -58,6 +59,7 @@
5859
import static oracle.weblogic.kubernetes.TestConstants.K8S_NODEPORT_HOST;
5960
import static oracle.weblogic.kubernetes.TestConstants.WEBLOGIC_IMAGE_TO_USE_IN_SPEC;
6061
import static oracle.weblogic.kubernetes.actions.ActionConstants.RESOURCE_DIR;
62+
import static oracle.weblogic.kubernetes.actions.TestActions.createNamespace;
6163
import static oracle.weblogic.kubernetes.actions.TestActions.deleteDomainCustomResource;
6264
import static oracle.weblogic.kubernetes.actions.TestActions.deletePersistentVolume;
6365
import static oracle.weblogic.kubernetes.actions.TestActions.deletePersistentVolumeClaim;
@@ -256,7 +258,7 @@ void testDomainK8sEventsNonExistingManagedServer() {
256258
assertTrue(patchDomainCustomResource(domainUid, domainNamespace1, patch, V1Patch.PATCH_FORMAT_JSON_PATCH),
257259
"Failed to patch domain");
258260

259-
logger.info("verify the DomainProcessingCompleted event is generated");
261+
logger.info("verify the DomainChanged event is generated");
260262
checkEvent(opNamespace, domainNamespace1, domainUid, DOMAIN_CHANGED, "Normal", timestamp);
261263
}
262264

@@ -815,6 +817,33 @@ void testK8SEventsStartStopWatchingNSWithLabelSelector(boolean enableClusterRole
815817
logger.info("verify NamespaceWatchingStopped event is logged in namespace {0}", domainNamespace3);
816818
checkNamespaceWatchingStoppedEvent(opNamespace, domainNamespace3, null, "Normal", timestamp,
817819
enableClusterRoleBinding);
820+
821+
if (enableClusterRoleBinding) {
822+
String newNSWithoutLabels = "ns-newnamespace1";
823+
String newNSWithLabels = "ns-newnamespace2";
824+
825+
assertDoesNotThrow(() -> createNamespaces(newNSWithoutLabels, newNSWithLabels),
826+
"Failed to create new namespaces");
827+
828+
new Command()
829+
.withParams(new CommandParams()
830+
.command("kubectl label ns " + newNSWithLabels + " weblogic-operator=enabled --overwrite"))
831+
.execute();
832+
833+
logger.info("verify NamespaceWatchingStarted event is logged in namespace {0}", newNSWithLabels);
834+
checkEvent(opNamespace, newNSWithLabels, null, NAMESPACE_WATCHING_STARTED, "Normal", timestamp);
835+
836+
// verify there is no event logged in domainNamespace4
837+
logger.info("verify NamespaceWatchingStarted event is not logged in {0}", domainNamespace4);
838+
assertFalse(domainEventExists(opNamespace, newNSWithoutLabels, null, NAMESPACE_WATCHING_STARTED,
839+
"Normal", timestamp), "domain event " + NAMESPACE_WATCHING_STARTED + " is logged in "
840+
+ newNSWithoutLabels + ", expected no such event will be logged");
841+
}
842+
}
843+
844+
private void createNamespaces(String newNSWithoutLabels, String newNSWithLabels) throws ApiException {
845+
createNamespace(newNSWithoutLabels);
846+
createNamespace(newNSWithLabels);
818847
}
819848

820849
/**

operator/src/main/java/oracle/kubernetes/operator/DomainRecheck.java

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2020, 2021, Oracle and/or its affiliates.
1+
// Copyright (c) 2020, 2022, Oracle and/or its affiliates.
22
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
33

44
package oracle.kubernetes.operator;
@@ -144,7 +144,6 @@ public Step getDefaultSelection() {
144144
*/
145145
Step readExistingNamespaces() {
146146
return new CallBuilder()
147-
.withLabelSelectors(Namespaces.getLabelSelectors())
148147
.listNamespaceAsync(new NamespaceListResponseStep());
149148
}
150149

@@ -171,7 +170,7 @@ private boolean useBackupStrategy(CallResponse<V1NamespaceList> callResponse) {
171170

172171
@Override
173172
public NextAction onSuccess(Packet packet, CallResponse<V1NamespaceList> callResponse) {
174-
final Set<String> domainNamespaces = getNamespacesToStart(getNames(callResponse.getResult()));
173+
final Set<String> domainNamespaces = getNamespacesToStart(callResponse.getResult());
175174
Namespaces.getFoundDomainNamespaces(packet).addAll(domainNamespaces);
176175

177176
return doContinueListOrNext(callResponse, packet, createNextSteps(domainNamespaces));
@@ -194,16 +193,13 @@ private boolean haveExplicitlyConfiguredNamespacesToManage() {
194193
return Namespaces.getConfiguredDomainNamespaces() != null;
195194
}
196195

197-
private Set<String> getNamespacesToStart(List<String> namespaceNames) {
198-
return namespaceNames.stream().filter(Namespaces::isDomainNamespace).collect(Collectors.toSet());
199-
}
200-
201-
private List<String> getNames(V1NamespaceList result) {
202-
return result.getItems().stream()
203-
.map(V1Namespace::getMetadata)
204-
.filter(Objects::nonNull)
205-
.map(V1ObjectMeta::getName)
206-
.collect(Collectors.toList());
196+
private Set<String> getNamespacesToStart(V1NamespaceList namespaces) {
197+
return namespaces.getItems().stream()
198+
.filter(Namespaces::isDomainNamespace)
199+
.map(V1Namespace::getMetadata)
200+
.filter(Objects::nonNull)
201+
.map(V1ObjectMeta::getName)
202+
.collect(Collectors.toSet());
207203
}
208204
}
209205

operator/src/main/java/oracle/kubernetes/operator/Main.java

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2017, 2021, Oracle and/or its affiliates.
1+
// Copyright (c) 2017, 2022, Oracle and/or its affiliates.
22
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
33

44
package oracle.kubernetes.operator;
@@ -20,7 +20,6 @@
2020
import java.util.concurrent.TimeUnit;
2121
import java.util.concurrent.atomic.AtomicBoolean;
2222
import java.util.concurrent.atomic.AtomicReference;
23-
import java.util.stream.Collectors;
2423
import javax.annotation.Nonnull;
2524

2625
import io.kubernetes.client.openapi.models.CoreV1EventList;
@@ -85,8 +84,7 @@ public class Main {
8584
private NamespaceWatcher namespaceWatcher;
8685
protected OperatorEventWatcher operatorNamespaceEventWatcher;
8786
private boolean warnedOfCrdAbsence;
88-
private static NextStepFactory NEXT_STEP_FACTORY =
89-
(next) -> createInitializeInternalIdentityStep(next);
87+
private static final NextStepFactory NEXT_STEP_FACTORY = Main::createInitializeInternalIdentityStep;
9088

9189
private static String getConfiguredServiceAccount() {
9290
return TuningParameters.getInstance().get("serviceaccount");
@@ -187,8 +185,7 @@ private void logStartup(LoggingFacade loggingFacade) {
187185
}
188186

189187
private void logConfiguredNamespaces(LoggingFacade loggingFacade, Collection<String> configuredDomainNamespaces) {
190-
loggingFacade.info(MessageKeys.OP_CONFIG_DOMAIN_NAMESPACES,
191-
configuredDomainNamespaces.stream().collect(Collectors.joining(", ")));
188+
loggingFacade.info(MessageKeys.OP_CONFIG_DOMAIN_NAMESPACES, String.join(", ", configuredDomainNamespaces));
192189
}
193190

194191
@Override
@@ -521,21 +518,21 @@ private NamespaceWatcher createNamespaceWatcher(String initialResourceVersion) {
521518
return NamespaceWatcher.create(
522519
threadFactory,
523520
initialResourceVersion,
524-
Namespaces.getLabelSelectors(),
525521
TuningParameters.getInstance().getWatchTuning(),
526522
this::dispatchNamespaceWatch,
527523
new AtomicBoolean(false));
528524
}
529525

530526
void dispatchNamespaceWatch(Watch.Response<V1Namespace> item) {
531527
String ns = Optional.ofNullable(item.object).map(V1Namespace::getMetadata).map(V1ObjectMeta::getName).orElse(null);
528+
532529
if (ns == null) {
533530
return;
534531
}
535532

536533
switch (item.type) {
537534
case "ADDED":
538-
if (!Namespaces.isDomainNamespace(ns)) {
535+
if (!Namespaces.isDomainNamespace(item.object)) {
539536
return;
540537
}
541538

operator/src/main/java/oracle/kubernetes/operator/NamespaceWatcher.java

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2019, 2021, Oracle and/or its affiliates.
1+
// Copyright (c) 2019, 2022, Oracle and/or its affiliates.
22
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
33

44
package oracle.kubernetes.operator;
@@ -19,23 +19,19 @@
1919
* the operator for processing.
2020
*/
2121
public class NamespaceWatcher extends Watcher<V1Namespace> {
22-
private final String[] labelSelectors;
2322

2423
private NamespaceWatcher(
2524
String initialResourceVersion,
26-
String[] labelSelectors,
2725
WatchTuning tuning,
2826
WatchListener<V1Namespace> listener,
2927
AtomicBoolean isStopping) {
3028
super(initialResourceVersion, tuning, isStopping, listener);
31-
this.labelSelectors = labelSelectors;
3229
}
3330

3431
/**
3532
* Create a namespace watcher.
3633
* @param factory the ThreadFactory to run the watcher
3734
* @param initialResourceVersion at which to start returning watch events
38-
* @param labelSelector label selector
3935
* @param tuning any WatchTuning parameters
4036
* @param listener the WatchListener
4137
* @param isStopping whether the watcher is stopping
@@ -44,21 +40,18 @@ private NamespaceWatcher(
4440
public static NamespaceWatcher create(
4541
ThreadFactory factory,
4642
String initialResourceVersion,
47-
String[] labelSelector,
4843
WatchTuning tuning,
4944
WatchListener<V1Namespace> listener,
5045
AtomicBoolean isStopping) {
5146

52-
NamespaceWatcher watcher =
53-
new NamespaceWatcher(initialResourceVersion, labelSelector, tuning, listener, isStopping);
47+
NamespaceWatcher watcher = new NamespaceWatcher(initialResourceVersion, tuning, listener, isStopping);
5448
watcher.start(factory);
5549
return watcher;
5650
}
5751

5852
@Override
5953
public Watchable<V1Namespace> initiateWatch(WatchBuilder watchBuilder) throws ApiException {
6054
return watchBuilder
61-
.withLabelSelectors(labelSelectors)
6255
.createNamespacesWatch();
6356
}
6457

operator/src/main/java/oracle/kubernetes/operator/Namespaces.java

Lines changed: 48 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
// Copyright (c) 2020, 2021, Oracle and/or its affiliates.
1+
// Copyright (c) 2020, 2022, Oracle and/or its affiliates.
22
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
33

44
package oracle.kubernetes.operator;
55

6+
import java.util.Arrays;
67
import java.util.Collection;
78
import java.util.Collections;
89
import java.util.HashSet;
@@ -16,6 +17,8 @@
1617
import javax.annotation.Nonnull;
1718
import javax.annotation.Nullable;
1819

20+
import io.kubernetes.client.openapi.models.V1Namespace;
21+
import io.kubernetes.client.openapi.models.V1ObjectMeta;
1922
import jakarta.validation.constraints.NotNull;
2023
import oracle.kubernetes.operator.helpers.EventHelper.EventData;
2124
import oracle.kubernetes.operator.helpers.HelmAccess;
@@ -27,6 +30,7 @@
2730
import oracle.kubernetes.operator.work.NextAction;
2831
import oracle.kubernetes.operator.work.Packet;
2932
import oracle.kubernetes.operator.work.Step;
33+
import org.apache.commons.lang3.ArrayUtils;
3034

3135
import static oracle.kubernetes.operator.helpers.EventHelper.EventItem.NAMESPACE_WATCHING_STOPPED;
3236
import static oracle.kubernetes.operator.helpers.EventHelper.EventItem.STOP_MANAGING_NAMESPACE;
@@ -47,11 +51,11 @@ public class Namespaces {
4751
private static final String ALL_DOMAIN_NAMESPACES = "ALL_DOMAIN_NAMESPACES";
4852

4953
/**
50-
* Returns true if the specified string is the name of a domain namespace.
51-
* @param ns a namespace name
54+
* Returns true if the specified namespace is managed by the operator.
55+
* @param namespace namespace object to check
5256
*/
53-
static boolean isDomainNamespace(String ns) {
54-
return getSelectionStrategy().isDomainNamespace(ns);
57+
static boolean isDomainNamespace(@Nonnull V1Namespace namespace) {
58+
return getSelectionStrategy().isDomainNamespace(namespace);
5559
}
5660

5761
/**
@@ -68,22 +72,15 @@ static boolean isDomainNamespace(String ns) {
6872
return getSelectionStrategy().getFoundDomainNamespaces(packet);
6973
}
7074

71-
/**
72-
* Returns an array of the label selectors that will determine that a namespace is being used to manage domains.
73-
*/
74-
static String[] getLabelSelectors() {
75-
return getSelectionStrategy().getLabelSelectors();
76-
}
77-
7875
static <R> R getSelection(NamespaceStrategyVisitor<R> visitor) {
7976
return getSelectionStrategy().getSelection(visitor);
8077
}
8178

8279
public enum SelectionStrategy {
8380
List {
8481
@Override
85-
public boolean isDomainNamespace(@Nonnull String namespaceName) {
86-
return getConfiguredDomainNamespaces().contains(namespaceName);
82+
public boolean isDomainNamespace(@Nonnull V1Namespace namespace) {
83+
return getConfiguredDomainNamespaces().contains(getNSName(namespace));
8784
}
8885

8986
@Override
@@ -110,26 +107,47 @@ private String getConfiguredNamespaceList() {
110107
}
111108
},
112109
LabelSelector {
113-
@Override
114-
public String[] getLabelSelectors() {
115-
return new String[]{TuningParameters.getInstance().get("domainNamespaceLabelSelector")};
116-
}
117-
118110
@Override
119111
public <V> V getSelection(NamespaceStrategyVisitor<V> visitor) {
120112
return visitor.getLabelSelectorStrategySelection();
121113
}
122114

123115
@Override
124-
public boolean isDomainNamespace(@Nonnull String namespaceName) {
125-
return true; // filtering is done by Kubernetes list call
116+
public boolean isDomainNamespace(@Nonnull V1Namespace namespace) {
117+
return matchSpecifiedLabelSelectors(namespace.getMetadata(), getLabelSelectors());
118+
}
119+
120+
private String[] getLabelSelectors() {
121+
return Optional.ofNullable(TuningParameters.getInstance().get("domainNamespaceLabelSelector"))
122+
.map(s -> new String[]{s})
123+
.orElse(new String[0]);
124+
}
125+
126+
private boolean matchSpecifiedLabelSelectors(@NotNull V1ObjectMeta nsMetadata, String[] selectors) {
127+
return ArrayUtils.isEmpty(selectors) || hasLabels(nsMetadata, selectors);
128+
}
129+
130+
private boolean hasLabels(@NotNull V1ObjectMeta metadata, String[] selectors) {
131+
return Arrays.stream(selectors).allMatch(s -> hasLabel(metadata, s));
132+
}
133+
134+
private boolean hasLabel(@Nonnull V1ObjectMeta metadata, String selector) {
135+
String[] split = selector.split("=");
136+
return includesLabel(metadata.getLabels(), split[0], split.length == 1 ? null : split[1]);
137+
}
138+
139+
private boolean includesLabel(Map<String, String> labels, String key, String value) {
140+
if (labels == null || !labels.containsKey(key)) {
141+
return false;
142+
}
143+
return value == null || value.equals(labels.get(key));
126144
}
127145
},
128146
RegExp {
129147
@Override
130-
public boolean isDomainNamespace(@Nonnull String namespaceName) {
148+
public boolean isDomainNamespace(@Nonnull V1Namespace namespace) {
131149
try {
132-
return getCompiledPattern(getRegExp()).matcher(namespaceName).find();
150+
return getCompiledPattern(getRegExp()).matcher(getNSName(namespace)).find();
133151
} catch (PatternSyntaxException e) {
134152
LOGGER.severe(MessageKeys.EXCEPTION, e);
135153
return false;
@@ -151,8 +169,8 @@ private Pattern getCompiledPattern(String regExp) {
151169
},
152170
Dedicated {
153171
@Override
154-
public boolean isDomainNamespace(@Nonnull String namespaceName) {
155-
return namespaceName.equals(getOperatorNamespace());
172+
public boolean isDomainNamespace(@Nonnull V1Namespace namespace) {
173+
return getNSName(namespace).equals(getOperatorNamespace());
156174
}
157175

158176
@Override
@@ -171,13 +189,7 @@ public Collection<String> getFoundDomainNamespaces(Packet packet) {
171189
}
172190
};
173191

174-
static final String[] NO_SELECTORS = new String[0];
175-
176-
public abstract boolean isDomainNamespace(@Nonnull String namespaceName);
177-
178-
public String[] getLabelSelectors() {
179-
return NO_SELECTORS;
180-
}
192+
public abstract boolean isDomainNamespace(@Nonnull V1Namespace namespace);
181193

182194
public @Nullable Collection<String> getConfiguredDomainNamespaces() {
183195
return null;
@@ -187,6 +199,10 @@ public String[] getLabelSelectors() {
187199

188200
private static final Map<String, Pattern> compiledPatterns = new WeakHashMap<>();
189201

202+
String getNSName(V1Namespace namespace) {
203+
return Optional.ofNullable(namespace).map(V1Namespace::getMetadata).map(V1ObjectMeta::getName).orElse(null);
204+
}
205+
190206
/**
191207
* Returns a modifiable collection of found namespace names in a packet.
192208
* Callers should use this to add to the collection.

0 commit comments

Comments
 (0)