-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Conversation
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.
@gitolicious Nice feature! I think the tests will need some tlc.
a83fe75
to
50bfc9f
Compare
Thanks. Tests fixed and rebase done. |
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.
@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?
50bfc9f
to
c7e47d7
Compare
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. |
I didn't fully understand that part. Could you explain your idea a bit more? Would the DAOs themselves (e.g. |
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.
@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/dao/registry.go
Outdated
@@ -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) { |
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.
An alternative would be to simply concatenate and hope for the best...
apiVersion + "/" + strings.ToLower(kind) + "s"
Too risky?
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.
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.
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.
Is this what you imagined?
Lines 131 to 143 in 0edc12f
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}, | |
}, | |
} |
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 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 {}
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 got pretty close to your suggestion. The map is gone now thanks to the RestMapper
.
719a336
to
531d1ac
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.
@gitolicious Very cool! Thank you for these updates!!
A few items up for tlc.
internal/dao/registry.go
Outdated
@@ -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) { |
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.
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/rs.go
Outdated
if err != nil { | ||
return nil, err | ||
} | ||
|
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 don't need to have the full hydrated instance to retrieve controllers ie o.GetOwnerReferences()
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.
How would I only get the OwnerReferences? I haven't found existing code to only get specific attributes of a 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.
u, ok := o.(*unstructured.Unstructured)
u.GetOwnerReferences()
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 the golden tip for me to finally make the function generic. So I moved GetOwners
to generic.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.
@derailed, what do you think about the current implementation? I would be really happy if we could get this feature added to k9s.
return nil | ||
} | ||
|
||
return o.showSelectOwnerDialog(owners) |
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 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?
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 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.
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 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.
The code got much cleaner now thanks to your suggestions and after me getting a better grasp on the structure of the code. |
7d4e699
to
fb857e8
Compare
fb857e8
to
21369c0
Compare
@derailed, still waiting for your feedback on this. I have rebased the branch after the |
docs: add description style: cleanup and error fmt
21369c0
to
e54c75b
Compare
Superseded by the merge of #2700. |
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.