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

docs: generate kubectl plugin docs #422

Merged
merged 4 commits into from
Mar 4, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ debug.test
coverage.out
coverage.html
site/
# generated
docs/generated
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ plugin-linux:
plugin-darwin:
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -v -i -ldflags '${LDFLAGS}' -o ${DIST_DIR}/${PLUGIN_CLI_NAME}-darwin-amd64 ./cmd/kubectl-argo-rollouts

.PHONY: plugin-docs
plugin-docs:
go run ./hack/gen-plugin-docs/main.go

.PHONY: builder-image
builder-image:
docker build -t $(IMAGE_PREFIX)argo-rollouts-ci-builder:$(IMAGE_TAG) --target builder .
Expand Down
1 change: 1 addition & 0 deletions docs/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ If you need to run the mkdocs server, you will need to do the following:

* Follow the instruction guide to install [mkDocs](https://www.mkdocs.org/#installation)
* Install the `material` theme with the [following guide](https://squidfunk.github.io/mkdocs-material/#quick-start)
* Run `make plugin-docs` to generate kubectl plugin documentation

Afterwards, you can run `mkdocs serve` and access your documentation at [http://127.0.0.1:8000/](http://127.0.0.1:8000/)

Expand Down
18 changes: 11 additions & 7 deletions docs/features/analysis.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,9 @@ spec:
- pause: {duration: 600}
```

Note: Previously, the analysis section had a field called "templateName" where a user would specify a single
AnalysisTemplate. This field has be depreciated in lieu of the templates field, and the field will be removed in v0.9.0.
!!! note
Previously, the analysis section had a field called "templateName" where a user would specify a single
`AnalysisTemplate.` This field has be depreciated in lieu of the templates field, and the field will be removed in v0.9.0.

```yaml
apiVersion: argoproj.io/v1alpha1
Expand Down Expand Up @@ -163,8 +164,9 @@ spec:
value: guestbook-svc.default.svc.cluster.local
```

Note: Previously, the analysis section had a field called "templateName" where a user would specify a single
AnalysisTemplate. This field has be depreciated in lieu of the templates field. and the field will be removed in v0.9.0.
!!! note
Previously, the analysis section had a field called "templateName" where a user would specify a single
`AnalysisTemplate`. This field has be depreciated in lieu of the templates field. and the field will be removed in v0.9.0.

In this example, the `AnalysisTemplate` is identical to the background analysis example, but since
no interval is specified, the analysis will perform a single measurement and complete.
Expand Down Expand Up @@ -321,9 +323,11 @@ spec:
))
```

Note: The controller will error when merging the templates if:
* multiple metrics in the templates have the same name
* Two arguments with the same name both have values
!!! note
The controller will error when merging the templates if:

* multiple metrics in the templates have the same name
* Two arguments with the same name both have values

## Failure Conditions

Expand Down
4 changes: 2 additions & 2 deletions docs/features/bluegreen.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ In addition to managing ReplicaSets, the rollout controller will modify a Servic

When there is a change to the `.spec.template` field of a rollout, the controller will create the new ReplicaSet. If the active service is not sending traffic to a ReplicaSet, the controller will immediately start sending traffic to the ReplicaSet. Otherwise, the active service will point at the old ReplicaSet while the ReplicaSet becomes available. Once the new ReplicaSet becomes available, the controller will modify the active service to point at the new ReplicaSet. After waiting some time configured by the `.spec.strategy.blueGreen.scaleDownDelaySeconds`, the controller will scale down the old ReplicaSet.

__Important note__
When the rollout changes the selector on a service, there is a propagation delay before all the nodes update their IP tables to send traffic to the new pods instead of the old. During this delay, traffic will be directed to the old pods if the nodes have not been updated yet. In order to prevent the packets from being sent to a node that killed the old pod, the rollout uses the scaleDownDelaySeconds field to give nodes enough time to broadcast the IP table changes.
!!! important
When the rollout changes the selector on a service, there is a propagation delay before all the nodes update their IP tables to send traffic to the new pods instead of the old. During this delay, traffic will be directed to the old pods if the nodes have not been updated yet. In order to prevent the packets from being sent to a node that killed the old pod, the rollout uses the scaleDownDelaySeconds field to give nodes enough time to broadcast the IP table changes.

## Configurable Features
Here are the optional fields that will change the behavior of BlueGreen deployment:
Expand Down
3 changes: 2 additions & 1 deletion docs/features/canary.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ spec:
Defaults to "25%".
### maxUnavailable
The maximum number of pods that can be unavailable during the update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). This can not be 0 if MaxSurge is 0.
// Defaults to 0

Defaults to 0

### CanaryService
`canaryService` references a Service that will be modified to send traffic to only the canary ReplicaSet. This allows users to only hit the canary ReplicaSet.
Expand Down
3 changes: 2 additions & 1 deletion docs/features/kubectl-plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ Argo Rollouts offers a Kubectl plugin to enrich the experience with Rollouts, Ex
curl -LO https://github.com/argoproj/argo-rollouts/releases/download/v0.6.0/kubectl-argo-rollouts-darwin-amd64
```

Note: For Linux dist, replace `darwin` with `linux`
!!! tip
For Linux dist, replace `darwin` with `linux`

1. Make the kubectl-argo-rollouts binary executable.

Expand Down
3 changes: 2 additions & 1 deletion docs/features/traffic-management/istio.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ spec:

When the above Rollout progresses through its steps, the controller changes Virtual Service's `stable-svc`'s weight to 95 and `canary-svc`'s to 5, wait 5 minutes, and then scales up the canary ReplicaSet to a full replica count. Once it is entirely healthy, the controller changes `stable-svc`'s selector to point at the canary ReplicaSet and switch the weight back to 100 to `stable-svc` and 0 to `canary-svc`.

Note: The Rollout does not make any other assumptions about the fields within the Virtual Service or the Istio mesh. The user could specify additional configurations for the virtual service like URI rewrite rules on the primary route or any other route if desired. The user can also create specific destination rules for each of the services.
!!! note
The Rollout does not make any other assumptions about the fields within the Virtual Service or the Istio mesh. The user could specify additional configurations for the virtual service like URI rewrite rules on the primary route or any other route if desired. The user can also create specific destination rules for each of the services.


## Integrating with GitOps
Expand Down
3 changes: 2 additions & 1 deletion docs/features/traffic-management/nginx.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Nginx

NOTE: This is being implemented for a later version and everything described below is subject to change.
!!! note "Work in Progress"
This is being implemented for a later version and everything described below is subject to change.

The [Nginx Ingress Controller](https://kubernetes.github.io/ingress-nginx/) enables traffic management through one or more Ingress objects to configure an Nginx deployment that routes traffic directly to pods. Each Nginx Ingress contains multiple annotations that modify the behavior of the Nginx Deployment. For traffic management between different versions of an application, the Nginx Ingress controller provides the capability to split traffic by introducing a second Ingress object (referred to as the canary Ingress) with some special annotations. Here are the canary specific annotations:

Expand Down
3 changes: 2 additions & 1 deletion docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ On GKE, you will need grant your account the ability to create new cluster roles
kubectl create clusterrolebinding YOURNAME-cluster-admin-binding --clusterrole=cluster-admin [email protected]
```

Note: The cluster-level installation assumes that Argo Rollouts is deployed into the `argo-rollouts` namespace. If you would like to install Argo Rollouts in another namespace, you will need to modify the `ClusterRoleBinding` resource that binds the ClusterRole to the ServiceAcccount created. The namespace for the ServiceAccount referenced in the ClusterRoleBinding needs to be modified to match your desired namespace.
!!! note
The cluster-level installation assumes that Argo Rollouts is deployed into the `argo-rollouts` namespace. If you would like to install Argo Rollouts in another namespace, you will need to modify the `ClusterRoleBinding` resource that binds the ClusterRole to the ServiceAcccount created. The namespace for the ServiceAccount referenced in the ClusterRoleBinding needs to be modified to match your desired namespace.

### Namespace-Level Installation
```bash
Expand Down
170 changes: 170 additions & 0 deletions hack/gen-plugin-docs/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
package main

import (
"bytes"
"fmt"
"io"
"log"
"os"
"path/filepath"
"sort"
"strings"

"github.com/spf13/cobra"

"github.com/argoproj/argo-rollouts/pkg/kubectl-argo-rollouts/cmd"
options "github.com/argoproj/argo-rollouts/pkg/kubectl-argo-rollouts/options/fake"
)

func main() {
tf, o := options.NewFakeArgoRolloutsOptions()
defer tf.Cleanup()
cmd := cmd.NewCmdArgoRollouts(o)
os.RemoveAll("./docs/generated/kubectl-argo-rollouts")
os.MkdirAll("./docs/generated/kubectl-argo-rollouts/", 0755)
err := GenMarkdownTree(cmd, "./docs/generated/kubectl-argo-rollouts")
if err != nil {
log.Fatal(err)
}
}

// the following is a custom markdown generator based on the default cobra/md_docs.go
// https://github.com/spf13/cobra/blob/master/doc/md_docs.go
func GenMarkdownTree(cmd *cobra.Command, dir string) error {
for _, c := range cmd.Commands() {
if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() {
continue
}
if err := GenMarkdownTree(c, dir); err != nil {
return err
}
}

basename := strings.Replace(cmd.CommandPath(), " ", "_", -1) + ".md"
filename := filepath.Join(dir, basename)
f, err := os.Create(filename)
if err != nil {
return err
}
defer f.Close()

if err := GenMarkdown(cmd, f); err != nil {
return err
}
return nil
}

func GenMarkdown(cmd *cobra.Command, w io.Writer) error {
cmd.InitDefaultHelpCmd()
cmd.InitDefaultHelpFlag()

buf := new(bytes.Buffer)
name := normalizeKubectlCmd(cmd.CommandPath())

short := cmd.Short
long := cmd.Long
if len(long) == 0 {
long = short
}

buf.WriteString("# " + name + "\n\n")
buf.WriteString(short + "\n\n")
buf.WriteString("## Synopsis\n\n")
buf.WriteString(long + "\n\n")

if cmd.Runnable() {
buf.WriteString(fmt.Sprintf("```shell\n%s\n```\n\n", normalizeKubectlCmd(cmd.UseLine())))
}

if len(cmd.Example) > 0 {
buf.WriteString("## Examples\n\n")
buf.WriteString(fmt.Sprintf("```shell\n%s\n```\n\n", trimLeadingSpace(cmd.Example)))
}

if hasAvailableCommands(cmd) {
buf.WriteString("## Available Commands\n\n")
children := cmd.Commands()
sort.Sort(byName(children))

for _, child := range children {
if !child.IsAvailableCommand() || child.IsAdditionalHelpTopicCommand() {
continue
}
cname := cmd.CommandPath() + " " + child.Name()
link := cname + ".md"
link = strings.Replace(link, " ", "_", -1)
buf.WriteString(fmt.Sprintf("* [%s](%s)\t - %s\n", normalizeKubectlCmd(cname), link, child.Short))
}
buf.WriteString("\n")
}

if err := printOptions(buf, cmd); err != nil {
return err
}

if cmd.HasParent() {
buf.WriteString("## See Also\n\n")
if cmd.HasParent() {
parent := cmd.Parent()
pname := parent.CommandPath()
link := pname + ".md"
link = strings.Replace(link, " ", "_", -1)
buf.WriteString(fmt.Sprintf("* [%s](%s)\t - %s\n", normalizeKubectlCmd(pname), link, parent.Short))
cmd.VisitParents(func(c *cobra.Command) {
if c.DisableAutoGenTag {
cmd.DisableAutoGenTag = c.DisableAutoGenTag
}
})
}
}

_, err := buf.WriteTo(w)
return err
}

func printOptions(buf *bytes.Buffer, cmd *cobra.Command) error {
flags := cmd.LocalFlags()
flags.SetOutput(buf)
if flags.HasAvailableFlags() {
buf.WriteString("## Options\n\n```\n")
flags.PrintDefaults()
buf.WriteString("```\n\n")
}

parentFlags := cmd.InheritedFlags()
parentFlags.SetOutput(buf)
if parentFlags.HasAvailableFlags() {
buf.WriteString("## Options inherited from parent commands\n\n```\n")
parentFlags.PrintDefaults()
buf.WriteString("```\n\n")
}
return nil
}

func hasAvailableCommands(cmd *cobra.Command) bool {
for _, c := range cmd.Commands() {
if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() {
continue
}
return true
}
return false
}

func trimLeadingSpace(s string) string {
var newLines []string
for _, line := range strings.Split(s, "\n") {
newLines = append(newLines, strings.TrimSpace(line))
}
return strings.Join(newLines, "\n")
}

func normalizeKubectlCmd(cmd string) string {
return strings.Replace(cmd, "kubectl-argo-rollouts", "kubectl argo rollouts", 1)
}

type byName []*cobra.Command

func (s byName) Len() int { return len(s) }
func (s byName) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s byName) Less(i, j int) bool { return s[i].Name() < s[j].Name() }
4 changes: 3 additions & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,14 @@ nav:
- Overview: features/traffic-management/index.md
- Istio: features/traffic-management/istio.md
- NGINX: features/traffic-management/nginx.md
- Kubectl Plugin: features/kubectl-plugin.md
- HPA Support: features/hpa-support.md
- Kustomize Support: features/kustomize.md
- Controller Metrics: features/controller-metrics.md
- Experiments: features/experiment.md
- Analysis: features/analysis.md
- Kubectl Plugin:
- Overview: features/kubectl-plugin.md
- Commands: generated/kubectl-argo-rollouts/kubectl-argo-rollouts.md
- Contributing: CONTRIBUTING.md
- Releases ⧉: https://github.com/argoproj/argo-rollouts/releases
- Roadmap ⧉: https://github.com/argoproj/argo-rollouts/milestones
Expand Down
2 changes: 1 addition & 1 deletion pkg/kubectl-argo-rollouts/cmd/get/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ type GetOptions struct {
// NewCmdGet returns a new instance of an `rollouts get` command
func NewCmdGet(o *options.ArgoRolloutsOptions) *cobra.Command {
var cmd = &cobra.Command{
Use: "get",
Use: "get <rollout|experiment> RESOURCE",
Short: "Get details about rollouts, experiments",
Example: o.Example(`
# Get a rollout
Expand Down
2 changes: 1 addition & 1 deletion pkg/kubectl-argo-rollouts/cmd/list/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ type ListOptions struct {
// NewCmdList returns a new instance of an `rollouts list` command
func NewCmdList(o *options.ArgoRolloutsOptions) *cobra.Command {
var cmd = &cobra.Command{
Use: "list",
Use: "list <rollout|experiment> RESOURCE",
Short: "List rollouts, experiments",
Example: o.Example(`
# List rollouts
Expand Down