Skip to content

Commit

Permalink
(#71) Add HelmChart BuildPlan support
Browse files Browse the repository at this point in the history
This patch refactors the #HelmChart definition to a BuildPlan.HelmCharts,
which executes a collection of HelmCharts.  The same behavior is
preserved, helm template executes then a kustomize post processor
executes.

```
❯ holos render --cluster-name=k2 ~/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/foundation/cloud/github/arc/... --log-level=debug
9:53PM DBG config.go:150 finalized config from flags version=0.60.1 state=finalized
9:53PM DBG builder.go:108 cue: building instances version=0.60.1
9:53PM DBG builder.go:95 cue: equivalent command: cue export --out yaml -t cluster=k2 ./platforms/reference/clusters/foundation/cloud/github/arc/... version=0.60.1
9:53PM DBG builder.go:100 cue: tags [cluster=k2] version=0.60.1
9:53PM DBG builder.go:122 cue: building instance version=0.60.1 dir=/home/jeff/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/foundation/cloud/github/arc
9:53PM DBG builder.go:127 cue: validating instance version=0.60.1 dir=/home/jeff/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/foundation/cloud/github/arc
9:53PM DBG builder.go:131 cue: decoding holos build plan version=0.60.1 dir=/home/jeff/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/foundation/cloud/github/arc
9:53PM DBG builder.go:122 cue: building instance version=0.60.1 dir=/home/jeff/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/foundation/cloud/github/arc/runner
9:53PM DBG builder.go:127 cue: validating instance version=0.60.1 dir=/home/jeff/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/foundation/cloud/github/arc/runner
9:53PM DBG builder.go:131 cue: decoding holos build plan version=0.60.1 dir=/home/jeff/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/foundation/cloud/github/arc/runner
9:53PM DBG result.go:61 ExternalSecret/controller-manager version=0.60.1 kind=ExternalSecret name=controller-manager
9:53PM DBG builder.go:122 cue: building instance version=0.60.1 dir=/home/jeff/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/foundation/cloud/github/arc/system
9:53PM DBG builder.go:127 cue: validating instance version=0.60.1 dir=/home/jeff/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/foundation/cloud/github/arc/system
9:53PM DBG builder.go:131 cue: decoding holos build plan version=0.60.1 dir=/home/jeff/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/foundation/cloud/github/arc/system
9:53PM DBG helm.go:95 helm: wrote values version=0.60.1 chart=oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set-controller path=/tmp/holos1163326896/values.yaml bytes=653
9:53PM DBG run.go:40 running: helm version=0.60.1 name=helm args="[template --no-hooks --include-crds --values /tmp/holos1163326896/values.yaml --namespace arc-system --kubeconfig /dev/null --version 0.8.3 gha-rs-controller /home/jeff/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/foundation/cloud/github/arc/system/vendor/gha-runner-scale-set-controller]"
9:53PM DBG remove.go:15 tmp: removed version=0.60.1 path=/tmp/holos1163326896
9:53PM DBG result.go:95 wrote: /tmp/holos.kustomize3569816247/resources.yaml version=0.60.1 op=write path=/tmp/holos.kustomize3569816247/resources.yaml bytes=2019229
9:53PM DBG result.go:108 wrote: /tmp/holos.kustomize3569816247/kustomization.yaml version=0.60.1 op=write path=/tmp/holos.kustomize3569816247/kustomization.yaml bytes=94
9:53PM DBG run.go:40 running: kubectl version=0.60.1 name=kubectl args="[kustomize /tmp/holos.kustomize3569816247]"
9:53PM DBG remove.go:15 tmp: removed version=0.60.1 path=/tmp/holos.kustomize3569816247
9:53PM DBG result.go:135 out: wrote deploy/clusters/k2/components/prod-github-arc-runner/prod-github-arc-runner.gen.yaml version=0.60.1 action=write path=deploy/clusters/k2/components/prod-github-arc-runner/prod-github-arc-runner.gen.yaml status=ok
9:53PM DBG result.go:135 out: wrote deploy/clusters/k2/holos/components/prod-github-arc-runner-kustomization.gen.yaml version=0.60.1 action=write path=deploy/clusters/k2/holos/components/prod-github-arc-runner-kustomization.gen.yaml status=ok
9:53PM INF render.go:43 rendered prod-github-arc-runner version=0.60.1 status=ok action=rendered name=prod-github-arc-runner
9:53PM DBG result.go:135 out: wrote deploy/clusters/k2/components/prod-github-arc-system/prod-github-arc-system.gen.yaml version=0.60.1 action=write path=deploy/clusters/k2/components/prod-github-arc-system/prod-github-arc-system.gen.yaml status=ok
9:53PM DBG result.go:135 out: wrote deploy/clusters/k2/holos/components/prod-github-arc-system-kustomization.gen.yaml version=0.60.1 action=write path=deploy/clusters/k2/holos/components/prod-github-arc-system-kustomization.gen.yaml status=ok
9:53PM INF render.go:43 rendered prod-github-arc-system version=0.60.1 status=ok action=rendered name=prod-github-arc-system
```
  • Loading branch information
jeffmccune committed Mar 22, 2024
1 parent 6f0928b commit 31280ac
Show file tree
Hide file tree
Showing 24 changed files with 212 additions and 184 deletions.
2 changes: 1 addition & 1 deletion api/v1alpha1/buildplan.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type BuildPlanComponents struct {
}

func (bp *BuildPlan) Validate() error {
errs := make([]string, 0, 10)
errs := make([]string, 0, 2)
if bp.Kind != BuildPlanKind {
errs = append(errs, fmt.Sprintf("kind invalid: want: %s have: %s", BuildPlanKind, bp.Kind))
}
Expand Down
2 changes: 2 additions & 0 deletions api/v1alpha1/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ const (
HelmChartKind = "HelmChart"
// ChartDir is the directory name created in the holos component directory to cache a chart.
ChartDir = "vendor"
// ResourcesFile is the file name used to store component output when post-processing with kustomize.
ResourcesFile = "resources.yaml"
)
9 changes: 5 additions & 4 deletions api/v1alpha1/helm.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ package v1alpha1
import (
"context"
"fmt"
"os"
"path/filepath"
"strings"

"github.com/holos-run/holos"
"github.com/holos-run/holos/pkg/logger"
"github.com/holos-run/holos/pkg/util"
"github.com/holos-run/holos/pkg/wrapper"
"os"
"path/filepath"
"strings"
)

// A HelmChart represents a helm command to provide chart values in order to render kubernetes api objects.
Expand All @@ -26,7 +27,7 @@ type Chart struct {
Name string `json:"name"`
Version string `json:"version"`
Release string `json:"release"`
Repository Repository `json:"repository"`
Repository Repository `json:"repository,omitempty"`
}

type Repository struct {
Expand Down
6 changes: 1 addition & 5 deletions api/v1alpha1/kubernetesobjects.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,7 @@ type KubernetesObjects struct {

// Render produces kubernetes api objects from the APIObjectMap
func (o *KubernetesObjects) Render(ctx context.Context, path holos.PathComponent) (*Result, error) {
result := Result{
TypeMeta: o.TypeMeta,
Metadata: o.Metadata,
Kustomization: o.Kustomization,
}
result := Result{HolosComponent: o.HolosComponent}
result.addObjectMap(ctx, o.APIObjectMap)
return &result, nil
}
4 changes: 0 additions & 4 deletions api/v1alpha1/result.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@ import (
// Result is the build result for display or writing. Holos components Render the Result as a data pipeline.
type Result struct {
HolosComponent
TypeMeta `json:",inline" yaml:",inline"`
Kustomization `json:",inline" yaml:",inline"`
Kustomize `json:",inline" yaml:",inline"`
Metadata ObjectMeta `json:"metadata,omitempty"`
// accumulatedOutput accumulates rendered api objects.
accumulatedOutput string
}
Expand Down
27 changes: 8 additions & 19 deletions cmd/holos/testdata/constraints.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# Want support for intermediary constraints
exec holos build ./foo/... --log-level debug
stdout '^bf2bc7f9-9ba0-4f9e-9bd2-9a205627eb0b$'
stderr 'processing holos component kind Skip'

-- cue.mod --
package holos
Expand All @@ -12,31 +11,21 @@ metadata: name: "jeff"
-- foo/bar/bar.cue --
package holos

#KubernetesObjects & {
apiObjectMap: foo: bar: "bf2bc7f9-9ba0-4f9e-9bd2-9a205627eb0b"
}
spec: components: KubernetesObjects: [
#KubernetesObjects & {
apiObjectMap: foo: bar: "bf2bc7f9-9ba0-4f9e-9bd2-9a205627eb0b"
}
]
-- schema.cue --
package holos

cluster: string @tag(cluster, string)

// #OutputTypeMeta is shared among all output types
#OutputTypeMeta: {
apiVersion: "holos.run/v1alpha1"
kind: #KubernetesObjects.kind | #NoOutput.kind
metadata: name: string
}

#KubernetesObjects: {
#OutputTypeMeta
apiVersion: "holos.run/v1alpha1"
kind: "KubernetesObjects"
apiObjectMap: {...}
}

#NoOutput: {
#OutputTypeMeta
kind: string | *"Skip"
metadata: name: string | *"skipped"
}

#NoOutput & {}
apiVersion: "holos.run/v1alpha1"
kind: "BuildPlan"
8 changes: 4 additions & 4 deletions cmd/holos/testdata/issue15_cue_errors.txt
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
# Want cue errors to show files and lines
! exec holos build .
stderr '^apiObjectMap.foo.bar: cannot convert non-concrete value string'
stderr '/component.cue:7:20$'
stderr 'apiObjectMap.foo.bar: cannot convert non-concrete value string:'
stderr '/component.cue:\d+:\d+$'

-- cue.mod --
package holos
-- component.cue --
package holos

apiVersion: "holos.run/v1alpha1"
kind: "KubernetesObjects"
kind: "BuildPlan"
cluster: string @tag(cluster, string)

apiObjectMap: foo: bar: baz
baz: string
spec: components: KubernetesObjects: [{apiObjectMap: foo: bar: baz}]
7 changes: 4 additions & 3 deletions cmd/holos/testdata/issue25_apiobjects_cue.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,17 @@ package holos
package holos

apiVersion: "holos.run/v1alpha1"
kind: "KubernetesObjects"
kind: "BuildPlan"
spec: components: KubernetesObjects: [{apiObjectMap: #APIObjects.apiObjectMap}]

cluster: string @tag(cluster, string)

#SecretStore: {
kind: string
metadata: name: string
}

#APIObjects & {
#APIObjects: {
apiObjects: {
SecretStore: {
default: #SecretStore & { metadata: name: "default" }
Expand Down Expand Up @@ -54,4 +56,3 @@ import "encoding/yaml"
}
}
}

7 changes: 4 additions & 3 deletions cmd/holos/testdata/issue25_apiobjects_helm.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,17 @@ package holos
package holos

apiVersion: "holos.run/v1alpha1"
kind: "HelmChart"
kind: "BuildPlan"
spec: components: HelmCharts: [{apiObjectMap: #APIObjects.apiObjectMap}]

cluster: string @tag(cluster, string)

#SecretStore: {
kind: string
metadata: name: string
}

#APIObjects & {
#APIObjects: {
apiObjects: {
SecretStore: {
default: #SecretStore & { metadata: name: "default" }
Expand Down Expand Up @@ -55,4 +57,3 @@ import "encoding/yaml"
}
}
}

31 changes: 18 additions & 13 deletions cmd/holos/testdata/issue33_helm_stderr.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,28 @@ package holos
-- zitadel.cue --
package holos

apiVersion: "holos.run/v1alpha1"
kind: "BuildPlan"
spec: components: HelmCharts: [_HelmChart]

cluster: string @tag(cluster, string)

apiVersion: "holos.run/v1alpha1"
kind: "HelmChart"
metadata: name: "zitadel"
namespace: "zitadel"
chart: {
name: "zitadel"
version: "7.9.0"
release: name
repository: {
name: "zitadel"
url: "https://charts.zitadel.com"
}
_HelmChart: {
apiVersion: "holos.run/v1alpha1"
kind: "HelmChart"
metadata: name: "zitadel"
namespace: "zitadel"
chart: {
name: "zitadel"
version: "7.9.0"
release: name
repository: {
name: "zitadel"
url: "https://charts.zitadel.com"
}
}
}


-- vendor/zitadel/templates/secret_zitadel-masterkey.yaml --
{{- if (or (and .Values.zitadel.masterkey .Values.zitadel.masterkeySecretName) (and (not .Values.zitadel.masterkey) (not .Values.zitadel.masterkeySecretName)) ) }}
{{- fail "Either set .Values.zitadel.masterkey xor .Values.zitadel.masterkeySecretName" }}
Expand Down
7 changes: 5 additions & 2 deletions cmd/holos/testdata/issue42_kustomize_build_kind.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,22 @@ package holos
cluster: string @tag(cluster, string)

apiVersion: "holos.run/v1alpha1"
kind: "KustomizeBuild"
metadata: name: "kstest"
kind: "BuildPlan"
spec: components: KustomizeBuilds: [{metadata: name: "kstest"}]

-- kustomization.yaml --
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: mynamespace
resources:
- serviceaccount.yaml

-- serviceaccount.yaml --
apiVersion: v1
kind: ServiceAccount
metadata:
name: test

-- want.yaml --
apiVersion: v1
kind: ServiceAccount
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@ package v1alpha1

// ChartDir is the directory name created in the holos component directory to cache a chart.
#ChartDir: "vendor"

// ResourcesFile is the file name used to store component output when post processing with kustomize.
#ResourcesFile: "resources.yaml"
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ package v1alpha1
}

#Chart: {
name: string @go(Name)
version: string @go(Version)
release: string @go(Release)
repository: #Repository @go(Repository)
name: string @go(Name)
version: string @go(Version)
release: string @go(Release)
repository?: #Repository @go(Repository)
}

#Repository: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,4 @@ package v1alpha1
// Result is the build result for display or writing. Holos components Render the Result as a data pipeline.
#Result: {
HolosComponent: #HolosComponent

#TypeMeta

#Kustomization

#Kustomize
metadata?: #ObjectMeta @go(Metadata)
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
package v1alpha1

#HolosComponent: Skip: true | *false

#HelmChart: enableHooks: true | *false
52 changes: 50 additions & 2 deletions docs/examples/holos.cue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package holos
import (
"encoding/yaml"
h "github.com/holos-run/holos/api/v1alpha1"
kc "sigs.k8s.io/kustomize/api/types"
ksv1 "kustomize.toolkit.fluxcd.io/kustomization/v1"
)

Expand All @@ -13,20 +14,50 @@ import (
// Constrain each CUE instance to output a BuildPlan.
{} & h.#BuildPlan

let DependsOn = {[Name=_]: name: string & Name}

// #HolosComponent defines struct fields common to all holos component types.
#HolosComponent: {
h.#HolosComponent
_dependsOn: DependsOn
let DEPENDS_ON = _dependsOn
metadata: name: string
#namelen: len(metadata.name) & >=1
let Name = metadata.name
ksContent: yaml.Marshal(#Kustomization & {
_dependsOn: DEPENDS_ON
metadata: name: Name
})
// Leave the HolosComponent open for components with additional fields like HelmChart.
// Refer to https://cuelang.org/docs/tour/types/closed/
...
}

//#KustomizeFiles represents resources for holos to write into files for kustomize post-processing.
#KustomizeFiles: {
// Objects collects files for Holos to write for kustomize post-processing.
Objects: "kustomization.yaml": #Kustomize
// Files holds the marshaled output of Objects holos writes to the filesystem before calling the kustomize post-processor.
Files: {
for filename, obj in Objects {
"\(filename)": yaml.Marshal(obj)
}
}
}

// Holos component types.
#HelmChart: #HolosComponent & h.#HelmChart
#HelmChart: #HolosComponent & h.#HelmChart & {
_values: _
_kustomizeFiles: #KustomizeFiles

// Render the values to yaml for holos to provide to helm.
valuesContent: yaml.Marshal(_values)
// Kustomize post-processor
// resources is the intermediate file name for api objects.
resourcesFile: h.#ResourcesFile
// kustomizeFiles represents the files in a kustomize directory tree.
kustomizeFiles: _kustomizeFiles.Files
}
#KubernetesObjects: #HolosComponent & h.#KubernetesObjects
#KustomizeBuild: #HolosComponent & h.#KustomizeBuild

Expand All @@ -35,7 +66,7 @@ import (

// Flux Kustomization CRDs
#Kustomization: #NamespaceObject & ksv1.#Kustomization & {
_dependsOn: [Name=_]: name: string & Name
_dependsOn: DependsOn

metadata: {
name: string
Expand All @@ -61,3 +92,20 @@ import (
dependsOn: [for k, v in _dependsOn {v}, ...]
}
}

// #KustomizeTree represents a kustomize build.
#KustomizeFiles: {
}

// #Kustomize represents the kustomize post processor.
#Kustomize: kc.#Kustomization & {
_patches: {[_]: kc.#Patch}
apiVersion: "kustomize.config.k8s.io/v1beta1"
kind: "Kustomization"
// resources are file names holos will use to store intermediate component output for kustomize to post-process (i.e. helm template | kubectl kustomize)
// See the related resourcesFile field of the holos component.
resources: [h.#ResourcesFile]
if len(_patches) > 0 {
patches: [for v in _patches {v}]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ let CAPatch = #Patch & {
patch: yaml.Marshal(DatabaseCACertPatch)
}

// TODO: Replace with #Kustomize & { _patches: foo: {} }
#KustomizePatches: {
mesh: {
target: {
Expand Down
Loading

0 comments on commit 31280ac

Please sign in to comment.