Compare commits
2 commits
main
...
generate-d
Author | SHA1 | Date | |
---|---|---|---|
![]() |
17431ba9dd | ||
![]() |
8f237e2b82 |
8 changed files with 1255 additions and 216 deletions
8
Makefile
8
Makefile
|
@ -99,3 +99,11 @@ delete-kind:
|
|||
kind delete cluster --name ${KIND_CLUSTER_NAME} || :
|
||||
|
||||
.PHONY: values-schema test-image test-unit test-bats test test-acceptance test-destroy test-provision acceptance provision-cluster destroy-cluster
|
||||
|
||||
# Generate Helm reference docs from values.yaml and update Vault website.
|
||||
# Usage: make gen-helm-docs vault=<path-to-vault-repo>.
|
||||
# If no options are given, the local copy of docs/helm.mdx will be updated, which can
|
||||
# be used to submit a PR to vault docs.
|
||||
# Adapted from https://github.com/hashicorp/consul-k8s/tree/main/hack/helm-reference-gen
|
||||
gen-helm-docs:
|
||||
@cd hack/helm-reference-gen; go run ./... --vault=$(vault)
|
||||
|
|
199
hack/helm-reference-gen/doc_node.go
Normal file
199
hack/helm-reference-gen/doc_node.go
Normal file
|
@ -0,0 +1,199 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const UnknownKindError = "unknown kind"
|
||||
|
||||
// DocNode is a node in the final generated reference document.
|
||||
// For example this would be a single DocNode:
|
||||
// ```
|
||||
// - `global` ((#v-global)) - Holds values that affect multiple components of the chart.
|
||||
// ```
|
||||
type DocNode struct {
|
||||
// Column is the character column (i.e. indent) this node should be displayed
|
||||
// at.
|
||||
// For example, if this is a root node, then its column will be 0 because it
|
||||
// shouldn't be indented.
|
||||
Column int
|
||||
|
||||
// ParentBreadcrumb is the path to this node's parent from the root.
|
||||
// It is used for the HTML anchor, e.g. `#v-global-name`.
|
||||
// If this node were global.name, then this would be set to "global".
|
||||
ParentBreadcrumb string
|
||||
|
||||
// ParentWasMap is true when the parent of this node was a map.
|
||||
ParentWasMap bool
|
||||
|
||||
// Key is the key of this node, e.g. if `key: value` then Key would be "key".
|
||||
Key string
|
||||
|
||||
// Default is the default value for this node, e.g. if key defaults to false,
|
||||
// Default would be "false".
|
||||
Default string
|
||||
|
||||
// Comment is the YAML comment that described this node.
|
||||
Comment string
|
||||
|
||||
// KindTag is the YAML parsed kind tag from the YAML library. This has values
|
||||
// like "!!seq" and "!!str".
|
||||
KindTag string
|
||||
|
||||
// Children are other nodes that should be displayed as sub-keys of this node.
|
||||
Children []DocNode
|
||||
}
|
||||
|
||||
// Validate returns an error if this node is invalid, else nil.
|
||||
func (n DocNode) Validate() error {
|
||||
kind := n.FormattedKind()
|
||||
if strings.Contains(kind, UnknownKindError) {
|
||||
return errors.New(kind)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// HTMLAnchor constructs the HTML anchor to be used to link to this node.
|
||||
func (n DocNode) HTMLAnchor() string {
|
||||
return fmt.Sprintf("%s-%s", n.ParentBreadcrumb, strings.ToLower(n.Key))
|
||||
}
|
||||
|
||||
// FormattedDefault returns the default value for this node formatted properly.
|
||||
func (n DocNode) FormattedDefault() string {
|
||||
// Check for the annotation first.
|
||||
if match := defaultAnnotation.FindAllStringSubmatch(n.Comment, -1); len(match) > 0 {
|
||||
// Handle it being set > 1 time. Use the last match.
|
||||
return match[len(match)-1][1]
|
||||
}
|
||||
|
||||
// We don't show the default if the kind is a map of arrays or map because the
|
||||
// default will be too big to show inline.
|
||||
if n.FormattedKind() == "array<map>" || n.FormattedKind() == "map" {
|
||||
return ""
|
||||
}
|
||||
|
||||
if n.Default != "" && n.Default != "null" {
|
||||
// Don't show multiline string defaults since it wouldn't fit.
|
||||
// We use > 2 because if it's extraConfig, e.g. `{}` then we want to
|
||||
// show it but if it's affinity then it doesn't make sense to show it.
|
||||
if len(strings.Split(n.Default, "\n")) > 2 {
|
||||
return ""
|
||||
}
|
||||
if n.FormattedKind() == "string" {
|
||||
return fmt.Sprintf("\"%s\"", strings.TrimSpace(n.Default))
|
||||
}
|
||||
return strings.TrimSpace(n.Default)
|
||||
}
|
||||
|
||||
// If we get here then the default is an empty string. We return quotes
|
||||
// in this case so it's clear it's an empty string. Otherwise it would look
|
||||
// like: `string: ` vs. `string: ""`.
|
||||
return `""`
|
||||
}
|
||||
|
||||
// FormattedDocumentation returns the formatted documentation for this node.
|
||||
func (n DocNode) FormattedDocumentation() string {
|
||||
doc := n.Comment
|
||||
|
||||
// Replace all leading YAML comment characters, e.g.
|
||||
// `# yaml comment` => `yaml comment`.
|
||||
doc = commentPrefix.ReplaceAllString(n.Comment, "")
|
||||
doc = strings.ReplaceAll(doc, "https://developer.hashicorp.com/vault/docs", "/vault/docs")
|
||||
|
||||
// Indent each line of the documentation so it lines up correctly.
|
||||
var indentedLines []string
|
||||
var inCodeBlock bool
|
||||
for i, line := range strings.Split(doc, "\n") {
|
||||
if strings.HasPrefix(line, "```") {
|
||||
inCodeBlock = !inCodeBlock
|
||||
}
|
||||
// If the line is a @type, @default or @recurse annotation we don't include it in
|
||||
// the markdown description.
|
||||
// This check must be before the i == 0 check because if there's only
|
||||
// one line in the description and it's the type description then we
|
||||
// want to discard it.
|
||||
if len(typeAnnotation.FindStringSubmatch(line)) > 0 ||
|
||||
len(defaultAnnotation.FindStringSubmatch(line)) > 0 ||
|
||||
len(recurseAnnotation.FindStringSubmatch(line)) > 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
var indentedLine string
|
||||
// The first line is printed inline with the key information so it
|
||||
// doesn't need to be indented, e.g.
|
||||
// `key - first line docs`
|
||||
if i == 0 {
|
||||
indentedLine = line
|
||||
} else if line != "" {
|
||||
if !inCodeBlock && !strings.HasPrefix(line, "```") {
|
||||
indentedLines[len(indentedLines)-1] += " " + line
|
||||
continue
|
||||
}
|
||||
indent := n.Column + 1
|
||||
if n.ParentWasMap {
|
||||
indent = n.Column
|
||||
}
|
||||
indentedLine = strings.Repeat(" ", indent) + line
|
||||
} else {
|
||||
// No need to add whitespace indent to a newline.
|
||||
}
|
||||
indentedLines = append(indentedLines, indentedLine)
|
||||
}
|
||||
|
||||
// Trim all final newlines and whitespace.
|
||||
return strings.TrimRight(strings.Join(indentedLines, "\n"), "\n ")
|
||||
}
|
||||
|
||||
// FormattedKind returns the kind of this node, e.g. string, boolean, etc.
|
||||
func (n DocNode) FormattedKind() string {
|
||||
// Check for the annotation first.
|
||||
if match := typeAnnotation.FindAllStringSubmatch(n.Comment, -1); len(match) > 0 {
|
||||
// Handle it being set > 1 time. Use the last match.
|
||||
return match[len(match)-1][1]
|
||||
}
|
||||
|
||||
// Special case for secretName, secretKey so they don't need to set
|
||||
// # type: string.
|
||||
if n.Key == "secretName" || n.Key == "secretKey" {
|
||||
return "string"
|
||||
}
|
||||
|
||||
// The YAML kind tag looks like "!!str".
|
||||
switch strings.TrimLeft(n.KindTag, "!") {
|
||||
case "str":
|
||||
return "string"
|
||||
case "int":
|
||||
return "int"
|
||||
case "bool":
|
||||
return "boolean"
|
||||
case "map":
|
||||
// We don't show the kind if its of type because it's obvious it's a map
|
||||
// because it will have subkeys and so showing the type as map would
|
||||
// just complicate reading without any benefit.
|
||||
// NOTE: If it's been explicitly annotated with @type: map then we
|
||||
// will show it as that is handled above via the typeAnnotation regex
|
||||
// match.
|
||||
return ""
|
||||
case "seq":
|
||||
return "array"
|
||||
case "null":
|
||||
return ""
|
||||
default:
|
||||
return fmt.Sprintf("%s '%v'", UnknownKindError, n.KindTag)
|
||||
}
|
||||
}
|
||||
|
||||
// LeadingIndent returns the leading indentation for the first line of this
|
||||
// node.
|
||||
func (n DocNode) LeadingIndent() string {
|
||||
indent := n.Column - 1
|
||||
if n.ParentWasMap {
|
||||
indent = n.Column - 3
|
||||
}
|
||||
return strings.Repeat(" ", indent)
|
||||
}
|
13
hack/helm-reference-gen/go.mod
Normal file
13
hack/helm-reference-gen/go.mod
Normal file
|
@ -0,0 +1,13 @@
|
|||
module github.com/hashicorp/consul-k8s/hack/helm-reference-gen
|
||||
|
||||
go 1.19
|
||||
|
||||
require (
|
||||
github.com/stretchr/testify v1.6.1
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
)
|
12
hack/helm-reference-gen/go.sum
Normal file
12
hack/helm-reference-gen/go.sum
Normal file
|
@ -0,0 +1,12 @@
|
|||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/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=
|
425
hack/helm-reference-gen/main.go
Normal file
425
hack/helm-reference-gen/main.go
Normal file
|
@ -0,0 +1,425 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package main
|
||||
|
||||
// This script generates markdown documentation out of the values.yaml file
|
||||
// for use on vault.io.
|
||||
//
|
||||
// Usage: make gen-helm-docs [vault-repo-path] [-validate]
|
||||
// Where [vault-repo-path] is the location of the hashicorp/vault repo. Defaults to ../../../vault.
|
||||
// If -validate is set, the generated docs won't be output anywhere.
|
||||
// This is useful in CI to ensure the generation will succeed.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
const (
|
||||
tocPrefix = "## Top-Level Stanzas\n\nUse these links to navigate to a particular top-level stanza.\n\n"
|
||||
tocSuffix = "\n## All Values"
|
||||
)
|
||||
|
||||
var (
|
||||
// typeAnnotation matches the @type annotation. It captures the value of @type.
|
||||
typeAnnotation = regexp.MustCompile(`(?m).*@type: (.*)$`)
|
||||
|
||||
// defaultAnnotation matches the @default annotation. It captures the value of @default.
|
||||
defaultAnnotation = regexp.MustCompile(`(?m).*@default: (.*)$`)
|
||||
|
||||
// recurseAnnotation matches the @recurse annotation. It captures the value of @recurse.
|
||||
recurseAnnotation = regexp.MustCompile(`(?m).*@recurse: (.*)$`)
|
||||
|
||||
// commentPrefix matches on the YAML comment prefix, e.g.
|
||||
// ```
|
||||
// # comment here
|
||||
// # comment with indent
|
||||
// ```
|
||||
// Will match on "comment here" and "comment with indent".
|
||||
//
|
||||
// It also properly handles YAML comments inside code fences, e.g.
|
||||
// ```
|
||||
// # Example:
|
||||
// # ```yaml
|
||||
// # # yaml comment
|
||||
// # ````
|
||||
// ```
|
||||
// And will not match the "# yaml comment" incorrectly.
|
||||
commentPrefix = regexp.MustCompile(`(?m)^[^\S\n]*#[^\S\n]?`)
|
||||
|
||||
funcMap = template.FuncMap{
|
||||
"ToLower": strings.ToLower,
|
||||
}
|
||||
|
||||
// docNodeTmpl is the go template used to print a DocNode node.
|
||||
// We use $ instead of ` in the template so we can use the golang raw string
|
||||
// format. We then do the replace from $ => `.
|
||||
docNodeTmpl = template.Must(
|
||||
template.New("").Funcs(funcMap).Parse(
|
||||
strings.Replace(
|
||||
`{{- if eq .Column 1 }}## {{ .Key }}
|
||||
|
||||
{{ end }}{{ .LeadingIndent }}- ${{ .Key }}${{ if ne .FormattedKind "" }} (${{ .FormattedKind }}{{ if .FormattedDefault }}: {{ .FormattedDefault }}{{ end }}$){{ end }}{{ if .FormattedDocumentation}} - {{ .FormattedDocumentation }}{{ end }}`,
|
||||
"$", "`", -1)),
|
||||
)
|
||||
)
|
||||
|
||||
func main() {
|
||||
validateFlag := flag.Bool("validate", false, "only validate that the markdown can be generated, don't actually generate anything")
|
||||
vaultMdxFlag := flag.String("vault", "", "path to the helm reference documentation file")
|
||||
chartDocsPath := "../../"
|
||||
flag.Parse()
|
||||
|
||||
if *vaultMdxFlag == "" {
|
||||
*vaultMdxFlag = "docs/helm.mdx"
|
||||
}
|
||||
|
||||
if len(os.Args) > 3 {
|
||||
fmt.Println("Error: extra arguments")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if !*validateFlag {
|
||||
// Only argument is path to Vault repo. If not set then we default.
|
||||
if len(os.Args) < 2 {
|
||||
abs, _ := filepath.Abs(chartDocsPath)
|
||||
fmt.Printf("Defaulting to Vault repo path: %s\n", abs)
|
||||
} else {
|
||||
// Support absolute and relative paths to the Vault repo.
|
||||
if filepath.IsAbs(os.Args[1]) {
|
||||
chartDocsPath = os.Args[1]
|
||||
} else {
|
||||
chartDocsPath = filepath.Join("../..", *vaultMdxFlag)
|
||||
}
|
||||
abs, _ := filepath.Abs(chartDocsPath)
|
||||
fmt.Printf("Using Vault repo path: %s\n", abs)
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the values.yaml file.
|
||||
inputBytes, err := os.ReadFile("../../values.yaml")
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
out, err := GenerateDocs(string(inputBytes))
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// If we're just validating that generation will succeed then we're done.
|
||||
if *validateFlag {
|
||||
fmt.Println("Validation successful")
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
// Otherwise we'll go on to write the changes to the helm docs.
|
||||
helmReferenceFile := filepath.Join(chartDocsPath)
|
||||
helmReferenceBytes, err := os.ReadFile(helmReferenceFile)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
helmReferenceContents := string(helmReferenceBytes)
|
||||
|
||||
// Swap out the contents between the codegen markers.
|
||||
startStr := "<!-- codegen: start -->\n\n"
|
||||
endStr := "\n<!-- codegen: end -->"
|
||||
start := strings.Index(helmReferenceContents, startStr)
|
||||
if start == -1 {
|
||||
fmt.Printf("%q not found in %q\n", startStr, helmReferenceFile)
|
||||
os.Exit(1)
|
||||
}
|
||||
end := strings.Index(helmReferenceContents, endStr)
|
||||
if end == -1 {
|
||||
fmt.Printf("%q not found in %q\n", endStr, helmReferenceFile)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
newMdx := helmReferenceContents[0:start+len(startStr)] + out + helmReferenceContents[end:]
|
||||
err = os.WriteFile(helmReferenceFile, []byte(newMdx), 0o644)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
abs, _ := filepath.Abs(helmReferenceFile)
|
||||
fmt.Printf("Updated with generated docs: %s\n", abs)
|
||||
}
|
||||
|
||||
func GenerateDocs(yamlStr string) (string, error) {
|
||||
node, err := Parse(yamlStr)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to parse values.yaml: %w", err)
|
||||
}
|
||||
|
||||
children, err := generateDocsFromNode(docNodeTmpl, node)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// enterpriseSubst := strings.ReplaceAll(strings.Join(children, "\n\n"), "[Enterprise Only]", "<EnterpriseAlert inline />")
|
||||
|
||||
// // Add table of contents.
|
||||
// toc := generateTOC(node)
|
||||
return strings.Join(children, "\n\n") + "\n\n", nil
|
||||
}
|
||||
|
||||
// Parse parses yamlStr into a tree of DocNode's.
|
||||
func Parse(yamlStr string) (DocNode, error) {
|
||||
var node yaml.Node
|
||||
err := yaml.Unmarshal([]byte(yamlStr), &node)
|
||||
if err != nil {
|
||||
return DocNode{}, err
|
||||
}
|
||||
|
||||
// Due to how the YAML is parsed this is the first real node.
|
||||
rootNode := node.Content[0].Content
|
||||
children, err := parseNodeContent(rootNode, "", false)
|
||||
if err != nil {
|
||||
return DocNode{}, err
|
||||
}
|
||||
return DocNode{
|
||||
Column: 0,
|
||||
Children: children,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// parseNodeContent recursively parses the yaml nodes and outputs a DocNode
|
||||
// tree.
|
||||
func parseNodeContent(nodeContent []*yaml.Node, parentBreadcrumb string, parentWasMap bool) ([]DocNode, error) {
|
||||
var docNodes []DocNode
|
||||
|
||||
// This is a special type of node where it's an array of maps.
|
||||
// e.g.
|
||||
// ````
|
||||
// ingressGateways:
|
||||
// - name: name
|
||||
// ````
|
||||
//
|
||||
// In this case we show the docs as:
|
||||
// - ingress-gateway: ingress gateway descrip
|
||||
// - name: name descrip.
|
||||
//
|
||||
// To do that, we actually need to skip the map node.
|
||||
if len(nodeContent) == 1 {
|
||||
return parseNodeContent(nodeContent[0].Content, parentBreadcrumb, true)
|
||||
}
|
||||
|
||||
// skipNext is true if we should skip the next node. Due to how the YAML is
|
||||
// parsed, a key: value pair results in two YAML nodes but we only need
|
||||
// doc node out of that so in the loop we look ahead to the next node
|
||||
// and use it to construct our DocNode. Then we can skip it on the next
|
||||
// iteration.
|
||||
skipNext := false
|
||||
for i, child := range nodeContent {
|
||||
if skipNext {
|
||||
skipNext = false
|
||||
continue
|
||||
}
|
||||
|
||||
docNode, err := buildDocNode(i, child, nodeContent, parentBreadcrumb, parentWasMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := docNode.Validate(); err != nil {
|
||||
return nil, &ParseError{
|
||||
FullAnchor: docNode.HTMLAnchor(),
|
||||
Err: err.Error(),
|
||||
}
|
||||
}
|
||||
|
||||
docNodes = append(docNodes, docNode)
|
||||
skipNext = true
|
||||
continue
|
||||
}
|
||||
return docNodes, nil
|
||||
}
|
||||
|
||||
func generateDocsFromNode(tm *template.Template, node DocNode) ([]string, error) {
|
||||
var out []string
|
||||
for _, child := range node.Children {
|
||||
var nodeOut bytes.Buffer
|
||||
err := tm.Execute(&nodeOut, child)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
childOut, err := generateDocsFromNode(tm, child)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out = append(append(out, nodeOut.String()), childOut...)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// allScalars returns true if content contains only scalar nodes
|
||||
// with no chidren.
|
||||
func allScalars(content []*yaml.Node) bool {
|
||||
for _, n := range content {
|
||||
if n.Kind != yaml.ScalarNode || len(n.Content) > 0 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// toInlineYaml will return the yaml string representation for content
|
||||
// using the inline representation, i.e. `["a", "b"]`
|
||||
// instead of:
|
||||
// ```
|
||||
// - "a"
|
||||
// - "b"
|
||||
// ```
|
||||
func toInlineYaml(content []*yaml.Node) (string, error) {
|
||||
// We have to use this struct so we can set the struct tag "flow" so the
|
||||
// generated yaml uses the inline format.
|
||||
type intermediary struct {
|
||||
Arr []*yaml.Node `yaml:"arr,flow"`
|
||||
}
|
||||
i := intermediary{
|
||||
Arr: content,
|
||||
}
|
||||
out, err := yaml.Marshal(i)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
// Hack: because we had to use our struct, it has the key "arr: " which
|
||||
// we need to trim. Before trimming it will look like:
|
||||
// `arr: ["a","b"]`.
|
||||
return strings.TrimPrefix(string(out), "arr: "), nil
|
||||
}
|
||||
|
||||
func buildDocNode(nodeContentIdx int, currNode *yaml.Node, nodeContent []*yaml.Node, parentBreadcrumb string, parentWasMap bool) (DocNode, error) {
|
||||
// Check for the @recurse: false annotation.
|
||||
// In this case we construct our node and then don't recurse further.
|
||||
if match := recurseAnnotation.FindStringSubmatch(currNode.HeadComment); len(match) > 0 && match[1] == "false" {
|
||||
return DocNode{
|
||||
Column: currNode.Column,
|
||||
ParentBreadcrumb: parentBreadcrumb,
|
||||
ParentWasMap: false,
|
||||
Key: currNode.Value,
|
||||
Comment: currNode.HeadComment,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Nodes should come in pairs.
|
||||
if len(nodeContent) < nodeContentIdx+1 {
|
||||
return DocNode{}, &ParseError{
|
||||
ParentAnchor: parentBreadcrumb,
|
||||
CurrAnchor: currNode.Value,
|
||||
Err: fmt.Sprintf("content length incorrect, expected %d got %d", nodeContentIdx+1, len(nodeContent)),
|
||||
}
|
||||
}
|
||||
|
||||
next := nodeContent[nodeContentIdx+1]
|
||||
|
||||
switch next.Kind {
|
||||
|
||||
// If it's a scalar then this is a simple key: value node.
|
||||
case yaml.ScalarNode:
|
||||
return DocNode{
|
||||
ParentBreadcrumb: parentBreadcrumb,
|
||||
ParentWasMap: parentWasMap,
|
||||
Column: currNode.Column,
|
||||
Key: currNode.Value,
|
||||
Comment: currNode.HeadComment,
|
||||
KindTag: next.Tag,
|
||||
Default: next.Value,
|
||||
}, nil
|
||||
|
||||
// If it's a map then we will need to recurse into it.
|
||||
case yaml.MappingNode:
|
||||
docNode := DocNode{
|
||||
ParentBreadcrumb: parentBreadcrumb,
|
||||
ParentWasMap: parentWasMap,
|
||||
Column: currNode.Column,
|
||||
Key: currNode.Value,
|
||||
Comment: currNode.HeadComment,
|
||||
KindTag: next.Tag,
|
||||
}
|
||||
var err error
|
||||
docNode.Children, err = parseNodeContent(next.Content, docNode.HTMLAnchor(), false)
|
||||
if err != nil {
|
||||
return DocNode{}, err
|
||||
}
|
||||
return docNode, nil
|
||||
|
||||
// If it's a sequence, i.e. array, then we have to handle it differently
|
||||
// depending on its contents.
|
||||
case yaml.SequenceNode:
|
||||
// If it's empty then its just a key with a default of empty array.
|
||||
if len(next.Content) == 0 {
|
||||
return DocNode{
|
||||
ParentBreadcrumb: parentBreadcrumb,
|
||||
ParentWasMap: parentWasMap,
|
||||
Column: currNode.Column,
|
||||
Key: currNode.Value,
|
||||
// Default is empty array.
|
||||
Default: "[]",
|
||||
Comment: currNode.HeadComment,
|
||||
KindTag: next.Tag,
|
||||
}, nil
|
||||
|
||||
// If it's full of scalars, e.g. key: [a, b] then we can stop recursing
|
||||
// and use the value as the default.
|
||||
} else if allScalars(next.Content) {
|
||||
inlineYaml, err := toInlineYaml(next.Content)
|
||||
if err != nil {
|
||||
return DocNode{}, &ParseError{
|
||||
ParentAnchor: parentBreadcrumb,
|
||||
CurrAnchor: currNode.Value,
|
||||
Err: err.Error(),
|
||||
}
|
||||
}
|
||||
return DocNode{
|
||||
ParentBreadcrumb: parentBreadcrumb,
|
||||
ParentWasMap: parentWasMap,
|
||||
Column: currNode.Column,
|
||||
Key: currNode.Value,
|
||||
// Default will be the yaml value.
|
||||
Default: inlineYaml,
|
||||
Comment: currNode.HeadComment,
|
||||
KindTag: next.Tag,
|
||||
}, nil
|
||||
} else {
|
||||
|
||||
// Otherwise we need to recurse into each element of the array.
|
||||
docNode := DocNode{
|
||||
ParentBreadcrumb: parentBreadcrumb,
|
||||
ParentWasMap: parentWasMap,
|
||||
Column: currNode.Column,
|
||||
Key: currNode.Value,
|
||||
Comment: currNode.HeadComment,
|
||||
KindTag: next.Tag,
|
||||
}
|
||||
var err error
|
||||
docNode.Children, err = parseNodeContent(next.Content, docNode.HTMLAnchor(), false)
|
||||
if err != nil {
|
||||
return DocNode{}, err
|
||||
}
|
||||
return docNode, nil
|
||||
}
|
||||
}
|
||||
return DocNode{}, fmt.Errorf("fell through cases unexpectedly at breadcrumb: %s", parentBreadcrumb)
|
||||
}
|
||||
|
||||
func generateTOC(node DocNode) string {
|
||||
toc := tocPrefix
|
||||
|
||||
for _, c := range node.Children {
|
||||
toc += fmt.Sprintf("- [`%s`](#h-%s)\n", c.Key, strings.ToLower(c.Key))
|
||||
}
|
||||
|
||||
return toc + tocSuffix
|
||||
}
|
190
hack/helm-reference-gen/main_test.go
Normal file
190
hack/helm-reference-gen/main_test.go
Normal file
|
@ -0,0 +1,190 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// Test various smaller cases and special cases.
|
||||
func Test(t *testing.T) {
|
||||
cases := map[string]struct {
|
||||
Input string
|
||||
Exp string
|
||||
}{
|
||||
"string value": {
|
||||
Input: `---
|
||||
# Line 1
|
||||
# Line 2
|
||||
key: value`,
|
||||
Exp: `- [$key$](#h-key)
|
||||
|
||||
## All Values
|
||||
|
||||
### key ((#h-key))
|
||||
|
||||
- $key$ ((#v-key)) ($string: value$) - Line 1\n Line 2
|
||||
`,
|
||||
},
|
||||
"integer value": {
|
||||
Input: `---
|
||||
# Line 1
|
||||
# Line 2
|
||||
replicas: 3`,
|
||||
Exp: `- [$replicas$](#h-replicas)
|
||||
|
||||
## All Values
|
||||
|
||||
### replicas ((#h-replicas))
|
||||
|
||||
- $replicas$ ((#v-replicas)) ($integer: 3$) - Line 1\n Line 2
|
||||
`,
|
||||
},
|
||||
"boolean value": {
|
||||
Input: `---
|
||||
# Line 1
|
||||
# Line 2
|
||||
enabled: true`,
|
||||
Exp: `- [$enabled$](#h-enabled)
|
||||
|
||||
## All Values
|
||||
|
||||
### enabled ((#h-enabled))
|
||||
|
||||
- $enabled$ ((#v-enabled)) ($boolean: true$) - Line 1\n Line 2
|
||||
`,
|
||||
},
|
||||
"map": {
|
||||
Input: `---
|
||||
# Map line 1
|
||||
# Map line 2
|
||||
map:
|
||||
# Key line 1
|
||||
# Key line 2
|
||||
key: value`,
|
||||
Exp: `- [$map$](#h-map)
|
||||
|
||||
## All Values
|
||||
|
||||
### map ((#h-map))
|
||||
|
||||
- $map$ ((#v-map)) - Map line 1\n Map line 2
|
||||
|
||||
- $key$ ((#v-map-key)) ($string: value$) - Key line 1\n Key line 2
|
||||
`,
|
||||
},
|
||||
"map with multiple keys": {
|
||||
Input: `---
|
||||
# Map line 1
|
||||
# Map line 2
|
||||
map:
|
||||
# Key line 1
|
||||
# Key line 2
|
||||
key: value
|
||||
# Int docs
|
||||
int: 1
|
||||
# Bool docs
|
||||
bool: true`,
|
||||
Exp: `- [$map$](#h-map)
|
||||
|
||||
## All Values
|
||||
|
||||
### map ((#h-map))
|
||||
|
||||
- $map$ ((#v-map)) - Map line 1\n Map line 2
|
||||
|
||||
- $key$ ((#v-map-key)) ($string: value$) - Key line 1
|
||||
Key line 2
|
||||
|
||||
- $int$ ((#v-map-int)) ($integer: 1$) - Int docs
|
||||
|
||||
- $bool$ ((#v-map-bool)) ($boolean: true$) - Bool docs
|
||||
`,
|
||||
},
|
||||
"null value": {
|
||||
Input: `---
|
||||
# key docs
|
||||
# @type: string
|
||||
key: null`,
|
||||
Exp: `- [$key$](#h-key)
|
||||
|
||||
## All Values
|
||||
|
||||
### key ((#h-key))
|
||||
|
||||
- $key$ ((#v-key)) ($string: null$) - key docs
|
||||
`,
|
||||
},
|
||||
"description with empty line": {
|
||||
Input: `---
|
||||
# line 1
|
||||
#
|
||||
# line 2
|
||||
key: value`,
|
||||
Exp: `- [$key$](#h-key)
|
||||
|
||||
## All Values
|
||||
|
||||
### key ((#h-key))
|
||||
|
||||
- $key$ ((#v-key)) ($string: value$) - line 1\n\n line 2
|
||||
`,
|
||||
},
|
||||
"array of strings": {
|
||||
Input: `---
|
||||
# line 1
|
||||
# @type: array<string>
|
||||
serverAdditionalDNSSANs: []
|
||||
`,
|
||||
Exp: `- [$serverAdditionalDNSSANs$](#h-serveradditionaldnssans)
|
||||
|
||||
## All Values
|
||||
|
||||
### serverAdditionalDNSSANs ((#h-serveradditionaldnssans))
|
||||
|
||||
- $serverAdditionalDNSSANs$ ((#v-serveradditionaldnssans)) ($array<string>: []$) - line 1
|
||||
`,
|
||||
},
|
||||
}
|
||||
|
||||
for name, c := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
// Swap $ for `.
|
||||
input := strings.Replace(c.Input, "$", "`", -1)
|
||||
|
||||
out, err := GenerateDocs(input)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Swap $ for `.
|
||||
exp := strings.Replace(c.Exp, "$", "`", -1)
|
||||
|
||||
// Swap \n for real \n.
|
||||
exp = strings.Replace(exp, "\\n", "\n", -1)
|
||||
|
||||
exp = tocPrefix + exp
|
||||
|
||||
require.Equal(t, exp, out)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Test against a full values file and compare against a golden file.
|
||||
func TestFullValues(t *testing.T) {
|
||||
inputBytes, err := os.ReadFile(filepath.Join("fixtures", "full-values.yaml"))
|
||||
require.NoError(t, err)
|
||||
expBytes, err := os.ReadFile(filepath.Join("fixtures", "full-values.golden"))
|
||||
require.NoError(t, err)
|
||||
|
||||
actual, err := GenerateDocs(string(inputBytes))
|
||||
require.NoError(t, err)
|
||||
if actual != string(expBytes) {
|
||||
require.NoError(t, os.WriteFile(filepath.Join("fixtures", "full-values.actual"), []byte(actual), 0o644))
|
||||
require.FailNow(t, "output not equal, actual output to full-values.actual")
|
||||
}
|
||||
}
|
23
hack/helm-reference-gen/parse_error.go
Normal file
23
hack/helm-reference-gen/parse_error.go
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
// ParseError is an error that occurs during parsing.
|
||||
// It's used to include information about which node failed to parse.
|
||||
type ParseError struct {
|
||||
ParentAnchor string
|
||||
CurrAnchor string
|
||||
FullAnchor string
|
||||
Err string
|
||||
}
|
||||
|
||||
func (p *ParseError) Error() string {
|
||||
anchor := p.FullAnchor
|
||||
if anchor == "" {
|
||||
anchor = fmt.Sprintf("%s-%s", p.ParentAnchor, p.CurrAnchor)
|
||||
}
|
||||
return fmt.Sprintf("%s: %s", anchor, p.Err)
|
||||
}
|
601
values.yaml
601
values.yaml
|
@ -3,187 +3,260 @@
|
|||
|
||||
# Available parameters and their default values for the Vault chart.
|
||||
|
||||
# These global values affect multiple components of the chart.
|
||||
global:
|
||||
# enabled is the master enabled switch. Setting this to true or false
|
||||
# will enable or disable all the components within this chart by default.
|
||||
# The global enabled/disabled configuration. If this is true, most components
|
||||
# will be installed by default. If this is false, no components will be
|
||||
# installed by default and manually opting-in is required, such as by setting
|
||||
# `server.enabled` to true.
|
||||
enabled: true
|
||||
|
||||
# Image pull secret to use for registry authentication.
|
||||
# Alternatively, the value may be specified as an array of strings.
|
||||
imagePullSecrets: []
|
||||
# References secrets to be used when pulling images from private registries.
|
||||
# See [Pull an Image from a Private Registry](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/)
|
||||
# for more details. May be specified as an array of name map entries or just
|
||||
# as an array of names:
|
||||
#
|
||||
# ```yaml
|
||||
# imagePullSecrets:
|
||||
# - name: image-pull-secret
|
||||
# # or
|
||||
# imagePullSecrets:
|
||||
# - image-pull-secret
|
||||
# ```
|
||||
imagePullSecrets: []
|
||||
|
||||
# TLS for end-to-end encrypted transport
|
||||
# When set to `true`, changes URLs from `https` to `http` (such as the
|
||||
# `VAULT_ADDR=http://127.0.0.1:8200` environment variable set on the
|
||||
# Vault pods).
|
||||
tlsDisable: true
|
||||
|
||||
# External vault server address for the injector and CSI provider to use.
|
||||
# Setting this will disable deployment of a vault server.
|
||||
# Setting this will disable deployment of a vault server. A service account
|
||||
# with token review permissions is automatically created if
|
||||
# `server.serviceAccount.create=true` is set for the external Vault server
|
||||
# to use.
|
||||
externalVaultAddr: ""
|
||||
|
||||
# If deploying to OpenShift
|
||||
# If `true`, enables configuration specific to OpenShift such as NetworkPolicy,
|
||||
# SecurityContext, and Route.
|
||||
openshift: false
|
||||
|
||||
# Create PodSecurityPolicy for pods
|
||||
# Values that configure Pod Security Policy.
|
||||
psp:
|
||||
# When set to `true`, enables Pod Security Policies for Vault and Vault Agent Injector.
|
||||
enable: false
|
||||
# Annotation for PodSecurityPolicy.
|
||||
# This is a multi-line templated string map, and can also be set as YAML.
|
||||
# This value defines additional annotations to add to the Pod Security
|
||||
# Policies. This can either be YAML or a YAML-formatted multi-line templated
|
||||
# string.
|
||||
#
|
||||
# ```yaml
|
||||
# annotations:
|
||||
# seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/default,runtime/default
|
||||
# apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default
|
||||
# seccomp.security.alpha.kubernetes.io/defaultProfileName: runtime/default
|
||||
# apparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default
|
||||
# # or
|
||||
# annotations: |
|
||||
# seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/default,runtime/default
|
||||
# apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default
|
||||
# seccomp.security.alpha.kubernetes.io/defaultProfileName: runtime/default
|
||||
# apparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default
|
||||
# ```
|
||||
annotations: |
|
||||
seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/default,runtime/default
|
||||
apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default
|
||||
seccomp.security.alpha.kubernetes.io/defaultProfileName: runtime/default
|
||||
apparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default
|
||||
|
||||
# Values that configure metrics and telemetry.
|
||||
serverTelemetry:
|
||||
# Enable integration with the Prometheus Operator
|
||||
# See the top level serverTelemetry section below before enabling this feature.
|
||||
# When set to `true`, enables integration with the Prometheus Operator. Be
|
||||
# sure to configure the top-level [`serverTelemetry`](https://developer.hashicorp.com/vault/docs/platform/k8s/helm/configuration#servertelemetry-1)
|
||||
# section for more details and required configuration values.
|
||||
prometheusOperator: false
|
||||
|
||||
# Values that configure running a Vault Agent Injector Admission Webhook
|
||||
# Controller within Kubernetes.
|
||||
injector:
|
||||
# True if you want to enable vault agent injection.
|
||||
# @default: global.enabled
|
||||
# When set to `true`, the Vault Agent Injector Admission Webhook controller
|
||||
# will be created. When set to `"-"`, defaults to the value of `global.enabled`.
|
||||
# @type: boolean or string
|
||||
enabled: "-"
|
||||
|
||||
replicas: 1
|
||||
|
||||
# Configures the port the injector should listen on
|
||||
port: 8080
|
||||
|
||||
# If multiple replicas are specified, by default a leader will be determined
|
||||
# so that only one injector attempts to create TLS certificates.
|
||||
leaderElector:
|
||||
enabled: true
|
||||
|
||||
# If true, will enable a node exporter metrics endpoint at /metrics.
|
||||
metrics:
|
||||
enabled: false
|
||||
|
||||
# Deprecated: Please use global.externalVaultAddr instead.
|
||||
|
||||
# Deprecated: Please use [global.externalVaultAddr](https://developer.hashicorp.com/vault/docs/platform/k8s/helm/configuration#externalvaultaddr)
|
||||
# instead.
|
||||
externalVaultAddr: ""
|
||||
|
||||
# image sets the repo and tag of the vault-k8s image to use for the injector.
|
||||
# The number of pods to deploy to create a highly available cluster of Vault
|
||||
# Agent Injectors. Requires Vault K8s 0.7.0 to have more than 1 replica.
|
||||
replicas: 1
|
||||
|
||||
# Values that configure the Vault Agent Injector leader election for HA
|
||||
# deployments.
|
||||
leaderElector:
|
||||
# When set to `true`, enables leader election for Vault Agent Injector. This
|
||||
# is required when using auto-tls and more than 1 replica.
|
||||
enabled: true
|
||||
|
||||
# Values that configure the Vault Agent Injector Docker image.
|
||||
image:
|
||||
# The name of the Docker image for Vault Agent Injector.
|
||||
repository: "hashicorp/vault-k8s"
|
||||
# The tag of the Docker image for the Vault Agent Injector. **This should
|
||||
# be pinned to a specific version when running in production.** Otherwise,
|
||||
# other changes to the chart may inadvertently upgrade your admission controller.
|
||||
tag: "1.2.1"
|
||||
# The pull policy for container images. The default pull policy is `IfNotPresent`
|
||||
# which causes the Kubelet to skip pulling an image if it already exists.
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
# agentImage sets the repo and tag of the Vault image to use for the Vault Agent
|
||||
# containers. This should be set to the official Vault image. Vault 1.3.1+ is
|
||||
# required.
|
||||
# Values that configure the Vault Agent sidecar image.
|
||||
agentImage:
|
||||
# The name of the Docker image for the Vault Agent sidecar. This should be
|
||||
# set to the official Vault Docker image.
|
||||
repository: "hashicorp/vault"
|
||||
# The tag of the Vault Docker image to use for the Vault Agent Sidecar.
|
||||
# **Vault 1.3.1+ is required by the admission controller**.
|
||||
tag: "1.13.1"
|
||||
|
||||
# The default values for the injected Vault Agent containers.
|
||||
# Values that configure the injected Vault Agent containers default values.
|
||||
# For more information on configuring resources, see the Kubernetes documentation:
|
||||
# https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
|
||||
agentDefaults:
|
||||
# For more information on configuring resources, see the K8s documentation:
|
||||
# https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
|
||||
# The default CPU limit for injected Vault Agent containers.
|
||||
cpuLimit: "500m"
|
||||
# The default CPU request for injected Vault Agent containers.
|
||||
cpuRequest: "250m"
|
||||
# The default memory limit for injected Vault Agent containers.
|
||||
memLimit: "128Mi"
|
||||
# The default memory request for injected Vault Agent containers.
|
||||
memRequest: "64Mi"
|
||||
|
||||
# Default template type for secrets when no custom template is specified.
|
||||
# Possible values include: "json" and "map".
|
||||
# The default template type for rendered secrets if no custom templates are
|
||||
# defined. Possible values include `map` and `json`.
|
||||
template: "map"
|
||||
|
||||
# Default values within Agent's template_config stanza.
|
||||
# Default values within Agent's [`template_config` stanza](https://developer.hashicorp.com/vault/docs/agent/template).
|
||||
templateConfig:
|
||||
# Controls whether Vault Agent exits after it has exhausted its number of
|
||||
# template retry attempts due to failures.
|
||||
exitOnRetryFailure: true
|
||||
# Configures how often Vault Agent Template should render non-leased secrets
|
||||
# such as KV v2. See the [Vault Agent Templates documentation](/docs/agent/template#non-renewable-secrets)
|
||||
# for more details.
|
||||
staticSecretRenderInterval: ""
|
||||
|
||||
# Used to define custom livenessProbe settings
|
||||
livenessProbe:
|
||||
# When a probe fails, Kubernetes will try failureThreshold times before giving up
|
||||
failureThreshold: 2
|
||||
# Number of seconds after the container has started before probe initiates
|
||||
initialDelaySeconds: 5
|
||||
# How often (in seconds) to perform the probe
|
||||
periodSeconds: 2
|
||||
# Minimum consecutive successes for the probe to be considered successful after having failed
|
||||
successThreshold: 1
|
||||
# Number of seconds after which the probe times out.
|
||||
timeoutSeconds: 5
|
||||
# Used to define custom readinessProbe settings
|
||||
readinessProbe:
|
||||
# When a probe fails, Kubernetes will try failureThreshold times before giving up
|
||||
failureThreshold: 2
|
||||
# Number of seconds after the container has started before probe initiates
|
||||
initialDelaySeconds: 5
|
||||
# How often (in seconds) to perform the probe
|
||||
periodSeconds: 2
|
||||
# Minimum consecutive successes for the probe to be considered successful after having failed
|
||||
successThreshold: 1
|
||||
# Number of seconds after which the probe times out.
|
||||
timeoutSeconds: 5
|
||||
# Used to define custom startupProbe settings
|
||||
startupProbe:
|
||||
# When a probe fails, Kubernetes will try failureThreshold times before giving up
|
||||
failureThreshold: 12
|
||||
# Number of seconds after the container has started before probe initiates
|
||||
initialDelaySeconds: 5
|
||||
# How often (in seconds) to perform the probe
|
||||
periodSeconds: 5
|
||||
# Minimum consecutive successes for the probe to be considered successful after having failed
|
||||
successThreshold: 1
|
||||
# Number of seconds after which the probe times out.
|
||||
timeoutSeconds: 5
|
||||
# Values that configure the Vault Agent Injector metric exporter.
|
||||
metrics:
|
||||
# When set to `true`, the Vault Agent Injector exports Prometheus metrics at
|
||||
# the `/metrics` path.
|
||||
enabled: false
|
||||
|
||||
# Mount Path of the Vault Kubernetes Auth Method.
|
||||
# Mount path of the Vault Kubernetes Auth Method.
|
||||
authPath: "auth/kubernetes"
|
||||
|
||||
# Configures the log verbosity of the injector.
|
||||
# Supported log levels include: trace, debug, info, warn, error
|
||||
# Configures the log verbosity of the injector. Supported log levels: trace,
|
||||
# debug, error, warn, info.
|
||||
logLevel: "info"
|
||||
|
||||
# Configures the log format of the injector. Supported log formats: "standard", "json".
|
||||
# Configures the log format of the injector. Supported log formats: "standard",
|
||||
# "json".
|
||||
logFormat: "standard"
|
||||
|
||||
# Configures all Vault Agent sidecars to revoke their token when shutting down
|
||||
# Configures all Vault Agent sidecars to revoke their token when shutting down.
|
||||
revokeOnShutdown: false
|
||||
|
||||
webhook:
|
||||
# Configures failurePolicy of the webhook. The "unspecified" default behaviour depends on the
|
||||
# API Version of the WebHook.
|
||||
# To block pod creation while the webhook is unavailable, set the policy to `Fail` below.
|
||||
# See https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#failure-policy
|
||||
# Security context for the pod template and the injector container.
|
||||
securityContext:
|
||||
# Defines the securityContext for the injector Pod, as YAML or a YAML-formatted
|
||||
# multi-line templated string. Default if not specified:
|
||||
#
|
||||
# ```yaml
|
||||
# runAsNonRoot: true
|
||||
# runAsGroup: {{ .Values.injector.gid | default 1000 }}
|
||||
# runAsUser: {{ .Values.injector.uid | default 100 }}
|
||||
# fsGroup: {{ .Values.injector.gid | default 1000 }}
|
||||
# ```
|
||||
# @type: dictionary
|
||||
# @default: {}
|
||||
pod: {}
|
||||
# Defines the securityContext for the injector container, as YAML or a
|
||||
# YAML-formatted multi-line templated string. Default if not specified:
|
||||
#
|
||||
# ```yaml
|
||||
# allowPrivilegeEscalation: false
|
||||
# capabilities:
|
||||
# drop:
|
||||
# - ALL
|
||||
# ```
|
||||
# @type: dictionary
|
||||
# @default: {}
|
||||
container: {}
|
||||
|
||||
# The resource requests and limits (CPU, memory, etc.) for each container of
|
||||
# the injector. This should be a YAML dictionary of a Kubernetes
|
||||
# [ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#resourcerequirements-v1-core)
|
||||
# object. If this isn't specified, then the pods won't request any specific
|
||||
# amount of resources, which limits the ability for Kubernetes to make
|
||||
# efficient use of compute resources.
|
||||
#
|
||||
# **Setting this is highly recommended.**
|
||||
#
|
||||
# ```yaml
|
||||
# resources:
|
||||
# requests:
|
||||
# memory: '256Mi'
|
||||
# cpu: '250m'
|
||||
# limits:
|
||||
# memory: '256Mi'
|
||||
# cpu: '250m'
|
||||
# ```
|
||||
# @type: dictionary
|
||||
# @default: {}
|
||||
resources: {}
|
||||
|
||||
# Values that control the Mutating Webhook Configuration.
|
||||
webhook:
|
||||
# Configures failurePolicy of the webhook. To block pod creation while the
|
||||
# webhook is unavailable, set the policy to `"Fail"`. See
|
||||
# [Failure Policy](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#failure-policy).
|
||||
failurePolicy: Ignore
|
||||
|
||||
# matchPolicy specifies the approach to accepting changes based on the rules of
|
||||
# the MutatingWebhookConfiguration.
|
||||
# See https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#matching-requests-matchpolicy
|
||||
# for more details.
|
||||
#
|
||||
# Specifies the approach to accepting changes based on the rules of the
|
||||
# MutatingWebhookConfiguration. See
|
||||
# [Match Policy](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#matching-requests-matchpolicy).
|
||||
matchPolicy: Exact
|
||||
|
||||
# timeoutSeconds is the amount of seconds before the webhook request will be ignored
|
||||
# or fails.
|
||||
# If it is ignored or fails depends on the failurePolicy
|
||||
# See https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#timeouts
|
||||
# for more details.
|
||||
#
|
||||
# Specifies the number of seconds before the webhook request will be ignored
|
||||
# or fails. If it is ignored or fails depends on the `failurePolicy`. See
|
||||
# [timeouts](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#timeouts).
|
||||
timeoutSeconds: 30
|
||||
|
||||
# namespaceSelector is the selector for restricting the webhook to only
|
||||
# specific namespaces.
|
||||
# See https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#matching-requests-namespaceselector
|
||||
# for more details.
|
||||
# Example:
|
||||
# The selector used by the admission webhook controller to limit what
|
||||
# namespaces where injection can happen. If unset, all non-system namespaces
|
||||
# are eligible for injection. See
|
||||
# [Matching requests: namespace selector](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#matching-requests-namespaceselector).
|
||||
#
|
||||
# ```yaml
|
||||
# namespaceSelector:
|
||||
# matchLabels:
|
||||
# sidecar-injector: enabled
|
||||
# matchLabels:
|
||||
# sidecar-injector: enabled
|
||||
# ```
|
||||
# @type: object
|
||||
# @default: {}
|
||||
namespaceSelector: {}
|
||||
|
||||
# objectSelector is the selector for restricting the webhook to only
|
||||
# specific labels.
|
||||
# See https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#matching-requests-objectselector
|
||||
# for more details.
|
||||
# Example:
|
||||
# The selector used by the admission webhook controller to limit what objects
|
||||
# can be affected by mutation. See
|
||||
# [Matching requests: object selector](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#matching-requests-objectselector).
|
||||
#
|
||||
# ```yaml
|
||||
# objectSelector:
|
||||
# matchLabels:
|
||||
# vault-sidecar-injector: enabled
|
||||
# matchLabels:
|
||||
# sidecar-injector: enabled
|
||||
# ```
|
||||
# @type: object
|
||||
# @default: {}
|
||||
objectSelector: |
|
||||
matchExpressions:
|
||||
- key: app.kubernetes.io/name
|
||||
|
@ -191,95 +264,91 @@ injector:
|
|||
values:
|
||||
- {{ template "vault.name" . }}-agent-injector
|
||||
|
||||
# Extra annotations to attach to the webhook
|
||||
# Defines additional annotations to attach to the webhook. This can either be
|
||||
# YAML or a YAML-formatted multi-line templated string.
|
||||
# @type: string or object
|
||||
# @default: {}
|
||||
annotations: {}
|
||||
|
||||
# Deprecated: please use 'webhook.failurePolicy' instead
|
||||
# Configures failurePolicy of the webhook. The "unspecified" default behaviour depends on the
|
||||
# API Version of the WebHook.
|
||||
# To block pod creation while webhook is unavailable, set the policy to `Fail` below.
|
||||
# See https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#failure-policy
|
||||
#
|
||||
failurePolicy: Ignore
|
||||
|
||||
# Deprecated: please use 'webhook.namespaceSelector' instead
|
||||
# namespaceSelector is the selector for restricting the webhook to only
|
||||
# specific namespaces.
|
||||
# See https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#matching-requests-namespaceselector
|
||||
# for more details.
|
||||
# Example:
|
||||
# namespaceSelector:
|
||||
# matchLabels:
|
||||
# sidecar-injector: enabled
|
||||
# Deprecated: please use
|
||||
# [`webhook.namespaceSelector`](https://developer.hashicorp.com/vault/docs/platform/k8s/helm/configuration#namespaceselector) instead.
|
||||
# @type: dictionary
|
||||
# @default: {}
|
||||
namespaceSelector: {}
|
||||
|
||||
# Deprecated: please use 'webhook.objectSelector' instead
|
||||
# objectSelector is the selector for restricting the webhook to only
|
||||
# specific labels.
|
||||
# See https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#matching-requests-objectselector
|
||||
# for more details.
|
||||
# Example:
|
||||
# objectSelector:
|
||||
# matchLabels:
|
||||
# vault-sidecar-injector: enabled
|
||||
# Deprecated: please use
|
||||
# [`webhook.objectSelector`](https://developer.hashicorp.com/vault/docs/platform/k8s/helm/configuration#objectselector) instead.
|
||||
# @type: dictionary
|
||||
# @default: {}
|
||||
objectSelector: {}
|
||||
|
||||
# Deprecated: please use 'webhook.annotations' instead
|
||||
# Extra annotations to attach to the webhook
|
||||
webhookAnnotations: {}
|
||||
# This value defines additional labels for Vault Agent Injector pods.
|
||||
#
|
||||
# ```yaml
|
||||
# extraLabels:
|
||||
# 'sample/label1': 'foo'
|
||||
# 'sample/label2': 'bar'
|
||||
# ```
|
||||
# @type: dictionary
|
||||
# @default: {}
|
||||
extraLabels: {}
|
||||
|
||||
# The certs section configures how the webhook TLS certs are configured. These
|
||||
# are the TLS certs for the Kube apiserver communicating to the webhook. By
|
||||
# default, the injector will generate and manage its own certs, but this
|
||||
# requires the ability for the injector to update its own
|
||||
# `MutatingWebhookConfiguration`. In a production environment, custom certs
|
||||
# should probably be used. Configure the values below to enable this.
|
||||
certs:
|
||||
# secretName is the name of the secret that has the TLS certificate and
|
||||
# private key to serve the injector webhook. If this is null, then the
|
||||
# injector will default to its automatic management mode that will assign
|
||||
# a service account to the injector to generate its own certificates.
|
||||
# secretName is the name of the Kubernetes secret that has the TLS certificate
|
||||
# and private key to serve the injector webhook. If this is null, then the
|
||||
# injector will default to its automatic management mode.
|
||||
secretName: null
|
||||
|
||||
# caBundle is a base64-encoded PEM-encoded certificate bundle for the CA
|
||||
# that signed the TLS certificate that the webhook serves. This must be set
|
||||
# if secretName is non-null unless an external service like cert-manager is
|
||||
# keeping the caBundle updated.
|
||||
# The PEM-encoded CA public certificate bundle for the TLS certificate served
|
||||
# by the injector. This must be specified as a string and can't come from a
|
||||
# secret because it must be statically configured on the Kubernetes
|
||||
# `MutatingAdmissionWebhook` resource. This only needs to be specified if
|
||||
# `secretName` is not null.
|
||||
caBundle: ""
|
||||
|
||||
# certName and keyName are the names of the files within the secret for
|
||||
# the TLS cert and private key, respectively. These have reasonable
|
||||
# defaults but can be customized if necessary.
|
||||
# The name of the certificate file within the `secretName` secret.
|
||||
certName: tls.crt
|
||||
# The name of the key file within the `secretName` secret.
|
||||
keyName: tls.key
|
||||
|
||||
# Security context for the pod template and the injector container
|
||||
# The default pod securityContext is:
|
||||
# runAsNonRoot: true
|
||||
# runAsGroup: {{ .Values.injector.gid | default 1000 }}
|
||||
# runAsUser: {{ .Values.injector.uid | default 100 }}
|
||||
# fsGroup: {{ .Values.injector.gid | default 1000 }}
|
||||
# and for container is
|
||||
# allowPrivilegeEscalation: false
|
||||
# capabilities:
|
||||
# drop:
|
||||
# - ALL
|
||||
securityContext:
|
||||
pod: {}
|
||||
container: {}
|
||||
|
||||
resources: {}
|
||||
# resources:
|
||||
# requests:
|
||||
# memory: 256Mi
|
||||
# cpu: 250m
|
||||
# limits:
|
||||
# memory: 256Mi
|
||||
# cpu: 250m
|
||||
|
||||
# extraEnvironmentVars is a list of extra environment variables to set in the
|
||||
# injector deployment.
|
||||
# Extra environment variables to set in the injector deployment.
|
||||
#
|
||||
# ```yaml
|
||||
# # Example setting injector TLS options in a deployment:
|
||||
# extraEnvironmentVars:
|
||||
# AGENT_INJECT_TLS_MIN_VERSION: tls13
|
||||
# AGENT_INJECT_TLS_CIPHER_SUITES: ...
|
||||
# ```
|
||||
# @type: dictionary
|
||||
# @default: {}
|
||||
extraEnvironmentVars: {}
|
||||
# KUBERNETES_SERVICE_HOST: kubernetes.default.svc
|
||||
|
||||
# Affinity Settings for injector pods
|
||||
# This can either be a multi-line string or YAML matching the PodSpec's affinity field.
|
||||
# Commenting out or setting as empty the affinity variable, will allow
|
||||
# deployment of multiple replicas to single node services such as Minikube.
|
||||
# This value defines the [affinity](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity)
|
||||
# for Vault Agent Injector pods. This can either be multi-line string or YAML
|
||||
# matching the PodSpec's affinity field. It defaults to allowing only a single
|
||||
# pod on each node, which minimizes risk of the cluster becoming unusable if
|
||||
# a node is lost. If you need to run more pods per node (for example, testing
|
||||
# on Minikube), set this value to `null`.
|
||||
#
|
||||
# ```yaml
|
||||
# # Recommended default server affinity:
|
||||
# affinity: |
|
||||
# podAntiAffinity:
|
||||
# requiredDuringSchedulingIgnoredDuringExecution:
|
||||
# - labelSelector:
|
||||
# matchLabels:
|
||||
# app.kubernetes.io/name: {{ template "vault.name" . }}-agent-injector
|
||||
# app.kubernetes.io/instance: "{{ .Release.Name }}"
|
||||
# component: webhook
|
||||
# topologyKey: kubernetes.io/hostname
|
||||
# ```
|
||||
# @type: string or dictionary
|
||||
affinity: |
|
||||
podAntiAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
|
@ -290,64 +359,164 @@ injector:
|
|||
component: webhook
|
||||
topologyKey: kubernetes.io/hostname
|
||||
|
||||
# Topology settings for injector pods
|
||||
# ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/
|
||||
# This should be either a multi-line string or YAML matching the topologySpreadConstraints array
|
||||
# in a PodSpec.
|
||||
# [Topology settings](https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/)
|
||||
# for injector pods. This can either be YAML or a YAML-formatted multi-line
|
||||
# templated string.
|
||||
topologySpreadConstraints: []
|
||||
|
||||
# Toleration Settings for injector pods
|
||||
# This should be either a multi-line string or YAML matching the Toleration array
|
||||
# in a PodSpec.
|
||||
# Toleration Settings for injector pods. This should be either a multi-line
|
||||
# string or YAML matching the Toleration array.
|
||||
tolerations: []
|
||||
|
||||
# nodeSelector labels for server pod assignment, formatted as a multi-line string or YAML map.
|
||||
# ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector
|
||||
# Example:
|
||||
# The nodeSelector labels for injector pod assignment, formatted as a multi-line
|
||||
# string or YAML map. See https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector
|
||||
#
|
||||
# ```yaml
|
||||
# nodeSelector:
|
||||
# beta.kubernetes.io/arch: amd64
|
||||
# ```
|
||||
# @type: dictionary
|
||||
# @default: {}
|
||||
nodeSelector: {}
|
||||
|
||||
# Priority class for injector pods
|
||||
# Priority class for injector pods.
|
||||
priorityClassName: ""
|
||||
|
||||
# Extra annotations to attach to the injector pods
|
||||
# This can either be YAML or a YAML-formatted multi-line templated string map
|
||||
# of the annotations to apply to the injector pods
|
||||
# This value defines additional annotations for injector pods. This can either
|
||||
# be YAML or a YAML-formatted multi-line templated string.
|
||||
#
|
||||
# ```yaml
|
||||
# annotations:
|
||||
# "sample/annotation1": "foo"
|
||||
# "sample/annotation2": "bar"
|
||||
# # or
|
||||
# annotations: |
|
||||
# "sample/annotation1": "foo"
|
||||
# "sample/annotation2": "bar"
|
||||
# ```
|
||||
# @type: dictionary
|
||||
# @default: {}
|
||||
annotations: {}
|
||||
|
||||
# Extra labels to attach to the agent-injector
|
||||
# This should be a YAML map of the labels to apply to the injector
|
||||
extraLabels: {}
|
||||
# Deprecated: please use [`webhook.failurePolicy`](https://developer.hashicorp.com/vault/docs/platform/k8s/helm/configuration#failurepolicy) instead.
|
||||
failurePolicy: Ignore
|
||||
|
||||
# Should the injector pods run on the host network (useful when using
|
||||
# an alternate CNI in EKS)
|
||||
# Deprecated: please use [`webhook.annotations`](https://developer.hashicorp.com/vault/docs/platform/k8s/helm/configuration#annotations-1) instead.
|
||||
# @type: dictionary
|
||||
# @default: {}
|
||||
webhookAnnotations: {}
|
||||
|
||||
# The service section configures the Kubernetes service for the Vault Agent
|
||||
# Injector.
|
||||
service:
|
||||
# This value defines additional annotations to add to the Vault Agent Injector
|
||||
# service. This can either be YAML or a YAML-formatted multi-line templated string.
|
||||
#
|
||||
# ```yaml
|
||||
# annotations:
|
||||
# "sample/annotation1": "foo"
|
||||
# "sample/annotation2": "bar"
|
||||
# # or
|
||||
# annotations: |
|
||||
# "sample/annotation1": "foo"
|
||||
# "sample/annotation2": "bar"
|
||||
# ```
|
||||
# @type: dictionary
|
||||
# @default: {}
|
||||
annotations: {}
|
||||
|
||||
# Injector serviceAccount specific config.
|
||||
serviceAccount:
|
||||
# Extra annotations to attach to the injector serviceAccount. This can either
|
||||
# be YAML or a YAML-formatted multi-line templated string.
|
||||
# @type: dictionary
|
||||
# @default: {}
|
||||
annotations: {}
|
||||
|
||||
# When set to true, configures the Vault Agent Injector to run on the host
|
||||
# network. This is useful when alternative cluster networking is used.
|
||||
hostNetwork: false
|
||||
|
||||
# Injector service specific config
|
||||
service:
|
||||
# Extra annotations to attach to the injector service
|
||||
annotations: {}
|
||||
|
||||
# Injector serviceAccount specific config
|
||||
serviceAccount:
|
||||
# Extra annotations to attach to the injector serviceAccount
|
||||
annotations: {}
|
||||
# Configures the port the Vault Agent Injector listens on.
|
||||
port: 8080
|
||||
|
||||
# A disruption budget limits the number of pods of a replicated application
|
||||
# that are down simultaneously from voluntary disruptions
|
||||
podDisruptionBudget: {}
|
||||
# that are down simultaneously from voluntary disruptions.
|
||||
#
|
||||
# ```yaml
|
||||
# podDisruptionBudget:
|
||||
# maxUnavailable: 1
|
||||
# ```
|
||||
# @type: dictionary
|
||||
# @default: {}
|
||||
podDisruptionBudget: {}
|
||||
|
||||
# strategy for updating the deployment. This can be a multi-line string or a
|
||||
# Strategy for updating the deployment. This can be a multi-line string or a
|
||||
# YAML map.
|
||||
strategy: {}
|
||||
#
|
||||
# ```yaml
|
||||
# strategy:
|
||||
# rollingUpdate:
|
||||
# maxSurge: 25%
|
||||
# maxUnavailable: 25%
|
||||
# type: RollingUpdate
|
||||
# # or
|
||||
# strategy: |
|
||||
# rollingUpdate:
|
||||
# maxSurge: 25%
|
||||
# maxUnavailable: 25%
|
||||
# type: RollingUpdate
|
||||
# ```
|
||||
# @type: dictionary
|
||||
# @default: {}
|
||||
strategy: {}
|
||||
|
||||
# Values that configure the liveness probe for the injector.
|
||||
livenessProbe:
|
||||
# When set to a value, configures how many probe failures will be tolerated
|
||||
# by Kubernetes.
|
||||
failureThreshold: 2
|
||||
# Sets the initial delay of the liveness probe when the container starts.
|
||||
initialDelaySeconds: 5
|
||||
# When set to a value, configures how often (in seconds) to perform the probe.
|
||||
periodSeconds: 2
|
||||
# When set to a value, configures the minimum consecutive successes for the
|
||||
# probe to be considered successful after having failed.
|
||||
successThreshold: 1
|
||||
# When set to a value, configures the number of seconds after which the probe
|
||||
# times out.
|
||||
timeoutSeconds: 5
|
||||
# Values that configure the readiness probe for the injector.
|
||||
readinessProbe:
|
||||
# When set to a value, configures how many probe failures will be tolerated
|
||||
# by Kubernetes.
|
||||
failureThreshold: 2
|
||||
# Sets the initial delay of the readiness probe when the container starts.
|
||||
initialDelaySeconds: 5
|
||||
# When set to a value, configures how often (in seconds) to perform the probe.
|
||||
periodSeconds: 2
|
||||
# When set to a value, configures the minimum consecutive successes for the probe
|
||||
# to be considered successful after having failed.
|
||||
successThreshold: 1
|
||||
# When set to a value, configures the number of seconds after which the probe
|
||||
# times out.
|
||||
timeoutSeconds: 5
|
||||
# Values that configure the startup probe for the injector.
|
||||
startupProbe:
|
||||
# When set to a value, configures how many probe failures will be tolerated
|
||||
# by Kubernetes.
|
||||
failureThreshold: 12
|
||||
# Sets the initial delay of the startup probe when the container starts.
|
||||
initialDelaySeconds: 5
|
||||
# When set to a value, configures how often (in seconds) to perform the probe.
|
||||
periodSeconds: 5
|
||||
# When set to a value, configures the minimum consecutive successes for the probe
|
||||
# to be considered successful after having failed.
|
||||
successThreshold: 1
|
||||
# When set to a value, configures the number of seconds after which the probe
|
||||
# times out.
|
||||
timeoutSeconds: 5
|
||||
|
||||
|
||||
server:
|
||||
# If true, or "-" with global.enabled true, Vault server will be installed.
|
||||
|
|
Loading…
Reference in a new issue