Skip to content
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

Show owner of pod, rs (#1747) #2133

Closed
wants to merge 17 commits into from

Conversation

gitolicious
Copy link
Contributor

I reused the code from #1564 and used it for navigating "upstream" from pods to replica sets and daemon sets as well as from replica sets to deployments.

This fixes parts of what was discussed in #1747 though I didn't find a generic way that would work for all kinds of resources. Also it is a step-wise approach, not going all the way to the controller. If that is preferred, at least for pods it would be easy to directly jump to the deployment. But quickly hitting o twice also gets you there.

Copy link
Owner

@derailed derailed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gitolicious Nice feature! I think the tests will need some tlc.

@derailed derailed added enhancement New feature or request needs-tlc Pr needs additional updates labels Nov 12, 2023
@gitolicious gitolicious force-pushed the 1747-show-owner branch 2 times, most recently from a83fe75 to 50bfc9f Compare November 12, 2023 18:39
@gitolicious
Copy link
Contributor Author

Thanks. Tests fixed and rebase done.

@gitolicious gitolicious requested a review from derailed November 12, 2023 18:41
Copy link
Owner

@derailed derailed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gitolicious Thank you for the updates!!

I think this is actually a bit more involved ;(

What if there are more than one controllers?

Also we would need to offer a similar feature for other controllers ie job, cronjob, ds, ... so that behavior is universal on pods no matter what the owing controller is.

I think the best approach here would be to define a view extender to dry up this code and inject the owner action aka OwnerExtender (see ***_ext.go in the view pkg).
On the dao side implement an Owner interface that would return a collection of gvr/fqn tuples for the owning controllers.
Would this make sense?

@gitolicious
Copy link
Contributor Author

Thanks for the feedback. I migrated the logic to a view extender. Handling multiple owners and the gvr/fqn tuples are still missing. Will work on that in the next days probably.
If you find the time, you can let me know if I am on the right track.

@gitolicious
Copy link
Contributor Author

On the dao side implement an Owner interface that would return a collection of gvr/fqn tuples for the owning controllers.

I didn't fully understand that part. Could you explain your idea a bit more? Would the DAOs themselves (e.g. dao/pod.go) provide their owners? Would it actually be simpler than what I have implemented at the moment, or would it result in more redundant code?

Copy link
Owner

@derailed derailed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gitolicious Thank you for the updates. I think this can be greatly simplified if we delegate the owners behavior to the daos. Please take a look at scale or image extenders for examples. I think if we define an Owned interface on the dao with something like GetOwners() map[client.GVR][]string where the value slice in a collection of fqn ie ns/name. This should be enough to power the extender needs.

Would this make sense?

internal/view/owner_extender.go Outdated Show resolved Hide resolved
internal/view/owner_extender.go Outdated Show resolved Hide resolved
internal/view/owner_extender.go Outdated Show resolved Hide resolved
internal/view/owner_extender.go Outdated Show resolved Hide resolved
internal/view/owner_extender.go Outdated Show resolved Hide resolved
@@ -117,6 +118,77 @@ func AccessorFor(f Factory, gvr client.GVR) (Accessor, error) {
return r, nil
}

func GVRForKind(apiVersion string, kind string) (string, bool, error) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An alternative would be to simply concatenate and hope for the best...

apiVersion + "/" + strings.ToLower(kind) + "s"

Too risky?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed! I think there are only a handful of qualified controllers. I think we could just simply have a map kind->resource. Might be easier to maintain in the future should these go thru an api rev.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this what you imagined?

var gvrs = map[string]map[string]gvrInfo{
"apps/v1": {
"ReplicaSet": {client.NewGVR("apps/v1/replicasets"), true},
"DaemonSet": {client.NewGVR("apps/v1/daemonsets"), true},
"StatefulSet": {client.NewGVR("apps/v1/statefulsets"), true},
"Deployment": {client.NewGVR("apps/v1/deployments"), true},
"Jobs": {client.NewGVR("apps/v1/jobs"), true},
"CronJobs": {client.NewGVR("apps/v1/cronjobs"), true},
},
"v1": {
"Node": {client.NewGVR("v1/nodes"), false},
},
}

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the best way to handle getting to gvr/fqn in the helper is as follows:

mapper := RestMapper{Connection: c}
m, err := mapper.ToRESTMapper()
rm, err := m.RESTMapping(schema.GroupKind{Group: g, Kind: k}, v)
gvr := client.NewGVR(rm.Resource.String())
meta, err := MetaAccess.MetaFor(gvr)
if meta.Namespaced {} else {}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got pretty close to your suggestion. The map is gone now thanks to the RestMapper.

Copy link
Owner

@derailed derailed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gitolicious Very cool! Thank you for these updates!!
A few items up for tlc.

@@ -117,6 +118,77 @@ func AccessorFor(f Factory, gvr client.GVR) (Accessor, error) {
return r, nil
}

func GVRForKind(apiVersion string, kind string) (string, bool, error) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed! I think there are only a handful of qualified controllers. I think we could just simply have a map kind->resource. Might be easier to maintain in the future should these go thru an api rev.

internal/dao/registry.go Outdated Show resolved Hide resolved
internal/dao/registry.go Outdated Show resolved Hide resolved
internal/dao/rs.go Outdated Show resolved Hide resolved
internal/dao/registry.go Outdated Show resolved Hide resolved
if err != nil {
return nil, err
}

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to have the full hydrated instance to retrieve controllers ie o.GetOwnerReferences()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How would I only get the OwnerReferences? I haven't found existing code to only get specific attributes of a resource.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

u, ok  := o.(*unstructured.Unstructured)
u.GetOwnerReferences()

Copy link
Contributor Author

@gitolicious gitolicious Jan 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was the golden tip for me to finally make the function generic. So I moved GetOwners to generic.go.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@derailed, what do you think about the current implementation? I would be really happy if we could get this feature added to k9s.

internal/dao/types.go Outdated Show resolved Hide resolved
internal/dao/types.go Outdated Show resolved Hide resolved
internal/view/owner_extender.go Outdated Show resolved Hide resolved
return nil
}

return o.showSelectOwnerDialog(owners)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if there are multiple controllers then we should use the same mechanic we currently use for sec/cm aka 'Used By` and show a new view vs a picker to list out controllers fqn/gvr (please see view.reference.go)
The picker is fine but think it might be more consistent.
What do you think?

Copy link
Contributor Author

@gitolicious gitolicious Jan 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't too sure about the picker myself. Its UX is a bit cumbersome for this purpose. But, let's be honest, a resource with multiple owners is rarely seen in the wild. The picker was easy to implement so I went with it. Will look into the view as an alternative if you think it would be required.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes you are correct! Most instances will be a straight nav. Extending reference view/model, I think is more elegant and could provide more info/actions.
Given one of the aspect of owner refs is gc, possible this will be more prevalent in crd land.

@gitolicious
Copy link
Contributor Author

The code got much cleaner now thanks to your suggestions and after me getting a better grasp on the structure of the code.

@gitolicious
Copy link
Contributor Author

@derailed, still waiting for your feedback on this. I have rebased the branch after the O hotkey got snagged in the meantime.

@gitolicious
Copy link
Contributor Author

Superseded by the merge of #2700.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request needs-tlc Pr needs additional updates
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants