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

[GSoD'20] Update how the Kubernetes website serves API references #23809

Closed
feloy opened this issue Sep 11, 2020 · 17 comments
Closed

[GSoD'20] Update how the Kubernetes website serves API references #23809

feloy opened this issue Sep 11, 2020 · 17 comments
Labels
kind/feature Categorizes issue or PR as related to a new feature. priority/backlog Higher priority than priority/awaiting-more-evidence. triage/accepted Indicates an issue or PR is ready to be actively worked on.

Comments

@feloy
Copy link
Member

feloy commented Sep 11, 2020

This issue helps following my Google Season of Docs project: https://developers.google.com/season-of-docs/docs/participants/project-cncf-feloy and resumes the first discussions in #23294 and this doc.

Introduction

Currently, the Kubernetes API references are large HTML documents generated from Swagger specs by scripts hosted outside the website repository, then added into this website repository.

On another side, the Kubernetes documentation website is built with Hugo from documentation written in Markdown format in the website repository, using the Docsy Hugo theme.

The goal of this project is to integrate the generation of the Kubernetes API references into the process that builds the documentation website.

swaggerui

Specifically, we will focus on the swaggerui shortcode, wrapper around swagger-ui, provided by the Docsy Hugo theme and on specific tooling, enabling the insertion of parts of the API specification in the flow of the Kubernetes documentation.

The actual generation of the API Reference has some drawbacks:

  • a single huge HTML page containing all the API reference
  • its format is not adapted to mobile reading
  • its design is not integrated with the kubernetes.io/docs website
  • its content cannot be referenced by search engines

With this project, we will try to address some of these drawbacks:

  • the single page would be addressed by splitting the API reference into several pages,
  • mobile format and integration to kubernetes.io/docs website would be addressed by using a specific theme with the swaggerui shortcode.

Some drawbacks won't be addressed by the proposed solution:

  • as the swaggerui generates HTML dynamically, the content of these pages won't be indexed by search engines.

Splitting the API Specs

Specific tooling will be needed as swagger-ui is able to output the complete specification described in a swagger file, but not parts of it. The Kubernetes API is too big to be displayed in one part only.

We will use or create a tool that gets as input the complete swagger file of the Kubernetes API found here and that outputs a new swagger file for a specific endpoint or a limited number of endpoints, and its associated resources and definitions, then use these swagger files as input of swaggerui shortcodes at specific places in the Kubernetes documentation website.

Interactivity

There are "Authorize"/"Try it out" features that come default with most Swagger renderings. Kubernetes is usually deployed "on prem", i.e. by and for a specific team, rather than being an API available to anyone with auth access. Maintaining a k8s deployment for people to 'try it out' on could also pose security risks.

We will first disable these features, and consider to make a version distribuable to end-users to install locally and to use interactively on their own cluster.

Classification

The Kubernetes API contains several dozens of Resources and several hundreds of endpoints.

We want to first classify the endpoints grouped by Kubernetes Resources (Pods, Deployments, etc), and also classify the Resources. Two classifications come to mind for the Resources:

  • either by API Group and Version (core/v1, batch/v1, etc)
  • or by following the classification of the concepts section (Container, Workloads, Services, Storage, Configuration, Security, Policies, Scheduling, Cluster, Extending)

In the first case, the whole set of reference pages would be regrouped in a specific section (the reference section itself).

In the second case, the reference pages would be placed at the end of each corresponding sub-section in the concepts section.

Landing Page

We will work on a landing page that points to all the reference pages of the specification. Also, this page will make clear if translations exist for some pages.

Generation

As the sources of the specifications reside in other repositories than the sources of the documentation, we will need to find a way to automatically update them in the documentation repository when they change.

I18n

As the Kubernetes documentation is available in different languages, we will pay special attention to the possibility of publishing translations for the Kubernetes API reference.

kubernetes-resource-reference

It turned out to be difficult to customize the page generated by swagger UI to highlight the Resources of the API instead of the Endpoints, as it is done traditionally. We want to highlight the Resources because users are currently writing K8s manifests based on the Resources, and are not calling HTTP endpoints directly but are essentially using kubectl to call the API.

For this reason, we decided to experiment the integration of the pages generated by the tool https://github.com/feloy/kubernetes-resources-reference that I created lastly to create the website k8sref.io.

Here the list of features implemented by this tool:

  • the resources are categorized, in the categories Workloads, Services, Config&Storage, Authn, Authz, Policies, Extend, Cluster. This is configurable with a simple toc.yaml (https://github.com/feloy/kubernetes-resources-reference/blob/master/config/v1.19/toc.yaml)
  • each page displays at the first level the associated resources, ex Pod, PodSpec, PodStatus, PodList
  • each resource inlines its definitions (breaking the recursion for JSONSchemaProps)
  • some widely used definitions are referenced from another page (ex ObjectMeta)
  • required fields are indicated, and placed first
  • fields of a resource can be categorized and ordered, with the help of a fields.yaml file (https://github.com/feloy/kubernetes-resources-reference/blob/master/config/v1.19/fields.yaml)
  • maps fields are indicated (ex pod.spec.nodeSelector is map[string]string, instead of object) using the value of x-kubernetes-list-type swagger extension
  • patch strategies are indicated
  • apiVersion and kind display the value, not the string type
  • on top of the page, the Go import necessary to use these resources from a Go program is displayed
@sftim
Copy link
Contributor

sftim commented Sep 14, 2020

Great to see this work starting @feloy!

@sftim
Copy link
Contributor

sftim commented Sep 14, 2020

Another site that might be useful for inspiration: https://k8syaml.com/

That's a reference for manifests, not the API.

@sftim

This comment has been minimized.

@feloy
Copy link
Member Author

feloy commented Sep 14, 2020

I have created this generic swagger-filter CLI that is able to filter a swagger definition by endpoints (complete path, prefix or regexp).

As an example, a script using this CLI filters the complete Kubernetes API definition to output new swagger definitions for each K8s API Group:

https://github.com/feloy/swagger-filter

I would like to be able to include the files generated by this CLI into the kubernetes/website repository, so we can reference these files from swagger-ui shortcodes. What would be the best process to use such a CLI?

One solution I can imagine is to create a public external service (hosted in a Cloud Run container for example) based on this code, that could be queried from a script in the script/ directory.

@kbhawkey
Copy link
Contributor

Thanks @feloy for opening this issue. I will review the swagger-filter code.

@kbhawkey
Copy link
Contributor

Hi @feloy . I quickly looked at the filter code. Will review in detail. Some initial questions:

  • Could you use the apiserver to create the individual files (add new flags)?
  • Instead of a using a static list of API groups could you parse the OpenAPI spec to derive this list?

@feloy
Copy link
Member Author

feloy commented Sep 18, 2020

Hi @kbhawkey,

Hi @feloy . I quickly looked at the filter code. Will review in detail. Some initial questions:

  • Could you use the apiserver to create the individual files (add new flags)?

I will need to dive into the API server code before to reply, but I can imagine it could be possible, in a similar way it is possible to start the API server with specific groups only, with the --runtime-config flag.

  • Instead of a using a static list of API groups could you parse the OpenAPI spec to derive this list?

You are right, the x-kubernetes-group-version-kind swagger extension is added to Operations and Definitions on the swagger spec, to materialize the corresponding Kubernetes Actions and Kubernetes Resources. Thanks to these extensions, we can extract the operations belonging to specific GVKs. (more on x-kubernetes-* extensions)

I wanted to make a generic filter, reusable for any OpenAPI spec, not coupled to the Kubernetes API spec. If we use such a method, it will become a dedicated tool for the API spec.

@kbhawkey
Copy link
Contributor

Hi @kbhawkey,

Hi @feloy . I quickly looked at the filter code. Will review in detail. Some initial questions:

  • Could you use the apiserver to create the individual files (add new flags)?

I will need to dive into the API server code before to reply, but I can imagine it could be possible, in a similar way it is possible to start the API server with specific groups only, with the --runtime-config flag.

  • Instead of a using a static list of API groups could you parse the OpenAPI spec to derive this list?

You are right, the x-kubernetes-group-version-kind swagger extension is added to Operations and Definitions on the swagger spec, to materialize the corresponding Kubernetes Actions and Kubernetes Resources. Thanks to these extensions, we can extract the operations belonging to specific GVKs. (more on x-kubernetes-* extensions)

OK. I'd avoid manually creating and maintaining a list of API groups.

I wanted to make a generic filter, reusable for any OpenAPI spec, not coupled to the Kubernetes API spec. If we use such a method, it will become a dedicated tool for the API spec.

OK. Seems reasonable. You have created a new command line tool based off the spf13/cobra code to parse the complete spec and generate individual or groups of openAPI files (or snippets?).

@sftim
Copy link
Contributor

sftim commented Oct 8, 2020

@feloy, how do you think the Swagger approach is working out?
Looking at issue #23889, that made me wonder what kind of API documentation readers would most value? I'm sure you will have some thoughts on this.

For example: details of everything that can go in YAML manifests vs. the JSON or protobuf on-the-wire representation vs. Golang source code.

@feloy
Copy link
Member Author

feloy commented Oct 10, 2020

@feloy, how do you think the Swagger approach is working out?
Looking at issue #23889, that made me wonder what kind of API documentation readers would most value? I'm sure you will have some thoughts on this.

For example: details of everything that can go in YAML manifests vs. the JSON or protobuf on-the-wire representation vs. Golang source code.

@sftim I think the documentation reader first needs an help to write YAMLs manifests for the moment. In a more or less near future, when the writing of Operators and Cloud Native apps is democratized, an help for writing the Go structures rpresenting the K8s resources would be helpful.

I'm not very satisfied with the actual presentation of the swagger-ui documentation for the following reasons:

  • the endpoints are the most visible, but this information is not relevant for most users, as they are not calling the APIs endpoints themselves, but are using kubectl, client-go or other library to make the calls.

  • The relevant information for the reader is the structure of the Resource they want to work with (Deployment, Service, etc). This specific Resource is not easy to find in this list of all Definitions displayed on the page.

  • swagger-ui is building the page dynamically, into the browser, each time a user is opening a swagger page. I think it is a waste of time (and energy) to build this page every time, as the data to display does not change between users, or over the time (between 2 releases). I think it would be more efficient to build the page in the Markdown format and let Hugo build the HTML page once and for all at release time.

@sftim
Copy link
Contributor

sftim commented Oct 10, 2020

I'm not very satisfied with the actual presentation of the swagger-ui documentation

Building the page as Markdown sounds more viable. Are you thinking of proposing a change to https://github.com/kubernetes-sigs/reference-docs ?

@feloy
Copy link
Member Author

feloy commented Oct 10, 2020

I'm not very satisfied with the actual presentation of the swagger-ui documentation

Building the page as Markdown sounds more viable. Are you thinking of proposing a change to https://github.com/kubernetes-sigs/reference-docs ?

Yes, as this generator uses an interface for the writer, it would be interesting to try and implement a writer for Markdown pages

@feloy
Copy link
Member Author

feloy commented Oct 11, 2020

More on Markdown output at kubernetes-sigs/reference-docs#173

@sftim
Copy link
Contributor

sftim commented Nov 19, 2020

/kind feature
/triage accepted
/priority backlog
(but it's a very valuable backlog item!)

@k8s-ci-robot k8s-ci-robot added kind/feature Categorizes issue or PR as related to a new feature. triage/accepted Indicates an issue or PR is ready to be actively worked on. priority/backlog Higher priority than priority/awaiting-more-evidence. labels Nov 19, 2020
@sftim
Copy link
Contributor

sftim commented Dec 8, 2020

I've logged #25505 specifically to track the work to do with migrating from the existing generator (and the pages in generates) to the new one.

@sftim
Copy link
Contributor

sftim commented Dec 8, 2020

@feloy are you happy to close this issue?

@sftim
Copy link
Contributor

sftim commented Jan 20, 2021

/close

Remaining work is in #25505

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/feature Categorizes issue or PR as related to a new feature. priority/backlog Higher priority than priority/awaiting-more-evidence. triage/accepted Indicates an issue or PR is ready to be actively worked on.
Projects
None yet
Development

No branches or pull requests

4 participants