Skip to content

fix(deps): bump io.javaoperatorsdk:operator-framework from 4.9.7 to 5.0.1 #626

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
Show file tree
Hide file tree
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
11 changes: 7 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ plugins {
id 'org.sonarqube' version '6.0.1.5171'
id "com.diffplug.spotless" version "7.0.2"
id "com.google.cloud.tools.jib" version "3.4.4"
id 'org.cyclonedx.bom' version '2.0.0'
id 'org.cyclonedx.bom' version '2.1.0'
}

cyclonedxBom {
Expand Down Expand Up @@ -51,8 +51,8 @@ jib {
project.ext {
mongoDbDriverVersion = "5.3.1"
slf4jVersion = "2.0.16"
operatorFrameworkVersion = "4.9.7"
kubernetesServerMockVersion = "6.13.4" // align with transitive dependency of operator framework
operatorFrameworkVersion = "5.0.1"
kubernetesServerMockVersion = "7.1.0" // align with transitive dependency of operator framework
mockitoVersion = "5.2.0"
jacksonVersion = "2.18.2"
logbackContribVersion = "0.1.5"
Expand Down Expand Up @@ -105,7 +105,7 @@ dependencies {
exclude group: "ch.qos.logback", module: "logback-core"
}

implementation 'io.micrometer:micrometer-registry-prometheus:1.14.3'
implementation 'io.micrometer:micrometer-registry-prometheus:1.14.4'

// test
testImplementation enforcedPlatform("org.junit:junit-bom:5.11.4")
Expand Down Expand Up @@ -144,6 +144,9 @@ dependencies {
// CVE-2020-15250 in 4.12
// -> pulled transitively from OkHttp3 mockwebserver used by kubernetes-server-mock
testImplementation 'junit:junit:4.13.2'
testImplementation 'com.squareup.okhttp3:okhttp:3.12.12', {
exclude group: 'com.squareup.okio', module: 'okio'
}
}

dependencyLocking { lockAllConfigurations() }
Expand Down
5 changes: 4 additions & 1 deletion docs/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,17 @@ The MongoDB Operator requires a `ServiceAccount` with some privileges for the Ku
* `list`
* `get`
* `update`
* `patch`
* For the resource `mongodbs/status` the following verbs are required:
* `watch`
* `list`
* `get`
* `update`
* `patch`
* For the resource `secrets` the following verbs are required:
* `create`
* `update`
* `patch`
* For the resource `customresourcedefinitions` with the resource name
`mongodbs.persistence.sda-se.com` the following verbs are required:
* `get`
Expand All @@ -104,7 +107,7 @@ The [CRD `mongodbs`](https://github.com/SDA-SE/mongodb-operator/tree/master/kust
must be applied.


### Database
### Database

A MongoDB database instance or an AWS DocumentDB cluster must be set up separately from the
deployment of the MongoDB Operator.
Expand Down
6 changes: 3 additions & 3 deletions kustomize/bases/operator/mongodb-operator-cr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ metadata:
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["create", "update"]
verbs: ["create", "update", "patch"]
- apiGroups: ["persistence.sda-se.com"]
resources: ["mongodbs"]
verbs: ["watch", "list", "get", "update"]
verbs: ["watch", "list", "get", "update", "patch"]
- apiGroups: ["persistence.sda-se.com"]
resources: ["mongodbs/status"]
verbs: ["watch", "list", "get", "update"]
verbs: ["watch", "list", "get", "update", "patch"]
- apiGroups: ["apiextensions.k8s.io"]
resources: ["customresourcedefinitions"]
resourceNames:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,9 @@ UpdateControl<MongoDbCustomResource> createStatusUpdate(MongoDbCustomResource re
createSecretSuccessful,
resource.getStatus().getAttempts());
if (allConditionsTrue(resource)) {
return UpdateControl.updateStatus(resource);
return UpdateControl.patchStatus(resource);
} else {
return UpdateControl.updateStatus(resource)
return UpdateControl.patchStatus(resource)
.rescheduleAfter(
RECONCILE_REQUEST_MIN_DURATION_ON_ERROR_SECONDS * resource.getStatus().getAttempts(),
TimeUnit.SECONDS);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.tuple;
import static org.assertj.core.api.SoftAssertions.assertSoftly;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
Expand All @@ -24,6 +23,7 @@
import com.sdase.k8s.operator.mongodb.model.v1beta1.DatabaseSpec;
import com.sdase.k8s.operator.mongodb.model.v1beta1.MongoDbCustomResource;
import com.sdase.k8s.operator.mongodb.model.v1beta1.MongoDbSpec;
import com.sdase.k8s.operator.mongodb.model.v1beta1.MongoDbStatus;
import com.sdase.k8s.operator.mongodb.model.v1beta1.SecretSpec;
import io.fabric8.kubernetes.api.model.Condition;
import io.fabric8.kubernetes.api.model.ObjectMeta;
Expand All @@ -35,13 +35,16 @@
import io.javaoperatorsdk.operator.api.reconciler.Context;
import io.javaoperatorsdk.operator.api.reconciler.DeleteControl;
import io.javaoperatorsdk.operator.api.reconciler.IndexedResourceCache;
import io.javaoperatorsdk.operator.api.reconciler.ResourceDiscriminator;
import io.javaoperatorsdk.operator.api.reconciler.RetryInfo;
import io.javaoperatorsdk.operator.api.reconciler.dependent.managed.ManagedDependentResourceContext;
import io.javaoperatorsdk.operator.api.reconciler.UpdateControl;
import io.javaoperatorsdk.operator.api.reconciler.dependent.managed.ManagedWorkflowAndDependentResourceContext;
import io.javaoperatorsdk.operator.processing.event.EventSourceRetriever;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
Expand Down Expand Up @@ -92,7 +95,7 @@ void shouldPerformDefaultDelete() {

var actual = mongoDbController.cleanup(given, new MongoDbCustomResourceContext());

// By default owned resources (like the created secret) will be deleted as well.
// By default, owned resources (like the created secret) will be deleted as well.
assertThat(actual).usingRecursiveComparison().isEqualTo(DeleteControl.defaultDelete());
verify(mongoDbServiceMock).dropDatabaseUser("the-namespace_the-name", "the-namespace_the-name");
verifyNoMoreInteractions(mongoDbServiceMock);
Expand All @@ -118,7 +121,7 @@ void shouldSkipDeleteDatabaseAfterLastAttempt() {

var actual = mongoDbController.cleanup(given, contextMock);

// By default owned resources (like the created secret) will be deleted as well.
// By default, owned resources (like the created secret) will be deleted as well.
assertThat(actual).usingRecursiveComparison().isEqualTo(DeleteControl.defaultDelete());
verify(mongoDbServiceMock).dropDatabaseUser("the-namespace_the-name", "the-namespace_the-name");
verifyNoMoreInteractions(mongoDbServiceMock);
Expand All @@ -140,7 +143,7 @@ void shouldFailWhenUserCantBeDeleted() {
assertThatExceptionOfType(IllegalStateException.class)
.isThrownBy(() -> mongoDbController.cleanup(given, givenContext));

// By default owned resources (like the created secret) will be deleted as well.
// By default, owned resources (like the created secret) will be deleted as well.
verify(mongoDbServiceMock).dropDatabaseUser("the-namespace_the-name", "the-namespace_the-name");
}

Expand All @@ -159,7 +162,7 @@ void shouldPerformDeleteWithPruneDb() {

var actual = mongoDbController.cleanup(given, new MongoDbCustomResourceContext());

// By default owned resources (like the created secret) will be deleted as well.
// By default, owned resources (like the created secret) will be deleted as well.
assertThat(actual).usingRecursiveComparison().isEqualTo(DeleteControl.defaultDelete());
verify(mongoDbServiceMock).dropDatabaseUser("the-namespace_the-name", "the-namespace_the-name");
verify(mongoDbServiceMock).dropDatabase("the-namespace_the-name");
Expand All @@ -186,7 +189,7 @@ void shouldShouldFailWhenPruneDbNotPossible() {
assertThatExceptionOfType(IllegalStateException.class)
.isThrownBy(() -> mongoDbController.cleanup(given, contextMock));

// By default owned resources (like the created secret) will be deleted as well.
// By default, owned resources (like the created secret) will be deleted as well.
verify(mongoDbServiceMock).dropDatabaseUser("the-namespace_the-name", "the-namespace_the-name");
verify(mongoDbServiceMock).dropDatabase("the-namespace_the-name");
}
Expand Down Expand Up @@ -261,14 +264,10 @@ void shouldCallAllNecessaryServicesForSuccess() {

// For the moment no updates to the original resource, this may change in the future if
// needed.
softly.assertThat(actual.isUpdateResource()).isFalse();
softly.assertThat(actual.isUpdateStatus()).isTrue();
softly
.assertThat(actual.getResource().getStatus().getConditions())
.isNotEmpty()
.extracting(Condition::getStatus)
.containsOnly("True");
softly.assertThat(actual.isUpdateResourceAndStatus()).isFalse();
softly.assertThat(actual.isPatchResource()).isFalse();
softly.assertThat(actual.isPatchStatus()).isTrue();
softly.assertThat(areAllStatusConditionsTrue(actual)).isTrue();
softly.assertThat(actual.isPatchResourceAndStatus()).isFalse();
softly.assertThat(actual.isNoUpdate()).isFalse();
});
}
Expand Down Expand Up @@ -301,16 +300,14 @@ void shouldFailWithBadConditionsForTooLongName() {
softly -> {
// For the moment no updates to the original resource, this may change in the future if
// needed.
softly.assertThat(actual.isUpdateResource()).isFalse();
softly.assertThat(actual.isUpdateStatus()).isTrue();
softly.assertThat(actual.isPatchResource()).isFalse();
softly.assertThat(actual.isPatchStatus()).isTrue();
softly
.assertThat(actual.getResource().getStatus().getConditions())
.extracting(Condition::getType, Condition::getStatus)
.containsExactlyInAnyOrder(
tuple("CreateUsername", "False"),
tuple("CreateDatabase", "Unknown"),
tuple("CreateSecret", "Unknown"));
softly.assertThat(actual.isUpdateResourceAndStatus()).isFalse();
.assertThat(extractStatusConditions(actual))
.containsEntry("CreateUsername", "False")
.containsEntry("CreateDatabase", "Unknown")
.containsEntry("CreateSecret", "Unknown");
softly.assertThat(actual.isPatchResourceAndStatus()).isFalse();
softly.assertThat(actual.isNoUpdate()).isFalse();
});
}
Expand Down Expand Up @@ -353,16 +350,14 @@ void shouldFailWhenSecretCantBeCreated() {
.extracting(Secret::getData)
.extracting("u", "p")
.containsExactly("dGhlLW5hbWVzcGFjZV90aGUtbmFtZQ==", "c3RhdGljLXRlc3QtcGFzc3dvcmQ=");
softly.assertThat(actual.isUpdateResource()).isFalse();
softly.assertThat(actual.isUpdateStatus()).isTrue();
softly.assertThat(actual.isPatchResource()).isFalse();
softly.assertThat(actual.isPatchStatus()).isTrue();
softly
.assertThat(actual.getResource().getStatus().getConditions())
.extracting(Condition::getType, Condition::getStatus)
.containsExactlyInAnyOrder(
tuple("CreateUsername", "True"),
tuple("CreateDatabase", "True"),
tuple("CreateSecret", "False"));
softly.assertThat(actual.isUpdateResourceAndStatus()).isFalse();
.assertThat(extractStatusConditions(actual))
.containsEntry("CreateUsername", "True")
.containsEntry("CreateDatabase", "True")
.containsEntry("CreateSecret", "False");
softly.assertThat(actual.isPatchResourceAndStatus()).isFalse();
softly.assertThat(actual.isNoUpdate()).isFalse();
});
}
Expand All @@ -388,16 +383,14 @@ void shouldNotCreateSecretButFailWhenNoDatabaseHasBeenCreated() {
verifyNoInteractions(kubernetesClientAdapterMock);
assertSoftly(
softly -> {
softly.assertThat(actual.isUpdateResource()).isFalse();
softly.assertThat(actual.isUpdateStatus()).isTrue();
softly.assertThat(actual.isPatchResource()).isFalse();
softly.assertThat(actual.isPatchStatus()).isTrue();
softly
.assertThat(actual.getResource().getStatus().getConditions())
.extracting(Condition::getType, Condition::getStatus)
.containsExactlyInAnyOrder(
tuple("CreateUsername", "True"),
tuple("CreateDatabase", "False"),
tuple("CreateSecret", "Unknown"));
softly.assertThat(actual.isUpdateResourceAndStatus()).isFalse();
.assertThat(extractStatusConditions(actual))
.containsEntry("CreateUsername", "True")
.containsEntry("CreateDatabase", "False")
.containsEntry("CreateSecret", "Unknown");
softly.assertThat(actual.isPatchResourceAndStatus()).isFalse();
softly.assertThat(actual.isNoUpdate()).isFalse();
});
}
Expand All @@ -423,16 +416,14 @@ void shouldUpdateStatusOfExistingResourcesWithoutStatus() {
verifyNoInteractions(kubernetesClientAdapterMock);
assertSoftly(
softly -> {
softly.assertThat(actual.isUpdateResource()).isFalse();
softly.assertThat(actual.isUpdateStatus()).isTrue();
softly.assertThat(actual.isPatchResource()).isFalse();
softly.assertThat(actual.isPatchStatus()).isTrue();
softly
.assertThat(actual.getResource().getStatus().getConditions())
.extracting(Condition::getType, Condition::getStatus)
.containsExactlyInAnyOrder(
tuple("CreateUsername", "True"),
tuple("CreateDatabase", "True"),
tuple("CreateSecret", "True"));
softly.assertThat(actual.isUpdateResourceAndStatus()).isFalse();
.assertThat(extractStatusConditions(actual))
.containsEntry("CreateUsername", "True")
.containsEntry("CreateDatabase", "True")
.containsEntry("CreateSecret", "True");
softly.assertThat(actual.isPatchResourceAndStatus()).isFalse();
softly.assertThat(actual.isNoUpdate()).isFalse();
});
}
Expand All @@ -444,27 +435,48 @@ void shouldDoNothingWhenStatusIsComplete() {
new ObjectMetaBuilder().withNamespace("the-namespace").withName("the-name").build());
givenMongoDbCr.setSpec(
new MongoDbSpec().setSecret(new SecretSpec().setUsernameKey("u").setPasswordKey("p")));
//noinspection OptionalGetWithoutIsPresent
givenMongoDbCr =
new MongoDbResourceConditions()
.applyUsernameCreated("the-namespace_the-name")
.applyDatabaseCreated()
.applySecretCreated()
.createStatusUpdate(givenMongoDbCr)
.getResource();
.getResource()
.get();
var givenContext = new MongoDbCustomResourceContext();

var actual = mongoDbController.reconcile(givenMongoDbCr, givenContext);

assertSoftly(
softly -> {
softly.assertThat(actual.isUpdateResource()).isFalse();
softly.assertThat(actual.isUpdateStatus()).isFalse();
softly.assertThat(actual.isUpdateResourceAndStatus()).isFalse();
softly.assertThat(actual.isPatchResource()).isFalse();
softly.assertThat(actual.isPatchStatus()).isFalse();
softly.assertThat(actual.isPatchResourceAndStatus()).isFalse();
softly.assertThat(actual.isNoUpdate()).isTrue();
});
verifyNoInteractions(taskFactorySpy, mongoDbServiceMock, kubernetesClientAdapterMock);
}

private boolean areAllStatusConditionsTrue(UpdateControl<MongoDbCustomResource> resource) {
Map<String, String> conditionsByName = extractStatusConditions(resource);
return !conditionsByName.isEmpty()
&& conditionsByName.values().stream().allMatch("True"::equals);
}

private Map<String, String> extractStatusConditions(
UpdateControl<MongoDbCustomResource> resource) {
return resource
.getResource()
.map(MongoDbCustomResource::getStatus)
.map(MongoDbStatus::getConditions)
.map(
conditions ->
conditions.stream()
.collect(Collectors.toMap(Condition::getType, Condition::getStatus)))
.orElse(new HashMap<>());
}

private class MongoDbCustomResourceContext implements Context<MongoDbCustomResource> {

@Override
Expand All @@ -478,24 +490,17 @@ public <T> Set<T> getSecondaryResources(Class<T> expectedType) {
}

@Override
@SuppressWarnings("removal")
public <T> Optional<T> getSecondaryResource(Class<T> expectedType, String eventSourceName) {
return Optional.empty();
}

@Override
public <R> Optional<R> getSecondaryResource(
Class<R> expectedType, ResourceDiscriminator<R, MongoDbCustomResource> discriminator) {
return Optional.empty();
}

@Override
public ControllerConfiguration<MongoDbCustomResource> getControllerConfiguration() {
return null;
}

@Override
public ManagedDependentResourceContext managedDependentResourceContext() {
public ManagedWorkflowAndDependentResourceContext managedWorkflowAndDependentResourceContext() {
return null;
}

Expand All @@ -518,5 +523,10 @@ public ExecutorService getWorkflowExecutorService() {
public IndexedResourceCache<MongoDbCustomResource> getPrimaryCache() {
return null;
}

@Override
public boolean isNextReconciliationImminent() {
return false;
}
}
}
Loading