mirror of
https://github.com/gravitational/teleport.git
synced 2026-10-12 02:15:01 +00:00
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:
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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=
|
||||
|
||||
@@ -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'"
|
||||
Reference in New Issue
Block a user