Giter Club home page Giter Club logo

helm-docs's People

Contributors

armsnyder avatar artus-lhind avatar bmcustodio avatar ccremer avatar chenrui333 avatar dependabot[bot] avatar dirtycajunrice avatar ebuildy avatar edmondop avatar goostleek avatar haepaxlog avatar j-buczak avatar jlec avatar jsoref avatar lhriley avatar lucacome avatar lucernae avatar matheusfm avatar maxwinterstein avatar nepo26 avatar norwoodj avatar nvtkaszpir avatar rbren avatar retgal avatar rottj006 avatar sagikazarmark avatar sblundy avatar sc250024 avatar skang0601 avatar terricain avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

helm-docs's Issues

README.md templating

First off, let me say this is an awesome project! This saves so much time, so thank you for doing it!

  • I'm submitting a ...

    • bug report
    • feature request
    • support request => Please do not submit support request here, see note at the top of this template.
  • Do you want to request a feature or report a bug?

This is a feature request to have the CLI read from a README.md.tpl. The idea is that the user can then write some custom text for their README.md file, while also keeping the nice autogenerated Helm name, description, and variables.

It would be nice if the CLI could read from a file README.md.tpl, which is defined by the user, specified in a command line flag. That way, something like the following could be done:

README.md.tpl

{{ block "chart_name" }}

{{ block "chart_description" }}

# My custom section 1
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non semper purus, et aliquet mauris. Quisque ligula metus, semper maximus faucibus eu, venenatis et augue. Aenean eget dapibus mi. Mauris sed nibh sit amet nibh scelerisque convallis vitae et nisl. Aliquam vulputate dolor et vehicula venenatis. Sed quis nisi a massa venenatis aliquet. Maecenas sit amet lorem ipsum. Proin iaculis justo et dolor viverra, eu consequat ex pellentesque. Etiam rhoncus, nisl nec egestas pretium, massa magna tristique metus, eu euismod erat lacus non nisi. Donec quis rhoncus sapien. Praesent at venenatis tellus. Integer cursus nec massa quis scelerisque. Nam luctus urna vitae gravida viverra. Nunc mi turpis, tincidunt id condimentum sed, egestas et magna. Nam id gravida est. Integer ultricies dapibus quam nec commodo.

## My custom subsection

Praesent at venenatis tellus. Integer cursus nec massa quis scelerisque. Nam luctus urna vitae gravida viverra. Nunc mi turpis, tincidunt id condimentum sed, egestas et magna. Nam id gravida est. Integer ultricies dapibus quam nec commodo.

> ```yaml
> some:
>   important:
>     example:
>       foo: bar
> ```

{{ block "chart_variables" }}

The helm-docs CLI would then populate the chart_name, chart_description, and chart_variables configuration blocks from chart specifications. The custom text in the middle (or wherever the user chooses) will be kept, resulting in a more complete README.md file for Helm charts.

The command might be helm-docs --template README.me.tpl, and the template file would follow the Golang specification.

  • What is the current behavior?

Currently, the README.md file is written from the helm-docs command reading only the Chart.yaml file.

Feature: allow for custom name of generated files

Hey!
Would it be possible to include a flag to specify a new name for the generated markdown files ? :) I didn't find a way to change the names to something other than "README.md", and some other readme's of the project I'm using this tool for are getting overwritten...
Thanks!

panic when defining a type with empty description

When specifying a type but leaving description empty, like this:

controller:
  # -- (int)
  replicas:

helm-docs panics:

time="2021-07-30T19:02:11Z" level=info msg="Generating README Documentation for chart /helm-docs"
panic: runtime error: slice bounds out of range [6:5]

goroutine 18 [running]:
github.com/norwoodj/helm-docs/pkg/document.parseNilValueType(0xc0002fd000, 0x39, 0xc0001bd9f5, 0x5, 0x0, 0x0, 0xc0001bd9f5, 0x5, 0x0, 0x0, ...)
        /home/runner/work/helm-docs/helm-docs/pkg/document/values.go:87 +0x257
github.com/norwoodj/helm-docs/pkg/document.createValueRow(0xc0002fd000, 0x39, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0001bd9f5, 0x5, ...)
        /home/runner/work/helm-docs/helm-docs/pkg/document/values.go:154 +0x4a9
github.com/norwoodj/helm-docs/pkg/document.createValueRowsFromField(0xc0002fd000, 0x39, 0xc000214aa0, 0xc000214b40, 0xc00016bd40, 0x1, 0xc0003076c0, 0x1, 0x1, 0x0, ...)
        /home/runner/work/helm-docs/helm-docs/pkg/document/values.go:317 +0x914
github.com/norwoodj/helm-docs/pkg/document.createValueRowsFromObject(0xc0002dcf20, 0x17, 0xc000214460, 0xc000214500, 0xc00016bd40, 0x1, 0xc0003072d0, 0x1, 0x1, 0x0, ...)
        /home/runner/work/helm-docs/helm-docs/pkg/document/values.go:282 +0x6f0
github.com/norwoodj/helm-docs/pkg/document.createValueRowsFromField(0xc0002dcf20, 0x17, 0xc000214460, 0xc000214500, 0xc00016bd40, 0x1, 0xc0003072d0, 0x1, 0x1, 0x0, ...)
        /home/runner/work/helm-docs/helm-docs/pkg/document/values.go:303 +0x152
github.com/norwoodj/helm-docs/pkg/document.createValueRowsFromObject(0xc00029d310, 0xb, 0xc000211e00, 0xc000211ea0, 0xc00016bd40, 0x1, 0xc000304000, 0x3d, 0x49, 0x0, ...)
        /home/runner/work/helm-docs/helm-docs/pkg/document/values.go:282 +0x6f0
github.com/norwoodj/helm-docs/pkg/document.createValueRowsFromField(0xc00029d310, 0xb, 0xc000211e00, 0xc000211ea0, 0xc00016bd40, 0x1, 0x52, 0xaa, 0x49, 0x0, ...)
        /home/runner/work/helm-docs/helm-docs/pkg/document/values.go:303 +0x152
github.com/norwoodj/helm-docs/pkg/document.createValueRowsFromObject(0x0, 0x0, 0x0, 0xc0001cb720, 0xc00016bd40, 0x1, 0x69a605, 0xc0002ca800, 0x203000, 0x40d630, ...)
        /home/runner/work/helm-docs/helm-docs/pkg/document/values.go:282 +0x6f0
github.com/norwoodj/helm-docs/pkg/document.createValueRowsFromField(0x0, 0x0, 0x0, 0xc0001cb720, 0xc00016bd40, 0x1, 0xc0001c52b0, 0xc0001213e8, 0x69812f, 0xc0001213f8, ...)
        /home/runner/work/helm-docs/helm-docs/pkg/document/values.go:303 +0x152
github.com/norwoodj/helm-docs/pkg/document.getSortedValuesTableRows(0xc0001cb720, 0xc00016bd40, 0x6ff22eecfa3e7f8b, 0x6f0000c00016ea00, 0x6f00000000000030, 0x1, 0x6ff22eecfa3e7f8b)
        /home/runner/work/helm-docs/helm-docs/pkg/document/model.go:32 +0x65
github.com/norwoodj/helm-docs/pkg/document.getChartTemplateData(0xc0000b7f08, 0x2, 0xc0000b7f5a, 0x6, 0xc0000b7fb0, 0x9, 0xc0001bc004, 0x6, 0x0, 0xc000114d20, ...)
        /home/runner/work/helm-docs/helm-docs/pkg/document/model.go:85 +0xcb
github.com/norwoodj/helm-docs/pkg/document.PrintDocumentation(0xc0000b7f08, 0x2, 0xc0000b7f5a, 0x6, 0xc0000b7fb0, 0x9, 0xc0001bc004, 0x6, 0x0, 0xc000114d20, ...)
        /home/runner/work/helm-docs/helm-docs/pkg/document/generate.go:44 +0x2bc
main.retrieveInfoAndPrintDocumentation(0x889ba5, 0x1, 0xc0000b79c0, 0xa, 0xc0000978d0, 0x1, 0x1, 0xc0000b7ed0, 0x6010100)
        /home/runner/work/helm-docs/helm-docs/cmd/helm-docs/main.go:26 +0x2d5
created by main.helmDocs
        /home/runner/work/helm-docs/helm-docs/cmd/helm-docs/main.go:69 +0x4f1

[Enhancement] Replicate Helm functionality allowing access to .Files

For complex Helm charts where additional resource files and manifest templates are split into multiple files and directories, it can be useful to allow programatic enumeration of the files within the chart to help generate documentation.

For example I have a large chart that splits up many micro-service components into ./templates/components/COMPONENT.yaml.

This is useful for splitting discrete tables of .Values documentation out per component. At the moment I have to create a list with all the component names in manually so that it can be looped around.

Adding a .Files interface in the same way that Helm does would be very helpful. Specifically being able to use .Files.Glob would be fantastic.

https://helm.sh/docs/chart_template_guide/accessing_files/

I have included an example of the specific use-case. Just imagine it with dozens more components instead of 5. :-)

{{- $dependencies := list "dep1" "dep2" "dep3" "dep4" "dep4" }}

{{- $components := list }}
{{- $components := append $components "component1" }}
{{- $components := append $components "component2" }}
{{- $components := append $components "component3" }}
{{- $components := append $components "component4" }}
{{- $components := append $components "component5" }}

{{- $componentDefaults := list "replicaCount" }}
{{- $componentDefaults := append $componentDefaults "replicaCount" }}
{{- $componentDefaults := append $componentDefaults "image" }}
{{- $componentDefaults := append $componentDefaults "imagePullSecrets" }}
{{- $componentDefaults := append $componentDefaults "serviceAccount" }}
{{- $componentDefaults := append $componentDefaults "podAnnotations" }}
{{- $componentDefaults := append $componentDefaults "podSecurityContext" }}
{{- $componentDefaults := append $componentDefaults "securityContext" }}
{{- $componentDefaults := append $componentDefaults "ingress" }}
{{- $componentDefaults := append $componentDefaults "resources" }}
{{- $componentDefaults := append $componentDefaults "autoscaling" }}
{{- $componentDefaults := append $componentDefaults "nodeSelector" }}
{{- $componentDefaults := append $componentDefaults "tolerations" }}
{{- $componentDefaults := append $componentDefaults "affinity" }}



## Global Values

| Key | Type | Default | Description |
|-----|------|---------|-------------|
{{- range .Values }}
{{- if has ((splitList "." .Key) | first) $dependencies | not }}
{{- if has ((splitList "." .Key) | first) $componentDefaults | not }}
{{- if has ((splitList "." .Key) | first) $components | not }}
| {{ .Key }} | {{ .Type }} | {{ if .Default }}{{ .Default }}{{ else }}{{ .AutoDefault }}{{ end }} | {{ if .Description }}{{ .Description }}{{ else }}{{ .AutoDescription }}{{ end }} |
{{- end }}
{{- end }}
{{- end }}
{{- end }}


## Default Values

| Key | Type | Default | Description |
|-----|------|---------|-------------|
{{- range .Values }}
{{- if has ((splitList "." .Key) | first) $componentDefaults }}
| {{ .Key }} | {{ .Type }} | {{ if .Default }}{{ .Default }}{{ else }}{{ .AutoDefault }}{{ end }} | {{ if .Description }}{{ .Description }}{{ else }}{{ .AutoDescription }}{{ end }} |
{{- end }}
{{- end }}


## Component Values

| Key | Type | Default | Description |
|-----|------|---------|-------------|
{{- range .Values }}
{{- $firstPart := (splitList "." .Key) | first }}
{{- $secondPart := (splitList "." .Key) | rest | first }}
{{- if has $firstPart $components }}
{{- if has $secondPart $componentDefaults | not }}
{{- if has ((splitList "." .Key) | first) $componentDefaults | not }}
| {{ .Key }} | {{ .Type }} | {{ if .Default }}{{ .Default }}{{ else }}{{ .AutoDefault }}{{ end }} | {{ if .Description }}{{ .Description }}{{ else }}{{ .AutoDescription }}{{ end }} |
{{- end }}
{{- end }}
{{- end }}
{{- end }}


## Sub-chart Dependency Values

| Key | Type | Default | Description |
|-----|------|---------|-------------|
{{- range .Values }}
{{- if has ((splitList "." .Key) | first) $dependencies }}
| {{ .Key }} | {{ .Type }} | {{ if .Default }}{{ .Default }}{{ else }}{{ .AutoDefault }}{{ end }} | {{ if .Description }}{{ .Description }}{{ else }}{{ .AutoDescription }}{{ end }} |
{{- end }}
{{- end }}

Merge into existing README.md

Thanks for this great tool!
It would be awesome if it could merge it's content into an existing README w/o overwriting the contents - a bit similar to how terraform-docs works - by placing a placeholder in the original README:

<!--- BEGIN_TF_DOCS --->

it replaces the block with its generated contents.

Recursive documentation in one README file

Dear maintainers,

Firstly, this is a great tool for producing the documentation. In my case, i have a helm chart with lot of dependencies packed in a tar.gz file. Is it possible to generate one README file with the values from all the dependent charts instead of the README recursively generated in all the sub-chart directories.

Templates not defined error with complicated README

Description

The title of the issue is admittedly a bit weird, but I'm not sure what else is going on with the underlying README.md.gotmpl file I am using.

Long story short, I am helping to move the cluster-autoscaler Helm chart from the helm/charts repository to the kubernetes/autoscaler repository because of the eventual deprecation of the stable channel.

I am hoping to make the new README enabled with helm-docs, but I noticed that when trying to template the README.md file from that project, I receive errors that some of the templates are "not defined."

Expected Behavior

The template should render successfully, just like full-template example.

Actual behavior

I get error messages for some of the templates, but not all of them:

  • Working templates - no errors
    • {{ template "chart.header" . }}
    • {{ template "chart.description" . }}
    • {{ template "chart.type" . }}
    • {{ template "chart.typeLine" . }}
  • Non-working templates - receive an error
    • {{ template "chart.typeBadge" . }}
    • {{ template "chart.appVersion" . }}
    • {{ template "chart.appVersionLine" . }}
    • {{ template "chart.appVersionBadge" . }}
    • {{ template "chart.appVersion" . }}
    • {{ template "chart.appVersionLine" . }}
    • {{ template "chart.appVersionBadge" . }}
    • {{ template "chart.homepage" . }}
    • {{ template "chart.homepageLine" . }}
    • {{ template "chart.maintainersHeader" . }}
    • {{ template "chart.maintainersTable" . }}
    • {{ template "chart.maintainersSection" . }}
    • {{ template "chart.sourcesHeader" . }}
    • {{ template "chart.sourcesList" . }}
    • {{ template "chart.sourcesSection" . }}

All of the non-working templates receive an error similar to this:

WARN[2020-07-22T17:08:07+02:00] Error generating documentation for chart cluster-autoscaler: template: cluster-autoscaler:9:12: executing "cluster-autoscaler" at <{{template "chart.typeBadge" .}}>: template "chart.typeBadge" not defined

Additional

Here's the information of my underlying environment:

  • Helm version: version.BuildInfo{Version:"v3.2.4", GitCommit:"0ad800ef43d3b826f31a5ad8dfbb4fe05d143688", GitTreeState:"dirty", GoVersion:"go1.14.3"}
  • Helm-docs version: helm-docs version 0.13.0

Are here are the files I used. Note that the README.md.gotmpl contains all templates that work. Adding any of the Non-working templates list above results in an error, and does not render.

README.md.gotmpl
{{ template "chart.header" . }}

{{ template "chart.description" . }}

{{ template "chart.type" . }}

{{ template "chart.typeLine" . }}

## TL;DR:

```console
$ helm repo add autoscaler https://kubernetes.github.io/autoscaler

$ helm install autoscaler/cluster-autoscaler --name my-release --set "autoscalingGroups[0].name=your-asg-name,autoscalingGroups[0].maxSize=10,autoscalingGroups[0].minSize=1"
```

## Introduction

This chart bootstraps a cluster-autoscaler deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager.

## Prerequisites

- Helm 3+
- Kubernetes 1.8+
  - [Older versions](https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler#releases) may work by overriding the `image`. Cluster autoscaler internally simulates the scheduler and bugs between mismatched versions may be subtle.
- Azure AKS specific Prerequisites:
  - Kubernetes 1.10+ with RBAC-enabled.

## Previous Helm Chart

The previous `cluster-autoscaler` Helm chart hosted at [helm/charts](https://github.com/helm/charts) has been moved to this repository in accordance with the [Deprecation timeline](https://github.com/helm/charts#deprecation-timeline). Note that a few things have changed between this version and the old version:

- This repository **only** supports Helm chart installations using Helm 3+ since the `apiVersion` on the charts has been marked as `v2`.
- Previous versions of the Helm chart have not been migrated, and the version was reset to `1.0.0` at the onset. If you are looking for old versions of the chart, it's best to run `helm pull stable/cluster-autoscaler --version ` until you are ready to move to this repository's version.

## Installing the Chart

**By default, no deployment is created and nothing will autoscale**.

You must provide some minimal configuration, either to specify instance groups or enable auto-discovery. It is not recommended to do both.

Either:

- Set `autoDiscovery.clusterName` and tag your autoscaling groups appropriately (`--cloud-provider=aws` only) **or**
- Set at least one ASG as an element in the `autoscalingGroups` array with its three values: `name`, `minSize` and `maxSize`.

To install the chart with the release name `my-release`:

### AWS - Using auto-discovery of tagged instance groups

Auto-discovery finds ASGs tags as below and automatically manages them based on the min and max size specified in the ASG. `cloudProvider=aws` only.

- Tag the ASGs with keys to match `.Values.autoDiscovery.tags`, by default: `k8s.io/cluster-autoscaler/enabled` and `k8s.io/cluster-autoscaler/`
- Verify the [IAM Permissions](#iam)
- Set `autoDiscovery.clusterName=`
- Set `awsRegion=`
- Set `awsAccessKeyID=` and `awsSecretAccessKey=` if you want to [use AWS credentials directly instead of an instance role](https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md#using-aws-credentials)

```console
$ helm install autoscaler/cluster-autoscaler --name my-release --set autoDiscovery.clusterName=
```

#### Specifying groups manually

Without autodiscovery, specify an array of elements each containing ASG name, min size, max size. The sizes specified here will be applied to the ASG, assuming IAM permissions are correctly configured.

- Verify the [IAM Permissions](#iam)
- Either provide a yaml file setting `autoscalingGroups` (see values.yaml) or use `--set` e.g.:

```console
$ helm install autoscaler/cluster-autoscaler --name my-release --set "autoscalingGroups[0].name=your-asg-name,autoscalingGroups[0].maxSize=10,autoscalingGroups[0].minSize=1"
```

#### Auto-discovery

For auto-discovery of instances to work, they must be tagged with the keys in `.Values.autoDiscovery.tags`, which by default are
`k8s.io/cluster-autoscaler/enabled` and `k8s.io/cluster-autoscaler/`

The value of the tag does not matter, only the key.

An example kops spec excerpt:

```
apiVersion: kops/v1alpha2
kind: Cluster
metadata:
  name: my.cluster.internal
spec:
  additionalPolicies:
    node: |
      [
        {"Effect":"Allow","Action":["autoscaling:DescribeAutoScalingGroups","autoscaling:DescribeAutoScalingInstances","autoscaling:DescribeLaunchConfigurations","autoscaling:DescribeTags","autoscaling:SetDesiredCapacity","autoscaling:TerminateInstanceInAutoScalingGroup"],"Resource":"*"}
      ]
      ...
---
apiVersion: kops/v1alpha2
kind: InstanceGroup
metadata:
  labels:
    kops.k8s.io/cluster: my.cluster.internal
  name: my-instances
spec:
  cloudLabels:
    k8s.io/cluster-autoscaler/enabled: ""
    k8s.io/cluster-autoscaler/my.cluster.internal: ""
  image: kops.io/k8s-1.8-debian-jessie-amd64-hvm-ebs-2018-01-14
  machineType: r4.large
  maxSize: 4
  minSize: 0
```

In this example you would need to `--set autoDiscovery.clusterName=my.cluster.internal` when installing.

It is not recommended to try to mix this with setting `autoscalingGroups`

See [autoscaler AWS documentation](https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md#auto-discovery-setup) for a more discussion of the setup.

### GCE

The following parameters are required:

- `autoDiscovery.clusterName=any-name`
- `cloud-provider=gce`
- `autoscalingGroupsnamePrefix[0].name=your-ig-prefix,autoscalingGroupsnamePrefix[0].maxSize=10,autoscalingGroupsnamePrefix[0].minSize=1`

To use Managed Instance Group (MIG) auto-discovery, provide a YAML file setting `autoscalingGroupsnamePrefix` (see values.yaml) or use `--set` when installing the Chart - e.g.

```console
$ helm install autoscaler/cluster-autoscaler \
--name my-release \
--set autoDiscovery.clusterName= \
--set cloudProvider=gce \
--set "autoscalingGroupsnamePrefix[0].name=your-ig-prefix,autoscalingGroupsnamePrefix[0].maxSize=10,autoscalingGroupsnamePrefix[0].minSize=1"
```

Note that `your-ig-prefix` should be a _prefix_ matching one or more MIGs, and _not_ the full name of the MIG. For example, to match multiple instance groups - `k8s-node-group-a-standard`, `k8s-node-group-b-gpu`, you would use a prefix of `k8s-node-group-`.

In the event you want to explicitly specify MIGs instead of using auto-discovery, set members of the `autoscalingGroups` array directly - e.g.

```
# where 'n' is the index, starting at 0
-- set autoscalingGroups[n].name=https://content.googleapis.com/compute/v1/projects/$PROJECTID/zones/$ZONENAME/instanceGroupManagers/$FULL-MIG-NAME,autoscalingGroups[n].maxSize=$MAXSIZE,autoscalingGroups[n].minSize=$MINSIZE
```

### Azure AKS

The following parameters are required:

- `cloudProvider=azure`
- `autoscalingGroups[0].name=your-agent-pool,autoscalingGroups[0].maxSize=10,autoscalingGroups[0].minSize=1`
- `azureClientID: "your-service-principal-app-id"`
- `azureClientSecret: "your-service-principal-client-secret"`
- `azureSubscriptionID: "your-azure-subscription-id"`
- `azureTenantID: "your-azure-tenant-id"`
- `azureClusterName: "your-aks-cluster-name"`
- `azureResourceGroup: "your-aks-cluster-resource-group-name"`
- `azureVMType: "AKS"`
- `azureNodeResourceGroup: "your-aks-cluster-node-resource-group"`

## Uninstalling the Chart

To uninstall `my-release`:

```console
$ helm uninstall my-release
```

The command removes all the Kubernetes components associated with the chart and deletes the release.

> **Tip**: List all releases using `helm list` or start clean with `helm uninstall my-release`

## Additional Configuration

### AWS - IAM

The worker running the cluster autoscaler will need access to certain resources and actions:

```
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "autoscaling:DescribeAutoScalingGroups",
        "autoscaling:DescribeAutoScalingInstances",
        "autoscaling:DescribeLaunchConfigurations",
        "autoscaling:DescribeTags",
        "autoscaling:SetDesiredCapacity",
        "autoscaling:TerminateInstanceInAutoScalingGroup"
      ],
      "Resource": "*"
    }
  ]
}
```

- `DescribeTags` is required for autodiscovery.
- `DescribeLaunchConfigurations` is required to scale up an ASG from 0.

Unfortunately AWS does not support ARNs for autoscaling groups yet so you must use "*" as the resource. More information [here](http://docs.aws.amazon.com/autoscaling/latest/userguide/IAM.html#UsingWithAutoScaling_Actions).

### AWS - IAM Roles for Service Accounts (IRSA)

For Kubernetes clusters that use Amazon EKS, the service account can be configured with an IAM role using [IAM Roles for Service Accounts](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) to avoid needing to grant access to the worker nodes for AWS resources.

In order to accomplish this, you will first need to create a new IAM role with the above mentions policies.  Take care in [configuring the trust relationship](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-technical-overview.html#iam-role-configuration) to restrict access just to the service account used by cluster autoscaler.

Once you have the IAM role configured, you would then need to `--set rbac.serviceAccountAnnotations."eks\.amazonaws\.com/role-arn"=arn:aws:iam::123456789012:role/MyRoleName` when installing.

## Troubleshooting

The chart will succeed even if the container arguments are incorrect. A few minutes after starting
`kubectl logs -l "app=aws-cluster-autoscaler" --tail=50` should loop through something like

```
polling_autoscaler.go:111] Poll finished
static_autoscaler.go:97] Starting main loop
utils.go:435] No pod using affinity / antiaffinity found in cluster, disabling affinity predicate for this loop
static_autoscaler.go:230] Filtering out schedulables
```

If not, find a pod that the deployment created and `describe` it, paying close attention to the arguments under `Command`. e.g.:

```
Containers:
  cluster-autoscaler:
    Command:
      ./cluster-autoscaler
      --cloud-provider=aws
# if specifying ASGs manually
      --nodes=1:10:your-scaling-group-name
# if using autodiscovery
      --node-group-auto-discovery=asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/
      --v=4
```

### PodSecurityPolicy

Though enough for the majority of installations, the default PodSecurityPolicy _could_ be too restrictive depending on the specifics of your release. Please make sure to check that the template fits with any customizations made or disable it by setting `rbac.pspEnabled` to `false`.

{{ template "chart.valuesSection" . }}
Chart.yaml
apiVersion: v2
appVersion: 1.18.1
description: Scales Kubernetes worker nodes within autoscaling groups.
engine: gotpl
home: https://github.com/kubernetes/autoscaler
icon: https://github.com/kubernetes/kubernetes/blob/master/logo/logo.png
maintainers:
  - email: [email protected]
    name: gjtempleton
  - email: [email protected]
    name: mgoodness
  - email: [email protected]
    name: sc250024
  - email: [email protected]
    name: yurrriq
name: cluster-autoscaler
sources:
  - https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler
  - https://github.com/spotinst/kubernetes-autoscaler/tree/master/cluster-autoscaler
type: application
version: 1.0.0
values.yaml
## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity
# affinity -- Affinity for pod assignment
affinity: {}

autoDiscovery:
  # Only cloudProvider `aws` and `gce` are supported by auto-discovery at this time
  # AWS: Set tags as described in https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md#auto-discovery-setup
  # autoDiscovery.clusterName -- Enable autodiscovery for name in ASG tag (only `cloudProvider=aws`). Must be set for `cloudProvider=gce`, but no MIG tagging required.
  clusterName:  # cluster.local
  # autoDiscovery.tags -- ASG tags to match, run through `tpl`.
  tags:
  - k8s.io/cluster-autoscaler/enabled
  - k8s.io/cluster-autoscaler/{{ .Values.autoDiscovery.clusterName }}
  # - kubernetes.io/cluster/{{ .Values.autoDiscovery.clusterName }}

# autoscalingGroups -- For AWS. At least one element is required if not using `autoDiscovery`. For example:
# <pre>
# - name: asg1<br />
#   maxSize: 2<br />
#   minSize: 1
# </pre>
autoscalingGroups: []
# - name: asg1
#   maxSize: 2
#   minSize: 1
# - name: asg2
#   maxSize: 2
#   minSize: 1

# autoscalingGroupsnamePrefix -- For GCE. At least one element is required if not using `autoDiscovery`. For example:
# <pre>
# - name: ig01<br />
#   maxSize: 10<br />
#   minSize: 0
# </pre>
autoscalingGroupsnamePrefix: []
# - name: ig01
#   maxSize: 10
#   minSize: 0
# - name: ig02
#   maxSize: 10
#   minSize: 0

# awsAccessKeyID -- AWS access key ID ([if AWS user keys used](https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md#using-aws-credentials))
awsAccessKeyID: ""

# awsRegion -- AWS region (required if `cloudProvider=aws`)
awsRegion: us-east-1

# awsSecretAccessKey -- AWS access secret key ([if AWS user keys used](https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md#using-aws-credentials))
awsSecretAccessKey: ""

# azureClientID -- Service Principal ClientID with contributor permission to Cluster and Node ResourceGroup.
# Required if `cloudProvider=azure`
azureClientID: ""

# azureClientSecret -- Service Principal ClientSecret with contributor permission to Cluster and Node ResourceGroup.
# Required if `cloudProvider=azure`
azureClientSecret: ""

# azureResourceGroup -- Azure resource group that the cluster is located.
# Required if `cloudProvider=azure`
azureResourceGroup: ""

# azureSubscriptionID -- Azure subscription where the resources are located.
# Required if `cloudProvider=azure`
azureSubscriptionID: ""

# azureTenantID -- Azure tenant where the resources are located.
# Required if `cloudProvider=azure`
azureTenantID: ""

# azureVMType -- Azure VM type.
azureVMType: "AKS"

# azureClusterName -- Azure AKS cluster name.
# Required if `cloudProvider=azure`
azureClusterName: ""

# azureNodeResourceGroup -- Azure resource group where the cluster's nodes are located, typically set as `MC_<cluster-resource-group-name>_<cluster-name>_<location>`.
# Required if `cloudProvider=azure`
azureNodeResourceGroup: ""

# azureUseManagedIdentityExtension -- Whether to use Azure's managed identity extension for credentials. If using MSI, ensure subscription ID and resource group are set.
azureUseManagedIdentityExtension: false

# cloudConfigPath -- Configuration file for cloud provider.
cloudConfigPath: /etc/gce.conf

# cloudProvider -- The cloud provider where the autoscaler runs.
# Currently only `gce`, `aws`, and `azure` are supported.
# `aws` supported for AWS. `gce` for GCE. `azure` for Azure AKS.
cloudProvider: aws

# containerSecurityContext -- [Security context for container](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)
containerSecurityContext: {}
  # capabilities:
  #   drop:
  #   - ALL

# dnsPolicy -- Defaults to `ClusterFirst`. Valid values are:
# `ClusterFirstWithHostNet`, `ClusterFirst`, `Default` or `None`.
# If autoscaler does not depend on cluster DNS, recommended to set this to `Default`.
dnsPolicy: ClusterFirst

## Priorities Expander
# expanderPriorities -- The expanderPriorities is used if `extraArgs.expander` is set to `priority` and expanderPriorities is also set with the priorities.
# If `extraArgs.expander` is set to `priority`, then expanderPriorities is used to define cluster-autoscaler-priority-expander priorities.
# See: https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/expander/priority/readme.md
expanderPriorities: {}

# extraArgs -- Additional container arguments.
extraArgs:
  logtostderr: true
  stderrthreshold: info
  v: 4
  # write-status-configmap: true
  # leader-elect: true
  # skip-nodes-with-local-storage: false
  # expander: least-waste
  # scale-down-enabled: true
  # balance-similar-node-groups: true
  # min-replica-count: 2
  # scale-down-utilization-threshold: 0.5
  # scale-down-non-empty-candidates-count: 5
  # max-node-provision-time: 15m0s
  # scan-interval: 10s
  # scale-down-delay-after-add: 10m
  # scale-down-delay-after-delete: 0s
  # scale-down-delay-after-failure: 3m
  # scale-down-unneeded-time: 10m
  # skip-nodes-with-local-storage: false
  # skip-nodes-with-system-pods: true

# extraEnv -- Additional container environment variables.
extraEnv: {}

# fullnameOverride -- String to fully override `cluster-autoscaler.fullname` template.
fullnameOverride: ""

image:
  # image.repository -- Image repository
  repository: us.gcr.io/k8s-artifacts-prod/autoscaling/cluster-autoscaler
  # image.tag -- Image tag
  tag: v1.18.1
  # image.pullPolicy -- Image pull policy
  pullPolicy: IfNotPresent
  ## Optionally specify an array of imagePullSecrets.
  ## Secrets must be manually created in the namespace.
  ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
  ##
  # image.pullSecrets -- Image pull secrets
  pullSecrets: []
  # - myRegistrKeySecretName

# kubeTargetVersionOverride -- Allow overridding the `.Capabilities.KubeVersion.GitVersion` check. Useful for `helm template` commands.
kubeTargetVersionOverride: ""

# nameOverride -- String to partially override `cluster-autoscaler.fullname` template (will maintain the release name)
nameOverride: ""

# nodeSelector -- Node labels for pod assignment. Ref: https://kubernetes.io/docs/user-guide/node-selection/.
nodeSelector: {}

# podAnnotations -- Annotations to add to each pod.
podAnnotations: {}

# podDisruptionBudget -- Pod disruption budget.
podDisruptionBudget:
  maxUnavailable: 1
  # minAvailable: 2

# podLabels -- Labels to add to each pod.
podLabels: {}

# priorityClassName -- priorityClassName
priorityClassName: ""

rbac:
  # rbac.create -- If `true`, create and use RBAC resources.
  create: true
  # rbac.pspEnabled -- If `true`, creates and uses RBAC resources required in the cluster with [Pod Security Policies](https://kubernetes.io/docs/concepts/policy/pod-security-policy/) enabled.
  # Must be used with `rbac.create` set to `true`.
  pspEnabled: false
  serviceAccount:
    # rbac.serviceAccount.annotations -- Additional Service Account annotations.
    annotations: {}
    # rbac.serviceAccount.create -- If `true` and `rbac.create` is also true, a Service Account will be created.
    create: true
    # rbac.serviceAccount.name -- The name of the ServiceAccount to use. If not set and create is `true`, a name is generated using the fullname template.
    name: ""

# replicaCount -- Desired number of pods
replicaCount: 1

# resources -- Pod resource requests and limits.
resources: {}
  # limits:
  #   cpu: 100m
  #   memory: 300Mi
  # requests:
  #   cpu: 100m
  #   memory: 300Mi

# securityContext -- [Security context for pod](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)
securityContext: {}
  # runAsNonRoot: true
  # runAsUser: 1001
  # runAsGroup: 1001

service:
  # service.annotations -- Annotations to add to service
  annotations: {}
  # service.externalIPs -- List of IP addresses at which the service is available. Ref: https://kubernetes.io/docs/user-guide/services/#external-ips.
  externalIPs: []

  # service.loadBalancerIP -- IP address to assign to load balancer (if supported).
  loadBalancerIP: ""
  # service.loadBalancerSourceRanges -- List of IP CIDRs allowed access to load balancer (if supported).
  loadBalancerSourceRanges: []
  # service.servicePort -- Service port to expose.
  servicePort: 8085
  # service.portName -- Name for service port.
  portName: http
  # service.type -- Type of service to create.
  type: ClusterIP

## Are you using Prometheus Operator?
serviceMonitor:
  # serviceMonitor.enabled -- If true, creates a Prometheus Operator ServiceMonitor.
  enabled: false
  # serviceMonitor.interval -- Interval that Prometheus scrapes Cluster Autoscaler metrics.
  interval: 10s
  # serviceMonitor.namespace -- Namespace which Prometheus is running in.
  namespace: monitoring
  ## [Prometheus Selector Label](https://github.com/helm/charts/tree/master/stable/prometheus-operator#prometheus-operator-1)
  ## [Kube Prometheus Selector Label](https://github.com/helm/charts/tree/master/stable/prometheus-operator#exporters)
  # serviceMonitor.selector -- Default to kube-prometheus install (CoreOS recommended), but should be set according to Prometheus install.
  selector:
    release: prometheus-operator
  # serviceMonitor.path -- The path to scrape for metrics; autoscaler exposes `/metrics` (this is standard)
  path: /metrics

# tolerations -- List of node taints to tolerate (requires Kubernetes >= 1.6).
tolerations: []

# updateStrategy -- [Deployment update strategy](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy)
updateStrategy: {}
  # rollingUpdate:
  #   maxSurge: 1
  #   maxUnavailable: 0
  # type: RollingUpdate

Template for chart's release name

I would like to use only one template for my charts with installation instructions like this:
$ helm install my-release stable/{{ template "chart.name" . }}

Generated badge URL should escape dash `-` to make Pre-release version string like 1.0.1-rc.1 work

Generated badge URL should escape dash - to make version string like 1.0.1-rc.1 work

For helm chart with Pre-release versions (e.g. 1.0.1-rc.1 or 1.0.1-alpha.0), helm-docs will generate badge markdown like:

![Version: 1.0.1-rc.1](https://img.shields.io/badge/Version-1.0.1-rc.1-informational?style=flat-square)

which will render as (because shields.io use dash "-" as separators in URL):
image

helm-docs should escape dash "-" as "--" according to shields.io.

Dashes --	โ†’	- Dash
Underscores __	โ†’	_ Underscore
_ or Space  	โ†’	  Space

i.e. the correct badge markdown should be:

![Version: 1.0.1-rc.1](https://img.shields.io/badge/Version-1.0.1--rc.1-informational?style=flat-square)

which will render the followings:

image

Including docs for subcharts

@norwoodj This is a feature request / conversational issue. In a sense, it's the opposite of the #12 issue filed by @knackaron.

How easy / difficult would it be to also document subcharts defined in the requirements.yaml file ? I know that typically this is not done. However, I'm in the process of writing a common Helm chart, and being able to document the common chart's values.yaml file, but include it in a parent chart, would be useful.

What do you think?

Proposal to add custom notation type

Hi @norwoodj .

First, I would like to say thanks for this great piece of tool. I can imagine I will use it a lot.

I would like to propose some feature addition that rises from the needs of maintaining my own helm charts.

Background

I managed helm chart recipe where some of the services are needed as dependencies to other charts.
Some chart bootstrap other charts from one single values.yaml file. To support some customization in the chart dependencies, some of the values needs to be clearly defined and interlinked (definition of possible values for chart A may reuse or refer the original definition of values in chart B). To support this kind of use case, I propose the following feature additions:

Proposed features

Support for tpl string

Some dependent chart's values needs to be injected from original chart via Go template string. A value that need a go template string can be like this:

global:
  siteName: 'mysite.org'

awesomeApp:
  enabled: true
  siteUrl: |
    https://{{ .Values.global.sitename }}

When chart was generated, the value awesomeApp.siteUrl is set dynamically at generation time as https://mysite.org. However, currently helm-docs will generate the default value of awesomeApp.siteUrl as a JSON escaped string. This doesn't look easy to understand because it will only be a one line string with some escaped character.

I would like to be able to show the default value as:

siteUrl: |
  https://{{ .Values.global.sitename }}

This way, user understands that the value expects a Go template string.

Support for non JSON default value rendering

In some cases, rendering the escaped JSON values looks very complicated. There is also another reason where I want the user to replace a value with a valid YAML structure, but since the default value is rendered as JSON, it looks misleading.

If the values.yaml looks like this:

parent:
  # -- child description
  child:
    name: "honk"
    age: 13
    hobby: "sleeping"

I want the default value to be rendered in YAML like this for the key parent.child:

name: "honk"
age: 13
hobby: "sleeping"

Support for custom value types

Currently, the value types are recognized directly from the YAML structure.
However in some cases, the value types have a clear defined structure that can be referenced elsewhere. Like k8s docs, other chart, or simple structure like email, URL, filepath, csv etc.

I would like to be able to put my own custom type like this:

# -- (string/email) This is a user email type
email: [email protected]
# -- (string/url) This has to be formatted as URL
url: https://somesite.org

At least these types can be parsed and rendered in the values table.

Support for custom notation types

Even if two values use string, that doesn't mean it should be rendered the same way in the default value column.
In some chart, I can put my own configuration file inside the values.yaml so that it can be included in the configmap.
All of it are string value, but we can improve the rendering to match the language syntax.

I propose we add another annotation: @notationType that can tell you what type of rendering it we should use.

# -- This is string, but should be rendered as python file
# @notationType -- python
djangoSettings: |
  import os
  # something pythony

# -- This is string, but can be rendered as nginx config file
# @notationType -- nginx
nginxConfig: |
  # nginx server block
  server {
    location / {
       # some nginx config
    }
  }

The rendering itself is a separate issue, but I was hoping that the @notationType was parsed first and available inside the template.

Support for more flexible value table rendering

My above use case seems to need the table to be generated directly as HTML tags.
I can do it myself, totally separate from helm-docs, however if this can be merged and supported, it would be good.

Basically the current values table are rendered using Github Markdown, from markdown syntax. But if we can provide HTML tags rendering, this would be possible:

  • Default values can be rendered as <pre> tag, multiline. So we can pretty print the default behaviour of rendering the default values as JSON
  • There's no way for me to display YAML or Go template string in one line using current markdown table syntax. I had to do it multiline using HTML table tags combined with codefence or <pre> tag directly.
  • Specifying id in the <td> or <tr> tag of the value rows can create anchor that can be referenced inside the markdown, or across the page. So my chart A can refer to value documentation at chart B.
  • Custom rendering the Type columns, so that it will hyperlinked to the data structure/value structure definition somewhere
  • Custom rendering the Default value columns, so that it appropriately consider @notationType and render suitable color syntax or format

I think, we can keep the usual value section in markdown and this HTML tables as separate template definition.

pre-commit hook template in subdir not working

Hi

thanks a lot for this great project.

i have a strange issue with a custom gotemplate within a subdir.
When i run helm-doc cli manually i got the exspected result:

โฏ helm-docs --chart-search-root=. --template-files=README.md.gotmpl --template-files=./templates/_templates.gotpl -l debug
DEBU[2021-03-23T17:44:25+01:00] No ignore file found at helm-charts/.helmdocsignore, using empty ignore rules 
INFO[2021-03-23T17:44:25+01:00] Found Chart directories [.]                  
DEBU[2021-03-23T17:44:25+01:00] Rendering from optional template files [README.md.gotmpl, templates/_templates.gotpl] 
INFO[2021-03-23T17:44:25+01:00] Generating README Documentation for chart helm-charts/example
DEBU[2021-03-23T17:44:25+01:00] Using template files [README.md.gotmpl templates/_templates.gotpl] for chart helm-charts/example

but when i run exactly the same via pre-commit hook the template within the subdir was not found

โฏ pre-commit run
Helm Docs................................................................Failed
- hook id: helm-docs
- files were modified by this hook

DEBU[2021-03-23T17:44:30+01:00] No ignore file found at helm-charts/.helmdocsignore, using empty ignore rules 
DEBU[2021-03-23T17:44:30+01:00] Ignoring directory helm-charts/.git 
INFO[2021-03-23T17:44:30+01:00] Found Chart directories [example] 
DEBU[2021-03-23T17:44:30+01:00] Rendering from optional template files [README.md.gotmpl, ./templates/_templates.gotpl] 
INFO[2021-03-23T17:44:30+01:00] Generating README Documentation for chart helm-charts/example 
DEBU[2021-03-23T17:44:30+01:00] Did not find template file ./templates/_templates.gotpl for chart helm-charts/example, using default template

when i move the _templates.gotpl under the chart root everything is working as expected.

Allow for documentation of subfield in default empty object {}

Can I generate documentation of subfields in object property whose default value is empty {} ?

worker:
  deployment: {}
    # expected format of `worker.deployment` is below:
    # replicaCount: 1
    # resources:
    #   cpu: "200m"
    #   memory: "512Mi"

In the example above, generated result was below:

Key Type Default Description
worker.deployment object {}

However, we wanna generate the documentation below:

Key Type Default Description
worker.deployment object {}
worker.deployment.replicaCount int
worker.deployment.resources.cpu string
worker.deployment.resources.memory string

Suggestions

My suggestion is introduction of the annotation (ex. @subfield) which allows us for documentation of subfield.

worker:
  # worker.deployment -- deployment of worker.
  # @subfield replicaCount -- (int) replicaCount of worker.
  # @subfield resources.cpu -- (string) cpu resources of worker.
  # @subfield resources.memory -- (string) memory resources of worker.
  deployment: {}
Key Type Default Description
worker.deployment object {} deployment of worker
worker.deployment.replicaCount int replicaCount of worker.
worker.deployment.resources.cpu string cpu resources of worker.
worker.deployment.resources.memory string memory resources of worker.

Allow Documentation for Lists and Maps

We should allow non-empty lists and maps to be included in the values table with descriptions. This issue asks that we implement the following behavior for values table generation:

  • Only leaf nodes (empty lists, empty objects, strings, ints, and floats) are automatically documented
  • If a list or object has a comment with a description, document it as a value, as you have done here. The default field for lists and objects in this case should be a jsonified string of the field
  • Documenting a list or object in the above fashion stops the automatic documentation of contained fields, that is, they will not be added to the values table. However, if a contained field has a description comment on it, then it will then be included.

An example:

exampleObjectNoDescriptions:
  key: value

exampleListNoDescriptions:
  - key: value

# exampleObjectDescription -- this object will be documented
exampleObjectDescription:
  keyNoDescription: value

  # exampleObjectDescription.keyWithDescription -- this object key will be documented
  keyWithDescription: value

# exampleListDescription -- this list will be documented
exampleListDescription:
  - keyNoDesciption: value

  # exampleListDescription[1].keyWithDescription -- this list item key will be documented
  - keyWithDescription: value

  # exampleListDescription[2] -- this list item will be documented
  - listItemWithDescription: value

Produces

Key Type Default Description
exampleObjectNoDescriptions.key string "value"
exampleListNoDesciptions[0].key string "value"
exampleObjectDescription object {"keyNoDescription": "value", "keyWithDescription": "value"} this object will be documented
exampleObjectDescription.keyWithDescription string "value" this object key will be documented
exampleListDescription list [{"keyNoDescription": "value"}, {"keyWithDescription": "value"}, {"listItemWithDescription": "value"}] this list will be documented
exampleListDescription[1].keyWithDescription string "value" this list item key will be documented
exampleListDescription[2] object {"listItemWithDescription": "value"} this list item will be documented

Note how exampleListDescription.keyNoDesciption and exampleObjectDescription.keyNoDescription aren't documented because the containing object and list themselves have description comments, but the other contained keys are documented because they do have description comments.

Optional custom template (rendering) per chart

Use case

When maintaining multiple charts in a single repository, it's inevitable that some charts require custom README templates.

Currently, this is possible using the --template-files option: if a template is not found, a builtin default template is loaded.

This works flawlessly, until you want to pair it with an other use case: define a custom, common template for all the other charts. In other words: chart a should use the template README.md.gotmpl, chart b and chart c should use ../../README.md.gotmpl (template files are relative to chart directories).

Since chart b and chart c don't have README.md.gotmpl, the builtin default template is loaded.

This issue can be worked around by symlinking the common template into every chart directory as needed, but that's not very elegant, is it? (You can see it working here though

One would think that passing both templates to the command would work (like this: --template-files ../../README.md.gotmpl --template-files README.md.gotmpl). Passing the following would however result in the default template being loaded (see #77 for more details). Even after fixing #77, the result of this command will be a readme with the content rendered twice (more precisely: two similar readmes rendered in one file).

This is because internally, all templates are loaded into a single template instance and the entire template is rendered, resulting in an output containing the custom readme template and the builtin default as well.

Solution#1

A simple solution to this problem would be introducing a convention for loading a README.md.gotmpl from the charts root directory as well. In this scenario, if no template files are defined, the default README.md.gotmpl should be checked in the chart directory first, then one directory above.

This is far from perfect though: it doesn't solve more advanced use cases (ie. multiple template files)

Solution#2

A more elegant solution would be using named templates:

package main

import (
	"os"
	"text/template"
)

func main() {
	// Load default template
	tpl := template.Must(template.New("main").Parse("default template"))
	
	// Define builtin templates
	template.Must(tpl.Parse(`{{ define "header" }}header{{ end }}`))
	
	// Load custom main templates
	template.Must(tpl.New("main").Parse(`custom template: {{ template "header" .}}`))
	
	// Load custom templates
	
	tpl.ExecuteTemplate(os.Stdout, "main", nil)
}

(See it in action: https://play.golang.org/p/uizMUHwK4sF)

In this case, templates rendering the output and templates providing "blocks" are kept separate. There is always one main template (that renders the output), but there can be any number of additional template providing building blocks (eg. common header for all chart README templates, etc)

There is one pitfall: named templates are already used here, so we have to make sure they don't overlap.

In terms of implementation, we could introduce a new flag for main templates in addition to the existing --template-files:

  • --main-template-files
  • --output-template-files

The new flag would work similarly to the solution outlined in #77: it would try to load all files, but instead of manually falling back to the default, the template system will take care of it for us, by each new template overriding the old one.

We can probably make this a backward compatible change: if no --main-template-files are passed to the command, the old behavior is kept.

Alternatively, we can keep using a single flag and prepend main template file names with main:: --template-files helpers.gotmpl --template-files main:../README.md.gotmpl --template-files main:README.md.gotmpl. I find it less elegant, but resolves the ambiguity if having two template file flags doing different things.

Solution#3

All of the solutions above presume applying the same settings to each chart. Solution#2 relies on defining multiple templates, falling back in the list if one is not found.

A more direct approach to chart specific changes is chart specific configuration in the chart directory.

For example, a docs.yaml:

templates:
   - README.md.gotmpl

This would also need some sort of fallback though (eg. in the repo root).

Alternatively, we could use annotations in Chart.yaml:

annotations:
    helm-docs-templates: ../helpers.gotmpl;README.md.gotmpl

Conclusion

The above use case uncovers multiple problems:

  • Every template passed to the renderer generates an output
  • There is no way to specify chart specific values

Solution#2 provides a solution for the first problem without a need to solve the second one. It feels like it doesn't really need solving at the moment. We can always implement it later.

Generated default README.md fails markdownlint

Hello and thanks for all the effort you put into this. It already saved me hours of typing all the values.yaml tables.

Now my issue is, that a generated default README.md fails the markdownlint of https://github.com/DavidAnson/markdownlint in default configuration.

E.g.:

markdownlint README.md
README.md:1 MD022/blanks-around-headings/blanks-around-headers Headings should be surrounded by blank lines [Expected: 1; Actual: 0; Below] [Context: "sys11prometheus-operator"]
README.md:7 MD012/no-multiple-blanks Multiple consecutive blank lines [Expected: 1; Actual: 2]
README.md:8 MD012/no-multiple-blanks Multiple consecutive blank lines [Expected: 1; Actual: 3]
README.md:9 MD003/heading-style/header-style Heading style [Expected: setext; Actual: atx]
README.md:13:81 MD013/line-length Line length [Expected: 80; Actual: 85]
README.md:13:3 MD034/no-bare-urls Bare URL used [Context: "https://kubernetes-charts.stor..."]
README.md:15 MD003/heading-style/header-style Heading style [Expected: setext; Actual: atx]
README.md:19:81 MD013/line-length Line length [Expected: 80; Actual: 98]
README.md:20:81 MD013/line-length Line length [Expected: 80; Actual: 102]
README.md:21:81 MD013/line-length Line length [Expected: 80; Actual: 100]
README.md:22:81 MD013/line-length Line length [Expected: 80; Actual: 104]
README.md:23:81 MD013/line-length Line length [Expected: 80; Actual: 133]
README.md:24:81 MD013/line-length Line length [Expected: 80; Actual: 135]
README.md:30:81 MD013/line-length Line length [Expected: 80; Actual: 82]
README.md:31:81 MD013/line-length Line length [Expected: 80; Actual: 90]
README.md:34:81 MD013/line-length Line length [Expected: 80; Actual: 83]
README.md:39:81 MD013/line-length Line length [Expected: 80; Actual: 88]
README.md:40:81 MD013/line-length Line length [Expected: 80; Actual: 86]
README.md:41:81 MD013/line-length Line length [Expected: 80; Actual: 89]
README.md:42:81 MD013/line-length Line length [Expected: 80; Actual: 87]
README.md:50:81 MD013/line-length Line length [Expected: 80; Actual: 96]
README.md:51:81 MD013/line-length Line length [Expected: 80; Actual: 87]
README.md:52:81 MD013/line-length Line length [Expected: 80; Actual: 105]
README.md:53:81 MD013/line-length Line length [Expected: 80; Actual: 94]
README.md:54:81 MD013/line-length Line length [Expected: 80; Actual: 98]
README.md:55:81 MD013/line-length Line length [Expected: 80; Actual: 95]
README.md:56:81 MD013/line-length Line length [Expected: 80; Actual: 99]
README.md:57:81 MD013/line-length Line length [Expected: 80; Actual: 90]
README.md:59:81 MD013/line-length Line length [Expected: 80; Actual: 99]
README.md:60:81 MD013/line-length Line length [Expected: 80; Actual: 100]
README.md:61:81 MD013/line-length Line length [Expected: 80; Actual: 91]
README.md:62:81 MD013/line-length Line length [Expected: 80; Actual: 109]
README.md:63:81 MD013/line-length Line length [Expected: 80; Actual: 133]
README.md:64:81 MD013/line-length Line length [Expected: 80; Actual: 136]

I know that I could write my own template or configure the yamllint to not fail on the default generated README.md (e.g. I guess I can ignore the line too long ones). I was just wondering whether you ever tried to lint the generated YAML and if you were open to changing the default template?

If so I am willing to provide a patch to fix the default template as far as possible.

Regards

Multi-line YAML using the <pre> tag for better readability

Greetings,

I'm opening this issue for feedback to see what people think; maybe it's been opened before. Basically, I would like multi-line YAML blocks to be formatted using <pre> tags in Markdown rather than the current behavior, which is a single line block using backtick characters.

If I have a multi-line YAML block in values.yaml file like so:

# -- Security context for the container level.
securityContext:
  capabilities:
    drop:
    - ALL
  readOnlyRootFilesystem: true
  runAsNonRoot: true
  runAsUser: 65534

This will be rendered as follows in the current version of Helm Docs:

{"capabilities":{"drop":["ALL"]},"readOnlyRootFilesystem":true,"runAsNonRoot":true,"runAsUser":65534}

As multi-line YAML blocks become large, this creates a slight readability problem. The https://github.com/terraform-docs/terraform-docs project handles this in a different way using <pre> blocks to look like the following directly in the Markdown:

securityContext:
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 65534

Here's the HTML of the above as it would be rendered in terraform-docs style:

<pre>securityContext:<br />  capabilities:<br />    drop:<br />    - ALL<br />  readOnlyRootFilesystem: true<br />  runAsNonRoot: true<br />  runAsUser: 65534</pre>

If you want to see a real example of this, you can check out the https://github.com/cloudposse/terraform-null-label#inputs repository, and under Inputs, look at the context block.

What do people think? Would this be preferred?

Feature request: Multiple gotmpl files

Just like templating of a group of charts can be done with one template, so can multiple groups of charts with similar templates. I would like to be able to either:
A. Be able to specify multiple template files and have them rendered in order or preferably
B. Be able to define templates at a global level that i can import in addition to the ones specified by the tool.
Thanks for helm-docs!

[Enhancement] Also use `values.schema.json`

It's possible to provide a schema for a Helm chart via values.schema.json.

The schema specifies the structure of the chart along with types and descriptions of variables.

The type field would help with properties such as lists of objects, which the documentation generation currently doesn't have a good method of rendering.

The description field in the schema would be especially useful in large charts with areas of reuse as you would be able to enter a description once when specify a definition.

If there is a schema present then validating the values.yaml before process eliminates a large number of edge cases to worry about.

Assuming the values.yaml is valid then the docs should render the distinct list of fields from both values.schema.json and values.yaml.

If both a description in the schema is present along with a comment in the values.yaml then the comment should probably take precedence.

Use cobra/viper for CLI parsing

The CLI parsing in this project is frankly garbage, because I wrote this when I was relatively inexperienced with go. We should use the wonderful cobra and viper libraries instead

Special characters being rendered in Unicode format

Description

You can file this one under "Is this a feature or a bug?" Basically, when a special character like & is present in an entry in values.yaml, the rendered README.md file shows the character as a Unicode sequence.

I encountered this because the elastic/elasticsearch charts allows specifying a value for clusterHealthCheckParams, which I override in the following way:

elasticsearch:
  # elasticsearch.clusterHealthCheckParams -- The Elasticsearch cluster health status params that will be used by readinessProbe command
  clusterHealthCheckParams: "wait_for_status=yellow&timeout=1s"

This results in the following output README.md file:

## Chart Values

| Key | Type | Default | Description |
|-----|------|---------|-------------|
| elasticsearch.clusterHealthCheckParams | string | `"wait_for_status=yellow\u0026timeout=1s"` | The Elasticsearch cluster health status params that will be used by readinessProbe command |

Expected result

Special characters such as & should not be rendered as a Unicode sequence, and should show up as normal in the README.md file as well.

Current result

A character like & will get rendered as \u0026.

Template lookup should not fail if a template is not found

Currently if a template is not found the template lookup:

  • stops looking up further templates
  • returns the default template

This is somewhat counterintuitive to me, because helm-docs can be used to generate README files for multiple charts. Having custom per-chart overrides sounds like a perfectly valid use-case.

My suggestion is:

  • if a template cannot be found continue template lookups (log the fact)
  • load the default template if a template lookup fails (for backwards compatibility)

I'd be happy to provide a PR.

Default annotation is not used when value is null

# -- Field description
# @default -- Default value description
field:

Will output: | field | string | `nil` | Field description |

Whereas

# -- Field description
# @default -- Default value description
field: ""

Outputs: | field | string | Default value description | Field description |

Avoid the need to prefix value documentation with '---'

v1 made it unnecessary to specify the entire value path to generate the documentation, which is great! It would be even more convenient if the '---' were no longer required either. Ie:

controller:
  # -- Configure the healthcheck for the ingress controller
  livenessProbe:
    httpGet:
      # -- This is the liveness check endpoint
      path: /healthz

Becomes:

controller:
  # Configure the healthcheck for the ingress controller
  livenessProbe:
    httpGet:
      # This is the liveness check endpoint
      path: /healthz

This helps keep the values files more readable/easier to add documentation.

[Enhancement] Allow us to set target file and directory

It seems impossible at the moment to customize the directory of the generated readme.

I have my helm chart in a sub-folder, and as a result, the README is always generated in that subfolder.

e.g:

my helm chart is located in the ./helm subfolder. My config looks like this:

- repo: https://github.com/norwoodj/helm-docs
  rev: v1.4.0
  hooks:
    - id: helm-docs
      args:
        - --chart-search-root=helm
        - --template-files=../README.md.gotmpl

I want to keep my helm directory clean, so I already managed to keep the template out of the helm folder by using ../README.md.gotmpl.

Now, how do I prevent the readme of being generated in the ./helm folder, and just in my top-level folder? Specifying the output destination of a generated file, doesn't feel like an uncommon thing...

Value Schema Generation

It would be great if helm-docs can also generate the values.schema.json. While one could argue helm-docs should only generate the Markdown I feel it's perfectly equipped to generate JSON schema especially with the description field.

I'm using https://github.com/karuppiah7890/helm-schema-gen atm but looking at the code it basically doesn't do anything really (see here).

Unable to generate README with Values injection into template files

We have values.yaml template and additional values-<env>.yaml per environment.
To install the chart, a YAML file that specifies the new values and overwrite the above default parameters are provided per environment:

helm install --name someapp -f values=values-qa.yaml stable/someapp

In this case, values-qa.yaml contains values that overwrite default values.yaml. When we run helm-docs it only reads values.yaml and output the default chart values, without the qa. Need ability to pass values like helm to output proper chart values table.

Support library charts

Following this guide for library charts there is no value file and no templates that produce yaml directly but only helpers.
It would be nice if helm-docs wasn't skipping the README generation upon missing values file but still render everything from the Chart.yaml meta-data so we get this part documented automatically.

This could either be implemented using a --library-chart etc. flag or as a breaking change where it doesn't skip the generation when the values file is missing.

The description includes description of previous commented values

Might be related to #92

values.yaml

# -- before desc
before: ~

# -- commented desc
#commented: ~

# -- after desc
after: ~

expected output

Key Type Default Description
after string nil after desc
before string nil before desc

actual output

Key Type Default Description
after string nil commented desc -- after desc
before string nil before desc

Array of scalars is hard to document

In my freshrss chart, I have an array of minutes for a cronjob to run, which by default is 23 and 53

freshrss:
  # freshrss.cron_min - What minutes of the hour should the cron script run
  cron_min: [23, 53]

produces

Key Type Default Description
freshrss.cron_min[0] int 23
freshrss.cron_min[1] int 53

Is there a way to tell it to document the entire array not the specific entries in the array?

Markdown rendering issue

As per the documentation, it says below we should be able to generate readme with description from the below example

  livenessProbe:
    httpGet:
      # -- This is the liveness check endpoint
      path: /healthz
      port: http

When I generate using docker image docker run --rm --volume "$(pwd):/helm-docs" -u $(id -u) jnorwood/helm-docs:latest --dry-run

ReadME generated but the description is not populated as described in the documentation
image

Documentation says
image

Repository Maintenance/Cleanup

Het @norwoodj. I saw you were having some personal issues via this comment and hope all is well. I would be more than happy to help maintain this repo and help clean up some of the legacy code/ci that exists (e.g. old cobra design and deprecated goreleaser config). I plan to use helm-docs for the ever growing k8s@home charts repo as well as a few other projects. If you would be more comfortable with me cloning the repo to preserve commits and starting in a new repository with attribution thats fine too!

Thanks!

add option to ignore subcharts

When subcharts are part of a Git repo and are only included for distribution (e.g., subchart as a Git submodule), helm-docs should have an option to ignore rendering docs for subcharts.

Example of undesirable behavior:

$ git submodule status
 e074e59e9b42fce856b029265d9ccc0163d22f13 charts/subchart2 (2019.0.0-1-ge074e59)
 f91a918ebc2ea969bfbcda884c57b7d8f83f45b2 charts/subchart1 (2019.0.2)

$ helm-docs
INFO[2019-08-05T17:55:03-04:00] Found Chart directories [., charts/subchart2, charts/subchart1] 
INFO[2019-08-05T17:55:03-04:00] Generating README Documentation for chart charts/subchart1  
INFO[2019-08-05T17:55:03-04:00] Generating README Documentation for chart .  
INFO[2019-08-05T17:55:03-04:00] Generating README Documentation for chart charts/subchart2 

$ git st
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)
  (commit or discard the untracked or modified content in submodules)

    modified:   README.md
    modified:   charts/subchart2 (modified content)
    modified:   charts/subchart1 (modified content)

no changes added to commit (use "git add" and/or "git commit -a")

[Feature request] Automatic field name

Hi,

Your README generator is really great ! ๐Ÿ‘
However we still have to "adapt" our value.yaml file to provide the field path which is "intrusive" and "error prone".

controller:
  # controller.persistentVolumeClaims -- List of persistent volume claims to create
  persistentVolumeClaims: []

There is this alternative project which automatically determine the field path : https://github.com/kubepack/chart-doc-gen

controller:
  # List of persistent volume claims to create
  persistentVolumeClaims: []

Do you think you could be able to provide the same automatic behavior ?

Thanks in advance

Create homebrew tap for helm-docs

In order to make it easier for folks to install helm-docs, we should add a homebrew tap so that one can simply brew install the tool.

Feature: Configuration file for various text snippets

I have created a README.md.gotmpl that follows the official helm charts repo more closely, e.g. README.md.

Unfortunately, not all information is present in the Chart.yml and therefore it's usually required to add more details to the README.md. This will then make it hard to update the README.md through helm-docs upon changes in the helm chart.

It would be great to have the ability to regenerate the README.md upon changes.

I suggest having a helm-docs configuration file, e.g. .helm-docs.yaml which can be located in each chart repo with relevant text snippets to be added to the final README.md.

Example:
README.md.gotmpl:

# {{ .Name }}

helm install {{ .cfg.ChartRepository }}/{{ .Name }}

{{ .cfg.SomeRandomText }}

.helm-docs.yaml:

ChartRepository: mychartrepo
SomeRandomText: |
  Lorem Ipsum

Make it possible to document objects and arrays that are empty by default

Let's consider this snippet:

znapzend:
  # znapzend.args -- List of command arguments
  args:
    - znapzend
    - --logto=/dev/stdout
    - --autoCreation
  # znapzend.backupPlans -- List of backup plans to create/ensure on startup, see
  # [values.yaml](./values.yaml) for an example
  backupPlans: []
  # - dataset: pool/dataset
  ##  znapzend.backupPlans[].plan -- A backup plan object
  #   plan:
  #     selfResetAfter: 5m # Only effective when `metrics.enabled=true`, optional, default `1h`
  #     delaySeconds: 600 # Optional, default `0`
  #     source:
  #       retention: 1days=>2hours,2weeks=>1days,6months=>1weeks
  #       recursive: false # Optional, default `false`
  #     targets:
  #     - host: target.host
  #       dataset: backup/dataset
  #       retention: 1days=>2hours,2weeks=>1days,6months=>1weeks

Here, the backupPlans[] is empty, as there isn't a sensible default possible because it's dependent on the user's setup. If they don't like it, it's impossible to disable this with Helm's merging behaviour unless the users provide their own list. Hence the empty array.

However, it would still be cool to have the objects in the array documented in the README, as it's kind of inconvenient to have them look in the values.yaml file (see znapzend.backupPlans[].plan).

It's going to be difficult to implement, as the default YAML parsers ignore comments. But maybe we can add a @type to the value similar to @default done in #29, within double hashtag comments, e.g.

  # znapzend.backupPlans -- List of backup plans to create/ensure on startup, see
  # [values.yaml](./values.yaml) for an example
  backupPlans: []
  ## znapzend.backupPlans[].dataset -- Source dataset path
  ## @type -- string
  ## @default -- ""
  # - dataset: pool/dataset
  ##  znapzend.backupPlans[].plan -- A backup plan object
  ## @type object
  #   plan: {} etc
  • And maybe even parse the default type from the @default, e.g. @default -- "" becomes string if not specified by @type?
  • From my PoV helm-docs doesn't even need to parse the example. Generating the README by just providing the ## key -- description and ## @default -- "" and so on would be enough for me.

At the moment the generated README is just

| znapzend.backupPlans | list | `[]` | List of backup plans to create/ensure on startup, see [values.yaml](./values.yaml) for an example |

which ignores the documented example in values.yaml completely

pre-commit hook in GitHub Action

Hey and thanks for this tool, it makes my life easier :)

I was wondering how I can use the pre-commit hook with a GitHub action? If I use the official GitHub action for pre-commit and install helm-docs like this, it fails with Please install helm-docs to run the pre-commit hook! https://github.com/norwoodj/helm-docs#installation:

  pre-commit:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/setup-go@v1
      with:
        go-version: '1.16.4'
    - name: Install helm-docs
      run: GO111MODULE=on go get github.com/norwoodj/helm-docs/cmd/helm-docs
    - run: helm docs
    - uses: actions/checkout@v2
    - uses: actions/setup-python@v2
    - uses: pre-commit/[email protected]

Is this due to the pre-commit action being run in its own container, can you maybe help me out here?

Columns re-order

Hello,

Question:
I wonder whether there is a way to change the order in the columns or not ?
I would like to switch description and default value columns.

Many thanks

Question: Generate the table of the values with sub-sections ?

Question

Is it possible to generate the table of the values as a collection of tables if we define within the values.yaml file the different sections

How it works now

Here is what it is generated by default

| Key | Type | Default | Description |
|-----|------|---------|-------------|
| deployment.containerPort | int | `8080` |  |
...

from the following definition

deployment:
  containerPort: 8080

What I propose

Generate a section level for a yaml root element

## Deployment

Deployment yaml resource containing the parameters to configure the containers, initContainers, volumes, .... 

| Key | Type | Default | Description |
|-----|------|---------|-------------|
| containerPort | int | `8080` |  |

using the following convention:

include a comment : # Section: xxxxx before a root element where the # Section will allow the tool to create a markdown ## Title containing the name of the field defined hereafter = deployment and using xxxxxx as text paragraph.

# Section: Deployment yaml resource containing the parameters to configure the containers, initContainers, volumes, .... 
deployment:
  containerPort: 8080

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.