tooling: introduce helm reference generator (#34861)

* tooling: introduce helm reference generator

This commit introduces a Helm reference generator. It reads the
description of the values from the chart's values.yaml and generates a
markdown file that can be included in our user documentation.

The check will be enabled in later commits as we start generating doc
reference with this tool.

* license
This commit is contained in:
Hugo Shaka
2023-11-23 21:47:28 +00:00
committed by GitHub
parent 0de4ced595
commit 5cea4c0296
11 changed files with 570 additions and 18 deletions
+1
View File
@@ -1075,6 +1075,7 @@ lint-helm:
yamllint -c examples/chart/.lint-config.yaml $${HELM_TEMP} || { cat -en $${HELM_TEMP}; exit 1; }; \
fi; \
done
$(MAKE) -C examples/chart check-chart-ref
ADDLICENSE := $(GOPATH)/bin/addlicense
ADDLICENSE_ARGS := -c 'Gravitational, Inc' -l apache \
@@ -0,0 +1,37 @@
## render-helm-ref
`render-helm-ref` reads a Helm chart `values.yaml` and generates a chart reference.
This reference can then be included in our user documentation.
### How to use
```shell
go run ./cmd/render-helm-ref/ \
-chart ../../examples/chart/teleport-cluster/charts/teleport-operator \
-output ../../docs/pages/reference/helm-reference/zz_generated.teleport-operator.mdx
```
### `values.yaml` syntax
See [the test data `values.yaml`](./testdata/values.yaml) for an example input,
and [its expected output](./testdata/values.yaml)
### Why?
- to stop maintaining twice the documentation (and because everyone forgets to
update either the values or the docs)
- to reduce the time-to-merge of Helm PRs (we need at least 1 round-trip to have
folks fix the docs)
- to make sure all informnation is available everywhere. Some users only read
the docs, other read the values. Without an automated sync, both are not
providing the same information.
### What about existing tools?
- [helm-docs](https://github.com/norwoodj/helm-docs) almost did the trick, but
its only output is a Markdown table. Its `pkg` is not reusable because it
relies to heavily on viper. We would also need to specify `@raw` everywhere,
which is cumbersome.
- [bitnami/readme-generator-for-helm](https://github.com/bitnami/readme-generator-for-helm)
would need to be extended to support non-table outputs. However, it is developed
in NodeJS while all our existing tooling is in go.
@@ -0,0 +1,254 @@
/*
Copyright 2023 Gravitational, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"bufio"
"encoding/json"
"flag"
"fmt"
"os"
"regexp"
"strings"
"github.com/gravitational/trace"
log "github.com/sirupsen/logrus"
"gopkg.in/yaml.v3"
"helm.sh/helm/v3/pkg/chart/loader"
)
// tagRegex matches tagged values with kind. For example:
// # full.path.valueName(kind) -- controls how to do X
var tagRegex = regexp.MustCompile(`^\s*#\s*(.*)\((.+)\)\s+--\s*(.*)$`)
// tagRegex matches tagged values without kind. For example:
// # full.path.valueName -- controls how to do X
var tagRegexNoKind = regexp.MustCompile(`^\s*#\s*(.*)\s+--\s*(.*)$`)
// defaultRegex matches the default override tag. For example:
// # @default -- see values.yaml
var defaultRegex = regexp.MustCompile(`^\s*# @default -- (.*)$`)
func main() {
var chartPath string
var outputPath string
flag.StringVar(&chartPath, "chart", "", "Path of the chart.")
flag.StringVar(&outputPath, "output", "-", "Path of the generated markdown reference, '-' means stdout.")
flag.Parse()
if chartPath == "" {
log.Error(trace.BadParameter("chart path must be specified"))
os.Exit(1)
}
reference, err := parseAndRender(chartPath)
if err != nil {
log.Errorf("failed parsing chart and rendering refence: %s", err)
os.Exit(1)
}
if outputPath == "-" {
fmt.Print(string(reference))
os.Exit(0)
}
err = os.WriteFile(outputPath, reference, 0o644)
if err != nil {
log.Errorf("failed writing file: %s", err)
os.Exit(1)
}
log.Infof("File %s successfully written", outputPath)
}
func parseAndRender(chartPath string) ([]byte, error) {
chartValues := chartPath + "/" + "values.yaml"
// First, we check if we can load all the data we need.
// We need both the Helm chart (for automatic default detection)
chrt, err := loader.Load(chartPath)
if err != nil {
return nil, trace.Wrap(err, "failed to load chart")
}
// And the raw values.yaml (for the documentation in comments)
valuesYAML, err := os.ReadFile(chartValues)
if err != nil {
return nil, trace.Wrap(err, "failed to open values '%s'", chartValues)
}
// We parse the YAML and extract all the documented values form its comments
var n yaml.Node
err = yaml.Unmarshal(valuesYAML, &n)
if err != nil {
return nil, trace.Wrap(err, "failed to unmarshall values")
}
values := processYAMLNode(&n)
// Then, we backfill the default value when possible
for _, value := range values {
// We can skip the default detection by setting no kind. This is useful when
// we are also documenting subfields and don't want an ugly Type/Default table.
if value.Kind != "" && value.Default == "" {
defaultValue, err := getDefaultForValue(value.Name, chrt.Values)
if err != nil {
log.Warnf("failed to get default for value %s, error: %s", value.Name, err)
} else {
value.Default = string(defaultValue)
}
}
}
// Finally we render
reference, err := renderTemplate(values)
return reference, trace.Wrap(err, "failed to render template")
}
func processYAMLNode(node *yaml.Node) []*Value {
// The YAML structure does not represent the value hierarchy
// So we process all comments the same way and don't care about their position
var values []*Value
if value := grabValue(node.HeadComment); value != nil {
values = append(values, value)
}
if value := grabValue(node.LineComment); value != nil {
values = append(values, value)
}
if value := grabValue(node.FootComment); value != nil {
values = append(values, value)
}
if len(node.Content) != 0 {
for _, subNode := range node.Content {
values = append(values, processYAMLNode(subNode)...)
}
}
return values
}
type Value struct {
Name string
Kind string
Description strings.Builder
Default string
}
type state struct {
isDescription bool
value *Value
}
// grabValue walks through a comment and checks if it has a value tag.
// Once the value tag is found, everything after it will be part of the description.
func grabValue(comment string) *Value {
if comment == "" {
return nil
}
scanner := bufio.NewScanner(strings.NewReader(comment))
var line string
s := state{}
for scanner.Scan() {
line = scanner.Text()
if !s.isDescription {
// We are not yet in a comment containing documentation
match, name, kind, remain := matchTag(line)
if !match {
// no tag on this line, we skip it
continue
}
// start of a value documentation
s.isDescription = true
s.value = &Value{Name: name, Kind: kind}
s.value.Description.WriteString(remain)
s.value.Description.WriteRune('\n')
continue
}
// We already saw a tag on a previous line
// If we find a default override tag we process it, else we just add the
// line to the existing value description.
if match, defaultValue := matchDefaultTag(line); match {
s.value.Default = defaultValue
continue
}
s.value.Description.WriteString(cleanLine(line))
s.value.Description.WriteRune('\n')
}
return s.value
}
func matchTag(line string) (match bool, name, kind, remain string) {
// If kind is specified
subMatches := tagRegex.FindStringSubmatch(line)
if len(subMatches) == 4 && subMatches[1] != "" {
return true, subMatches[1], subMatches[2], subMatches[3]
}
// If kind is not specified
subMatches = tagRegexNoKind.FindStringSubmatch(line)
if len(subMatches) == 3 && subMatches[1] != "" {
return true, subMatches[1], "", subMatches[2]
}
return false, "", "", ""
}
func matchDefaultTag(line string) (bool, string) {
subMatches := defaultRegex.FindStringSubmatch(line)
if len(subMatches) != 2 {
return false, ""
}
return true, subMatches[1]
}
func cleanLine(line string) string {
line2 := strings.TrimSpace(line)
if len(line2) < 3 {
return ""
}
if line2[0] != '#' {
log.Warnf("Misformatted line: %s", line)
return ""
}
return line2[2:]
}
// getDefaultForValue takes a value detected from the comments, and looks up its
// default value in the Helm chart.
func getDefaultForValue(valueName string, chartValues map[string]interface{}) ([]byte, error) {
parts := strings.Split(valueName, ".")
// Check if this is a nested value
if len(parts) > 1 {
chartValue, ok := chartValues[parts[0]]
if !ok {
// Stop if the value is unknown
return nil, trace.NotFound("value '%s' not found", parts[0])
}
// The value name is part0.part1...partX
// We expect the detected Helm value to be a map, else we don't know
// how to access "part1...partX"
if subValue, ok := chartValue.(map[string]interface{}); ok {
return getDefaultForValue(strings.Join(parts[1:], "."), subValue)
}
return nil, trace.CompareFailed("value %s cannot be cast to a map", parts[0])
}
// If the value is known we marshall it as JSON
if chartValue, ok := chartValues[parts[0]]; ok {
return json.Marshal(chartValue)
}
return nil, trace.NotFound("value '%s' not found", parts[0])
}
@@ -0,0 +1,40 @@
/*
Copyright 2023 Gravitational, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"os"
"testing"
"github.com/stretchr/testify/require"
)
const (
testChartPath = "./testdata"
testSnapshotPath = "./testdata/expected-output.mdx"
)
func Test_parseAndRender(t *testing.T) {
// Test setup: we load the fixtures
expected, err := os.ReadFile(testSnapshotPath)
require.NoError(t, err)
require.NotEmpty(t, expected)
// Test execution: we render templates, expect no error and check result
actual, err := parseAndRender(testChartPath)
require.NoError(t, err)
require.Equal(t, expected, actual)
}
@@ -0,0 +1,50 @@
/*
Copyright 2023 Gravitational, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"bytes"
"text/template"
"github.com/Masterminds/sprig/v3"
"github.com/gravitational/trace"
)
const referenceTemplate = `
{{- range .Values }}
#{{- range splitList "." .Name -}}#{{- end }} ` + "`" + `{{ .Name }}` + "`" + `
{{- if and .Kind .Default }}
| Type | Default |
|------|---------|
| ` + "`" + `{{.Kind}}` + "`" + ` | ` + "`" + `{{.Default}}` + "`" + ` |
{{- end }}
` + "`" + `{{.Name}}` + "`" + ` {{ .Description }}
{{- end -}}`
func renderTemplate(values []*Value) ([]byte, error) {
t := template.Must(template.New("reference").Funcs(sprig.FuncMap()).Parse(referenceTemplate))
params := struct {
Values []*Value
}{
values,
}
buf := &bytes.Buffer{}
err := t.Execute(buf, params)
return buf.Bytes(), trace.Wrap(err)
}
@@ -0,0 +1,7 @@
name: test-chart
apiVersion: v2
version: 0.0.0-test
appVersion: 0.0.0-test
description: This is a fake chart to test `render-helm-ref`
keywords:
- Test
@@ -0,0 +1,49 @@
## `authServer`
| Type | Default |
|------|---------|
| `string` | `""` |
`authServer` is the address of the Teleport cluster whose resources are managed
by the operator. The address must contain both the domain name and the port of
the Teleport cluster. It can be either the address of the auth servers or the
proxy servers.
For example:
- joining a Proxy: `teleport.example.com:443` or `teleport.example.com:3080`
- joining an Auth: `teleport-auth.example.com:3025`
## `annotations`
`annotations` allows to control Kubernetes annotations of the resources
created by the chart.
### `annotations.deployment`
| Type | Default |
|------|---------|
| `object` | `{}` |
`annotations.deployment` controls the Kubernetes Deployment annotations...
### `annotations.pod`
| Type | Default |
|------|---------|
| `object` | `{}` |
`annotations.pod` controls the Kubernetes Pod annotations...
## `podSecurityContext`
| Type | Default |
|------|---------|
| `object` | `{"fsGroup":65532,"runAsGroup":65532,"runAsNonRoot":true,"runAsUser":65532,"seccompProfile":"RuntimeDefault"}` |
`podSecurityContext` sets the pod security context for any pods created by the chart.
See [the Kubernetes documentation](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod)
for more details.
The default value supports running under the `restricted`
[Pod Security Standard](https://kubernetes.io/docs/concepts/security/pod-security-standards/).
@@ -0,0 +1,43 @@
# Simple documented value :)
# authServer(string) -- is the address of the Teleport cluster whose resources are managed
# by the operator. The address must contain both the domain name and the port of
# the Teleport cluster. It can be either the address of the auth servers or the
# proxy servers.
#
# For example:
# - joining a Proxy: `teleport.example.com:443` or `teleport.example.com:3080`
# - joining an Auth: `teleport-auth.example.com:3025`
authServer: ""
# Nested documented value, without the table on the parent.
# Here annotations will be documented but won't have a table showing its type
# and default value because its type is not specified.
# annotations -- allows to control Kubernetes annotations of the resources
# created by the chart.
annotations:
# annotations.deployment(object) -- controls the Kubernetes Deployment annotations...
deployment: {}
# annotations.pod(object) -- controls the Kubernetes Pod annotations...
pod: {}
# Nested values documented at the parent level.
# The podSecurityContext is documented as a single value. Its default will
# be serialized in JSON.
# podSecurityContext(object) -- sets the pod security context for any pods created by the chart.
# See [the Kubernetes documentation](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod)
# for more details.
#
# The default value supports running under the `restricted`
# [Pod Security Standard](https://kubernetes.io/docs/concepts/security/pod-security-standards/).
podSecurityContext:
seccompProfile: RuntimeDefault
runAsUser: 65532
runAsGroup: 65532
fsGroup: 65532
runAsNonRoot: true
# Undocumented value because there's no tag
foo: bar
+12 -9
View File
@@ -25,7 +25,7 @@ require (
require (
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.2.0 // indirect
github.com/Masterminds/semver/v3 v3.2.1 // indirect
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.15.0 // indirect
@@ -37,21 +37,21 @@ require (
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/huandu/xstrings v1.3.3 // indirect
github.com/imdario/mergo v0.3.11 // indirect
github.com/huandu/xstrings v1.4.0 // indirect
github.com/imdario/mergo v0.3.13 // indirect
github.com/jonboulle/clockwork v0.4.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mitchellh/copystructure v1.0.0 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/gon v0.2.5
github.com/mitchellh/reflectwalk v1.0.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rogpeppe/go-internal v1.11.0 // indirect
github.com/shopspring/decimal v1.2.0 // indirect
github.com/spf13/cast v1.3.1 // indirect
github.com/shopspring/decimal v1.3.1 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/xhit/go-str2duration/v2 v2.1.0 // indirect
golang.org/x/crypto v0.15.0 // indirect
golang.org/x/net v0.18.0 // indirect
@@ -63,7 +63,7 @@ require (
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gopkg.in/yaml.v3 v3.0.1
k8s.io/apimachinery v0.28.4 // indirect
k8s.io/klog/v2 v2.100.1 // indirect
k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect
@@ -71,9 +71,12 @@ require (
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
)
require helm.sh/helm/v3 v3.13.2
require (
github.com/google/go-github/v56 v56.0.0 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
)
replace github.com/alecthomas/kingpin/v2 => github.com/gravitational/kingpin/v2 v2.1.11-0.20230515143221-4ec6b70ecd33
+21 -9
View File
@@ -3,8 +3,9 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g=
github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0=
github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=
github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
@@ -26,7 +27,6 @@ github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XP
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -40,6 +40,7 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
@@ -112,10 +113,12 @@ github.com/hashicorp/go-retryablehttp v0.6.3/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER
github.com/hashicorp/go-retryablehttp v0.7.5 h1:bJj+Pj19UZMIweq/iie+1u5YCdGrnxCT9yvm0e+Nd5M=
github.com/hashicorp/go-retryablehttp v0.7.5/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
github.com/hashicorp/hcl/v2 v2.0.0/go.mod h1:oVVDG71tEinNGYCxinCYadcmKU9bglqW9pV3txagJ90=
github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4=
github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU=
github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=
github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
@@ -130,7 +133,6 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
@@ -144,18 +146,22 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ=
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/gon v0.2.5 h1:mVWtqTzV03W0avJqmqjk9M0qls3TDUXfc9ETJaPIOWY=
github.com/mitchellh/gon v0.2.5/go.mod h1:Ua18ZhqjZHg8VyqZo8kNHAY331ntV6nNJ9mT3s2mIo8=
github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY=
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
@@ -165,13 +171,15 @@ github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUz
github.com/sebdah/goldie v1.0.0 h1:9GNhIat69MSlz/ndaBg48vl9dF5fI+NBB6kfOxgfkMc=
github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -344,8 +352,11 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
helm.sh/helm/v3 v3.13.2 h1:IcO9NgmmpetJODLZhR3f3q+6zzyXVKlRizKFwbi7K8w=
helm.sh/helm/v3 v3.13.2/go.mod h1:GIHDwZggaTGbedevTlrQ6DB++LBN6yuQdeGj0HNaDx0=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0=
@@ -364,3 +375,4 @@ sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h6
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
+56
View File
@@ -0,0 +1,56 @@
# TODO(hugoShaka): uncomment the additional targets as we start sync-ing
# the reference and the values.yaml
.PHONY: render-chart-ref
render-chart-ref: render-chart-ref-example # render-chart-ref-teleport-cluster render-chart-ref-teleport-kube-agent render-chart-ref-teleport-operator
.PHONY: render-chart-ref-example
render-chart-ref-example:
cd ../../build.assets/tooling && \
go run ./cmd/render-helm-ref -chart ./cmd/render-helm-ref/testdata -output ./cmd/render-helm-ref/testdata/expected-output.mdx
# .PHONY: render-chart-ref-teleport-cluster
# render-chart-ref-teleport-cluster:
# cd ../../build.assets/tooling && \
# go run ./cmd/render-helm-ref -chart ../../examples/chart/teleport-cluster/ -output ../../docs/pages/reference/helm-reference/include/zz_generated.teleport-cluster.mdx
#
#
# .PHONY: render-chart-ref-teleport-kube-agent
# render-chart-ref-teleport-kube-agent:
# cd ../../build.assets/tooling && \
# go run ./cmd/render-helm-ref -chart ../../examples/chart/teleport-kube-agent/ -output ../../docs/pages/reference/helm-reference/include/zz_generated.teleport-kube-agent.mdx
#
# .PHONY: render-chart-ref-teleport-operator
# render-chart-ref-teleport-operator:
# cd ../../build.assets/tooling && \
# go run ./cmd/render-helm-ref -chart ../../examples/chart/teleport-operator/ -output ../../docs/pages/reference/helm-reference/include/zz_generated.teleport-operator.mdx
.PHONY: check-chart-ref
check-chart-ref: check-chart-ref-example #check-chart-ref-teleport-cluster check-chart-ref-teleport-kube-agent check-chart-ref-teleport-operator
.PHONY: check-chart-ref-example
check-chart-ref-example:
echo "Checking example chart reference"
cd ../../build.assets/tooling && \
go run ./cmd/render-helm-ref -chart ./cmd/render-helm-ref/testdata -output - | diff ../../build.assets/tooling/cmd/render-helm-ref/testdata/expected-output.mdx - || \
echo "Chart values.yaml and reference differ, please run 'make render-chart-ref'"
# .PHONY: check-chart-ref-teleport-cluster
# check-chart-ref-teleport-cluster:
# echo "Checking teleport-cluster reference"
# cd ../../build.assets/tooling && \
# go run ./cmd/render-helm-ref -chart ../../examples/chart/teleport-cluster -output - | diff ../../docs/pages/reference/helm-reference/include/zz_generated.teleport-cluster.mdx - || \
# echo "Chart values.yaml and reference differ, please run 'make render-chart-ref'"
#
# .PHONY: check-chart-ref-teleport-kube-agent
# check-chart-ref-teleport-kube-agent:
# echo "Checking teleport-kube-agent reference"
# cd ../../build.assets/tooling && \
# go run ./cmd/render-helm-ref -chart ../../examples/chart/teleport-kube-agent -output - | diff ../../docs/pages/reference/helm-reference/include/zz_generated.teleport-kube-agent.mdx - || \
# echo "Chart values.yaml and reference differ, please run 'make render-chart-ref'"
#
# .PHONY: check-chart-ref-teleport-operator
# check-chart-ref-teleport-operator:
# echo "Checking teleport-operator reference"
# cd ../../build.assets/tooling && \
# go run ./cmd/render-helm-ref -chart ../../examples/chart/teleport-cluster/charts/teleport-operator -output - | diff ../../docs/pages/reference/helm-reference/include/zz_generated.teleport-operator.mdx - || \
# echo "Chart values.yaml and reference differ, please run 'make render-chart-ref'"