-
Notifications
You must be signed in to change notification settings - Fork 532
Implement orphaning-deletion commands #1008
Conversation
dcd6f8d
to
7884655
Compare
Thank you for doing this! I am reviewing. |
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 your code. The function is fine to me. Please see my comments below.
By the way, we need to add test code for the related function for CI. It is fine to have a sepearated PR for that.
pkg/kubefedctl/orphaning/disable.go
Outdated
|
||
orphaning_disable_example = ` | ||
# Removes the "orphaning enable" annotation from a federated resources of Deployment foo, | ||
kubefedctl orphaning disable deployments.apps foo --host-cluster-context=cluster1` |
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.
deployments.apps
is type config object name. If my understanding is right, it should be Federated* type. Same comments for enable.go
, status.go
.
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 is an example of the command (flag) usage, so it operates with a specific types. In the above explanation mentions a generic "federated resource"
The same convention exists with others kubefedctl
and kubectl
commands
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 think the command line can operate on a specified federated type with object name specified as documented in user guide.
kubefedctl orphaning-deletion enable <federated type> <name>
My question is about the example of using <federated type>
deployments.apps
is a FederatedTypeConfig
object but not a federated type.
$ kubectl -n kube-federation-system get federatedtypeconfigs deployments.apps
NAME AGE
deployments.apps 7m
I think a name with Federated
prefixed makes more sense for the example. E.g. kubefedctl orphaning enable FederatedDeployment foo
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.
Got it, thanks for the explanation. Fixed.
pkg/kubefedctl/orphaning/disable.go
Outdated
return nil | ||
} | ||
st, ok := annotations[sync.OrphanManagedResources] | ||
if !ok || st == "false" { |
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.
[sugguestion] functionally, it is good. To me, a definite consistent behavior should be better for a command line operation. If enable
, add/update annotation to be true
. If disable
, there should no the annotation no matter it is false
or true
before the command line is executed.
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 wanted to save an addition update, but I'd agree with you, better have a consistent behavior.
Fixed.
Hi @xunpan , thanks for your review. I fixed part of your comments and added responses to others. Please take a look, if it is OK now. |
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.
2 minor readability comments.
And for commits
, could you please squash them. It is not encouraged to keep commits that are only used to fix previous commit in one PR.
pkg/kubefedctl/federate/util.go
Outdated
"sigs.k8s.io/kubefed/pkg/apis/core/typeconfig" | ||
ctlutil "sigs.k8s.io/kubefed/pkg/controller/util" | ||
"sigs.k8s.io/kubefed/pkg/kubefedctl/enable" | ||
"sigs.k8s.io/kubefed/pkg/kubefedctl/options" | ||
"sigs.k8s.io/kubefed/pkg/kubefedctl/util" | ||
"sigs.k8s.io/yaml" |
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.
For better readability, it is import convention in kubefed:
import(
"core-packages"
"3rd-party-packages"
"kubefed-packages"
)
E.g.:
import (
"io"
"os"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/kubefed/pkg/kubefedctl/enable"
"sigs.k8s.io/kubefed/pkg/kubefedctl/options"
)
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.
Fixed it,
looks like kubefed uses a slightly different import convention:
import(
"core-packages"
"3rd-party-packages"
"K8s packages"
"kubefed-packages"
) ```
Is it correct ?
pkg/kubefedctl/orphaning/enable.go
Outdated
|
||
// RunEnable implements the `enable` command. | ||
func (o *orphanResource) RunEnable(cmdOut io.Writer, config util.FedConfig) error { | ||
fedResource, resources, err := o.GetFederatedResource(config) |
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.
resources
is actually a resourceClient
I think. It is also better to have resources
in GetFederatedResource
as resourceClient
. It is a little confuse to use resource
and resources
in GetFederatedResource
for different types of object.
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.
agree, fixed
@roytman |
86d2310
to
1bbd937
Compare
|
Done, thanks |
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 code looks fine to me.
The comment is for .gitignore
.
.gitignore
Outdated
|
||
# Files generated by JetBrains IDEs, e.g. IntelliJ IDEA | ||
.idea/ | ||
*.iml |
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.
.gitignore
is used for project related files maintenance in kubefed
.
I finally agreed this rule after thinking it over. I saw some projects which use .gitignore
file with hundreds of lines code with editor specific ignore. It is hard to read and maintain. You can refer to #871.
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 see the point.
Actually, I copied the entries from the Kubernetes main repository, and probably worth to be inline with it. But this discussion is out of this PR scope.
I removed the entries.
Thanks Roytman! |
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.
Nits aside, this is looking good!
Without #828 there isn't an easy path to testing of the cli just yet, but I would appreciate some common code paths being created (in the vein of the managed label helpers) to leverage the coverage for the sync controller check and crudtester check.
edce614
to
9286659
Compare
@marun , thanks for the review.
I updated the code. |
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.
Thank you for cleanup, nice work! A few more nits inline. The only functional change request is to allow the addition or removal of the annotation for resources that don't pass the weak check for a federated resource.
func (o *orphanResource) GetFederatedResource(resourceClient dynamic.ResourceInterface) (*unstructured.Unstructured, error) { | ||
resource, err := resourceClient.Get(o.resourceName, metav1.GetOptions{}) | ||
if err != nil { | ||
return nil, errors.Wrapf(err, "Error retrieving resource %s %q", o.typeName, |
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.
Would it be possible to use the kind here rather than the type name the user passed in?
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.
Due to separation of GetResourceClient
and GetFederatedResource
, it will be complicated. In the GetFederatedResource
I don't have a reference to resourceClient
only to the dynamic.ResourceInterface
.
In order to use Kind, I have to
- or return
Kind
fromGetResourceClient
and provide it toGetFederatedResource
- or move
targetClient.Resources(o.resourceNamespace)
out ofGetResourceClient
.
Both options look problematic for me. What do you think ?
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 think the first option is a change worth making to ensure the UX consistency.
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 implemented the first option.
For generalizing, GetResourceClient
returns entire *metav1.APIResource
, but it can be easily replace by Kind
only.
However, there is an additional option: the current error message looks like
Error: Error retrieving resource FederatedConfigMap "default/game-config1": federatedconfigmaps.types.kubefed.k8s.io "game-config1" not found
Do we really have to print the resource Kind
or its user provided type? Anyway the dynamic client prints (at list in the most common case) the resource name and group. Maybe we should just return the dynamic client error.
What do you think?
If a resource doesn't pass the weak check for a federated resource, I suggest to print a warning and continue the processing. What do you think ? |
7dda275
to
c8356c3
Compare
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.
👍 to printing a warning if the weak check passes rather than failing.
Thank you for cleanup! Nothing functional remains. Nits inline, and there are still some outstanding requests for change from my previous review that you may have missed (mainly wording of help text).
func (o *orphanResource) GetFederatedResource(resourceClient dynamic.ResourceInterface) (*unstructured.Unstructured, error) { | ||
resource, err := resourceClient.Get(o.resourceName, metav1.GetOptions{}) | ||
if err != nil { | ||
return nil, errors.Wrapf(err, "Error retrieving resource %s %q", o.typeName, |
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 think the first option is a change worth making to ensure the UX consistency.
} | ||
klog.V(2).Infof("API Resource for %s.%s/%s found", apiResource.Name, apiResource.Group, apiResource.Version) | ||
if !util.IsFederatedAPIResource(apiResource.Kind, apiResource.Group) { | ||
fmt.Fprintf(cmdOut, "Warning: looks like the resource %s.%s/%s is not a Federated object\n", |
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.
s/looks like the resource//
s/is not a Federated object/does not appear to be a federated resource/
As to how to compose name and group to avoid a trailing .
for core groups, please use the GroupQualifiedName function.
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 was not aware about the GroupQualifiedName
function, thanks.
I changed the warning message according to your suggestion, however, as I understood the function IsFederatedAPIResource
cannot 100% guarantee that the checked resource is not a Federated resource. Therefore, I'd suggest a weaker statement.
What do you think about might not be a federated resource
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 think does not appear to be
is equivalent to might not be
(i.e. this does not appear to be correct
vs this is not correct
).
On second thought, please go ahead with your proposed change might not be a federated resource
.
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.
Done
Thanks for your reviews and sorry for the missed comments. |
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.
Github isn't letting me reply to your comment about GetFederatedResource
. I agree that the message that resulted from my suggestion is unnecessarily verbose, and I apologize for causing you extra work. How about Failed to retrieve resource: %v
(no need for kind in that case)?
Nice work, thank you! /approve |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: marun, roytman The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Fix for #690