-
Notifications
You must be signed in to change notification settings - Fork 1k
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
feat(kubernetes): improve messaging in the delete (manifest) stage #5605
Open
dbyron-sf
wants to merge
2
commits into
spinnaker:master
Choose a base branch
from
dbyron-sf:improve-messaging-in-delete-manifest
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Does this work for dynamically registered CRDs (those that are not specified in the kubernetes account configuration)? I think it should work based on previous PRs to fix delete and patch manifest stages for CRDs, but I'd like to double check.
There's a risk of breaking backwards compatibility for an obscure use case: native kubernetes kinds are hardcoded in this file, and we're not keeping it up to date with changes in kubernetes API versions, which is ok, because the way clouddriver works is that if it finds a kind that is not a CRD and is not in that list, it assigns the
NONE
kind. Then the default implementation of delete uses the name of the manifest for the kubectl call, which becomes something likekubectl delete corekind
, which works because it doesn't need the group name to be specified, because it's a core kind.In the end, this
if
condition breaks the case of deleting core kinds which are not in the hardcoded list in clouddriver. For example, try deleting a ReplicationController or ResourceQuota.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.
Yes it does. This test still passes with this PR.
Hmmm...any thoughts on a good way forward that doesn't break this case?
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 can think on these options:
kubectl api-resources
in a newer version cluster). One problem is that this is an ongoing effort, if kubernetes adds another core kind in the future and clouddriver is not updated, spinnaker will not be able to delete those kinds.KubectlException
here when runningdeployer.delete
and parse the error message to know if it is because of a truly missing kind in the cluster. I don't know if the error message is clear enough to be parsed.isValidKind
toKubectlJobExecutor
that runs akubectl api-resources
, and call it before a delete. If the kind is valid, register it dynamically like CRDs, so subsequent deletes have the right KubernetesKind instance: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.
Thanks for these suggestions. Of these, I think the third one has the best chance of success. If we were using a java client library instead of invoking kubectl, perhaps option 2 would be more feasible, but I think it'll be tough to get right as it is. And I agree that the maintenance burden of option 1 is too big.
I started pondering how to implement this. Probably makes sense to discuss in the sig, but using #5334 as a model, it feels like adding code to KubernetesCredentials to periodically call a new KubectlJobExecutor method that runs
kubectl api-resources
makes sense. Not sure what subclass of KubernetesHandler will make sense...maybe one that already exists, or maybe a new one. At least by name,KubernetesCustomResourceHandler
doesn't feel right, but it may do the right thing.From there, adding a new member and mutator method to GlobalResourcePropertyRegistry and adjusting the get method to use it...and then I'm not sure whether KubernetesKindRegistry needs to know about these new kinds or not.
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.
Sounds right, the only thing is that probably we can get away without another memoizer periodically calling
kubectl api-resources
, if we call it on demand when trying to process a kindNONE
, or better yet, when creating the instance ofKubernetesKind
that assignsNONE
when there's no known kind in the hardcoded list or in the CRD dynamic list.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.
One more link that I think is helpful is to KubectlJobExecutor::kubectlLookupInfo, which KubectlJobExecutor::delete uses to build the kubectl command.
@german-muzquiz I'm questioning this:
Doesn't this mean the kind is important / shows up in the resulting command in addition to the name? Instead of
kubectl delete corekind
we'd end up withkubectl delete none/corekind
? Or maybe I'm missing something. Adding a test is the likely way forward, but still wanted to raise the question here.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.
The kind needs to be included in the command, so if the manifest name is not empty the command in the current implementation is
kubectl delete corekind/name
rather thankubectl delete none/corekind
.This is because the
KubernetesKind
is a dynamically created kind with the right name but with groupNONE
, sokind.toString()
iscorekind
.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.
Aaah, ok. I seem to have lost the place where that dynamically created kind comes from.
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.
We discussed this in the kubernetes sig. See the minutes from 2022-03-08. Because
deployer.delete
gets the kind from the credentials (as opposed to thec
object orc.getKind()
, it's not clear how deleting core kinds not mentioned in KubernetesKindProperties::getGlobalKindProperties could ever work...but we generally think it does. Time to add some tests....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've actually just run into a very similar sounding issue. If a custom
Kind
is not explicitly registered in the credentials definition, and there are no instances of that resource in the account, then theKubernetesUnregisteredCustomResourceHandler
handler is used and returns anone
kind, and theDelete (Manifest)
stage fails.If there are one or more the resources in the account, the
KubernetesCustomResourceHandler
is used and this returns the correct kind. This behaviour seems to have been introduced by #5334 and I'm really not sure how best to tackle it.On the one hand it makes sense that the Delete stage fails if the thing you're trying to delete doesn't exist. On the other hand - does it matter? Perhaps we should introduce an option for the
--ignore-not-found
kubectl flag in the stage?