-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Extension development using only api and resource/resourceList implementations #3858
Conversation
6ec6bd1
to
f31e881
Compare
also deprecating extra ApiVersionUtil classes moving resource interfaces in service-catalog client from internal to dsl
9a9c091
to
61c10f4
Compare
The next commit refines the initial one:
It also makes an initial stab at consolidating the resource (related to #3407) / withItem logic - I'm proposing to change KubernetesClient.resource from returning NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicable to a new interface NamespaceableResource (which I'm proposing to not be Namespaceable as explained in one of the comments). NamespaceableResourceAdapter encapsulates the behavior this exposes. The methods lost from NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicable where already deprecated, so this should be fine for a major version change. ResourceTest has been updated to use an intermediate resource variable as was suggested in the deprecation comment. I did not take this logic fully through yet - the resource list behavior is still based upon the legacy logic - but once that is changed we'll be able to fully remove several interfaces and supporting classes. With those changes, it was helpful to also pull in validation changes mentioned from #3859. @manusa @rohanKanojia let me know if you have any qualms with this. ResourceIT shows the full replacement for resource.deletingExisting().createOrReplace(); as resource.delete(); resource.waitUntilCondition(Objects::isNull...); resource.create(); If this seems like too long of a replacement sequence, there are a couple of options:
The withItem method has not been added to an interface. There are a couple of options - add Itemable, or alter Loadable to be Loadable<R, T> to support R withItem. There is also the similarity with the resource entry method - but that one has additional namespace side effects. What makes sense? |
61c10f4
to
ed141c1
Compare
Kubernetes.resource now returns NamespaceableResource also adds sanity checks useful for fabric8io#3859 as well
ed141c1
to
0e6b058
Compare
The next commit more fully realizes the resource changes for #3407 - it had seemed like I need to get Resource usage straightened out prior to proceeding with #3845, but now it looks like it's more separable than I thought. In any case I'll go back to that now and clean up the Handler logic. I'll leave switching over the other extension until a later pr. |
ea29ffe
to
f8689f4
Compare
Rather than make this pr larger, I've added #3875 #3876 to address after this. The only thing this pr does not do, which would be a nice to have, is for the three argument resources call to validate the Resource class subtype that will eventually be used - however this requires a lot of bookkeeping of the class type, so for now I'm okay with just letting later class cast exceptions be seen. It's not expected that users will call that method directly - they should instead be using other dsl methods. |
f8689f4
to
5568828
Compare
…n logic also various cleanups and adding some migration docs
5568828
to
4af1a5c
Compare
@iocanel from my perspective this is ready for review - do you want to leave the WIP on until you complete a review? |
I have the changes ready that implement the previous comment (and related cleanups) should we want to go that direction: shawkins#6 |
@manusa this should be ready for review again. after the merge from master this also includes the removal of KubernetesClient.lists After this is committed I'll open a pr with the work from shawkins#6 and the additional changes to namespace handling. |
extension-api # Conflicts: # extensions/service-catalog/client/src/main/java/io/fabric8/servicecatalog/client/internal/ClusterServiceBrokerOperationsImpl.java # extensions/service-catalog/client/src/main/java/io/fabric8/servicecatalog/client/internal/ClusterServiceClassOperationsImpl.java # extensions/service-catalog/client/src/main/java/io/fabric8/servicecatalog/client/internal/ClusterServicePlanOperationsImpl.java # extensions/service-catalog/client/src/main/java/io/fabric8/servicecatalog/client/internal/ServiceBindingOperationsImpl.java # extensions/service-catalog/client/src/main/java/io/fabric8/servicecatalog/client/internal/ServiceInstanceOperationsImpl.java # extensions/volumesnapshot/client/src/main/java/io/fabric8/volumesnapshot/client/internal/VolumeSnapshotClassOperationsImpl.java # extensions/volumesnapshot/client/src/main/java/io/fabric8/volumesnapshot/client/internal/VolumeSnapshotContentOperationsImpl.java # extensions/volumesnapshot/client/src/main/java/io/fabric8/volumesnapshot/client/internal/VolumeSnapshotOperationsImpl.java # kubernetes-client/src/main/java/io/fabric8/kubernetes/client/BaseClient.java # kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/BaseOperation.java # kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/GenericKubernetesResourceOperationsImpl.java # kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableImpl.java # kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableListImpl.java # kubernetes-client/src/main/java/io/fabric8/kubernetes/client/osgi/ManagedKubernetesClient.java # kubernetes-client/src/main/java/io/fabric8/kubernetes/client/utils/internal/DeleteAndCreateHelper.java # kubernetes-client/src/test/java/io/fabric8/kubernetes/client/utils/internal/DeleteAndCreateHelperTest.java # kubernetes-client/src/test/java/io/fabric8/kubernetes/client/utils/internal/PodOperationUtilTest.java also removing KubernetesClient.lists
d42bac9
to
a210718
Compare
Thought it might be better just to show the totality of changes, this commit should fail on things that expect an exception on a namespace mismatch. I'll correct that and add migration notes in another commit. |
a210718
to
1b9f52f
Compare
into extension-api # Conflicts: # kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/ListVisitFromServerGetDeleteRecreateWaitApplicable.java # kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/extended/run/RunOperationsTest.java # kubernetes-client/src/main/java/io/fabric8/kubernetes/client/BaseKubernetesClient.java # kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/KubernetesListOperationsImpl.java # kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/batch/v1beta1/CronJobOperationsImpl.java # kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/core/v1/BindingOperationsImpl.java # kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/core/v1/ComponentStatusOperationsImpl.java # kubernetes-client/src/main/java/io/fabric8/kubernetes/client/extended/run/RunOperationsImpl.java # kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/KubernetesListTest.java # openshift-client/src/main/java/io/fabric8/openshift/client/DefaultOpenShiftClient.java also removing generickuberntesclient and applying the same namespacing logic to all items
1b9f52f
to
c30c2d9
Compare
extension-api # Conflicts: # kubernetes-client/src/main/java/io/fabric8/kubernetes/client/DefaultKubernetesClient.java
The test failures https://github.com/fabric8io/kubernetes-client/runs/5300256746?check_suite_focus=true#step:6:680 are being caused by a new sequence of events such that the wrong apiGroupName is being used. Essentially OperationContext.setApiGroupName is implemented by looking at the item first if non null, then will take the passed in value. The test resources, like the BuildConfig for BuildConfigIT have apiVersion: "v1" - so if you create the context by first associating the invalid item then doing any other operation, it will revert to a null apiGroupName. My workaround in the next commit is to call updateApiVersion(item) in withItem, but it does look like some of this needs changed - because it appears in the context that the item is the primary place for the apiGroupName, then in the Operation logic it appears that the context (typically without an item the value is coming from the class/rdc or is hardcoded in the XXXOperationsImpl constructor) is primary. That commit was updated to include an additional change - RouteIT was not setting the currentNamespace, so it was effectively calling inNamespace(null). Prior to these changes it appears that meant "use the default namespace", with these changes it's effectively a usage error meaning "in any namespace", but returning a NonNamespaceOperation. @manusa @rohanKanojia are there any expectations when calling inNamespace(null)? |
also updating the test to set the namespace
398b7f1
to
71be32d
Compare
3bbb5f1
to
cfd501a
Compare
public static void setNamespace(HasMetadata entity, String namespace) { | ||
if (entity != null) { | ||
ObjectMeta metadata = entity.getMetadata(); | ||
if (metadata != null) { | ||
metadata.setNamespace(namespace); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't checked the purpose of this util.
But was wondering if it might be interesting to initialize metadata instead of just ignoring if it's null:
public static void setNamespace(HasMetadata entity, String namespace) { | |
if (entity != null) { | |
ObjectMeta metadata = entity.getMetadata(); | |
if (metadata != null) { | |
metadata.setNamespace(namespace); | |
} | |
} | |
} | |
public static void setNamespace(HasMetadata entity, String namespace) { | |
if (entity != null) { | |
if (entity.getMetadata() == null) { | |
entity.setMetadata(new ObjectMeta()); | |
} | |
entity.getMetadata().setNamespace(namespace); | |
} | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was for consistency with setResourceVersion and in the usage with this pr if there is no objectmetadata the scenario will fail regardless as there would then be no name. However I'm open to anything - you could also consider moving methods like this to HasMetadata under #3625 which was a follow-on to the convenience methods added for finalizers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It makes sense to me that in scope of this class, both methods should initialize the entity's metadata if necessary.
Maybe we can consider this as a future change.
protected <T> T correctNamespace(T item) { | ||
if (!isResourceNamespaced() || this.context.isDefaultNamespace() || !(item instanceof HasMetadata)) { | ||
return item; | ||
} | ||
String itemNs = KubernetesResourceUtil.getNamespace((HasMetadata)item); | ||
|
||
if (Utils.isNotNullOrEmpty(namespace) && Utils.isNotNullOrEmpty(itemNs) && !namespace.equals(itemNs)) { | ||
item = Serialization.clone(item); | ||
KubernetesResourceUtil.setNamespace((HasMetadata)item, namespace); | ||
} | ||
return item; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if we have an explicit test for this, but full coverage and documentation of conditions should be provided since it's determinant for the Namespace resolution logic.
I'm not sure if this PR also includes the default
namespace fallback logic discussed in some meetings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if we have an explicit test for this, but full coverage and documentation of conditions should be provided since it's determinant for the Namespace resolution logic.
There's an addition to the migration guide https://github.com/fabric8io/kubernetes-client/pull/3858/files#diff-6cf6f0d1132c6d642456eda0b231e404d9b3743c0c0ff86346055c5f7c78c268R15
And https://github.com/fabric8io/kubernetes-client/blob/cfd501a75f96c8e02e2e554ecdfb4d3dd56f161c/kubernetes-tests/src/test/java/io/fabric8/openshift/client/server/mock/NamespacedItemTest.java highlighting the usage of the explicit namespace.
I'm not sure if this PR also includes the default namespace fallback logic discussed in some meetings.
It does not, that issue is if the Config has no default namespace, and still in the 6.0.0 bucket. It is a little related to the discussion about what should inNamespace(null) mean.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And https://github.com/fabric8io/kubernetes-client/blob/cfd501a75f96c8e02e2e554ecdfb4d3dd56f161c/kubernetes-tests/src/test/java/io/fabric8/openshift/client/server/mock/NamespacedItemTest.java highlighting the usage of the explicit namespace.
This is what I was looking for 👍 😃
static class ChangeNamespace extends TypedVisitor<ObjectMetaBuilder> { | ||
|
||
private final String explicitNamespace; | ||
|
||
ChangeNamespace(String explicitNamespace) { | ||
this.explicitNamespace = explicitNamespace; | ||
} | ||
|
||
@Override | ||
public void visit(ObjectMetaBuilder builder) { | ||
builder.withNamespace(explicitNamespace); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was an idea floating around about having some common reusable visitors or decorators.
This one seems like a good addition, since we have one that does effectively the same in JKube (https://github.com/eclipse/jkube/blob/2d5a744f2d842bb666da840d26111d4ebc2a521f/jkube-kit/enricher/generic/src/main/java/org/eclipse/jkube/enricher/generic/DefaultNamespaceEnricher.java#L91)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
extension-api # Conflicts: # doc/MIGRATION-v6.md # kubernetes-tests/src/test/java/io/fabric8/openshift/client/server/mock/OpenShiftLoadTest.java
@manusa I've updated with the changes discussed in the meeting. Feel free to squash this. |
SonarCloud Quality Gate failed. |
Description
See #3845 - this shows what the ServiceCatalog and Camel-K extensions could look like written only against the api.
The core of the changes are:
These changes by themselves are not breaking as you could still use a dependency on kubernetes-client to use the existing functionality.
There are some additional cleanup to be pursued:
Type of change
test, version modification, documentation, etc.)
Checklist