Skip to content

Commit 4586bc1

Browse files
committed
Skip validating domain list ability if operator has already read, created, or updated CRD
1 parent b0a64e6 commit 4586bc1

File tree

5 files changed

+131
-29
lines changed

5 files changed

+131
-29
lines changed

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

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import javax.annotation.Nonnull;
2424

2525
import io.kubernetes.client.openapi.models.CoreV1EventList;
26+
import io.kubernetes.client.openapi.models.V1CustomResourceDefinition;
2627
import io.kubernetes.client.openapi.models.V1Namespace;
2728
import io.kubernetes.client.openapi.models.V1NamespaceList;
2829
import io.kubernetes.client.openapi.models.V1ObjectMeta;
@@ -137,6 +138,7 @@ static class MainDelegateImpl implements MainDelegate, DomainProcessorDelegate {
137138
private final Engine engine;
138139
private final DomainProcessor domainProcessor;
139140
private final DomainNamespaces domainNamespaces;
141+
private final AtomicReference<V1CustomResourceDefinition> crdRefernce;
140142

141143
public MainDelegateImpl(Properties buildProps, ScheduledExecutorService scheduledExecutorService) {
142144
buildVersion = getBuildVersion(buildProps);
@@ -152,6 +154,8 @@ public MainDelegateImpl(Properties buildProps, ScheduledExecutorService schedule
152154
domainNamespaces = new DomainNamespaces(productVersion);
153155

154156
PodHelper.setProductVersion(productVersion.toString());
157+
158+
crdRefernce = new AtomicReference<>();
155159
}
156160

157161
private static String getBuildVersion(Properties buildProps) {
@@ -248,6 +252,11 @@ public FiberGate createFiberGate() {
248252
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) {
249253
return engine.getExecutor().scheduleWithFixedDelay(command, initialDelay, delay, unit);
250254
}
255+
256+
@Override
257+
public AtomicReference<V1CustomResourceDefinition> getCrdReference() {
258+
return crdRefernce;
259+
}
251260
}
252261

253262
/**
@@ -428,7 +437,7 @@ private Step createDomainRecheckSteps(OffsetDateTime now) {
428437
final DomainRecheck domainRecheck = new DomainRecheck(delegate, isFullRecheck);
429438
return Step.chain(
430439
domainRecheck.createOperatorNamespaceReview(),
431-
CrdHelper.createDomainCrdStep(delegate.getKubernetesVersion(), delegate.getProductVersion()),
440+
CrdHelper.createDomainCrdStep(delegate),
432441
createCRDPresenceCheck(),
433442
domainRecheck.createReadNamespacesStep());
434443
}
@@ -437,12 +446,30 @@ private Step createDomainRecheckSteps(OffsetDateTime now) {
437446
// domains in the operator's namespace. That should succeed (although usually returning an empty list)
438447
// if the CRD is present.
439448
Step createCRDPresenceCheck() {
440-
return new CallBuilder().listDomainAsync(getOperatorNamespace(), new CrdPresenceResponseStep());
449+
return new CrdPresenceStep();
450+
}
451+
452+
class CrdPresenceStep extends Step {
453+
454+
@Override
455+
public NextAction apply(Packet packet) {
456+
V1CustomResourceDefinition existingCrd = delegate.getCrdReference().get();
457+
if (existingCrd != null) {
458+
warnedOfCrdAbsence = false;
459+
return doNext(packet);
460+
}
461+
return doNext(new CallBuilder().listDomainAsync(getOperatorNamespace(),
462+
new CrdPresenceResponseStep(getNext())), packet);
463+
}
441464
}
442465

443466
// on failure, aborts the processing.
444467
class CrdPresenceResponseStep extends DefaultResponseStep<DomainList> {
445468

469+
CrdPresenceResponseStep(Step next) {
470+
super(next);
471+
}
472+
446473
@Override
447474
public NextAction onSuccess(Packet packet, CallResponse<DomainList> callResponse) {
448475
warnedOfCrdAbsence = false;

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
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

66
import java.util.concurrent.ScheduledFuture;
77
import java.util.concurrent.TimeUnit;
8+
import java.util.concurrent.atomic.AtomicReference;
89

10+
import io.kubernetes.client.openapi.models.V1CustomResourceDefinition;
911
import oracle.kubernetes.operator.helpers.KubernetesVersion;
1012
import oracle.kubernetes.operator.helpers.SemanticVersion;
1113
import oracle.kubernetes.operator.work.Packet;
@@ -14,7 +16,7 @@
1416
/**
1517
* Definition of an interface that returns values that the Main class requires.
1618
*/
17-
interface MainDelegate {
19+
public interface MainDelegate {
1820

1921
SemanticVersion getProductVersion();
2022

@@ -33,4 +35,6 @@ default void runSteps(Step firstStep) {
3335
KubernetesVersion getKubernetesVersion();
3436

3537
ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit);
38+
39+
AtomicReference<V1CustomResourceDefinition> getCrdReference();
3640
}

operator/src/main/java/oracle/kubernetes/operator/helpers/CrdHelper.java

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2018, 2021, Oracle and/or its affiliates.
1+
// Copyright (c) 2018, 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.helpers;
@@ -17,6 +17,7 @@
1717
import java.util.List;
1818
import java.util.Map;
1919
import java.util.Objects;
20+
import java.util.Optional;
2021
import java.util.function.Function;
2122
import java.util.stream.Collectors;
2223

@@ -35,6 +36,7 @@
3536
import okhttp3.internal.http2.StreamResetException;
3637
import oracle.kubernetes.operator.KubernetesConstants;
3738
import oracle.kubernetes.operator.LabelConstants;
39+
import oracle.kubernetes.operator.MainDelegate;
3840
import oracle.kubernetes.operator.calls.CallResponse;
3941
import oracle.kubernetes.operator.logging.LoggingFacade;
4042
import oracle.kubernetes.operator.logging.LoggingFactory;
@@ -74,7 +76,7 @@ public static void main(String[] args) throws URISyntaxException {
7476
}
7577

7678
static void writeCrdFiles(String crdFileName) throws URISyntaxException {
77-
CrdContext context = new CrdContext(null, null, null);
79+
CrdContext context = new CrdContext(null, null);
7880

7981
final URI outputFile = asFileURI(crdFileName);
8082

@@ -120,8 +122,8 @@ private static void dumpYaml(Writer writer, Object model) {
120122
// Map = gson.fromJson(Map.class)
121123
// yaml dump ? // ordering and format likely to change massively
122124

123-
public static Step createDomainCrdStep(KubernetesVersion version, SemanticVersion productVersion) {
124-
return new CrdStep(version, productVersion);
125+
public static Step createDomainCrdStep(MainDelegate mainDelegate) {
126+
return new CrdStep(mainDelegate);
125127
}
126128

127129
private static List<ResourceVersion> getVersions(V1CustomResourceDefinition crd) {
@@ -144,8 +146,8 @@ boolean isOutdatedCrd(
144146
static class CrdStep extends Step {
145147
final CrdContext context;
146148

147-
CrdStep(KubernetesVersion version, SemanticVersion productVersion) {
148-
context = new CrdContext(version, productVersion, this);
149+
CrdStep(MainDelegate mainDelegate) {
150+
context = new CrdContext(mainDelegate, this);
149151
}
150152

151153
@Override
@@ -158,14 +160,12 @@ public NextAction apply(Packet packet) {
158160
static class CrdContext {
159161
private final Step conflictStep;
160162
private final V1CustomResourceDefinition model;
161-
private final KubernetesVersion version;
162-
private final SemanticVersion productVersion;
163+
private final MainDelegate mainDelegate;
163164

164-
CrdContext(KubernetesVersion version, SemanticVersion productVersion, Step conflictStep) {
165-
this.version = version;
166-
this.productVersion = productVersion;
165+
CrdContext(MainDelegate mainDelegate, Step conflictStep) {
166+
this.mainDelegate = mainDelegate;
167167
this.conflictStep = conflictStep;
168-
this.model = createModel(productVersion);
168+
this.model = createModel(Optional.ofNullable(mainDelegate).map(MainDelegate::getProductVersion).orElse(null));
169169
}
170170

171171
static V1CustomResourceDefinition createModel(SemanticVersion productVersion) {
@@ -294,7 +294,7 @@ ResponseStep<V1CustomResourceDefinition> createCreateResponseStep(Step next) {
294294
}
295295

296296
private boolean isOutdatedCrd(V1CustomResourceDefinition existingCrd) {
297-
return COMPARATOR.isOutdatedCrd(productVersion, existingCrd, this.model);
297+
return COMPARATOR.isOutdatedCrd(mainDelegate.getProductVersion(), existingCrd, this.model);
298298
}
299299

300300
private boolean existingCrdContainsVersion(V1CustomResourceDefinition existingCrd) {
@@ -349,6 +349,8 @@ class ReadResponseStep extends DefaultResponseStep<V1CustomResourceDefinition> {
349349
public NextAction onSuccess(
350350
Packet packet, CallResponse<V1CustomResourceDefinition> callResponse) {
351351
V1CustomResourceDefinition existingCrd = callResponse.getResult();
352+
mainDelegate.getCrdReference().set(existingCrd);
353+
352354
if (existingCrd == null) {
353355
return doNext(createCrd(getNext()), packet);
354356
} else if (isOutdatedCrd(existingCrd)) {
@@ -362,6 +364,7 @@ public NextAction onSuccess(
362364

363365
@Override
364366
protected NextAction onFailureNoRetry(Packet packet, CallResponse<V1CustomResourceDefinition> callResponse) {
367+
mainDelegate.getCrdReference().set(null);
365368
return isNotAuthorizedOrForbidden(callResponse)
366369
? doNext(packet) : super.onFailureNoRetry(packet, callResponse);
367370
}
@@ -381,7 +384,10 @@ public NextAction onFailure(
381384
@Override
382385
public NextAction onSuccess(
383386
Packet packet, CallResponse<V1CustomResourceDefinition> callResponse) {
384-
LOGGER.info(MessageKeys.CREATING_CRD, callResponse.getResult().getMetadata().getName());
387+
V1CustomResourceDefinition existingCrd = callResponse.getResult();
388+
mainDelegate.getCrdReference().set(existingCrd);
389+
390+
LOGGER.info(MessageKeys.CREATING_CRD, existingCrd.getMetadata().getName());
385391
return doNext(packet);
386392
}
387393

@@ -407,7 +413,9 @@ public NextAction onFailure(
407413
@Override
408414
public NextAction onSuccess(
409415
Packet packet, CallResponse<V1CustomResourceDefinition> callResponse) {
410-
LOGGER.info(MessageKeys.CREATING_CRD, callResponse.getResult().getMetadata().getName());
416+
V1CustomResourceDefinition existingCrd = callResponse.getResult();
417+
mainDelegate.getCrdReference().set(existingCrd);
418+
LOGGER.info(MessageKeys.CREATING_CRD, existingCrd.getMetadata().getName());
411419
return doNext(packet);
412420
}
413421

operator/src/test/java/oracle/kubernetes/operator/MainTest.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2018, 2021, Oracle and/or its affiliates.
1+
// Copyright (c) 2018, 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;
@@ -15,6 +15,7 @@
1515
import java.util.Properties;
1616
import java.util.Random;
1717
import java.util.concurrent.ConcurrentHashMap;
18+
import java.util.concurrent.atomic.AtomicReference;
1819
import java.util.logging.Level;
1920
import java.util.logging.LogRecord;
2021
import java.util.stream.Collectors;
@@ -24,6 +25,7 @@
2425
import com.meterware.simplestub.StaticStubSupport;
2526
import io.kubernetes.client.openapi.models.CoreV1Event;
2627
import io.kubernetes.client.openapi.models.V1ConfigMap;
28+
import io.kubernetes.client.openapi.models.V1CustomResourceDefinition;
2729
import io.kubernetes.client.openapi.models.V1Namespace;
2830
import io.kubernetes.client.openapi.models.V1ObjectMeta;
2931
import io.kubernetes.client.openapi.models.V1ObjectReference;
@@ -358,12 +360,23 @@ private void runCreateReadNamespacesStep() {
358360
void whenNoCRD_logReasonForFailure() {
359361
loggerControl.withLogLevel(Level.SEVERE).collectLogMessages(logRecords, CRD_NOT_INSTALLED);
360362
simulateMissingCRD();
363+
delegate.hideCRD();
361364

362365
recheckDomains();
363366

364367
assertThat(logRecords, containsSevere(CRD_NOT_INSTALLED));
365368
}
366369

370+
@Test
371+
void whenCRDCreated_dontLogFailure() {
372+
loggerControl.withLogLevel(Level.SEVERE).collectLogMessages(logRecords, CRD_NOT_INSTALLED);
373+
simulateMissingCRD();
374+
375+
recheckDomains();
376+
377+
assertThat(logRecords, not(containsSevere(CRD_NOT_INSTALLED)));
378+
}
379+
367380
@Test
368381
void afterLoggedCRDMissing_dontDoItASecondTime() {
369382
loggerControl.withLogLevel(Level.SEVERE).collectLogMessages(logRecords, CRD_NOT_INSTALLED);
@@ -380,6 +393,7 @@ void afterLoggedCRDMissing_dontDoItASecondTime() {
380393
void afterMissingCRDdetected_correctionOfTheConditionAllowsProcessingToOccur() {
381394
defineSelectionStrategy(SelectionStrategy.Dedicated);
382395
simulateMissingCRD();
396+
delegate.hideCRD();
383397
recheckDomains();
384398

385399
testSupport.cancelFailures();
@@ -397,6 +411,7 @@ void afterMissingCRDcorrected_subsequentFailureLogsReasonForFailure() {
397411

398412
loggerControl.withLogLevel(Level.SEVERE).collectLogMessages(logRecords, CRD_NOT_INSTALLED);
399413
simulateMissingCRD();
414+
delegate.hideCRD();
400415
recheckDomains();
401416

402417
assertThat(logRecords, containsSevere(CRD_NOT_INSTALLED));
@@ -1155,6 +1170,8 @@ void withNamespaceDedicated_changeToList_onCreateReadNamespaces_StartManagingNSE
11551170
abstract static class MainDelegateStub implements MainDelegate {
11561171
private final FiberTestSupport testSupport;
11571172
private final DomainNamespaces domainNamespaces;
1173+
private final AtomicReference<V1CustomResourceDefinition> crdReference = new AtomicReference<>();
1174+
private boolean hideCRD = false;
11581175

11591176
public MainDelegateStub(FiberTestSupport testSupport, DomainNamespaces domainNamespaces) {
11601177
this.testSupport = testSupport;
@@ -1187,6 +1204,15 @@ public KubernetesVersion getKubernetesVersion() {
11871204
public SemanticVersion getProductVersion() {
11881205
return SemanticVersion.TEST_VERSION;
11891206
}
1207+
1208+
public void hideCRD() {
1209+
this.hideCRD = true;
1210+
}
1211+
1212+
@Override
1213+
public AtomicReference<V1CustomResourceDefinition> getCrdReference() {
1214+
return hideCRD ? new AtomicReference<>() : crdReference;
1215+
}
11901216
}
11911217

11921218
static class TestStepFactory implements Main.NextStepFactory {

0 commit comments

Comments
 (0)