From 85b94d50963463be76ff84d8be2ef3f506221988 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Wed, 18 Nov 2020 16:48:58 +0100 Subject: [PATCH 01/23] feat: upgrade to k8s client 5.0 to simplify CR handling --- .../operator/ControllerUtils.java | 52 +-------- .../io/javaoperatorsdk/operator/Operator.java | 31 ++--- .../operator/processing/EventDispatcher.java | 63 +++++------ .../operator/ControllerUtilsTest.java | 2 - .../operator/IntegrationTestSupport.java | 27 ++--- pom.xml | 2 +- .../sample/CustomServiceController.java | 29 ++--- samples/tomcat/pom.xml | 5 - .../operator/sample/TomcatController.java | 50 ++++---- .../operator/sample/TomcatOperator.java | 7 +- .../operator/sample/WebServerController.java | 107 +++++++++--------- .../starter/model/TestResourceDoneable.java | 10 -- 12 files changed, 152 insertions(+), 233 deletions(-) delete mode 100644 spring-boot-starter/src/test/java/io/javaoperatorsdk/operator/springboot/starter/model/TestResourceDoneable.java diff --git a/operator-framework/src/main/java/io/javaoperatorsdk/operator/ControllerUtils.java b/operator-framework/src/main/java/io/javaoperatorsdk/operator/ControllerUtils.java index ee55c152f3..49b10d938d 100644 --- a/operator-framework/src/main/java/io/javaoperatorsdk/operator/ControllerUtils.java +++ b/operator-framework/src/main/java/io/javaoperatorsdk/operator/ControllerUtils.java @@ -1,28 +1,17 @@ package io.javaoperatorsdk.operator; +import io.fabric8.kubernetes.client.CustomResource; import io.javaoperatorsdk.operator.api.Controller; import io.javaoperatorsdk.operator.api.ResourceController; -import io.fabric8.kubernetes.api.builder.Function; -import io.fabric8.kubernetes.client.CustomResource; -import io.fabric8.kubernetes.client.CustomResourceDoneable; -import javassist.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.HashMap; -import java.util.Map; - public class ControllerUtils { private final static double JAVA_VERSION = Double.parseDouble(System.getProperty("java.specification.version")); private static final String FINALIZER_NAME_SUFFIX = "/finalizer"; - - // this is just to support testing, this way we don't try to create class multiple times in memory with same name. - // note that other solution is to add a random string to doneable class name - private static Map, Class>> - doneableClassCache = new HashMap<>(); - + static String getFinalizer(ResourceController controller) { final String annotationFinalizerName = getAnnotation(controller).finalizerName(); if (!Controller.NULL.equals(annotationFinalizerName)) { @@ -43,42 +32,7 @@ static Class getCustomResourceClass(ResourceContro static String getCrdName(ResourceController controller) { return getAnnotation(controller).crdName(); } - - - public static Class> - getCustomResourceDoneableClass(ResourceController controller) { - try { - Class customResourceClass = getAnnotation(controller).customResourceClass(); - String className = customResourceClass.getPackage().getName() + "." + customResourceClass.getSimpleName() + "CustomResourceDoneable"; - - if (doneableClassCache.containsKey(customResourceClass)) { - return (Class>) doneableClassCache.get(customResourceClass); - } - - ClassPool pool = ClassPool.getDefault(); - pool.appendClassPath(new LoaderClassPath(Thread.currentThread().getContextClassLoader())); - - CtClass superClass = pool.get(CustomResourceDoneable.class.getName()); - CtClass function = pool.get(Function.class.getName()); - CtClass customResource = pool.get(customResourceClass.getName()); - CtClass[] argTypes = {customResource, function}; - CtClass customDoneable = pool.makeClass(className, superClass); - CtConstructor ctConstructor = CtNewConstructor.make(argTypes, null, "super($1, $2);", customDoneable); - customDoneable.addConstructor(ctConstructor); - - Class> doneableClass; - if (JAVA_VERSION >= 9) { - doneableClass = (Class>) customDoneable.toClass(customResourceClass); - } else { - doneableClass = (Class>) customDoneable.toClass(); - } - doneableClassCache.put(customResourceClass, doneableClass); - return doneableClass; - } catch (CannotCompileException | NotFoundException e) { - throw new IllegalStateException(e); - } - } - + private static Controller getAnnotation(ResourceController controller) { return controller.getClass().getAnnotation(Controller.class); } diff --git a/operator-framework/src/main/java/io/javaoperatorsdk/operator/Operator.java b/operator-framework/src/main/java/io/javaoperatorsdk/operator/Operator.java index 73e03a44c2..3271b2023b 100644 --- a/operator-framework/src/main/java/io/javaoperatorsdk/operator/Operator.java +++ b/operator-framework/src/main/java/io/javaoperatorsdk/operator/Operator.java @@ -1,26 +1,24 @@ package io.javaoperatorsdk.operator; -import io.javaoperatorsdk.operator.api.ResourceController; -import io.javaoperatorsdk.operator.processing.EventDispatcher; -import io.javaoperatorsdk.operator.processing.EventScheduler; -import io.javaoperatorsdk.operator.processing.retry.GenericRetry; -import io.javaoperatorsdk.operator.processing.retry.Retry; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + import io.fabric8.kubernetes.api.model.apiextensions.v1beta1.CustomResourceDefinition; import io.fabric8.kubernetes.client.CustomResource; -import io.fabric8.kubernetes.client.CustomResourceDoneable; -import io.fabric8.kubernetes.client.CustomResourceList; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.dsl.MixedOperation; import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext; import io.fabric8.kubernetes.client.dsl.internal.CustomResourceOperationsImpl; import io.fabric8.kubernetes.internal.KubernetesDeserializer; +import io.javaoperatorsdk.operator.api.ResourceController; +import io.javaoperatorsdk.operator.processing.EventDispatcher; +import io.javaoperatorsdk.operator.processing.EventScheduler; +import io.javaoperatorsdk.operator.processing.retry.GenericRetry; +import io.javaoperatorsdk.operator.processing.retry.Retry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - @SuppressWarnings("rawtypes") public class Operator { @@ -56,9 +54,9 @@ private void registerController(ResourceController CustomResourceDefinitionContext crd = getCustomResourceDefinitionForController(controller); KubernetesDeserializer.registerCustomKind(crd.getVersion(), crd.getKind(), resClass); String finalizer = ControllerUtils.getFinalizer(controller); - MixedOperation client = k8sClient.customResources(crd, resClass, CustomResourceList.class, ControllerUtils.getCustomResourceDoneableClass(controller)); + MixedOperation client = k8sClient.customResources(resClass); EventDispatcher eventDispatcher = new EventDispatcher(controller, - finalizer, new EventDispatcher.CustomResourceFacade(client), ControllerUtils.getGenerationEventProcessing(controller)); + finalizer, new EventDispatcher.CustomResourceFacade(client), ControllerUtils.getGenerationEventProcessing(controller)); EventScheduler eventScheduler = new EventScheduler(eventDispatcher, retry); registerWatches(controller, client, resClass, watchAllNamespaces, targetNamespaces, eventScheduler); } @@ -97,12 +95,7 @@ private CustomResourceDefinitionContext getCustomResourceDefinitionForController public Map, CustomResourceOperationsImpl> getCustomResourceClients() { return customResourceClients; } - - public , D extends CustomResourceDoneable> CustomResourceOperationsImpl - getCustomResourceClients(Class customResourceClass) { - return customResourceClients.get(customResourceClass); - } - + private String getKind(CustomResourceDefinition crd) { return crd.getSpec().getNames().getKind(); } diff --git a/operator-framework/src/main/java/io/javaoperatorsdk/operator/processing/EventDispatcher.java b/operator-framework/src/main/java/io/javaoperatorsdk/operator/processing/EventDispatcher.java index 2b102e8471..f53d0a18f2 100644 --- a/operator-framework/src/main/java/io/javaoperatorsdk/operator/processing/EventDispatcher.java +++ b/operator-framework/src/main/java/io/javaoperatorsdk/operator/processing/EventDispatcher.java @@ -1,18 +1,20 @@ package io.javaoperatorsdk.operator.processing; -import io.javaoperatorsdk.operator.ControllerUtils; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + import io.fabric8.kubernetes.client.CustomResource; import io.fabric8.kubernetes.client.Watcher; import io.fabric8.kubernetes.client.dsl.MixedOperation; import io.fabric8.kubernetes.client.dsl.Resource; -import io.javaoperatorsdk.operator.api.*; +import io.javaoperatorsdk.operator.api.Context; +import io.javaoperatorsdk.operator.api.DefaultContext; +import io.javaoperatorsdk.operator.api.ResourceController; +import io.javaoperatorsdk.operator.api.RetryInfo; +import io.javaoperatorsdk.operator.api.UpdateControl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.ArrayList; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - /** * Dispatches events to the Controller and handles Finalizers for a single type of Custom Resource. */ @@ -43,23 +45,24 @@ public void handleEvent(CustomResourceEvent event) { log.error("Received error for resource: {}", resource.getMetadata().getName()); return; } - if (markedForDeletion(resource) && !ControllerUtils.hasGivenFinalizer(resource, resourceFinalizer)) { - log.debug("Skipping event dispatching since its marked for deletion but does not have finalizer: {}", event); - return; - } + final boolean markedForDeletion = resource.isMarkedForDeletion(); + final boolean hasFinalizer = resource.hasFinalizer(resourceFinalizer); Context context = new DefaultContext(new RetryInfo(event.getRetryCount(), event.getRetryExecution().isLastExecution())); - if (markedForDeletion(resource)) { + if (markedForDeletion) { + if (!hasFinalizer) { + log.debug("Skipping event dispatching since its marked for deletion but has no default finalizer: {}", event); + return; + } boolean removeFinalizer = controller.deleteResource(resource, context); - boolean hasFinalizer = ControllerUtils.hasGivenFinalizer(resource, resourceFinalizer); - if (removeFinalizer && hasFinalizer) { + if (removeFinalizer) { removeFinalizer(resource); } else { log.debug("Skipping finalizer remove. removeFinalizer: {}, hasFinalizer: {} ", - removeFinalizer, hasFinalizer); + removeFinalizer, hasFinalizer); } cleanup(resource); } else { - if (!ControllerUtils.hasGivenFinalizer(resource, resourceFinalizer) && !markedForDeletion(resource)) { + if (!hasFinalizer) { /* We always add a finalizer if missing and not marked for deletion. We execute the controller processing only for processing the event sent as a results of the finalizer add. This will make sure that the resources are not created before @@ -105,8 +108,10 @@ private void markLastGenerationProcessed(CustomResource resource) { private void updateCustomResourceWithFinalizer(CustomResource resource) { log.debug("Adding finalizer for resource: {} version: {}", resource.getMetadata().getName(), - resource.getMetadata().getResourceVersion()); - addFinalizerIfNotPresent(resource); + resource.getMetadata().getResourceVersion()); + if (resource.addFinalizer(resourceFinalizer)) { + log.info("Adding default finalizer to {}", resource.getMetadata()); + } replace(resource); } @@ -128,27 +133,13 @@ private void replace(CustomResource resource) { log.debug("Trying to replace resource {}, version: {}", resource.getMetadata().getName(), resource.getMetadata().getResourceVersion()); customResourceFacade.replaceWithLock(resource); } - - private void addFinalizerIfNotPresent(CustomResource resource) { - if (!ControllerUtils.hasGivenFinalizer(resource, resourceFinalizer) && !markedForDeletion(resource)) { - log.info("Adding finalizer {} to {}", resourceFinalizer, resource.getMetadata()); - if (resource.getMetadata().getFinalizers() == null) { - resource.getMetadata().setFinalizers(new ArrayList<>(1)); - } - resource.getMetadata().getFinalizers().add(resourceFinalizer); - } - } - - private boolean markedForDeletion(CustomResource resource) { - return resource.getMetadata().getDeletionTimestamp() != null && !resource.getMetadata().getDeletionTimestamp().isEmpty(); - } - + // created to support unit testing public static class CustomResourceFacade { - - private final MixedOperation> resourceOperation; - - public CustomResourceFacade(MixedOperation> resourceOperation) { + + private final MixedOperation> resourceOperation; + + public CustomResourceFacade(MixedOperation> resourceOperation) { this.resourceOperation = resourceOperation; } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerUtilsTest.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerUtilsTest.java index 4c8b48a009..fc63b599b7 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerUtilsTest.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerUtilsTest.java @@ -1,6 +1,5 @@ package io.javaoperatorsdk.operator; -import io.fabric8.kubernetes.client.CustomResourceDoneable; import io.javaoperatorsdk.operator.api.Context; import io.javaoperatorsdk.operator.api.Controller; import io.javaoperatorsdk.operator.api.ResourceController; @@ -22,7 +21,6 @@ public void returnsValuesFromControllerAnnotationFinalizer() { assertEquals(TestCustomResource.class, ControllerUtils.getCustomResourceClass(new TestCustomResourceController(null))); Assertions.assertEquals(TestCustomResourceController.CRD_NAME, ControllerUtils.getCrdName(new TestCustomResourceController(null))); assertFalse(ControllerUtils.getGenerationEventProcessing(new TestCustomResourceController(null))); - assertTrue(CustomResourceDoneable.class.isAssignableFrom(ControllerUtils.getCustomResourceDoneableClass(new TestCustomResourceController(null)))); } @Controller(crdName = "test.crd", customResourceClass = TestCustomResource.class, finalizerName = CUSTOM_FINALIZER_NAME) diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/IntegrationTestSupport.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/IntegrationTestSupport.java index 2c6e0274ce..9e55cbdf79 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/IntegrationTestSupport.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/IntegrationTestSupport.java @@ -1,27 +1,26 @@ package io.javaoperatorsdk.operator; -import io.javaoperatorsdk.operator.api.ResourceController; -import io.javaoperatorsdk.operator.sample.TestCustomResource; -import io.javaoperatorsdk.operator.sample.TestCustomResourceSpec; +import java.io.IOException; +import java.io.InputStream; +import java.util.concurrent.TimeUnit; + import io.fabric8.kubernetes.api.model.Namespace; import io.fabric8.kubernetes.api.model.NamespaceBuilder; import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; import io.fabric8.kubernetes.api.model.apiextensions.v1beta1.CustomResourceDefinition; import io.fabric8.kubernetes.client.CustomResource; -import io.fabric8.kubernetes.client.CustomResourceDoneable; import io.fabric8.kubernetes.client.CustomResourceList; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.dsl.MixedOperation; import io.fabric8.kubernetes.client.dsl.Resource; import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext; import io.fabric8.kubernetes.client.utils.Serialization; +import io.javaoperatorsdk.operator.api.ResourceController; +import io.javaoperatorsdk.operator.sample.TestCustomResource; +import io.javaoperatorsdk.operator.sample.TestCustomResourceSpec; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; -import java.io.InputStream; -import java.util.concurrent.TimeUnit; - import static org.assertj.core.api.Assertions.assertThat; import static org.awaitility.Awaitility.await; @@ -31,8 +30,7 @@ public class IntegrationTestSupport { public static final String TEST_CUSTOM_RESOURCE_PREFIX = "test-custom-resource-"; private final static Logger log = LoggerFactory.getLogger(IntegrationTestSupport.class); private KubernetesClient k8sClient; - private MixedOperation> crOperations; + private MixedOperation> crOperations; private Operator operator; private ResourceController controller; @@ -42,10 +40,9 @@ public void initialize(KubernetesClient k8sClient, ResourceController controller CustomResourceDefinition crd = loadCRDAndApplyToCluster(crdPath); CustomResourceDefinitionContext crdContext = CustomResourceDefinitionContext.fromCrd(crd); this.controller = controller; - - Class doneableClass = ControllerUtils.getCustomResourceDoneableClass(controller); + Class customResourceClass = ControllerUtils.getCustomResourceClass(controller); - crOperations = k8sClient.customResources(crdContext, customResourceClass, CustomResourceList.class, doneableClass); + this.crOperations = k8sClient.customResources(customResourceClass); if (k8sClient.namespaces().withName(TEST_NAMESPACE).get() == null) { k8sClient.namespaces().create(new NamespaceBuilder() @@ -145,8 +142,8 @@ public TestCustomResource createTestCustomResource(String id) { public KubernetesClient getK8sClient() { return k8sClient; } - - public MixedOperation> getCrOperations() { + + public MixedOperation> getCrOperations() { return crOperations; } diff --git a/pom.xml b/pom.xml index 8ec9328cbf..905fca7607 100644 --- a/pom.xml +++ b/pom.xml @@ -52,7 +52,7 @@ io.fabric8 openshift-client - 4.12.0 + 5.0.0-alpha-1 org.apache.commons diff --git a/samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomServiceController.java b/samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomServiceController.java index 1f489d81dc..414096ea65 100644 --- a/samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomServiceController.java +++ b/samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomServiceController.java @@ -1,17 +1,18 @@ package io.javaoperatorsdk.operator.sample; +import java.util.Collections; + +import io.fabric8.kubernetes.api.model.ServiceBuilder; +import io.fabric8.kubernetes.api.model.ServicePort; +import io.fabric8.kubernetes.api.model.ServiceSpec; +import io.fabric8.kubernetes.client.KubernetesClient; import io.javaoperatorsdk.operator.api.Context; import io.javaoperatorsdk.operator.api.Controller; import io.javaoperatorsdk.operator.api.ResourceController; import io.javaoperatorsdk.operator.api.UpdateControl; -import io.fabric8.kubernetes.api.model.ServicePort; -import io.fabric8.kubernetes.api.model.ServiceSpec; -import io.fabric8.kubernetes.client.KubernetesClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Collections; - /** * A very simple sample controller that creates a service with a label. */ @@ -39,19 +40,19 @@ public boolean deleteResource(CustomService resource, Context con @Override public UpdateControl createOrUpdateResource(CustomService resource, Context context) { log.info("Execution createOrUpdateResource for: {}", resource.getMetadata().getName()); - + ServicePort servicePort = new ServicePort(); servicePort.setPort(8080); ServiceSpec serviceSpec = new ServiceSpec(); serviceSpec.setPorts(Collections.singletonList(servicePort)); - - kubernetesClient.services().inNamespace(resource.getMetadata().getNamespace()).createOrReplaceWithNew() - .withNewMetadata() - .withName(resource.getSpec().getName()) - .addToLabels("testLabel", resource.getSpec().getLabel()) - .endMetadata() - .withSpec(serviceSpec) - .done(); + + kubernetesClient.services().inNamespace(resource.getMetadata().getNamespace()).createOrReplace(new ServiceBuilder() + .withNewMetadata() + .withName(resource.getSpec().getName()) + .addToLabels("testLabel", resource.getSpec().getLabel()) + .endMetadata() + .withSpec(serviceSpec) + .build()); return UpdateControl.updateCustomResource(resource); } } diff --git a/samples/tomcat/pom.xml b/samples/tomcat/pom.xml index 65b4ca7712..f2dfabd6d8 100644 --- a/samples/tomcat/pom.xml +++ b/samples/tomcat/pom.xml @@ -45,11 +45,6 @@ commons-io 2.8.0 - - io.fabric8 - kubernetes-client - 4.12.0 - diff --git a/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/TomcatController.java b/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/TomcatController.java index 1034ce1b39..bd89e199a5 100644 --- a/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/TomcatController.java +++ b/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/TomcatController.java @@ -1,31 +1,32 @@ package io.javaoperatorsdk.operator.sample; -import io.javaoperatorsdk.operator.api.Context; -import io.javaoperatorsdk.operator.api.Controller; -import io.javaoperatorsdk.operator.api.ResourceController; -import io.javaoperatorsdk.operator.api.UpdateControl; -import io.fabric8.kubernetes.api.model.DoneableService; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; + import io.fabric8.kubernetes.api.model.HasMetadata; +import io.fabric8.kubernetes.api.model.KubernetesResourceList; import io.fabric8.kubernetes.api.model.Service; import io.fabric8.kubernetes.api.model.apps.Deployment; -import io.fabric8.kubernetes.api.model.apps.DoneableDeployment; -import io.fabric8.kubernetes.client.*; +import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.KubernetesClientException; +import io.fabric8.kubernetes.client.Watcher; import io.fabric8.kubernetes.client.dsl.MixedOperation; import io.fabric8.kubernetes.client.dsl.Resource; import io.fabric8.kubernetes.client.dsl.RollableScalableResource; import io.fabric8.kubernetes.client.dsl.ServiceResource; import io.fabric8.kubernetes.client.utils.Serialization; +import io.javaoperatorsdk.operator.api.Context; +import io.javaoperatorsdk.operator.api.Controller; +import io.javaoperatorsdk.operator.api.ResourceController; +import io.javaoperatorsdk.operator.api.UpdateControl; import org.apache.commons.lang3.builder.EqualsBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.Optional; - @Controller(customResourceClass = Tomcat.class, crdName = "tomcats.tomcatoperator.io") public class TomcatController implements ResourceController { @@ -33,13 +34,14 @@ public class TomcatController implements ResourceController { private final Logger log = LoggerFactory.getLogger(getClass()); private final KubernetesClient kubernetesClient; - - private MixedOperation, CustomResourceDoneable, Resource>> tomcatOperations; + + private MixedOperation, Resource> tomcatOperations; private final List watchedResources = new ArrayList<>(); public TomcatController(KubernetesClient client) { this.kubernetesClient = client; + this.tomcatOperations = client.customResources(Tomcat.class); } private void updateTomcatStatus(Context context, Tomcat tomcat, Deployment deployment) { @@ -121,9 +123,9 @@ private Deployment createOrUpdateDeployment(Tomcat tomcat) { private void deleteDeployment(Tomcat tomcat) { log.info("Deleting Deployment {}", tomcat.getMetadata().getName()); - RollableScalableResource deployment = kubernetesClient.apps().deployments() - .inNamespace(tomcat.getMetadata().getNamespace()) - .withName(tomcat.getMetadata().getName()); + final RollableScalableResource deployment = kubernetesClient.apps().deployments() + .inNamespace(tomcat.getMetadata().getNamespace()) + .withName(tomcat.getMetadata().getName()); if (deployment.get() != null) { deployment.delete(); } @@ -141,9 +143,9 @@ private void createOrUpdateService(Tomcat tomcat) { private void deleteService(Tomcat tomcat) { log.info("Deleting Service {}", tomcat.getMetadata().getName()); - ServiceResource service = kubernetesClient.services() - .inNamespace(tomcat.getMetadata().getNamespace()) - .withName(tomcat.getMetadata().getName()); + ServiceResource service = kubernetesClient.services() + .inNamespace(tomcat.getMetadata().getNamespace()) + .withName(tomcat.getMetadata().getName()); if (service.get() != null) { service.delete(); } @@ -157,10 +159,6 @@ private T loadYaml(Class clazz, String yaml) { } } - public void setTomcatOperations(MixedOperation, CustomResourceDoneable, Resource>> tomcatOperations) { - this.tomcatOperations = tomcatOperations; - } - private static class WatchedResource { private final String type; private final String name; diff --git a/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/TomcatOperator.java b/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/TomcatOperator.java index fe1efe418f..7cc45d0e68 100644 --- a/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/TomcatOperator.java +++ b/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/TomcatOperator.java @@ -1,10 +1,12 @@ package io.javaoperatorsdk.operator.sample; -import io.javaoperatorsdk.operator.Operator; +import java.io.IOException; + import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.ConfigBuilder; import io.fabric8.kubernetes.client.DefaultKubernetesClient; import io.fabric8.kubernetes.client.KubernetesClient; +import io.javaoperatorsdk.operator.Operator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.takes.facets.fork.FkRegex; @@ -12,8 +14,6 @@ import org.takes.http.Exit; import org.takes.http.FtBasic; -import java.io.IOException; - public class TomcatOperator { private static final Logger log = LoggerFactory.getLogger(TomcatOperator.class); @@ -26,7 +26,6 @@ public static void main(String[] args) throws IOException { TomcatController tomcatController = new TomcatController(client); operator.registerControllerForAllNamespaces(tomcatController); - tomcatController.setTomcatOperations(operator.getCustomResourceClients(Tomcat.class)); operator.registerControllerForAllNamespaces(new WebappController(client)); diff --git a/samples/webserver/src/main/java/io/javaoperatorsdk/operator/sample/WebServerController.java b/samples/webserver/src/main/java/io/javaoperatorsdk/operator/sample/WebServerController.java index 984e6d3d43..c70344af40 100644 --- a/samples/webserver/src/main/java/io/javaoperatorsdk/operator/sample/WebServerController.java +++ b/samples/webserver/src/main/java/io/javaoperatorsdk/operator/sample/WebServerController.java @@ -1,91 +1,94 @@ package io.javaoperatorsdk.operator.sample; -import io.javaoperatorsdk.operator.api.Context; -import io.javaoperatorsdk.operator.api.Controller; -import io.javaoperatorsdk.operator.api.ResourceController; -import io.javaoperatorsdk.operator.api.UpdateControl; -import io.fabric8.kubernetes.api.model.*; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; + +import io.fabric8.kubernetes.api.model.ConfigMap; +import io.fabric8.kubernetes.api.model.ConfigMapBuilder; +import io.fabric8.kubernetes.api.model.ConfigMapVolumeSourceBuilder; +import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; +import io.fabric8.kubernetes.api.model.Service; import io.fabric8.kubernetes.api.model.apps.Deployment; -import io.fabric8.kubernetes.api.model.apps.DoneableDeployment; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.dsl.Resource; import io.fabric8.kubernetes.client.dsl.RollableScalableResource; import io.fabric8.kubernetes.client.dsl.ServiceResource; import io.fabric8.kubernetes.client.utils.Serialization; +import io.javaoperatorsdk.operator.api.Context; +import io.javaoperatorsdk.operator.api.Controller; +import io.javaoperatorsdk.operator.api.ResourceController; +import io.javaoperatorsdk.operator.api.UpdateControl; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; - @Controller(customResourceClass = WebServer.class, - crdName = "webservers.sample.javaoperatorsdk") + crdName = "webservers.sample.javaoperatorsdk") public class WebServerController implements ResourceController { - + private final Logger log = LoggerFactory.getLogger(getClass()); - + private final KubernetesClient kubernetesClient; - + public WebServerController(KubernetesClient kubernetesClient) { this.kubernetesClient = kubernetesClient; } - + @Override public UpdateControl createOrUpdateResource(WebServer webServer, Context context) { if (webServer.getSpec().getHtml().contains("error")) { throw new ErrorSimulationException("Simulating error"); } - + String ns = webServer.getMetadata().getNamespace(); - + Map data = new HashMap<>(); data.put("index.html", webServer.getSpec().getHtml()); - + ConfigMap htmlConfigMap = new ConfigMapBuilder() - .withMetadata(new ObjectMetaBuilder() - .withName(configMapName(webServer)) - .withNamespace(ns) - .build()) - .withData(data) - .build(); - + .withMetadata(new ObjectMetaBuilder() + .withName(configMapName(webServer)) + .withNamespace(ns) + .build()) + .withData(data) + .build(); + Deployment deployment = loadYaml(Deployment.class, "deployment.yaml"); deployment.getMetadata().setName(deploymentName(webServer)); deployment.getMetadata().setNamespace(ns); deployment.getSpec().getSelector().getMatchLabels().put("app", deploymentName(webServer)); deployment.getSpec().getTemplate().getMetadata().getLabels().put("app", deploymentName(webServer)); deployment.getSpec().getTemplate().getSpec().getVolumes().get(0).setConfigMap( - new ConfigMapVolumeSourceBuilder().withName(configMapName(webServer)).build()); - + new ConfigMapVolumeSourceBuilder().withName(configMapName(webServer)).build()); + Service service = loadYaml(Service.class, "service.yaml"); service.getMetadata().setName(serviceName(webServer)); service.getMetadata().setNamespace(ns); service.getSpec().setSelector(deployment.getSpec().getTemplate().getMetadata().getLabels()); - + ConfigMap existingConfigMap = kubernetesClient.configMaps() - .inNamespace(htmlConfigMap.getMetadata().getNamespace()) - .withName(htmlConfigMap.getMetadata().getName()).get(); - + .inNamespace(htmlConfigMap.getMetadata().getNamespace()) + .withName(htmlConfigMap.getMetadata().getName()).get(); + log.info("Creating or updating ConfigMap {} in {}", htmlConfigMap.getMetadata().getName(), ns); kubernetesClient.configMaps().inNamespace(ns).createOrReplace(htmlConfigMap); log.info("Creating or updating Deployment {} in {}", deployment.getMetadata().getName(), ns); kubernetesClient.apps().deployments().inNamespace(ns).createOrReplace(deployment); - + if (kubernetesClient.services().inNamespace(ns).withName(service.getMetadata().getName()).get() == null) { log.info("Creating Service {} in {}", service.getMetadata().getName(), ns); kubernetesClient.services().inNamespace(ns).createOrReplace(service); } - + if (existingConfigMap != null) { if (!StringUtils.equals(existingConfigMap.getData().get("index.html"), htmlConfigMap.getData().get("index.html"))) { log.info("Restarting pods because HTML has changed in {}", ns); kubernetesClient.pods().inNamespace(ns).withLabel("app", deploymentName(webServer)).delete(); } } - + WebServerStatus status = new WebServerStatus(); status.setHtmlConfigMap(htmlConfigMap.getMetadata().getName()); status.setAreWeGood("Yes!"); @@ -93,49 +96,49 @@ public UpdateControl createOrUpdateResource(WebServer webServer, Cont // throw new RuntimeException("Creating object failed, because it failed"); return UpdateControl.updateCustomResource(webServer); } - + @Override public boolean deleteResource(WebServer nginx, Context context) { log.info("Execution deleteResource for: {}", nginx.getMetadata().getName()); - + log.info("Deleting ConfigMap {}", configMapName(nginx)); - Resource configMap = kubernetesClient.configMaps() - .inNamespace(nginx.getMetadata().getNamespace()) - .withName(configMapName(nginx)); + Resource configMap = kubernetesClient.configMaps() + .inNamespace(nginx.getMetadata().getNamespace()) + .withName(configMapName(nginx)); if (configMap.get() != null) { configMap.delete(); } - + log.info("Deleting Deployment {}", deploymentName(nginx)); - RollableScalableResource deployment = kubernetesClient.apps().deployments() - .inNamespace(nginx.getMetadata().getNamespace()) - .withName(deploymentName(nginx)); + RollableScalableResource deployment = kubernetesClient.apps().deployments() + .inNamespace(nginx.getMetadata().getNamespace()) + .withName(deploymentName(nginx)); if (deployment.get() != null) { deployment.cascading(true).delete(); } - + log.info("Deleting Service {}", serviceName(nginx)); - ServiceResource service = kubernetesClient.services() - .inNamespace(nginx.getMetadata().getNamespace()) - .withName(serviceName(nginx)); + ServiceResource service = kubernetesClient.services() + .inNamespace(nginx.getMetadata().getNamespace()) + .withName(serviceName(nginx)); if (service.get() != null) { service.delete(); } return true; } - + private static String configMapName(WebServer nginx) { return nginx.getMetadata().getName() + "-html"; } - + private static String deploymentName(WebServer nginx) { return nginx.getMetadata().getName(); } - + private static String serviceName(WebServer nginx) { return nginx.getMetadata().getName(); } - + private T loadYaml(Class clazz, String yaml) { try (InputStream is = getClass().getResourceAsStream(yaml)) { return Serialization.unmarshal(is, clazz); diff --git a/spring-boot-starter/src/test/java/io/javaoperatorsdk/operator/springboot/starter/model/TestResourceDoneable.java b/spring-boot-starter/src/test/java/io/javaoperatorsdk/operator/springboot/starter/model/TestResourceDoneable.java deleted file mode 100644 index d3b249a134..0000000000 --- a/spring-boot-starter/src/test/java/io/javaoperatorsdk/operator/springboot/starter/model/TestResourceDoneable.java +++ /dev/null @@ -1,10 +0,0 @@ -package io.javaoperatorsdk.operator.springboot.starter.model; - -import io.fabric8.kubernetes.api.builder.Function; -import io.fabric8.kubernetes.client.CustomResourceDoneable; - -public class TestResourceDoneable extends CustomResourceDoneable { - public TestResourceDoneable(TestResource resource, Function function) { - super(resource, function); - } -} From ec6dc7e52e54cc28bd00de18c740a0b1123bf0a7 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Wed, 18 Nov 2020 17:03:16 +0100 Subject: [PATCH 02/23] fix: use proper format for default finalizer identifier --- .../main/java/io/javaoperatorsdk/operator/api/Controller.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/operator-framework/src/main/java/io/javaoperatorsdk/operator/api/Controller.java b/operator-framework/src/main/java/io/javaoperatorsdk/operator/api/Controller.java index 9edec45c75..59b8993c5e 100644 --- a/operator-framework/src/main/java/io/javaoperatorsdk/operator/api/Controller.java +++ b/operator-framework/src/main/java/io/javaoperatorsdk/operator/api/Controller.java @@ -1,12 +1,12 @@ package io.javaoperatorsdk.operator.api; -import io.fabric8.kubernetes.client.CustomResource; - import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import io.fabric8.kubernetes.client.CustomResource; + @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) public @interface Controller { From fa2c290ff4b9c596f442ea3d5bc8ce27a612d2e6 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Wed, 18 Nov 2020 22:20:29 +0100 Subject: [PATCH 03/23] fix: use CustomResourceList as list type --- .../io/javaoperatorsdk/operator/IntegrationTestSupport.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/IntegrationTestSupport.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/IntegrationTestSupport.java index 9e55cbdf79..7fc3158248 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/IntegrationTestSupport.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/IntegrationTestSupport.java @@ -13,7 +13,6 @@ import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.dsl.MixedOperation; import io.fabric8.kubernetes.client.dsl.Resource; -import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext; import io.fabric8.kubernetes.client.utils.Serialization; import io.javaoperatorsdk.operator.api.ResourceController; import io.javaoperatorsdk.operator.sample.TestCustomResource; @@ -37,12 +36,11 @@ public class IntegrationTestSupport { public void initialize(KubernetesClient k8sClient, ResourceController controller, String crdPath) { log.info("Initializing integration test in namespace {}", TEST_NAMESPACE); this.k8sClient = k8sClient; - CustomResourceDefinition crd = loadCRDAndApplyToCluster(crdPath); - CustomResourceDefinitionContext crdContext = CustomResourceDefinitionContext.fromCrd(crd); + loadCRDAndApplyToCluster(crdPath); this.controller = controller; Class customResourceClass = ControllerUtils.getCustomResourceClass(controller); - this.crOperations = k8sClient.customResources(customResourceClass); + this.crOperations = k8sClient.customResources(customResourceClass, CustomResourceList.class); if (k8sClient.namespaces().withName(TEST_NAMESPACE).get() == null) { k8sClient.namespaces().create(new NamespaceBuilder() From f292b49b4735fc01991deb8db74f126a85a7f060 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Thu, 19 Nov 2020 09:09:15 +0100 Subject: [PATCH 04/23] fix: use CustomResourceList as list type --- .../src/main/java/io/javaoperatorsdk/operator/Operator.java | 3 ++- .../javaoperatorsdk/operator/sample/TomcatController.java | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/operator-framework/src/main/java/io/javaoperatorsdk/operator/Operator.java b/operator-framework/src/main/java/io/javaoperatorsdk/operator/Operator.java index 3271b2023b..565b6102d7 100644 --- a/operator-framework/src/main/java/io/javaoperatorsdk/operator/Operator.java +++ b/operator-framework/src/main/java/io/javaoperatorsdk/operator/Operator.java @@ -6,6 +6,7 @@ import io.fabric8.kubernetes.api.model.apiextensions.v1beta1.CustomResourceDefinition; import io.fabric8.kubernetes.client.CustomResource; +import io.fabric8.kubernetes.client.CustomResourceList; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.dsl.MixedOperation; import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext; @@ -54,7 +55,7 @@ private void registerController(ResourceController CustomResourceDefinitionContext crd = getCustomResourceDefinitionForController(controller); KubernetesDeserializer.registerCustomKind(crd.getVersion(), crd.getKind(), resClass); String finalizer = ControllerUtils.getFinalizer(controller); - MixedOperation client = k8sClient.customResources(resClass); + MixedOperation client = k8sClient.customResources(resClass, CustomResourceList.class); EventDispatcher eventDispatcher = new EventDispatcher(controller, finalizer, new EventDispatcher.CustomResourceFacade(client), ControllerUtils.getGenerationEventProcessing(controller)); EventScheduler eventScheduler = new EventScheduler(eventDispatcher, retry); diff --git a/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/TomcatController.java b/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/TomcatController.java index bd89e199a5..aaa2d07d95 100644 --- a/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/TomcatController.java +++ b/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/TomcatController.java @@ -8,9 +8,9 @@ import java.util.Optional; import io.fabric8.kubernetes.api.model.HasMetadata; -import io.fabric8.kubernetes.api.model.KubernetesResourceList; import io.fabric8.kubernetes.api.model.Service; import io.fabric8.kubernetes.api.model.apps.Deployment; +import io.fabric8.kubernetes.client.CustomResourceList; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.KubernetesClientException; import io.fabric8.kubernetes.client.Watcher; @@ -35,13 +35,13 @@ public class TomcatController implements ResourceController { private final KubernetesClient kubernetesClient; - private MixedOperation, Resource> tomcatOperations; + private MixedOperation> tomcatOperations; private final List watchedResources = new ArrayList<>(); public TomcatController(KubernetesClient client) { this.kubernetesClient = client; - this.tomcatOperations = client.customResources(Tomcat.class); + this.tomcatOperations = client.customResources(Tomcat.class, CustomResourceList.class); } private void updateTomcatStatus(Context context, Tomcat tomcat, Deployment deployment) { From de8120a526373e493d34316af2d96652006ad946 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Thu, 19 Nov 2020 09:36:51 +0100 Subject: [PATCH 05/23] fix: use -e flag to get more exception details --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9fa3a779da..36c44f0d5a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,5 +33,5 @@ jobs: kubernetes version: ${{ matrix.kubernetes }} driver: 'docker' - name: Run integration tests - run: mvn -B package -P no-unit-tests --file pom.xml + run: mvn -e -B package -P no-unit-tests --file pom.xml From 9fbad96f57d23f61b203cc03c1f7fb49ce0b211c Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Thu, 19 Nov 2020 14:09:47 +0100 Subject: [PATCH 06/23] fix: CRs return their api version string for client to work correctly --- .../io/javaoperatorsdk/operator/Operator.java | 21 +------------------ .../operator/sample/TestCustomResource.java | 15 ++++++++----- .../SubResourceTestCustomResource.java | 15 ++++++++----- .../operator/sample/CustomService.java | 11 +++++++--- .../operator/sample/Schema.java | 9 ++++++-- .../operator/sample/Tomcat.java | 9 ++++++-- .../operator/sample/Webapp.java | 9 ++++++-- .../operator/sample/WebServer.java | 9 ++++++-- 8 files changed, 57 insertions(+), 41 deletions(-) diff --git a/operator-framework/src/main/java/io/javaoperatorsdk/operator/Operator.java b/operator-framework/src/main/java/io/javaoperatorsdk/operator/Operator.java index 565b6102d7..d86630afba 100644 --- a/operator-framework/src/main/java/io/javaoperatorsdk/operator/Operator.java +++ b/operator-framework/src/main/java/io/javaoperatorsdk/operator/Operator.java @@ -1,8 +1,6 @@ package io.javaoperatorsdk.operator; import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; import io.fabric8.kubernetes.api.model.apiextensions.v1beta1.CustomResourceDefinition; import io.fabric8.kubernetes.client.CustomResource; @@ -11,7 +9,6 @@ import io.fabric8.kubernetes.client.dsl.MixedOperation; import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext; import io.fabric8.kubernetes.client.dsl.internal.CustomResourceOperationsImpl; -import io.fabric8.kubernetes.internal.KubernetesDeserializer; import io.javaoperatorsdk.operator.api.ResourceController; import io.javaoperatorsdk.operator.processing.EventDispatcher; import io.javaoperatorsdk.operator.processing.EventScheduler; @@ -25,8 +22,7 @@ public class Operator { private final static Logger log = LoggerFactory.getLogger(Operator.class); private final KubernetesClient k8sClient; - private Map, CustomResourceOperationsImpl> customResourceClients = new HashMap<>(); - + public Operator(KubernetesClient k8sClient) { this.k8sClient = k8sClient; } @@ -52,8 +48,6 @@ public void registerController(ResourceController private void registerController(ResourceController controller, boolean watchAllNamespaces, Retry retry, String... targetNamespaces) throws OperatorException { Class resClass = ControllerUtils.getCustomResourceClass(controller); - CustomResourceDefinitionContext crd = getCustomResourceDefinitionForController(controller); - KubernetesDeserializer.registerCustomKind(crd.getVersion(), crd.getKind(), resClass); String finalizer = ControllerUtils.getFinalizer(controller); MixedOperation client = k8sClient.customResources(resClass, CustomResourceList.class); EventDispatcher eventDispatcher = new EventDispatcher(controller, @@ -78,7 +72,6 @@ private void registerWatches(ResourceController co log.debug("Registered controller for namespace: {}", targetNamespace); } } - customResourceClients.put(resClass, (CustomResourceOperationsImpl) client); log.info("Registered Controller: '{}' for CRD: '{}' for namespaces: {}", controller.getClass().getSimpleName(), resClass, targetNamespaces.length == 0 ? "[all/client namespace]" : Arrays.toString(targetNamespaces)); } @@ -92,16 +85,4 @@ private CustomResourceDefinitionContext getCustomResourceDefinitionForController CustomResourceDefinitionContext context = CustomResourceDefinitionContext.fromCrd(customResourceDefinition); return context; } - - public Map, CustomResourceOperationsImpl> getCustomResourceClients() { - return customResourceClients; - } - - private String getKind(CustomResourceDefinition crd) { - return crd.getSpec().getNames().getKind(); - } - - private String getApiVersion(CustomResourceDefinition crd) { - return crd.getSpec().getGroup() + "/" + crd.getSpec().getVersion(); - } } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/TestCustomResource.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/TestCustomResource.java index 3a2110960c..9af68c2c5c 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/TestCustomResource.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/TestCustomResource.java @@ -23,13 +23,18 @@ public TestCustomResourceStatus getStatus() { public void setStatus(TestCustomResourceStatus status) { this.status = status; } - + @Override public String toString() { return "TestCustomResource{" + - "spec=" + spec + - ", status=" + status + - ", extendedFrom=" + super.toString() + - '}'; + "spec=" + spec + + ", status=" + status + + ", extendedFrom=" + super.toString() + + '}'; + } + + @Override + public String getApiVersion() { + return "sample.javaoperatorsdk/v1"; } } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResource.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResource.java index caab91bfe6..a36d050c57 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResource.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResource.java @@ -23,13 +23,18 @@ public SubResourceTestCustomResourceStatus getStatus() { public void setStatus(SubResourceTestCustomResourceStatus status) { this.status = status; } - + @Override public String toString() { return "TestCustomResource{" + - "spec=" + spec + - ", status=" + status + - ", extendedFrom=" + super.toString() + - '}'; + "spec=" + spec + + ", status=" + status + + ", extendedFrom=" + super.toString() + + '}'; + } + + @Override + public String getApiVersion() { + return "sample.javaoperatorsdk/v1"; } } diff --git a/samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomService.java b/samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomService.java index 404a07c672..68a82d6ac3 100644 --- a/samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomService.java +++ b/samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomService.java @@ -3,14 +3,19 @@ import io.fabric8.kubernetes.client.CustomResource; public class CustomService extends CustomResource { - + private ServiceSpec spec; - + public ServiceSpec getSpec() { return spec; } - + public void setSpec(ServiceSpec spec) { this.spec = spec; } + + @Override + public String getApiVersion() { + return "sample.javaoperatorsdk/v1"; + } } diff --git a/samples/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/Schema.java b/samples/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/Schema.java index 93e028b716..ab961660cf 100644 --- a/samples/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/Schema.java +++ b/samples/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/Schema.java @@ -15,12 +15,17 @@ public SchemaSpec getSpec() { public void setSpec(SchemaSpec spec) { this.spec = spec; } - + public SchemaStatus getStatus() { return status; } - + public void setStatus(SchemaStatus status) { this.status = status; } + + @Override + public String getApiVersion() { + return "mysql.sample.javaoperatorsdk/v1"; + } } diff --git a/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/Tomcat.java b/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/Tomcat.java index 749048945f..be80406c5b 100644 --- a/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/Tomcat.java +++ b/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/Tomcat.java @@ -18,15 +18,20 @@ public TomcatSpec getSpec() { public void setSpec(TomcatSpec spec) { this.spec = spec; } - + public TomcatStatus getStatus() { if (status == null) { status = new TomcatStatus(); } return status; } - + public void setStatus(TomcatStatus status) { this.status = status; } + + @Override + public String getApiVersion() { + return "tomcatoperator.io/v1"; + } } \ No newline at end of file diff --git a/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/Webapp.java b/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/Webapp.java index 124a2ed454..a368605a1d 100644 --- a/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/Webapp.java +++ b/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/Webapp.java @@ -15,15 +15,20 @@ public WebappSpec getSpec() { public void setSpec(WebappSpec spec) { this.spec = spec; } - + public WebappStatus getStatus() { if (status == null) { status = new WebappStatus(); } return status; } - + public void setStatus(WebappStatus status) { this.status = status; } + + @Override + public String getApiVersion() { + return "tomcatoperator.io/v1"; + } } \ No newline at end of file diff --git a/samples/webserver/src/main/java/io/javaoperatorsdk/operator/sample/WebServer.java b/samples/webserver/src/main/java/io/javaoperatorsdk/operator/sample/WebServer.java index 9ec51c6954..4997af0fc9 100644 --- a/samples/webserver/src/main/java/io/javaoperatorsdk/operator/sample/WebServer.java +++ b/samples/webserver/src/main/java/io/javaoperatorsdk/operator/sample/WebServer.java @@ -15,12 +15,17 @@ public WebServerSpec getSpec() { public void setSpec(WebServerSpec spec) { this.spec = spec; } - + public WebServerStatus getStatus() { return status; } - + public void setStatus(WebServerStatus status) { this.status = status; } + + @Override + public String getApiVersion() { + return "sample.javaoperatorsdk/v1"; + } } From e1464a655c75e95cf1cddd116ec4ab36ef0891a3 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Thu, 19 Nov 2020 17:44:37 +0100 Subject: [PATCH 07/23] fix: finalizer name to follow proper format --- .../operator/EventDispatcherTest.java | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/EventDispatcherTest.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/EventDispatcherTest.java index eb120fbdb7..e51ff1fe64 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/EventDispatcherTest.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/EventDispatcherTest.java @@ -1,26 +1,32 @@ package io.javaoperatorsdk.operator; +import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; +import io.fabric8.kubernetes.client.CustomResource; +import io.fabric8.kubernetes.client.Watcher; import io.javaoperatorsdk.operator.api.ResourceController; import io.javaoperatorsdk.operator.api.UpdateControl; import io.javaoperatorsdk.operator.processing.CustomResourceEvent; import io.javaoperatorsdk.operator.processing.EventDispatcher; import io.javaoperatorsdk.operator.processing.retry.GenericRetry; import io.javaoperatorsdk.operator.sample.TestCustomResource; -import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; -import io.fabric8.kubernetes.client.CustomResource; -import io.fabric8.kubernetes.client.Watcher; -import io.javaoperatorsdk.operator.api.Controller; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.ArgumentMatchers; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.argThat; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; class EventDispatcherTest { - - public static final String FINALIZER_NAME = "finalizer"; + + public static final String FINALIZER_NAME = "example.com/finalizer"; private CustomResource testCustomResource; private EventDispatcher eventDispatcher; private final ResourceController controller = mock(ResourceController.class); @@ -28,8 +34,7 @@ class EventDispatcherTest { @BeforeEach void setup() { - eventDispatcher = new EventDispatcher(controller, - FINALIZER_NAME, customResourceFacade, false); + eventDispatcher = new EventDispatcher(controller, FINALIZER_NAME, customResourceFacade, false); testCustomResource = getResource(); @@ -46,9 +51,9 @@ void callCreateOrUpdateOnNewResource() { @Test void updatesOnlyStatusSubResource() { - testCustomResource.getMetadata().getFinalizers().add(FINALIZER_NAME); + testCustomResource.addFinalizer(FINALIZER_NAME); when(controller.createOrUpdateResource(eq(testCustomResource), any())) - .thenReturn(UpdateControl.updateStatusSubResource(testCustomResource)); + .thenReturn(UpdateControl.updateStatusSubResource(testCustomResource)); eventDispatcher.handleEvent(customResourceEvent(Watcher.Action.ADDED, testCustomResource)); @@ -67,14 +72,14 @@ void callCreateOrUpdateOnModifiedResource() { void addsFinalizerOnCreateIfNotThere() { eventDispatcher.handleEvent(customResourceEvent(Watcher.Action.MODIFIED, testCustomResource)); verify(controller, times(1)) - .createOrUpdateResource(argThat(testCustomResource -> - testCustomResource.getMetadata().getFinalizers().contains(FINALIZER_NAME)), any()); + .createOrUpdateResource(argThat(testCustomResource -> + testCustomResource.hasFinalizer(FINALIZER_NAME)), any()); } @Test void callsDeleteIfObjectHasFinalizerAndMarkedForDelete() { testCustomResource.getMetadata().setDeletionTimestamp("2019-8-10"); - testCustomResource.getMetadata().getFinalizers().add(FINALIZER_NAME); + testCustomResource.addFinalizer(FINALIZER_NAME); eventDispatcher.handleEvent(customResourceEvent(Watcher.Action.MODIFIED, testCustomResource)); @@ -182,8 +187,7 @@ void doesNotMarkNewGenerationInCaseOfException() { } void generationAwareMode() { - eventDispatcher = new EventDispatcher(controller, - FINALIZER_NAME, customResourceFacade, true); + eventDispatcher = new EventDispatcher(controller, FINALIZER_NAME, customResourceFacade, true); } private void markForDeletion(CustomResource customResource) { From 94a1251daa6c90bb079430b34caf7426f2e03f63 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Thu, 19 Nov 2020 20:30:14 +0100 Subject: [PATCH 08/23] fix: use proper kind --- .../javaoperatorsdk/operator/sample/TestCustomResource.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/TestCustomResource.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/TestCustomResource.java index 9af68c2c5c..bec41705e3 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/TestCustomResource.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/TestCustomResource.java @@ -33,6 +33,11 @@ public String toString() { '}'; } + @Override + public String getKind() { + return "CustomService"; + } + @Override public String getApiVersion() { return "sample.javaoperatorsdk/v1"; From d6cd795de7b1cd048c8bec7fe4f9158a635714f0 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Thu, 19 Nov 2020 21:06:11 +0100 Subject: [PATCH 09/23] fix: use proper kind --- .../operator/ControllerExecutionIT.java | 15 ++++++--------- .../operator/SubResourceUpdateIT.java | 12 +++++------- .../SubResourceTestCustomResource.java | 5 +++++ 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerExecutionIT.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerExecutionIT.java index e20492103a..a54d669f9f 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerExecutionIT.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerExecutionIT.java @@ -1,19 +1,17 @@ package io.javaoperatorsdk.operator; -import io.javaoperatorsdk.operator.sample.TestCustomResource; -import io.javaoperatorsdk.operator.sample.TestCustomResourceController; -import io.javaoperatorsdk.operator.sample.TestCustomResourceSpec; +import java.util.HashMap; +import java.util.concurrent.TimeUnit; + import io.fabric8.kubernetes.api.model.ConfigMap; import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; import io.fabric8.kubernetes.client.DefaultKubernetesClient; import io.fabric8.kubernetes.client.KubernetesClient; +import io.javaoperatorsdk.operator.sample.TestCustomResource; +import io.javaoperatorsdk.operator.sample.TestCustomResourceController; +import io.javaoperatorsdk.operator.sample.TestCustomResourceSpec; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.HashMap; -import java.util.concurrent.TimeUnit; import static org.assertj.core.api.Assertions.assertThat; import static org.awaitility.Awaitility.await; @@ -106,7 +104,6 @@ private TestCustomResource testCustomResource() { .withNamespace(IntegrationTestSupport.TEST_NAMESPACE) .build()); resource.getMetadata().setAnnotations(new HashMap<>()); - resource.setKind("CustomService"); resource.setSpec(new TestCustomResourceSpec()); resource.getSpec().setConfigMapName("test-config-map"); resource.getSpec().setKey("test-key"); diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/SubResourceUpdateIT.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/SubResourceUpdateIT.java index 540001c5e1..a883ab8dbc 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/SubResourceUpdateIT.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/SubResourceUpdateIT.java @@ -1,19 +1,18 @@ package io.javaoperatorsdk.operator; -import io.javaoperatorsdk.operator.sample.subresource.SubResourceTestCustomResource; -import io.javaoperatorsdk.operator.sample.subresource.SubResourceTestCustomResourceController; -import io.javaoperatorsdk.operator.sample.subresource.SubResourceTestCustomResourceSpec; +import java.util.concurrent.TimeUnit; + import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; import io.fabric8.kubernetes.client.DefaultKubernetesClient; import io.fabric8.kubernetes.client.KubernetesClient; -import io.javaoperatorsdk.operator.api.Controller; +import io.javaoperatorsdk.operator.sample.subresource.SubResourceTestCustomResource; +import io.javaoperatorsdk.operator.sample.subresource.SubResourceTestCustomResourceController; +import io.javaoperatorsdk.operator.sample.subresource.SubResourceTestCustomResourceSpec; import io.javaoperatorsdk.operator.sample.subresource.SubResourceTestCustomResourceStatus; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; -import java.util.concurrent.TimeUnit; - import static io.javaoperatorsdk.operator.IntegrationTestSupport.TEST_NAMESPACE; import static org.assertj.core.api.Assertions.assertThat; import static org.awaitility.Awaitility.await; @@ -106,7 +105,6 @@ public SubResourceTestCustomResource createTestCustomResource(String id) { .withNamespace(TEST_NAMESPACE) .withFinalizers(SubResourceTestCustomResourceController.FINALIZER_NAME) .build()); - resource.setKind("SubresourceSample"); resource.setSpec(new SubResourceTestCustomResourceSpec()); resource.getSpec().setValue(id); return resource; diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResource.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResource.java index a36d050c57..6ff6964a35 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResource.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResource.java @@ -33,6 +33,11 @@ public String toString() { '}'; } + @Override + public String getKind() { + return "SubresourceSample"; + } + @Override public String getApiVersion() { return "sample.javaoperatorsdk/v1"; From 046fd30307a51a3513afe4ca0cb2cda297af198f Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Fri, 20 Nov 2020 15:02:24 +0100 Subject: [PATCH 10/23] fix: CRs need to be marked as Namespaced to retrieve a NS-scoped client --- .../operator/sample/TestCustomResource.java | 11 ++++++----- .../SubResourceTestCustomResource.java | 16 ++++++---------- .../operator/sample/CustomService.java | 3 ++- .../javaoperatorsdk/operator/sample/Schema.java | 11 ++++++----- .../javaoperatorsdk/operator/sample/Tomcat.java | 9 +++++---- .../javaoperatorsdk/operator/sample/Webapp.java | 11 ++++++----- .../operator/sample/WebServer.java | 11 ++++++----- .../springboot/starter/model/TestResource.java | 3 ++- 8 files changed, 39 insertions(+), 36 deletions(-) diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/TestCustomResource.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/TestCustomResource.java index bec41705e3..a09435b958 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/TestCustomResource.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/TestCustomResource.java @@ -1,17 +1,18 @@ package io.javaoperatorsdk.operator.sample; +import io.fabric8.kubernetes.api.model.Namespaced; import io.fabric8.kubernetes.client.CustomResource; -public class TestCustomResource extends CustomResource { - +public class TestCustomResource extends CustomResource implements Namespaced { + private TestCustomResourceSpec spec; - + private TestCustomResourceStatus status; - + public TestCustomResourceSpec getSpec() { return spec; } - + public void setSpec(TestCustomResourceSpec spec) { this.spec = spec; } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResource.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResource.java index 6ff6964a35..25aac9b2e5 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResource.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResource.java @@ -1,17 +1,18 @@ package io.javaoperatorsdk.operator.sample.subresource; +import io.fabric8.kubernetes.api.model.Namespaced; import io.fabric8.kubernetes.client.CustomResource; -public class SubResourceTestCustomResource extends CustomResource { - +public class SubResourceTestCustomResource extends CustomResource implements Namespaced { + private SubResourceTestCustomResourceSpec spec; - + private SubResourceTestCustomResourceStatus status; - + public SubResourceTestCustomResourceSpec getSpec() { return spec; } - + public void setSpec(SubResourceTestCustomResourceSpec spec) { this.spec = spec; } @@ -37,9 +38,4 @@ public String toString() { public String getKind() { return "SubresourceSample"; } - - @Override - public String getApiVersion() { - return "sample.javaoperatorsdk/v1"; - } } diff --git a/samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomService.java b/samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomService.java index 68a82d6ac3..2ec03f2fed 100644 --- a/samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomService.java +++ b/samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomService.java @@ -1,8 +1,9 @@ package io.javaoperatorsdk.operator.sample; +import io.fabric8.kubernetes.api.model.Namespaced; import io.fabric8.kubernetes.client.CustomResource; -public class CustomService extends CustomResource { +public class CustomService extends CustomResource implements Namespaced { private ServiceSpec spec; diff --git a/samples/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/Schema.java b/samples/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/Schema.java index ab961660cf..603c426241 100644 --- a/samples/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/Schema.java +++ b/samples/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/Schema.java @@ -1,17 +1,18 @@ package io.javaoperatorsdk.operator.sample; +import io.fabric8.kubernetes.api.model.Namespaced; import io.fabric8.kubernetes.client.CustomResource; -public class Schema extends CustomResource { - +public class Schema extends CustomResource implements Namespaced { + private SchemaSpec spec; - + private SchemaStatus status; - + public SchemaSpec getSpec() { return spec; } - + public void setSpec(SchemaSpec spec) { this.spec = spec; } diff --git a/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/Tomcat.java b/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/Tomcat.java index be80406c5b..8e18ed66ab 100644 --- a/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/Tomcat.java +++ b/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/Tomcat.java @@ -1,13 +1,14 @@ package io.javaoperatorsdk.operator.sample; +import io.fabric8.kubernetes.api.model.Namespaced; import io.fabric8.kubernetes.client.CustomResource; -public class Tomcat extends CustomResource { - +public class Tomcat extends CustomResource implements Namespaced { + private TomcatSpec spec; - + private TomcatStatus status; - + public TomcatSpec getSpec() { if (spec == null) { spec = new TomcatSpec(); diff --git a/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/Webapp.java b/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/Webapp.java index a368605a1d..a5ea879795 100644 --- a/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/Webapp.java +++ b/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/Webapp.java @@ -1,17 +1,18 @@ package io.javaoperatorsdk.operator.sample; +import io.fabric8.kubernetes.api.model.Namespaced; import io.fabric8.kubernetes.client.CustomResource; -public class Webapp extends CustomResource { - +public class Webapp extends CustomResource implements Namespaced { + private WebappSpec spec; - + private WebappStatus status; - + public WebappSpec getSpec() { return spec; } - + public void setSpec(WebappSpec spec) { this.spec = spec; } diff --git a/samples/webserver/src/main/java/io/javaoperatorsdk/operator/sample/WebServer.java b/samples/webserver/src/main/java/io/javaoperatorsdk/operator/sample/WebServer.java index 4997af0fc9..4adef81f3b 100644 --- a/samples/webserver/src/main/java/io/javaoperatorsdk/operator/sample/WebServer.java +++ b/samples/webserver/src/main/java/io/javaoperatorsdk/operator/sample/WebServer.java @@ -1,17 +1,18 @@ package io.javaoperatorsdk.operator.sample; +import io.fabric8.kubernetes.api.model.Namespaced; import io.fabric8.kubernetes.client.CustomResource; -public class WebServer extends CustomResource { - +public class WebServer extends CustomResource implements Namespaced { + private WebServerSpec spec; - + private WebServerStatus status; - + public WebServerSpec getSpec() { return spec; } - + public void setSpec(WebServerSpec spec) { this.spec = spec; } diff --git a/spring-boot-starter/src/test/java/io/javaoperatorsdk/operator/springboot/starter/model/TestResource.java b/spring-boot-starter/src/test/java/io/javaoperatorsdk/operator/springboot/starter/model/TestResource.java index 06e41ad613..06e0924e6b 100644 --- a/spring-boot-starter/src/test/java/io/javaoperatorsdk/operator/springboot/starter/model/TestResource.java +++ b/spring-boot-starter/src/test/java/io/javaoperatorsdk/operator/springboot/starter/model/TestResource.java @@ -1,7 +1,8 @@ package io.javaoperatorsdk.operator.springboot.starter.model; +import io.fabric8.kubernetes.api.model.Namespaced; import io.fabric8.kubernetes.client.CustomResource; -public class TestResource extends CustomResource { +public class TestResource extends CustomResource implements Namespaced { } From 1f113c25f1e39699155e6d8d16d2bae4e37e10b5 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Fri, 20 Nov 2020 16:06:01 +0100 Subject: [PATCH 11/23] fix: restore missing getApiVersion --- .../sample/subresource/SubResourceTestCustomResource.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResource.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResource.java index 25aac9b2e5..bd2f2853d2 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResource.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResource.java @@ -38,4 +38,9 @@ public String toString() { public String getKind() { return "SubresourceSample"; } + + @Override + public String getApiVersion() { + return "sample.javaoperatorsdk/v1"; + } } From 86261bec2d20216f981262d9131a48ce150cde96 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Sat, 21 Nov 2020 18:00:35 +0100 Subject: [PATCH 12/23] fix: improper plural in CRD --- .../SubResourceTestCustomResourceController.java | 8 ++++---- .../io/javaoperatorsdk/operator/subresource-test-crd.yaml | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResourceController.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResourceController.java index 9b47305490..b5fbabe8f8 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResourceController.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResourceController.java @@ -1,5 +1,7 @@ package io.javaoperatorsdk.operator.sample.subresource; +import java.util.concurrent.atomic.AtomicInteger; + import io.javaoperatorsdk.operator.TestExecutionInfoProvider; import io.javaoperatorsdk.operator.api.Context; import io.javaoperatorsdk.operator.api.Controller; @@ -8,16 +10,14 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.concurrent.atomic.AtomicInteger; - @Controller( crdName = SubResourceTestCustomResourceController.CRD_NAME, customResourceClass = SubResourceTestCustomResource.class, generationAwareEventProcessing = false) public class SubResourceTestCustomResourceController implements ResourceController, TestExecutionInfoProvider { - - public static final String CRD_NAME = "subresourcesample.sample.javaoperatorsdk"; + + public static final String CRD_NAME = "subresourcesamples.sample.javaoperatorsdk"; public static final String FINALIZER_NAME = CRD_NAME + "/finalizer"; private static final Logger log = LoggerFactory.getLogger(SubResourceTestCustomResourceController.class); private final AtomicInteger numberOfExecutions = new AtomicInteger(0); diff --git a/operator-framework/src/test/resources/io/javaoperatorsdk/operator/subresource-test-crd.yaml b/operator-framework/src/test/resources/io/javaoperatorsdk/operator/subresource-test-crd.yaml index c39b9c117f..2b9b3db2b8 100644 --- a/operator-framework/src/test/resources/io/javaoperatorsdk/operator/subresource-test-crd.yaml +++ b/operator-framework/src/test/resources/io/javaoperatorsdk/operator/subresource-test-crd.yaml @@ -1,7 +1,7 @@ apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: - name: subresourcesample.sample.javaoperatorsdk + name: subresourcesamples.sample.javaoperatorsdk spec: group: sample.javaoperatorsdk version: v1 @@ -9,7 +9,7 @@ spec: status: {} scope: Namespaced names: - plural: subresourcesample + plural: subresourcesamples singular: subresourcesample kind: SubresourceSample shortNames: From 0ac9ea722986142868e64565543ab0887b25ecdc Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Sat, 21 Nov 2020 21:10:31 +0100 Subject: [PATCH 13/23] fix: use the controller's class canonical name as default finalizer name --- .../io/javaoperatorsdk/operator/ControllerUtils.java | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/operator-framework/src/main/java/io/javaoperatorsdk/operator/ControllerUtils.java b/operator-framework/src/main/java/io/javaoperatorsdk/operator/ControllerUtils.java index 49b10d938d..9437a9f99d 100644 --- a/operator-framework/src/main/java/io/javaoperatorsdk/operator/ControllerUtils.java +++ b/operator-framework/src/main/java/io/javaoperatorsdk/operator/ControllerUtils.java @@ -3,13 +3,9 @@ import io.fabric8.kubernetes.client.CustomResource; import io.javaoperatorsdk.operator.api.Controller; import io.javaoperatorsdk.operator.api.ResourceController; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; public class ControllerUtils { - - private final static double JAVA_VERSION = Double.parseDouble(System.getProperty("java.specification.version")); private static final String FINALIZER_NAME_SUFFIX = "/finalizer"; static String getFinalizer(ResourceController controller) { @@ -17,8 +13,7 @@ static String getFinalizer(ResourceController controller) { if (!Controller.NULL.equals(annotationFinalizerName)) { return annotationFinalizerName; } - final String crdName = getAnnotation(controller).crdName() + FINALIZER_NAME_SUFFIX; - return crdName; + return controller.getClass().getCanonicalName() + FINALIZER_NAME_SUFFIX; } static boolean getGenerationEventProcessing(ResourceController controller) { @@ -36,8 +31,4 @@ static String getCrdName(ResourceController controller) { private static Controller getAnnotation(ResourceController controller) { return controller.getClass().getAnnotation(Controller.class); } - - public static boolean hasGivenFinalizer(CustomResource resource, String finalizer) { - return resource.getMetadata().getFinalizers() != null && resource.getMetadata().getFinalizers().contains(finalizer); - } } From 76955ed3f6a12329a90fd33da9d0e807e4271309 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Sat, 21 Nov 2020 21:11:07 +0100 Subject: [PATCH 14/23] fix: use proper domain name for finalizer prefix --- .../sample/TestCustomResourceController.java | 20 +++++++++---------- ...bResourceTestCustomResourceController.java | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/TestCustomResourceController.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/TestCustomResourceController.java index 9f27896914..bcda6483ed 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/TestCustomResourceController.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/TestCustomResourceController.java @@ -1,21 +1,21 @@ package io.javaoperatorsdk.operator.sample; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; + +import io.fabric8.kubernetes.api.model.ConfigMap; +import io.fabric8.kubernetes.api.model.ConfigMapBuilder; +import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; +import io.fabric8.kubernetes.client.KubernetesClient; import io.javaoperatorsdk.operator.TestExecutionInfoProvider; import io.javaoperatorsdk.operator.api.Context; import io.javaoperatorsdk.operator.api.Controller; import io.javaoperatorsdk.operator.api.ResourceController; import io.javaoperatorsdk.operator.api.UpdateControl; -import io.fabric8.kubernetes.api.model.ConfigMap; -import io.fabric8.kubernetes.api.model.ConfigMapBuilder; -import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; -import io.fabric8.kubernetes.client.KubernetesClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; - @Controller( generationAwareEventProcessing = false, crdName = TestCustomResourceController.CRD_NAME, @@ -23,9 +23,9 @@ public class TestCustomResourceController implements ResourceController, TestExecutionInfoProvider { private static final Logger log = LoggerFactory.getLogger(TestCustomResourceController.class); - + public static final String CRD_NAME = "customservices.sample.javaoperatorsdk"; - public static final String FINALIZER_NAME = CRD_NAME + "/finalizer"; + public static final String FINALIZER_NAME = CRD_NAME + ".io/finalizer"; private final KubernetesClient kubernetesClient; private final boolean updateStatus; diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResourceController.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResourceController.java index b5fbabe8f8..996fea0b87 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResourceController.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResourceController.java @@ -18,7 +18,7 @@ public class SubResourceTestCustomResourceController implements ResourceControll TestExecutionInfoProvider { public static final String CRD_NAME = "subresourcesamples.sample.javaoperatorsdk"; - public static final String FINALIZER_NAME = CRD_NAME + "/finalizer"; + public static final String FINALIZER_NAME = CRD_NAME + ".io/finalizer"; private static final Logger log = LoggerFactory.getLogger(SubResourceTestCustomResourceController.class); private final AtomicInteger numberOfExecutions = new AtomicInteger(0); From 4c5847075c376277dbc3c530165e1bafc91ded01 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Sat, 21 Nov 2020 21:32:24 +0100 Subject: [PATCH 15/23] fix: unit test --- .../io/javaoperatorsdk/operator/ControllerUtils.java | 8 ++++++-- .../operator/ControllerUtilsTest.java | 12 +++++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/operator-framework/src/main/java/io/javaoperatorsdk/operator/ControllerUtils.java b/operator-framework/src/main/java/io/javaoperatorsdk/operator/ControllerUtils.java index 9437a9f99d..0f9d680c17 100644 --- a/operator-framework/src/main/java/io/javaoperatorsdk/operator/ControllerUtils.java +++ b/operator-framework/src/main/java/io/javaoperatorsdk/operator/ControllerUtils.java @@ -13,13 +13,17 @@ static String getFinalizer(ResourceController controller) { if (!Controller.NULL.equals(annotationFinalizerName)) { return annotationFinalizerName; } + return getDefaultFinalizerIdentifier(controller); + } + + static String getDefaultFinalizerIdentifier(ResourceController controller) { return controller.getClass().getCanonicalName() + FINALIZER_NAME_SUFFIX; } - + static boolean getGenerationEventProcessing(ResourceController controller) { return getAnnotation(controller).generationAwareEventProcessing(); } - + static Class getCustomResourceClass(ResourceController controller) { return (Class) getAnnotation(controller).customResourceClass(); } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerUtilsTest.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerUtilsTest.java index fc63b599b7..786cb3685d 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerUtilsTest.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerUtilsTest.java @@ -9,7 +9,8 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; class ControllerUtilsTest { @@ -17,10 +18,11 @@ class ControllerUtilsTest { @Test public void returnsValuesFromControllerAnnotationFinalizer() { - Assertions.assertEquals(TestCustomResourceController.CRD_NAME + "/finalizer", ControllerUtils.getFinalizer(new TestCustomResourceController(null))); - assertEquals(TestCustomResource.class, ControllerUtils.getCustomResourceClass(new TestCustomResourceController(null))); - Assertions.assertEquals(TestCustomResourceController.CRD_NAME, ControllerUtils.getCrdName(new TestCustomResourceController(null))); - assertFalse(ControllerUtils.getGenerationEventProcessing(new TestCustomResourceController(null))); + final TestCustomResourceController controller = new TestCustomResourceController(null); + Assertions.assertEquals(ControllerUtils.getDefaultFinalizerIdentifier(controller), ControllerUtils.getFinalizer(controller)); + assertEquals(TestCustomResource.class, ControllerUtils.getCustomResourceClass(controller)); + Assertions.assertEquals(TestCustomResourceController.CRD_NAME, ControllerUtils.getCrdName(controller)); + assertFalse(ControllerUtils.getGenerationEventProcessing(controller)); } @Controller(crdName = "test.crd", customResourceClass = TestCustomResource.class, finalizerName = CUSTOM_FINALIZER_NAME) From b95956e0d0f8c6e1a17e0d805a068934671702b5 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Sat, 21 Nov 2020 21:51:43 +0100 Subject: [PATCH 16/23] fix: actually create a valid finalizer name and check it is --- .../operator/ControllerUtils.java | 5 +++-- .../operator/ConcurrencyIT.java | 18 ++++++++++-------- .../operator/ControllerUtilsTest.java | 5 ++++- .../operator/SubResourceUpdateIT.java | 16 +++++++++++----- 4 files changed, 28 insertions(+), 16 deletions(-) diff --git a/operator-framework/src/main/java/io/javaoperatorsdk/operator/ControllerUtils.java b/operator-framework/src/main/java/io/javaoperatorsdk/operator/ControllerUtils.java index 0f9d680c17..ec62007cb6 100644 --- a/operator-framework/src/main/java/io/javaoperatorsdk/operator/ControllerUtils.java +++ b/operator-framework/src/main/java/io/javaoperatorsdk/operator/ControllerUtils.java @@ -6,7 +6,7 @@ public class ControllerUtils { - private static final String FINALIZER_NAME_SUFFIX = "/finalizer"; + private static final String FINALIZER_NAME_SUFFIX = ".javaoperatorsdk.io/finalizer"; static String getFinalizer(ResourceController controller) { final String annotationFinalizerName = getAnnotation(controller).finalizerName(); @@ -17,7 +17,8 @@ static String getFinalizer(ResourceController controller) { } static String getDefaultFinalizerIdentifier(ResourceController controller) { - return controller.getClass().getCanonicalName() + FINALIZER_NAME_SUFFIX; + final Class controllerClass = controller.getClass(); + return controllerClass.getSimpleName().toLowerCase() + FINALIZER_NAME_SUFFIX; } static boolean getGenerationEventProcessing(ResourceController controller) { diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/ConcurrencyIT.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/ConcurrencyIT.java index 845ab3a26c..eb8692989e 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/ConcurrencyIT.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/ConcurrencyIT.java @@ -1,10 +1,15 @@ package io.javaoperatorsdk.operator; -import io.javaoperatorsdk.operator.sample.TestCustomResource; -import io.javaoperatorsdk.operator.sample.TestCustomResourceController; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + import io.fabric8.kubernetes.api.model.ConfigMap; +import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.client.DefaultKubernetesClient; import io.fabric8.kubernetes.client.KubernetesClient; +import io.javaoperatorsdk.operator.sample.TestCustomResource; +import io.javaoperatorsdk.operator.sample.TestCustomResourceController; import org.awaitility.Awaitility; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; @@ -13,10 +18,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.List; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - import static org.assertj.core.api.Assertions.assertThat; @TestInstance(TestInstance.Lifecycle.PER_CLASS) @@ -32,8 +33,9 @@ public class ConcurrencyIT { @BeforeAll public void setup() { KubernetesClient k8sClient = new DefaultKubernetesClient(); - integrationTest.initialize(k8sClient, new TestCustomResourceController(k8sClient, true), - "test-crd.yaml"); + final TestCustomResourceController controller = new TestCustomResourceController(k8sClient, true); + assertThat(HasMetadata.DOMAIN_NAME_MATCHER.reset(ControllerUtils.getDefaultFinalizerIdentifier(controller)).matches()).isTrue(); + integrationTest.initialize(k8sClient, controller, "test-crd.yaml"); } @BeforeEach diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerUtilsTest.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerUtilsTest.java index 786cb3685d..7d04e1fc01 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerUtilsTest.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerUtilsTest.java @@ -1,5 +1,6 @@ package io.javaoperatorsdk.operator; +import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.api.Context; import io.javaoperatorsdk.operator.api.Controller; import io.javaoperatorsdk.operator.api.ResourceController; @@ -19,7 +20,9 @@ class ControllerUtilsTest { @Test public void returnsValuesFromControllerAnnotationFinalizer() { final TestCustomResourceController controller = new TestCustomResourceController(null); - Assertions.assertEquals(ControllerUtils.getDefaultFinalizerIdentifier(controller), ControllerUtils.getFinalizer(controller)); + final String finalizer = ControllerUtils.getFinalizer(controller); + Assertions.assertEquals(ControllerUtils.getDefaultFinalizerIdentifier(controller), finalizer); + Assertions.assertTrue(HasMetadata.DOMAIN_NAME_MATCHER.reset(finalizer).matches()); assertEquals(TestCustomResource.class, ControllerUtils.getCustomResourceClass(controller)); Assertions.assertEquals(TestCustomResourceController.CRD_NAME, ControllerUtils.getCrdName(controller)); assertFalse(ControllerUtils.getGenerationEventProcessing(controller)); diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/SubResourceUpdateIT.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/SubResourceUpdateIT.java index a883ab8dbc..b8c4ff5629 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/SubResourceUpdateIT.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/SubResourceUpdateIT.java @@ -2,6 +2,7 @@ import java.util.concurrent.TimeUnit; +import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; import io.fabric8.kubernetes.client.DefaultKubernetesClient; import io.fabric8.kubernetes.client.KubernetesClient; @@ -9,6 +10,7 @@ import io.javaoperatorsdk.operator.sample.subresource.SubResourceTestCustomResourceController; import io.javaoperatorsdk.operator.sample.subresource.SubResourceTestCustomResourceSpec; import io.javaoperatorsdk.operator.sample.subresource.SubResourceTestCustomResourceStatus; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; @@ -19,17 +21,21 @@ @TestInstance(TestInstance.Lifecycle.PER_CLASS) public class SubResourceUpdateIT { - + private IntegrationTestSupport integrationTestSupport = new IntegrationTestSupport(); - + + @BeforeAll + void checkFinalizer() { + assertThat(HasMetadata.DOMAIN_NAME_MATCHER.reset(ControllerUtils.getDefaultFinalizerIdentifier(new SubResourceTestCustomResourceController())).matches()).isTrue(); + } + @BeforeEach public void initAndCleanup() { KubernetesClient k8sClient = new DefaultKubernetesClient(); - integrationTestSupport.initialize(k8sClient, new SubResourceTestCustomResourceController(), - "subresource-test-crd.yaml"); + integrationTestSupport.initialize(k8sClient, new SubResourceTestCustomResourceController(), "subresource-test-crd.yaml"); integrationTestSupport.cleanup(); } - + @Test public void updatesSubResourceStatus() { integrationTestSupport.teardownIfSuccess(() -> { From 858ac6ee3c391ffd97ac5b20d6d6957b9fcdebb0 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Sat, 21 Nov 2020 22:49:54 +0100 Subject: [PATCH 17/23] fix: set finalizer name instead of using default to match expectations --- .../io/javaoperatorsdk/operator/ControllerUtilsTest.java | 2 +- .../operator/sample/TestCustomResourceController.java | 7 ++++--- .../SubResourceTestCustomResourceController.java | 9 +++++---- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerUtilsTest.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerUtilsTest.java index 7d04e1fc01..288fc9dae9 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerUtilsTest.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerUtilsTest.java @@ -21,7 +21,7 @@ class ControllerUtilsTest { public void returnsValuesFromControllerAnnotationFinalizer() { final TestCustomResourceController controller = new TestCustomResourceController(null); final String finalizer = ControllerUtils.getFinalizer(controller); - Assertions.assertEquals(ControllerUtils.getDefaultFinalizerIdentifier(controller), finalizer); + Assertions.assertEquals(TestCustomResourceController.FINALIZER_NAME, finalizer); Assertions.assertTrue(HasMetadata.DOMAIN_NAME_MATCHER.reset(finalizer).matches()); assertEquals(TestCustomResource.class, ControllerUtils.getCustomResourceClass(controller)); Assertions.assertEquals(TestCustomResourceController.CRD_NAME, ControllerUtils.getCrdName(controller)); diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/TestCustomResourceController.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/TestCustomResourceController.java index bcda6483ed..8b7baee080 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/TestCustomResourceController.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/TestCustomResourceController.java @@ -17,9 +17,10 @@ import org.slf4j.LoggerFactory; @Controller( - generationAwareEventProcessing = false, - crdName = TestCustomResourceController.CRD_NAME, - customResourceClass = TestCustomResource.class) + generationAwareEventProcessing = false, + crdName = TestCustomResourceController.CRD_NAME, + finalizerName = TestCustomResourceController.FINALIZER_NAME, + customResourceClass = TestCustomResource.class) public class TestCustomResourceController implements ResourceController, TestExecutionInfoProvider { private static final Logger log = LoggerFactory.getLogger(TestCustomResourceController.class); diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResourceController.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResourceController.java index 996fea0b87..12740fbb43 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResourceController.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResourceController.java @@ -11,9 +11,10 @@ import org.slf4j.LoggerFactory; @Controller( - crdName = SubResourceTestCustomResourceController.CRD_NAME, - customResourceClass = SubResourceTestCustomResource.class, - generationAwareEventProcessing = false) + crdName = SubResourceTestCustomResourceController.CRD_NAME, + finalizerName = SubResourceTestCustomResourceController.FINALIZER_NAME, + customResourceClass = SubResourceTestCustomResource.class, + generationAwareEventProcessing = false) public class SubResourceTestCustomResourceController implements ResourceController, TestExecutionInfoProvider { @@ -21,7 +22,7 @@ public class SubResourceTestCustomResourceController implements ResourceControll public static final String FINALIZER_NAME = CRD_NAME + ".io/finalizer"; private static final Logger log = LoggerFactory.getLogger(SubResourceTestCustomResourceController.class); private final AtomicInteger numberOfExecutions = new AtomicInteger(0); - + @Override public boolean deleteResource(SubResourceTestCustomResource resource, Context context) { return true; From e18a90bd0eee7631d751373a8ed728ab9db1aae8 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Tue, 24 Nov 2020 10:34:51 +0100 Subject: [PATCH 18/23] chore: remove commons-lang3 dependency --- operator-framework/pom.xml | 4 ---- pom.xml | 5 ---- samples/mysql-schema/pom.xml | 4 ---- .../starter/OperatorAutoConfiguration.java | 24 +++++++++---------- 4 files changed, 11 insertions(+), 26 deletions(-) diff --git a/operator-framework/pom.xml b/operator-framework/pom.xml index a5be06a274..88c800374a 100644 --- a/operator-framework/pom.xml +++ b/operator-framework/pom.xml @@ -36,10 +36,6 @@ io.fabric8 openshift-client - - org.apache.commons - commons-lang3 - org.slf4j slf4j-api diff --git a/pom.xml b/pom.xml index 905fca7607..7817b2fe49 100644 --- a/pom.xml +++ b/pom.xml @@ -54,11 +54,6 @@ openshift-client 5.0.0-alpha-1 - - org.apache.commons - commons-lang3 - 3.11 - org.slf4j slf4j-api diff --git a/samples/mysql-schema/pom.xml b/samples/mysql-schema/pom.xml index 88b943b7ef..e6ea90ea4d 100644 --- a/samples/mysql-schema/pom.xml +++ b/samples/mysql-schema/pom.xml @@ -51,10 +51,6 @@ mysql-connector-java 8.0.22 - - org.apache.commons - commons-lang3 - diff --git a/spring-boot-starter/src/main/java/io/javaoperatorsdk/operator/springboot/starter/OperatorAutoConfiguration.java b/spring-boot-starter/src/main/java/io/javaoperatorsdk/operator/springboot/starter/OperatorAutoConfiguration.java index b3c0b65656..c93d080675 100644 --- a/spring-boot-starter/src/main/java/io/javaoperatorsdk/operator/springboot/starter/OperatorAutoConfiguration.java +++ b/spring-boot-starter/src/main/java/io/javaoperatorsdk/operator/springboot/starter/OperatorAutoConfiguration.java @@ -1,6 +1,7 @@ package io.javaoperatorsdk.operator.springboot.starter; import java.util.List; +import java.util.Optional; import io.fabric8.kubernetes.client.ConfigBuilder; import io.fabric8.kubernetes.client.DefaultKubernetesClient; @@ -10,7 +11,6 @@ import io.javaoperatorsdk.operator.api.ResourceController; import io.javaoperatorsdk.operator.processing.retry.GenericRetry; import io.javaoperatorsdk.operator.processing.retry.Retry; -import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -22,24 +22,22 @@ @EnableConfigurationProperties({OperatorProperties.class, RetryProperties.class}) public class OperatorAutoConfiguration { private static final Logger log = LoggerFactory.getLogger(OperatorAutoConfiguration.class); - + @Bean @ConditionalOnMissingBean public KubernetesClient kubernetesClient(OperatorProperties operatorProperties) { ConfigBuilder config = new ConfigBuilder(); config.withTrustCerts(operatorProperties.isTrustSelfSignedCertificates()); - if (StringUtils.isNotBlank(operatorProperties.getUsername())) { - config.withUsername(operatorProperties.getUsername()); - } - if (StringUtils.isNotBlank(operatorProperties.getPassword())) { - config.withUsername(operatorProperties.getPassword()); - } - if (StringUtils.isNotBlank(operatorProperties.getMasterUrl())) { - config.withMasterUrl(operatorProperties.getMasterUrl()); - } + trimmedPropertyIfPresent(operatorProperties.getUsername()).ifPresent(config::withUsername); + trimmedPropertyIfPresent(operatorProperties.getPassword()).ifPresent(config::withPassword); + trimmedPropertyIfPresent(operatorProperties.getMasterUrl()).ifPresent(config::withMasterUrl); return operatorProperties.isOpenshift() ? new DefaultOpenShiftClient(config.build()) : new DefaultKubernetesClient(config.build()); } - + + private static Optional trimmedPropertyIfPresent(String string) { + return Optional.ofNullable(string).map(String::trim); + } + @Bean @ConditionalOnMissingBean(Operator.class) public Operator operator(KubernetesClient kubernetesClient, Retry retry, List resourceControllers) { @@ -47,7 +45,7 @@ public Operator operator(KubernetesClient kubernetesClient, Retry retry, List operator.registerControllerForAllNamespaces(r, retry)); return operator; } - + @Bean @ConditionalOnMissingBean public Retry retry(RetryProperties retryProperties) { From 126bd86ef9e5191a37041e132da2ba8268f56a4f Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Tue, 24 Nov 2020 10:35:51 +0100 Subject: [PATCH 19/23] chore: replace deprecated cascading by withPropagationPolicy call --- .../javaoperatorsdk/operator/sample/WebServerController.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/samples/webserver/src/main/java/io/javaoperatorsdk/operator/sample/WebServerController.java b/samples/webserver/src/main/java/io/javaoperatorsdk/operator/sample/WebServerController.java index c70344af40..b93d0a8007 100644 --- a/samples/webserver/src/main/java/io/javaoperatorsdk/operator/sample/WebServerController.java +++ b/samples/webserver/src/main/java/io/javaoperatorsdk/operator/sample/WebServerController.java @@ -8,6 +8,7 @@ import io.fabric8.kubernetes.api.model.ConfigMap; import io.fabric8.kubernetes.api.model.ConfigMapBuilder; import io.fabric8.kubernetes.api.model.ConfigMapVolumeSourceBuilder; +import io.fabric8.kubernetes.api.model.DeletionPropagation; import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; import io.fabric8.kubernetes.api.model.Service; import io.fabric8.kubernetes.api.model.apps.Deployment; @@ -114,7 +115,7 @@ public boolean deleteResource(WebServer nginx, Context context) { .inNamespace(nginx.getMetadata().getNamespace()) .withName(deploymentName(nginx)); if (deployment.get() != null) { - deployment.cascading(true).delete(); + deployment.withPropagationPolicy(DeletionPropagation.FOREGROUND).delete(); } log.info("Deleting Service {}", serviceName(nginx)); From 18735e844fb506f5a06989da84c5d16881b57790 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Tue, 24 Nov 2020 10:36:27 +0100 Subject: [PATCH 20/23] feat: update kube client to 5.0.0-alpha-2 --- .../operator/processing/EventScheduler.java | 20 +++++++++---------- .../operator/ConcurrencyIT.java | 2 +- .../operator/ControllerUtilsTest.java | 2 +- .../operator/SubResourceUpdateIT.java | 2 +- pom.xml | 2 +- .../operator/sample/TomcatController.java | 6 +++--- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/operator-framework/src/main/java/io/javaoperatorsdk/operator/processing/EventScheduler.java b/operator-framework/src/main/java/io/javaoperatorsdk/operator/processing/EventScheduler.java index d2ed63a218..92e3aa43bf 100644 --- a/operator-framework/src/main/java/io/javaoperatorsdk/operator/processing/EventScheduler.java +++ b/operator-framework/src/main/java/io/javaoperatorsdk/operator/processing/EventScheduler.java @@ -1,18 +1,18 @@ package io.javaoperatorsdk.operator.processing; -import io.javaoperatorsdk.operator.processing.retry.Retry; -import io.fabric8.kubernetes.client.CustomResource; -import io.fabric8.kubernetes.client.KubernetesClientException; -import io.fabric8.kubernetes.client.Watcher; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.Optional; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; +import io.fabric8.kubernetes.client.CustomResource; +import io.fabric8.kubernetes.client.Watcher; +import io.fabric8.kubernetes.client.WatcherException; +import io.javaoperatorsdk.operator.processing.retry.Retry; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * Requirements: *
    @@ -57,7 +57,7 @@ public void eventReceived(Watcher.Action action, CustomResource resource) { CustomResourceEvent event = new CustomResourceEvent(action, resource, retry); scheduleEventFromApi(event); } - + void scheduleEventFromApi(CustomResourceEvent event) { try { lock.lock(); @@ -137,9 +137,9 @@ private void scheduleNotYetScheduledEventForExecution(String uuid) { CustomResourceEvent notScheduledEvent = eventStore.removeEventNotScheduled(uuid); scheduleEventForExecution(notScheduledEvent); } - + @Override - public void onClose(KubernetesClientException e) { + public void onClose(WatcherException e) { log.error("Error: ", e); // we will exit the application if there was a watching exception, because of the bug in fabric8 client // see https://github.com/fabric8io/kubernetes-client/issues/1318 diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/ConcurrencyIT.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/ConcurrencyIT.java index eb8692989e..e12b642122 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/ConcurrencyIT.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/ConcurrencyIT.java @@ -34,7 +34,7 @@ public class ConcurrencyIT { public void setup() { KubernetesClient k8sClient = new DefaultKubernetesClient(); final TestCustomResourceController controller = new TestCustomResourceController(k8sClient, true); - assertThat(HasMetadata.DOMAIN_NAME_MATCHER.reset(ControllerUtils.getDefaultFinalizerIdentifier(controller)).matches()).isTrue(); + assertThat(HasMetadata.FINALIZER_NAME_MATCHER.reset(ControllerUtils.getDefaultFinalizerIdentifier(controller)).matches()).isTrue(); integrationTest.initialize(k8sClient, controller, "test-crd.yaml"); } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerUtilsTest.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerUtilsTest.java index 288fc9dae9..7280806d89 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerUtilsTest.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerUtilsTest.java @@ -22,7 +22,7 @@ public void returnsValuesFromControllerAnnotationFinalizer() { final TestCustomResourceController controller = new TestCustomResourceController(null); final String finalizer = ControllerUtils.getFinalizer(controller); Assertions.assertEquals(TestCustomResourceController.FINALIZER_NAME, finalizer); - Assertions.assertTrue(HasMetadata.DOMAIN_NAME_MATCHER.reset(finalizer).matches()); + Assertions.assertTrue(HasMetadata.FINALIZER_NAME_MATCHER.reset(finalizer).matches()); assertEquals(TestCustomResource.class, ControllerUtils.getCustomResourceClass(controller)); Assertions.assertEquals(TestCustomResourceController.CRD_NAME, ControllerUtils.getCrdName(controller)); assertFalse(ControllerUtils.getGenerationEventProcessing(controller)); diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/SubResourceUpdateIT.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/SubResourceUpdateIT.java index b8c4ff5629..7e7ae2ed87 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/SubResourceUpdateIT.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/SubResourceUpdateIT.java @@ -26,7 +26,7 @@ public class SubResourceUpdateIT { @BeforeAll void checkFinalizer() { - assertThat(HasMetadata.DOMAIN_NAME_MATCHER.reset(ControllerUtils.getDefaultFinalizerIdentifier(new SubResourceTestCustomResourceController())).matches()).isTrue(); + assertThat(HasMetadata.FINALIZER_NAME_MATCHER.reset(ControllerUtils.getDefaultFinalizerIdentifier(new SubResourceTestCustomResourceController())).matches()).isTrue(); } @BeforeEach diff --git a/pom.xml b/pom.xml index 7817b2fe49..c74328321e 100644 --- a/pom.xml +++ b/pom.xml @@ -52,7 +52,7 @@ io.fabric8 openshift-client - 5.0.0-alpha-1 + 5.0.0-alpha-2 org.slf4j diff --git a/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/TomcatController.java b/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/TomcatController.java index aaa2d07d95..7c65350cef 100644 --- a/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/TomcatController.java +++ b/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/TomcatController.java @@ -12,8 +12,8 @@ import io.fabric8.kubernetes.api.model.apps.Deployment; import io.fabric8.kubernetes.client.CustomResourceList; import io.fabric8.kubernetes.client.KubernetesClient; -import io.fabric8.kubernetes.client.KubernetesClientException; import io.fabric8.kubernetes.client.Watcher; +import io.fabric8.kubernetes.client.WatcherException; import io.fabric8.kubernetes.client.dsl.MixedOperation; import io.fabric8.kubernetes.client.dsl.Resource; import io.fabric8.kubernetes.client.dsl.RollableScalableResource; @@ -75,9 +75,9 @@ public void eventReceived(Action action, Deployment deployment) { log.error(ex.getMessage()); } } - + @Override - public void onClose(KubernetesClientException cause) { + public void onClose(WatcherException e) { } }); watchedResources.add(WatchedResource.fromResource(deployment)); From 8ec63d3a842633c62201b7fcef8f4a63e43b7638 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Wed, 25 Nov 2020 12:38:32 +0100 Subject: [PATCH 21/23] fix: use new finalizer generation logic --- .../java/io/javaoperatorsdk/operator/ControllerUtils.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/operator-framework/src/main/java/io/javaoperatorsdk/operator/ControllerUtils.java b/operator-framework/src/main/java/io/javaoperatorsdk/operator/ControllerUtils.java index ec62007cb6..448f01acea 100644 --- a/operator-framework/src/main/java/io/javaoperatorsdk/operator/ControllerUtils.java +++ b/operator-framework/src/main/java/io/javaoperatorsdk/operator/ControllerUtils.java @@ -6,7 +6,7 @@ public class ControllerUtils { - private static final String FINALIZER_NAME_SUFFIX = ".javaoperatorsdk.io/finalizer"; + private static final String FINALIZER_NAME_SUFFIX = "/finalizer"; static String getFinalizer(ResourceController controller) { final String annotationFinalizerName = getAnnotation(controller).finalizerName(); @@ -17,8 +17,7 @@ static String getFinalizer(ResourceController controller) { } static String getDefaultFinalizerIdentifier(ResourceController controller) { - final Class controllerClass = controller.getClass(); - return controllerClass.getSimpleName().toLowerCase() + FINALIZER_NAME_SUFFIX; + return getAnnotation(controller).crdName() + FINALIZER_NAME_SUFFIX; } static boolean getGenerationEventProcessing(ResourceController controller) { From 39dd757fc185af167991ac47e94f1c850072b473 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Wed, 25 Nov 2020 12:59:48 +0100 Subject: [PATCH 22/23] refactor: isolate finalizer validation until HasMetadata provides it See https://github.com/fabric8io/kubernetes-client/issues/2628 --- .../javaoperatorsdk/operator/ControllerUtils.java | 12 +++++++++++- .../javaoperatorsdk/operator/ConcurrencyIT.java | 4 +--- .../operator/ControllerUtilsTest.java | 15 +++++++-------- .../operator/IntegrationTestSupport.java | 4 +++- .../operator/SubResourceUpdateIT.java | 7 ------- 5 files changed, 22 insertions(+), 20 deletions(-) diff --git a/operator-framework/src/main/java/io/javaoperatorsdk/operator/ControllerUtils.java b/operator-framework/src/main/java/io/javaoperatorsdk/operator/ControllerUtils.java index 448f01acea..2c9b79c2b4 100644 --- a/operator-framework/src/main/java/io/javaoperatorsdk/operator/ControllerUtils.java +++ b/operator-framework/src/main/java/io/javaoperatorsdk/operator/ControllerUtils.java @@ -1,5 +1,6 @@ package io.javaoperatorsdk.operator; +import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.client.CustomResource; import io.javaoperatorsdk.operator.api.Controller; import io.javaoperatorsdk.operator.api.ResourceController; @@ -20,6 +21,15 @@ static String getDefaultFinalizerIdentifier(ResourceController controller) { return getAnnotation(controller).crdName() + FINALIZER_NAME_SUFFIX; } + /** + * @param finalizer + * @return + * @deprecated this should be removed once k8s client provides that method on HasMetadata + */ + static boolean isFinalizerValid(String finalizer) { + return HasMetadata.FINALIZER_NAME_MATCHER.reset(finalizer).matches(); + } + static boolean getGenerationEventProcessing(ResourceController controller) { return getAnnotation(controller).generationAwareEventProcessing(); } @@ -27,7 +37,7 @@ static boolean getGenerationEventProcessing(ResourceController controller) { static Class getCustomResourceClass(ResourceController controller) { return (Class) getAnnotation(controller).customResourceClass(); } - + static String getCrdName(ResourceController controller) { return getAnnotation(controller).crdName(); } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/ConcurrencyIT.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/ConcurrencyIT.java index e12b642122..f13a4d4846 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/ConcurrencyIT.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/ConcurrencyIT.java @@ -5,7 +5,6 @@ import java.util.stream.Collectors; import io.fabric8.kubernetes.api.model.ConfigMap; -import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.client.DefaultKubernetesClient; import io.fabric8.kubernetes.client.KubernetesClient; import io.javaoperatorsdk.operator.sample.TestCustomResource; @@ -34,10 +33,9 @@ public class ConcurrencyIT { public void setup() { KubernetesClient k8sClient = new DefaultKubernetesClient(); final TestCustomResourceController controller = new TestCustomResourceController(k8sClient, true); - assertThat(HasMetadata.FINALIZER_NAME_MATCHER.reset(ControllerUtils.getDefaultFinalizerIdentifier(controller)).matches()).isTrue(); integrationTest.initialize(k8sClient, controller, "test-crd.yaml"); } - + @BeforeEach public void cleanup() { integrationTest.cleanup(); diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerUtilsTest.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerUtilsTest.java index 7280806d89..c78f4f8454 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerUtilsTest.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerUtilsTest.java @@ -1,6 +1,5 @@ package io.javaoperatorsdk.operator; -import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.api.Context; import io.javaoperatorsdk.operator.api.Controller; import io.javaoperatorsdk.operator.api.ResourceController; @@ -14,34 +13,34 @@ import static org.junit.jupiter.api.Assertions.assertFalse; class ControllerUtilsTest { - + public static final String CUSTOM_FINALIZER_NAME = "a.custom/finalizer"; - + @Test public void returnsValuesFromControllerAnnotationFinalizer() { final TestCustomResourceController controller = new TestCustomResourceController(null); final String finalizer = ControllerUtils.getFinalizer(controller); Assertions.assertEquals(TestCustomResourceController.FINALIZER_NAME, finalizer); - Assertions.assertTrue(HasMetadata.FINALIZER_NAME_MATCHER.reset(finalizer).matches()); + Assertions.assertTrue(ControllerUtils.isFinalizerValid(finalizer)); assertEquals(TestCustomResource.class, ControllerUtils.getCustomResourceClass(controller)); Assertions.assertEquals(TestCustomResourceController.CRD_NAME, ControllerUtils.getCrdName(controller)); assertFalse(ControllerUtils.getGenerationEventProcessing(controller)); } - + @Controller(crdName = "test.crd", customResourceClass = TestCustomResource.class, finalizerName = CUSTOM_FINALIZER_NAME) static class TestCustomFinalizerController implements ResourceController { - + @Override public boolean deleteResource(TestCustomResource resource, Context context) { return false; } - + @Override public UpdateControl createOrUpdateResource(TestCustomResource resource, Context context) { return null; } } - + @Test public void returnCustomerFinalizerNameIfSet() { assertEquals(CUSTOM_FINALIZER_NAME, ControllerUtils.getFinalizer(new TestCustomFinalizerController())); diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/IntegrationTestSupport.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/IntegrationTestSupport.java index 7fc3158248..2844cdb4f9 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/IntegrationTestSupport.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/IntegrationTestSupport.java @@ -34,6 +34,8 @@ public class IntegrationTestSupport { private ResourceController controller; public void initialize(KubernetesClient k8sClient, ResourceController controller, String crdPath) { + assertThat(ControllerUtils.isFinalizerValid(ControllerUtils.getDefaultFinalizerIdentifier(controller))).isTrue(); + log.info("Initializing integration test in namespace {}", TEST_NAMESPACE); this.k8sClient = k8sClient; loadCRDAndApplyToCluster(crdPath); @@ -41,7 +43,7 @@ public void initialize(KubernetesClient k8sClient, ResourceController controller Class customResourceClass = ControllerUtils.getCustomResourceClass(controller); this.crOperations = k8sClient.customResources(customResourceClass, CustomResourceList.class); - + if (k8sClient.namespaces().withName(TEST_NAMESPACE).get() == null) { k8sClient.namespaces().create(new NamespaceBuilder() .withMetadata(new ObjectMetaBuilder().withName(TEST_NAMESPACE).build()).build()); diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/SubResourceUpdateIT.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/SubResourceUpdateIT.java index 7e7ae2ed87..9a68ee27ac 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/SubResourceUpdateIT.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/SubResourceUpdateIT.java @@ -2,7 +2,6 @@ import java.util.concurrent.TimeUnit; -import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; import io.fabric8.kubernetes.client.DefaultKubernetesClient; import io.fabric8.kubernetes.client.KubernetesClient; @@ -10,7 +9,6 @@ import io.javaoperatorsdk.operator.sample.subresource.SubResourceTestCustomResourceController; import io.javaoperatorsdk.operator.sample.subresource.SubResourceTestCustomResourceSpec; import io.javaoperatorsdk.operator.sample.subresource.SubResourceTestCustomResourceStatus; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; @@ -24,11 +22,6 @@ public class SubResourceUpdateIT { private IntegrationTestSupport integrationTestSupport = new IntegrationTestSupport(); - @BeforeAll - void checkFinalizer() { - assertThat(HasMetadata.FINALIZER_NAME_MATCHER.reset(ControllerUtils.getDefaultFinalizerIdentifier(new SubResourceTestCustomResourceController())).matches()).isTrue(); - } - @BeforeEach public void initAndCleanup() { KubernetesClient k8sClient = new DefaultKubernetesClient(); From fa9f9b81d4249d62add97c4bd9902bce5a84a552 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Wed, 25 Nov 2020 13:07:16 +0100 Subject: [PATCH 23/23] fix: add .io suffix to sample.javaoperatorsdk group The intent here is to use better groups for example CRDs. --- README.md | 2 +- .../operator/sample/TestCustomResource.java | 2 +- .../sample/TestCustomResourceController.java | 2 +- .../SubResourceTestCustomResource.java | 2 +- ...bResourceTestCustomResourceController.java | 2 +- .../operator/subresource-test-crd.yaml | 4 +-- .../io/javaoperatorsdk/operator/test-crd.yaml | 4 +-- samples/common/crd/crd.yaml | 4 +-- samples/common/crd/test_object.yaml | 2 +- .../operator/sample/CustomService.java | 2 +- .../sample/CustomServiceController.java | 2 +- samples/mysql-schema/README.md | 2 +- samples/mysql-schema/k8s/crd.yaml | 4 +-- samples/mysql-schema/k8s/example.yaml | 2 +- samples/mysql-schema/k8s/rbac.yaml | 4 +-- .../operator/sample/Schema.java | 2 +- .../operator/sample/SchemaController.java | 26 +++++++++---------- samples/webserver/README.md | 2 +- samples/webserver/crd/crd.yaml | 4 +-- samples/webserver/crd/webserver.yaml | 2 +- .../operator/sample/WebServer.java | 2 +- .../operator/sample/WebServerController.java | 2 +- 22 files changed, 40 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index 10d53fbc66..4750b11212 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ The Controller implements the business logic and describes all the classes neede ```java @Controller(customResourceClass = WebServer.class, - crdName = "webservers.sample.javaoperatorsdk") + crdName = "webservers.sample.javaoperatorsdk.io") public class WebServerController implements ResourceController { @Override diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/TestCustomResource.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/TestCustomResource.java index a09435b958..a868035934 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/TestCustomResource.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/TestCustomResource.java @@ -41,6 +41,6 @@ public String getKind() { @Override public String getApiVersion() { - return "sample.javaoperatorsdk/v1"; + return "sample.javaoperatorsdk.io/v1"; } } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/TestCustomResourceController.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/TestCustomResourceController.java index 8b7baee080..ff7eca2da1 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/TestCustomResourceController.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/TestCustomResourceController.java @@ -25,7 +25,7 @@ public class TestCustomResourceController implements ResourceController, TestExecutionInfoProvider { - public static final String CRD_NAME = "subresourcesamples.sample.javaoperatorsdk"; + public static final String CRD_NAME = "subresourcesamples.sample.javaoperatorsdk.io"; public static final String FINALIZER_NAME = CRD_NAME + ".io/finalizer"; private static final Logger log = LoggerFactory.getLogger(SubResourceTestCustomResourceController.class); private final AtomicInteger numberOfExecutions = new AtomicInteger(0); diff --git a/operator-framework/src/test/resources/io/javaoperatorsdk/operator/subresource-test-crd.yaml b/operator-framework/src/test/resources/io/javaoperatorsdk/operator/subresource-test-crd.yaml index 2b9b3db2b8..858998f5eb 100644 --- a/operator-framework/src/test/resources/io/javaoperatorsdk/operator/subresource-test-crd.yaml +++ b/operator-framework/src/test/resources/io/javaoperatorsdk/operator/subresource-test-crd.yaml @@ -1,9 +1,9 @@ apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: - name: subresourcesamples.sample.javaoperatorsdk + name: subresourcesamples.sample.javaoperatorsdk.io spec: - group: sample.javaoperatorsdk + group: sample.javaoperatorsdk.io version: v1 subresources: status: {} diff --git a/operator-framework/src/test/resources/io/javaoperatorsdk/operator/test-crd.yaml b/operator-framework/src/test/resources/io/javaoperatorsdk/operator/test-crd.yaml index ecc3a38587..2c1d2254c6 100644 --- a/operator-framework/src/test/resources/io/javaoperatorsdk/operator/test-crd.yaml +++ b/operator-framework/src/test/resources/io/javaoperatorsdk/operator/test-crd.yaml @@ -1,9 +1,9 @@ apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: - name: customservices.sample.javaoperatorsdk + name: customservices.sample.javaoperatorsdk.io spec: - group: sample.javaoperatorsdk + group: sample.javaoperatorsdk.io version: v1 scope: Namespaced names: diff --git a/samples/common/crd/crd.yaml b/samples/common/crd/crd.yaml index 67d2b82ecb..9fa67a28b9 100644 --- a/samples/common/crd/crd.yaml +++ b/samples/common/crd/crd.yaml @@ -1,9 +1,9 @@ apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: - name: customservices.sample.javaoperatorsdk + name: customservices.sample.javaoperatorsdk.io spec: - group: sample.javaoperatorsdk + group: sample.javaoperatorsdk.io version: v1 scope: Namespaced names: diff --git a/samples/common/crd/test_object.yaml b/samples/common/crd/test_object.yaml index f8e23e387b..c36212e256 100644 --- a/samples/common/crd/test_object.yaml +++ b/samples/common/crd/test_object.yaml @@ -1,4 +1,4 @@ -apiVersion: "sample.javaoperatorsdk/v1" +apiVersion: "sample.javaoperatorsdk.io/v1" kind: CustomService metadata: name: custom-service1 diff --git a/samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomService.java b/samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomService.java index 2ec03f2fed..2b39f172fe 100644 --- a/samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomService.java +++ b/samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomService.java @@ -17,6 +17,6 @@ public void setSpec(ServiceSpec spec) { @Override public String getApiVersion() { - return "sample.javaoperatorsdk/v1"; + return "sample.javaoperatorsdk.io/v1"; } } diff --git a/samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomServiceController.java b/samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomServiceController.java index 414096ea65..13ff1e62de 100644 --- a/samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomServiceController.java +++ b/samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomServiceController.java @@ -17,7 +17,7 @@ * A very simple sample controller that creates a service with a label. */ @Controller(customResourceClass = CustomService.class, - crdName = "customservices.sample.javaoperatorsdk") + crdName = "customservices.sample.javaoperatorsdk.io") public class CustomServiceController implements ResourceController { public static final String KIND = "CustomService"; diff --git a/samples/mysql-schema/README.md b/samples/mysql-schema/README.md index 2860d5ee47..ec558b343f 100644 --- a/samples/mysql-schema/README.md +++ b/samples/mysql-schema/README.md @@ -8,7 +8,7 @@ Access to the MySQL server is configured in the configuration of the operator, s This is an example input: ```yaml -apiVersion: "mysql.sample.javaoperatorsdk/v1" +apiVersion: "mysql.sample.javaoperatorsdk.io/v1" kind: MySQLSchema metadata: name: mydb diff --git a/samples/mysql-schema/k8s/crd.yaml b/samples/mysql-schema/k8s/crd.yaml index ef3aef057e..a877df8883 100644 --- a/samples/mysql-schema/k8s/crd.yaml +++ b/samples/mysql-schema/k8s/crd.yaml @@ -1,9 +1,9 @@ apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: - name: schemas.mysql.sample.javaoperatorsdk + name: schemas.mysql.sample.javaoperatorsdk.io spec: - group: mysql.sample.javaoperatorsdk + group: mysql.sample.javaoperatorsdk.io version: v1 subresources: status: {} diff --git a/samples/mysql-schema/k8s/example.yaml b/samples/mysql-schema/k8s/example.yaml index 054c9a1695..3117eb095c 100644 --- a/samples/mysql-schema/k8s/example.yaml +++ b/samples/mysql-schema/k8s/example.yaml @@ -1,4 +1,4 @@ -apiVersion: "mysql.sample.javaoperatorsdk/v1" +apiVersion: "mysql.sample.javaoperatorsdk.io/v1" kind: MySQLSchema metadata: name: mydb diff --git a/samples/mysql-schema/k8s/rbac.yaml b/samples/mysql-schema/k8s/rbac.yaml index ddd05d3b76..28b363a05a 100644 --- a/samples/mysql-schema/k8s/rbac.yaml +++ b/samples/mysql-schema/k8s/rbac.yaml @@ -4,13 +4,13 @@ metadata: name: mysql-schema-operator rules: - apiGroups: - - mysql.sample.javaoperatorsdk + - mysql.sample.javaoperatorsdk.io resources: - schemas verbs: - "*" - apiGroups: - - mysql.sample.javaoperatorsdk + - mysql.sample.javaoperatorsdk.io resources: - schemas/status verbs: diff --git a/samples/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/Schema.java b/samples/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/Schema.java index 603c426241..a7f8fe2e29 100644 --- a/samples/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/Schema.java +++ b/samples/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/Schema.java @@ -27,6 +27,6 @@ public void setStatus(SchemaStatus status) { @Override public String getApiVersion() { - return "mysql.sample.javaoperatorsdk/v1"; + return "mysql.sample.javaoperatorsdk.io/v1"; } } diff --git a/samples/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/SchemaController.java b/samples/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/SchemaController.java index bda42ac066..69b31914f8 100644 --- a/samples/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/SchemaController.java +++ b/samples/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/SchemaController.java @@ -1,16 +1,5 @@ package io.javaoperatorsdk.operator.sample; -import io.javaoperatorsdk.operator.api.Context; -import io.javaoperatorsdk.operator.api.Controller; -import io.javaoperatorsdk.operator.api.ResourceController; -import io.javaoperatorsdk.operator.api.UpdateControl; -import io.fabric8.kubernetes.api.model.Secret; -import io.fabric8.kubernetes.api.model.SecretBuilder; -import io.fabric8.kubernetes.client.KubernetesClient; -import org.apache.commons.lang3.RandomStringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; @@ -19,11 +8,22 @@ import java.sql.Statement; import java.util.Base64; +import io.fabric8.kubernetes.api.model.Secret; +import io.fabric8.kubernetes.api.model.SecretBuilder; +import io.fabric8.kubernetes.client.KubernetesClient; +import io.javaoperatorsdk.operator.api.Context; +import io.javaoperatorsdk.operator.api.Controller; +import io.javaoperatorsdk.operator.api.ResourceController; +import io.javaoperatorsdk.operator.api.UpdateControl; +import org.apache.commons.lang3.RandomStringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import static java.lang.String.format; @Controller( - crdName = "schemas.mysql.sample.javaoperatorsdk", - customResourceClass = Schema.class) + crdName = "schemas.mysql.sample.javaoperatorsdk.io", + customResourceClass = Schema.class) public class SchemaController implements ResourceController { static final String USERNAME_FORMAT = "%s-user"; static final String SECRET_FORMAT = "%s-secret"; diff --git a/samples/webserver/README.md b/samples/webserver/README.md index e9ac920442..160500ad44 100644 --- a/samples/webserver/README.md +++ b/samples/webserver/README.md @@ -7,7 +7,7 @@ the html. This is an example input: ```yaml -apiVersion: "sample.javaoperatorsdk/v1" +apiVersion: "sample.javaoperatorsdk.io/v1" kind: WebServer metadata: name: mynginx-hello diff --git a/samples/webserver/crd/crd.yaml b/samples/webserver/crd/crd.yaml index 0ed1d373a7..f66b2141fe 100644 --- a/samples/webserver/crd/crd.yaml +++ b/samples/webserver/crd/crd.yaml @@ -1,9 +1,9 @@ apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: - name: webservers.sample.javaoperatorsdk + name: webservers.sample.javaoperatorsdk.io spec: - group: sample.javaoperatorsdk + group: sample.javaoperatorsdk.io version: v1 scope: Namespaced names: diff --git a/samples/webserver/crd/webserver.yaml b/samples/webserver/crd/webserver.yaml index 0260bfb30f..d47875619d 100644 --- a/samples/webserver/crd/webserver.yaml +++ b/samples/webserver/crd/webserver.yaml @@ -1,4 +1,4 @@ -apiVersion: "sample.javaoperatorsdk/v1" +apiVersion: "sample.javaoperatorsdk.io/v1" kind: WebServer metadata: name: hellows diff --git a/samples/webserver/src/main/java/io/javaoperatorsdk/operator/sample/WebServer.java b/samples/webserver/src/main/java/io/javaoperatorsdk/operator/sample/WebServer.java index 4adef81f3b..5830fe269c 100644 --- a/samples/webserver/src/main/java/io/javaoperatorsdk/operator/sample/WebServer.java +++ b/samples/webserver/src/main/java/io/javaoperatorsdk/operator/sample/WebServer.java @@ -27,6 +27,6 @@ public void setStatus(WebServerStatus status) { @Override public String getApiVersion() { - return "sample.javaoperatorsdk/v1"; + return "sample.javaoperatorsdk.io/v1"; } } diff --git a/samples/webserver/src/main/java/io/javaoperatorsdk/operator/sample/WebServerController.java b/samples/webserver/src/main/java/io/javaoperatorsdk/operator/sample/WebServerController.java index b93d0a8007..388dba938f 100644 --- a/samples/webserver/src/main/java/io/javaoperatorsdk/operator/sample/WebServerController.java +++ b/samples/webserver/src/main/java/io/javaoperatorsdk/operator/sample/WebServerController.java @@ -26,7 +26,7 @@ import org.slf4j.LoggerFactory; @Controller(customResourceClass = WebServer.class, - crdName = "webservers.sample.javaoperatorsdk") + crdName = "webservers.sample.javaoperatorsdk.io") public class WebServerController implements ResourceController { private final Logger log = LoggerFactory.getLogger(getClass());