Compare commits

..

7 Commits

Author SHA1 Message Date
Jeff McCune
e9d1240d63 docs: make update-docs for version 0.103.0 2025-01-12 14:26:27 -08:00
Gary Larizza
03fa4eaaa2 docs: Helm Values test updates
* Convert all files with.period.separators to hyphen-separators.
* Rename and markdown_test.go to be specific to Helm Values.
* Move helm-values_test.go to be in the same directory as the Helm Values doc.
* Move Blackbox common configuration CUE file to `config/prometheus` so it can be imported as necessary.
* Use explicit import statements for Blackbox common config in `blackbox` and `prometheus` components.

Closes: #399
2025-01-12 14:25:44 -08:00
Jeff McCune
e363f3a597 docs: add make update-docs task
We need to run this prior to tagging a release otherwise the tests fail
for the new version string.
2025-01-12 14:22:58 -08:00
Jeff McCune
8b49ed93be docs: release version 0.103.0 2025-01-12 14:09:45 -08:00
Jeff McCune
d2be9fe278 helm: add valueFiles for migration from an ApplicationSet
Without this patch migrating from [helm hierarchies] to Holos requires
the user to unify the value hierarchy.  This is a problem because helm
hierarchies are difficult to unify because it's not clear if or why a
value is used in the final results.  This makes it difficult to identify
how to resolve conflicts.

This patch adds `valueFiles` field to the Helm component kind.  This
field is intended to provide a direct migration path from the
ApplicationSet.spec.template.spec.sources.helm.valueFiles field.  With
this patch, users can directly migrate the values files to CUE using
`@embed`, then directly migrate the valueFiles field to reference the
values from within CUE.

Note we actively discourage the use of Helm value hierarchies.  The
feature is intended as a temporary migration tool.  We encourage the use
of CUE unification instead.  After migration, the valueFiles field
should be refactored to the values field as one unified structure in
CUE.  The valueFiles field makes this second order migration easier
becuase we can inspect and verify the complete rendered output, allowing
us to determine if a value is actually used in the final configuration
or is overridden.

[helm hierarchies]: https://medium.com/containers-101/using-helm-hierarchies-in-multi-source-argo-cd-applications-for-promoting-to-different-gitops-133c3bc93678
2025-01-12 13:30:29 -08:00
Jeff McCune
6ec341bbb1 docs: redirect /docs/api/core 2025-01-10 15:02:12 -08:00
Jeff McCune
13a4305b78 docs: add redirect for /blog/rendered-manifest-pattern (manifest instead of manifests) 2025-01-10 14:50:26 -08:00
20 changed files with 131 additions and 27 deletions

View File

@@ -154,6 +154,10 @@ website: ## Build website
unity: ## https://cuelabs.dev/unity/
./scripts/unity
.PHONY: update-docs
update-docs: ## Update doc examples
HOLOS_UPDATE_SCRIPTS=1 go test -v ./doc/md/...
.PHONY: help
help: ## Display this help menu.
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-20s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)

View File

@@ -84,6 +84,9 @@ type Helm struct {
Chart core.Chart
// Values represents data to marshal into a values.yaml for helm.
Values core.Values
// ValueFiles represents value files for migration from helm value
// hierarchies. Use Values instead.
ValueFiles []core.ValueFile `json:",omitempty"`
// EnableHooks enables helm hooks when executing the `helm template` command.
EnableHooks bool `cue:"true | *false"`
// Namespace sets the helm chart namespace flag if provided.

View File

@@ -118,8 +118,12 @@ type Helm struct {
// Chart represents a helm chart to manage.
Chart Chart `json:"chart" yaml:"chart"`
// Values represents values for holos to marshal into values.yaml when
// rendering the chart.
// rendering the chart. Values follow ValueFiles when both are provided.
Values Values `json:"values" yaml:"values"`
// ValueFiles represents hierarchial value files passed in order to the helm
// template -f flag. Useful for migration from an ApplicationSet. Use Values
// instead. ValueFiles precede Values when both are provided.
ValueFiles []ValueFile `json:"valueFiles,omitempty" yaml:"valueFiles,omitempty"`
// EnableHooks enables helm hooks when executing the `helm template` command.
EnableHooks bool `json:"enableHooks,omitempty" yaml:"enableHooks,omitempty"`
// Namespace represents the helm namespace flag
@@ -130,6 +134,17 @@ type Helm struct {
KubeVersion string `json:"kubeVersion,omitempty" yaml:"kubeVersion,omitempty"`
}
// ValueFile represents one Helm value file produced from CUE.
type ValueFile struct {
// Name represents the file name, e.g. "region-values.yaml"
Name string `json:"name" yaml:"name"`
// Kind is a discriminator.
Kind string `json:"kind" yaml:"kind" cue:"\"Values\""`
// Values represents values for holos to marshal into the file name specified
// by Name when rendering the chart.
Values Values `json:"values,omitempty" yaml:"values,omitempty"`
}
// Values represents [Helm] Chart values generated from CUE.
type Values map[string]any

View File

@@ -86,6 +86,9 @@ type Helm struct {
Chart core.Chart
// Values represents data to marshal into a values.yaml for helm.
Values core.Values
// ValueFiles represents value files for migration from helm value
// hierarchies. Use Values instead.
ValueFiles []core.ValueFile `json:",omitempty"`
// EnableHooks enables helm hooks when executing the `helm template` command.
EnableHooks bool `cue:"true | *false"`
// Namespace sets the helm chart namespace flag if provided.

View File

@@ -43,6 +43,7 @@ Package core contains schemas for a [Platform](<#Platform>) and [BuildPlan](<#Bu
- [type Resources](<#Resources>)
- [type Transformer](<#Transformer>)
- [type Validator](<#Validator>)
- [type ValueFile](<#ValueFile>)
- [type Values](<#Values>)
@@ -283,8 +284,12 @@ type Helm struct {
// Chart represents a helm chart to manage.
Chart Chart `json:"chart" yaml:"chart"`
// Values represents values for holos to marshal into values.yaml when
// rendering the chart.
// rendering the chart. Values follow ValueFiles when both are provided.
Values Values `json:"values" yaml:"values"`
// ValueFiles represents hierarchial value files passed in order to the helm
// template -f flag. Useful for migration from an ApplicationSet. Use Values
// instead. ValueFiles precede Values when both are provided.
ValueFiles []ValueFile `json:"valueFiles,omitempty" yaml:"valueFiles,omitempty"`
// EnableHooks enables helm hooks when executing the `helm template` command.
EnableHooks bool `json:"enableHooks,omitempty" yaml:"enableHooks,omitempty"`
// Namespace represents the helm namespace flag
@@ -493,6 +498,23 @@ type Validator struct {
}
```
<a name="ValueFile"></a>
## type ValueFile {#ValueFile}
ValueFile represents one Helm value file produced from CUE.
```go
type ValueFile struct {
// Name represents the file name, e.g. "region-values.yaml"
Name string `json:"name" yaml:"name"`
// Kind is a discriminator.
Kind string `json:"kind" yaml:"kind" cue:"\"Values\""`
// Values represents values for holos to marshal into the file name specified
// by Name when rendering the chart.
Values Values `json:"values,omitempty" yaml:"values,omitempty"`
}
```
<a name="Values"></a>
## type Values {#Values}

View File

@@ -4,4 +4,4 @@ cmp stdout $WORK/output.txt
-- command.sh --
holos --version
-- output.txt --
0.102.5
0.103.0

View File

@@ -1,3 +1,3 @@
[main 1adcd08] add blackbox configuration
[main e1c6859] add blackbox configuration
1 file changed, 15 insertions(+)
create mode 100644 components/blackbox.cue
create mode 100644 config/prometheus/blackbox.cue

View File

@@ -1,2 +1,3 @@
[main 4221803] integrate blackbox and prometheus together
2 files changed, 4 insertions(+), 2 deletions(-)
[main 668706a] integrate blackbox and prometheus together
3 files changed, 1348 insertions(+), 2 deletions(-)
create mode 100644 components/prometheus/values.cue.orig

View File

@@ -1,4 +1,4 @@
[main 52e90ea] import values
[main 7bc6772] import values
2 files changed, 1815 insertions(+)
create mode 100644 components/blackbox/values.cue
create mode 100644 components/prometheus/values.cue

View File

@@ -1,3 +1,3 @@
rendered blackbox in 365.936792ms
rendered prometheus in 371.855875ms
rendered platform in 372.109916ms
rendered blackbox in 146.654292ms
rendered prometheus in 178.845292ms
rendered platform in 178.9115ms

View File

@@ -1,4 +1,4 @@
[main b5df111] add blackbox and prometheus
[main d144f24] add blackbox and prometheus
5 files changed, 1550 insertions(+)
create mode 100644 components/blackbox/blackbox.cue
create mode 100644 components/prometheus/prometheus.cue

View File

@@ -1,5 +1,3 @@
cached prometheus-blackbox-exporter 9.0.1
rendered blackbox in 3.825430417s
cached prometheus 25.27.0
rendered prometheus in 4.840089667s
rendered platform in 4.840137792s
rendered blackbox in 1.794799666s
rendered prometheus in 1.835097625s
rendered platform in 1.835185792s

View File

@@ -1,2 +1,2 @@
[main 67efe0d] render integrated blackbox and prometheus manifests
[main 1399737] render integrated blackbox and prometheus manifests
2 files changed, 7 insertions(+), 7 deletions(-)

View File

@@ -22,8 +22,12 @@
/docs/comparison/ /docs/v1alpha5/topics/comparison/ 301
/docs/support /docs/v1alpha5/tutorial/overview/#getting-help 301
/docs/support/ /docs/v1alpha5/tutorial/overview/#getting-help 301
/docs/api/core /docs/v1alpha5/api/core/ 301
/docs/api/core/ /docs/v1alpha5/api/core/ 301
/docs/api/author /docs/v1alpha5/api/author/ 301
/docs/api/author/ /docs/v1alpha5/api/author/ 301
# Redirect to our own take on the pattern once we figure out what to call it.
# See: https://discord.com/channels/1299051862418395216/1299055980738383882/1327347525354524805
/blog/the-rendered-manifests-pattern https://akuity.io/blog/the-rendered-manifests-pattern 301
# without the s which I always forget
/blog/the-rendered-manifest-pattern https://akuity.io/blog/the-rendered-manifests-pattern 301

View File

@@ -219,13 +219,38 @@ func (t generatorTask) helm(ctx context.Context) error {
}
}
// Write values file
// Write value files
tempDir, err := os.MkdirTemp("", "holos.helm")
if err != nil {
return errors.Format("could not make temp dir: %w", err)
}
defer util.Remove(ctx, tempDir)
// valueFiles represents the ordered list of value files to pass to helm
// template -f
var valueFiles []string
// valueFiles for the use case of migration from helm value hierarchies.
for _, valueFile := range t.generator.Helm.ValueFiles {
var data []byte
switch valueFile.Kind {
case "Values":
if data, err = yaml.Marshal(valueFile.Values); err != nil {
return errors.Format("could not marshal value file %s: %w", valueFile.Name, err)
}
default:
return errors.Format("could not marshal value file %s: unknown kind %s", valueFile.Name, valueFile.Kind)
}
valuesPath := filepath.Join(tempDir, valueFile.Name)
if err := os.WriteFile(valuesPath, data, 0666); err != nil {
return errors.Wrap(fmt.Errorf("could not write value file %s: %w", valueFile.Name, err))
}
log.DebugContext(ctx, fmt.Sprintf("wrote: %s", valuesPath))
valueFiles = append(valueFiles, valuesPath)
}
// The final values files
data, err := yaml.Marshal(t.generator.Helm.Values)
if err != nil {
return errors.Format("could not marshal values: %w", err)
@@ -235,7 +260,8 @@ func (t generatorTask) helm(ctx context.Context) error {
if err := os.WriteFile(valuesPath, data, 0666); err != nil {
return errors.Wrap(fmt.Errorf("could not write values: %w", err))
}
log.DebugContext(ctx, "wrote"+valuesPath)
log.DebugContext(ctx, fmt.Sprintf("wrote: %s", valuesPath))
valueFiles = append(valueFiles, valuesPath)
// Run charts
args := []string{"template"}
@@ -248,9 +274,11 @@ func (t generatorTask) helm(ctx context.Context) error {
if kubeVersion := t.generator.Helm.KubeVersion; kubeVersion != "" {
args = append(args, "--kube-version", kubeVersion)
}
args = append(args, "--include-crds")
for _, valueFilePath := range valueFiles {
args = append(args, "--values", valueFilePath)
}
args = append(args,
"--include-crds",
"--values", valuesPath,
"--namespace", t.generator.Helm.Namespace,
"--kubeconfig", "/dev/null",
"--version", t.generator.Helm.Chart.Version,

View File

@@ -95,6 +95,10 @@ import "github.com/holos-run/holos/api/core/v1alpha5:core"
// Values represents data to marshal into a values.yaml for helm.
Values: core.#Values
// ValueFiles represents value files for migration from helm value
// hierarchies. Use Values instead.
ValueFiles?: [...core.#ValueFile] @go(,[]core.ValueFile)
// EnableHooks enables helm hooks when executing the `helm template` command.
EnableHooks: bool & (true | *false)

View File

@@ -129,9 +129,14 @@ package core
chart: #Chart @go(Chart)
// Values represents values for holos to marshal into values.yaml when
// rendering the chart.
// rendering the chart. Values follow ValueFiles when both are provided.
values: #Values @go(Values)
// ValueFiles represents hierarchial value files passed in order to the helm
// template -f flag. Useful for migration from an ApplicationSet. Use Values
// instead. ValueFiles precede Values when both are provided.
valueFiles?: [...#ValueFile] @go(ValueFiles,[]ValueFile)
// EnableHooks enables helm hooks when executing the `helm template` command.
enableHooks?: bool @go(EnableHooks)
@@ -145,6 +150,19 @@ package core
kubeVersion?: string @go(KubeVersion)
}
// ValueFile represents one Helm value file produced from CUE.
#ValueFile: {
// Name represents the file name, e.g. "region-values.yaml"
name: string @go(Name)
// Kind is a discriminator.
kind: string & "Values" @go(Kind)
// Values represents values for holos to marshal into the file name specified
// by Name when rendering the chart.
values?: #Values @go(Values)
}
// Values represents [Helm] Chart values generated from CUE.
#Values: {...}

View File

@@ -95,6 +95,7 @@ import (
release: string | *name
}
Values: _
ValueFiles?: _
EnableHooks: _
Namespace?: _
APIVersions?: _
@@ -110,8 +111,11 @@ import (
kind: "Helm"
output: HelmOutput
helm: core.#Helm & {
chart: Chart
values: Values
chart: Chart
values: Values
if ValueFiles != _|_ {
valueFiles: ValueFiles
}
enableHooks: EnableHooks
if Namespace != _|_ {
namespace: Namespace

View File

@@ -1 +1 @@
102
103

View File

@@ -1 +1 @@
5
0