kubernetes / kubectl

Issue tracker and mirror of kubectl code
Apache License 2.0
2.75k stars 896 forks source link

Add parameter to kubectl explain for searching field descriptions #1557

Open isaacnboyd opened 5 months ago

isaacnboyd commented 5 months ago

What would you like to be added:

I would like kubectl explain to be able to function like find so that I can quickly search for a field that has certain description text.

Why is this needed:

I love kubectl explain. I use it often. I like to use it as a tool to quickly find if a CRD supports certain functionality. For example: I might want to quickly determine if a new operator supports custom TLS options. This often involves a process like:

kubectl explain {{CRD}}
kubectl explain {{CRD}}.spec | grep tls
kubectl explain {{CRD}}.spec.networking | grep tls
etc, etc

Depending on the size and formatting of the CRD this can be a long process.

I think it would be really helpful if I could use kubectl explain like kubectl explain {{CRD}} --find "tls" and the tool would find the fields with "tls" in the description and return explain output for each field. For example if kubectl explain {{CRD}} --find "tls" discovered reference in {{CRD}}.spec.tls then it would return output from kubectl explain {{CRD}}.spec.tls

kubectl explain {{CRD}} --recursive does not satisfy this requirement as it only lists field names and data type.

I am curious if there is any appetite for a feature like this to be added to kubectl.

apelisse commented 4 months ago

That seems like a very specific use-case, and I could see a verbose recursive version would possibly make more sense IMO, since you would be able to grep tls in the whole list and then find what you need?

ah8ad3 commented 4 months ago

I think we can discuss about adding an recursive verbose nested level (to define how many level of description should it print nested), so for example: Lets say we have an flag named nested with default value of 0 that act as what it is right now. If we increase this number we can get nested information from inside of the each field with full detail like this: with level 1:

GROUP:      apps
KIND:       Deployment
VERSION:    v1

DESCRIPTION:
    Deployment enables declarative updates for Pods and ReplicaSets.

FIELDS:
  apiVersion    <string>
    APIVersion defines the versioned schema of this representation of an object.
    Servers should convert recognized schemas to the latest internal value, and
    may reject unrecognized values. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources

  kind  <string>
    Kind is a string value representing the REST resource this object
    represents. Servers may infer this from the endpoint the client submits
    requests to. Cannot be updated. In CamelCase. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

  metadata  <ObjectMeta>
    Standard object's metadata. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
    FIELDS:
      annotations   <map[string]string>
        Annotations is an unstructured key value map stored with a resource that may
        be set by external tools to store and retrieve arbitrary metadata. They are
        not queryable and should be preserved when modifying objects. More info:
        https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations

And by increasing the level this nested behavior continues until there is nothing more to show. Also we can define a number like -1 that act as print all nested ones.

IDK maybe this seems like a lot of work, but it's just an idea we can discuss about it.

apelisse commented 4 months ago

I don't think that's so much work. Can we come-up with a better way to observe the level of nesting? Some ascii-art to show the structure? Maybe colors?

ah8ad3 commented 4 months ago

Sure let me check it out a little bit, i'll share my findings here soon

ah8ad3 commented 4 months ago

I think intent is the best way to show this kind of document, we can discuss about adding colors but personally i am not fan of colors in terminal, rather read it in black and white(seems easier for me but IDK), so i cleaned up the example i showed earlier and this is the result.

Lets say we have a flag named verbose-nested

for verbose-nested=0 or undefined act as what it is right now:

KIND:       Pod
VERSION:    v1

DESCRIPTION:
    Description 

FIELDS:
  field_name    <field_type>
    Description of this field

  field_name    <field_type>
    Description of this field

for verbose-nested=1 we add one level of details :

KIND:       Pod
VERSION:    v1

DESCRIPTION:
    Description 

FIELDS:
  field_name    <field_type>
    Description of this field

    FIELDS:
      field_name    <field_type>
        Description of this field

      field_name    <field_type>
        Description of this field

  field_name    <field_type>
    Description of this field

for verbose-nested=2 we add another level of details :

KIND:       Pod
VERSION:    v1

DESCRIPTION:
    Description 

FIELDS:
  field_name    <field_type>
    Description of this field

    FIELDS:
      field_name    <field_type>
        Description of this field

      field_name    <field_type>
        Description of this field

        FIELDS:
          field_name    <field_type>
        Description of this field

          field_name    <field_type>
        Description of this field

  field_name    <field_type>
    Description of this field

and for verbose-nested=-1 or something else we can do this until we show all the detail of this resource. The main difference with --recursive label is that we have more detail and we add \n for better readability but also we can change those too. I'm very open to suggestions to make it better and also willing to help implement this.

apelisse commented 4 months ago

I generally agree that colors are pointless, but I was more thinking of something similar to git log --graph. I would try something like this, in which case I think making each line in a different color would have a lot of value:

KIND:       Pod
VERSION:    v1

DESCRIPTION:
    Description 

FIELDS:
* field_name    <field_type>
|   Description of this field
|
|   FIELDS:
|   * field_name    <field_type>
|   |   Description of this field
|   |
|   * field_name    <field_type>
|   |   Description of this field
|   |
|   |   FIELDS:
|   |   * field_name    <field_type>
|   |   |   Description of this field
|   |   |   
|   |   * field_name    <field_type>
|   |   |   Description of this field
|  
* field_name    <field_type>
|   Description of this field
ah8ad3 commented 4 months ago

Its for sure interesting but i'm not sure which visual is easier to read for end user, if you agree we can discuss this at regular meeting and ask about other ones opinion as well, for example maybe using little dashes - to style it like yaml file can be interesting too. Maybe we can something like tree too. At least we are on same page to print FIELDS like this.

apelisse commented 4 months ago

My problem is that counting the spaces in a terminal is really confusing/hard, especially once we get much deeper inside the recursion.

ah8ad3 commented 4 months ago

Oh i see, i didn't pay attention to that. the art you mentioned before is very nice, even user can see the level with |. For example it can easily understandable that | | | Description of this field has 3 level of "nesting".

mpuckett159 commented 3 months ago

/triage accepted @ah8ad3 if want to take this that would be appreciated but if not we can leave this accepted and someone else can pick it up. This may be a bit of a complicated implementation, though.

ah8ad3 commented 3 months ago

Thanks @mpuckett159, i'll take it but i am not sure about implementation, yesterday unfortunately i wasn't available to the meeting, i wanted to ask about your'e opinion about implementation of what @apelisse suggest. I'll assign myself and start working on it. /assign

ah8ad3 commented 3 months ago

It's almost implemented, i have a questions about it. We already have a recursive flag that prints only key value of fields without descriptions (kubectl explain pod --recursive=true) . What name do you suggest for the flag to print all the details(description) for recursive flag? @apelisse @mpuckett159

And also the final view is something like this:

*  secretRef    <LocalObjectReference>
|  |  secretRef is name of the authentication secret for RBDUser. If provided overrides keyring. Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
|  |  
|  *  name      <string>
|  |  |  Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|  |  |  
*  user <string>
|  |  user is the rados user name. Default is admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it
|  |