Compare commits

...

2 commits

Author SHA1 Message Date
Tom Proctor
17431ba9dd
Delete fixtures 2023-04-20 12:33:55 +01:00
Tom Proctor
8f237e2b82
Generate helm docs 2023-04-19 20:43:49 +01:00
8 changed files with 1255 additions and 216 deletions

View file

@ -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)

View 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)
}

View 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
)

View 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=

View 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
}

View 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")
}
}

View 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)
}

View file

@ -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.