Skip to content

feat: dependent resource inherits namespaces from controller config #1020

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 2 commits into from
Mar 11, 2022
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
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ public InformerConfiguration<R, P> build() {

static <R extends HasMetadata, P extends HasMetadata> InformerConfigurationBuilder<R, P> from(
EventSourceContext<P> context, Class<R> resourceClass) {
return new InformerConfigurationBuilder<>(resourceClass, context.getConfigurationService());
return new InformerConfigurationBuilder<>(resourceClass, context.getControllerConfiguration()
.getConfigurationService());
}

static InformerConfigurationBuilder from(ConfigurationService configurationService,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

import java.util.Optional;

import io.javaoperatorsdk.operator.api.config.ConfigurationService;
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
import io.javaoperatorsdk.operator.api.reconciler.dependent.ManagedDependentResourceContext;

public interface Context {
public interface Context<P extends HasMetadata> {

Optional<RetryInfo> getRetryInfo();

Expand All @@ -15,7 +16,7 @@ default <T> Optional<T> getSecondaryResource(Class<T> expectedType) {

<T> Optional<T> getSecondaryResource(Class<T> expectedType, String eventSourceName);

ConfigurationService getConfigurationService();
ControllerConfiguration<P> getControllerConfiguration();

ManagedDependentResourceContext managedDependentResourceContext();
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,23 @@
import java.util.Optional;

import io.fabric8.kubernetes.api.model.HasMetadata;
import io.javaoperatorsdk.operator.api.config.ConfigurationService;
import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
import io.javaoperatorsdk.operator.api.reconciler.dependent.ManagedDependentResourceContext;
import io.javaoperatorsdk.operator.processing.Controller;

public class DefaultContext<P extends HasMetadata> implements Context {
public class DefaultContext<P extends HasMetadata> implements Context<P> {

private final RetryInfo retryInfo;
private final Controller<P> controller;
private final P primaryResource;
private final ConfigurationService configurationService;
private final ControllerConfiguration<P> controllerConfiguration;
private ManagedDependentResourceContext managedDependentResourceContext;

public DefaultContext(RetryInfo retryInfo, Controller<P> controller, P primaryResource) {
this.retryInfo = retryInfo;
this.controller = controller;
this.primaryResource = primaryResource;
this.configurationService = controller.getConfiguration().getConfigurationService();
this.controllerConfiguration = controller.getConfiguration();
this.managedDependentResourceContext = new ManagedDependentResourceContext(
controller.getDependents());
}
Expand All @@ -37,8 +37,8 @@ public <T> Optional<T> getSecondaryResource(Class<T> expectedType, String eventS
}

@Override
public ConfigurationService getConfigurationService() {
return configurationService;
public ControllerConfiguration<P> getControllerConfiguration() {
return controllerConfiguration;
}

public ManagedDependentResourceContext managedDependentResourceContext() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.javaoperatorsdk.operator.api.config.ConfigurationService;
import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
import io.javaoperatorsdk.operator.processing.event.source.EventSource;
import io.javaoperatorsdk.operator.processing.event.source.ResourceCache;

Expand All @@ -14,13 +14,14 @@
public class EventSourceContext<P extends HasMetadata> {

private final ResourceCache<P> primaryCache;
private final ConfigurationService configurationService;
private final ControllerConfiguration<P> controllerConfiguration;
private final KubernetesClient client;

public EventSourceContext(ResourceCache<P> primaryCache,
ConfigurationService configurationService, KubernetesClient client) {
ControllerConfiguration<P> controllerConfiguration,
KubernetesClient client) {
this.primaryCache = primaryCache;
this.configurationService = configurationService;
this.controllerConfiguration = controllerConfiguration;
this.client = client;
}

Expand All @@ -34,16 +35,13 @@ public ResourceCache<P> getPrimaryCache() {
}

/**
* Retrieves the {@link ConfigurationService} associated with the operator. This allows, in
* particular, to lookup global configuration information such as the configured
* {@link io.javaoperatorsdk.operator.api.monitoring.Metrics} or
* {@link io.javaoperatorsdk.operator.api.config.Cloner} implementations, which could be useful to
* event sources.
* Retrieves the {@link ControllerConfiguration} associated with the operator. This allows, in
* particular, to lookup controller and global configuration information such as the configured*
*
* @return the {@link ConfigurationService} associated with the operator
* @return the {@link ControllerConfiguration} associated with the operator
*/
public ConfigurationService getConfigurationService() {
return configurationService;
public ControllerConfiguration<P> getControllerConfiguration() {
return controllerConfiguration;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public interface Reconciler<R extends HasMetadata> {
* @return UpdateControl to manage updates on the custom resource (usually the status) after
* reconciliation.
*/
UpdateControl<R> reconcile(R resource, Context context);
UpdateControl<R> reconcile(R resource, Context<R> context);

/**
* Note that this method is used in combination with finalizers. If automatic finalizer handling
Expand All @@ -37,7 +37,7 @@ public interface Reconciler<R extends HasMetadata> {
* finalizer to indicate that the resource should not be deleted after all, in which case
* the controller should restore the resource's state appropriately.
*/
default DeleteControl cleanup(R resource, Context context) {
default DeleteControl cleanup(R resource, Context<R> context) {
return DeleteControl.defaultDelete();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public AbstractDependentResource() {
}

@Override
public void reconcile(P primary, Context context) {
public void reconcile(P primary, Context<P> context) {
final var creatable = isCreatable(primary, context);
final var updatable = isUpdatable(primary, context);
if (creatable || updatable) {
Expand Down Expand Up @@ -67,7 +67,7 @@ public void reconcile(P primary, Context context) {
}
}

protected void handleCreate(R desired, P primary, Context context) {
protected void handleCreate(R desired, P primary, Context<P> context) {
ResourceID resourceID = ResourceID.fromResource(primary);
R created = null;
try {
Expand Down Expand Up @@ -107,7 +107,7 @@ private void prepareEventFiltering(R desired, ResourceID resourceID) {
}
}

protected void handleUpdate(R actual, R desired, P primary, Context context) {
protected void handleUpdate(R actual, R desired, P primary, Context<P> context) {
ResourceID resourceID = ResourceID.fromResource(primary);
R updated = null;
try {
Expand All @@ -131,29 +131,29 @@ private RecentOperationCacheFiller<R> eventSourceAsRecentOperationCacheFiller()
}

@Override
public void cleanup(P primary, Context context) {
public void cleanup(P primary, Context<P> context) {
if (isDeletable(primary, context)) {
deleter.delete(primary, context);
}
}

protected R desired(P primary, Context context) {
protected R desired(P primary, Context<P> context) {
throw new IllegalStateException(
"desired method must be implemented if this DependentResource can be created and/or updated");
}

@SuppressWarnings("unused")
protected boolean isCreatable(P primary, Context context) {
protected boolean isCreatable(P primary, Context<P> context) {
return creatable;
}

@SuppressWarnings("unused")
protected boolean isUpdatable(P primary, Context context) {
protected boolean isUpdatable(P primary, Context<P> context) {
return updatable;
}

@SuppressWarnings("unused")
protected boolean isDeletable(P primary, Context context) {
protected boolean isDeletable(P primary, Context<P> context) {
return deletable;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@

@FunctionalInterface
public interface Creator<R, P extends HasMetadata> {
R create(R desired, P primary, Context context);
R create(R desired, P primary, Context<P> context);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@

@FunctionalInterface
public interface Deleter<P extends HasMetadata> {
void delete(P primary, Context context);
void delete(P primary, Context<P> context);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
import io.javaoperatorsdk.operator.api.reconciler.Context;

public interface DependentResource<R, P extends HasMetadata> {
void reconcile(P primary, Context context);
void reconcile(P primary, Context<P> context);

default void cleanup(P primary, Context context) {}
default void cleanup(P primary, Context<P> context) {}

Optional<R> getResource(P primaryResource);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public DesiredEqualsMatcher(AbstractDependentResource<R, P> abstractDependentRes
}

@Override
public Result<R> match(R actualResource, P primary, Context context) {
public Result<R> match(R actualResource, P primary, Context<P> context) {
var desired = abstractDependentResource.desired(primary, context);
return Result.computed(actualResource.equals(desired), desired);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@ public Optional<T> computedDesired() {
}
}

Result<R> match(R actualResource, P primary, Context context);
Result<R> match(R actualResource, P primary, Context<P> context);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import io.javaoperatorsdk.operator.api.reconciler.dependent.Matcher.Result;

public interface Updater<R, P extends HasMetadata> {
R update(R actual, R desired, P primary, Context context);
R update(R actual, R desired, P primary, Context<P> context);

Result<R> match(R actualResource, P primary, Context context);
Result<R> match(R actualResource, P primary, Context<P> context);
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,21 @@

@SuppressWarnings({"unchecked"})
@Ignore
public class Controller<R extends HasMetadata> implements Reconciler<R>,
LifecycleAware, EventSourceInitializer<R> {
public class Controller<P extends HasMetadata> implements Reconciler<P>,
LifecycleAware, EventSourceInitializer<P> {

private static final Logger log = LoggerFactory.getLogger(Controller.class);

private final Reconciler<R> reconciler;
private final ControllerConfiguration<R> configuration;
private final Reconciler<P> reconciler;
private final ControllerConfiguration<P> configuration;
private final KubernetesClient kubernetesClient;
private final EventSourceManager<R> eventSourceManager;
private final DependentResourceManager<R> dependents;
private final EventSourceManager<P> eventSourceManager;
private final DependentResourceManager<P> dependents;

private ConfigurationService configurationService;

public Controller(Reconciler<R> reconciler,
ControllerConfiguration<R> configuration,
public Controller(Reconciler<P> reconciler,
ControllerConfiguration<P> configuration,
KubernetesClient kubernetesClient) {
this.reconciler = reconciler;
this.configuration = configuration;
Expand All @@ -61,7 +61,7 @@ public Controller(Reconciler<R> reconciler,
}

@Override
public DeleteControl cleanup(R resource, Context context) {
public DeleteControl cleanup(P resource, Context<P> context) {
dependents.cleanup(resource, context);

return metrics().timeControllerExecution(
Expand Down Expand Up @@ -89,7 +89,7 @@ public DeleteControl execute() {
}

@Override
public UpdateControl<R> reconcile(R resource, Context context) {
public UpdateControl<P> reconcile(P resource, Context<P> context) {
dependents.reconcile(resource, context);

return metrics().timeControllerExecution(
Expand All @@ -105,7 +105,7 @@ public String controllerName() {
}

@Override
public String successTypeName(UpdateControl<R> result) {
public String successTypeName(UpdateControl<P> result) {
String successType = "resource";
if (result.isUpdateStatus()) {
successType = "status";
Expand All @@ -117,7 +117,7 @@ public String successTypeName(UpdateControl<R> result) {
}

@Override
public UpdateControl<R> execute() {
public UpdateControl<P> execute() {
return reconciler.reconcile(resource, context);
}
});
Expand All @@ -130,13 +130,13 @@ private Metrics metrics() {
}

@Override
public List<EventSource> prepareEventSources(EventSourceContext<R> context) {
public List<EventSource> prepareEventSources(EventSourceContext<P> context) {
final var dependentSources = dependents.prepareEventSources(context);
List<EventSource> sources = new LinkedList<>(dependentSources);

// add manually defined event sources
if (reconciler instanceof EventSourceInitializer) {
sources.addAll(((EventSourceInitializer<R>) reconciler).prepareEventSources(context));
sources.addAll(((EventSourceInitializer<P>) reconciler).prepareEventSources(context));
}
return sources;
}
Expand Down Expand Up @@ -164,19 +164,19 @@ public String toString() {
return "'" + configuration.getName() + "' Controller";
}

public Reconciler<R> getReconciler() {
public Reconciler<P> getReconciler() {
return reconciler;
}

public ControllerConfiguration<R> getConfiguration() {
public ControllerConfiguration<P> getConfiguration() {
return configuration;
}

public KubernetesClient getClient() {
return kubernetesClient;
}

public MixedOperation<R, KubernetesResourceList<R>, Resource<R>> getCRClient() {
public MixedOperation<P, KubernetesResourceList<P>, Resource<P>> getCRClient() {
return kubernetesClient.resources(configuration.getResourceClass());
}

Expand All @@ -189,7 +189,7 @@ public MixedOperation<R, KubernetesResourceList<R>, Resource<R>> getCRClient() {
* @throws OperatorException if a problem occurred during the registration process
*/
public void start() throws OperatorException {
final Class<R> resClass = configuration.getResourceClass();
final Class<P> resClass = configuration.getResourceClass();
final String controllerName = configuration.getName();
final var crdName = configuration.getResourceTypeName();
final var specVersion = "v1";
Expand All @@ -215,8 +215,7 @@ public void start() throws OperatorException {
}

final var context = new EventSourceContext<>(
eventSourceManager.getControllerResourceEventSource(),
configurationService(), kubernetesClient);
eventSourceManager.getControllerResourceEventSource(), configuration, kubernetesClient);

prepareEventSources(context).forEach(eventSourceManager::registerEventSource);

Expand Down Expand Up @@ -273,7 +272,7 @@ private void failOnMissingCurrentNS() {
}
}

public EventSourceManager<R> getEventSourceManager() {
public EventSourceManager<P> getEventSourceManager() {
return eventSourceManager;
}

Expand Down
Loading