Compare commits
66 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8d2984a635 | ||
|
|
032f72b435 | ||
|
|
2380223794 | ||
|
|
e6892c3b16 | ||
|
|
847fd2958e | ||
|
|
cf622835db | ||
|
|
1f5dc3a082 | ||
|
|
9f4da68dc9 | ||
|
|
2ee056be9f | ||
|
|
394e2cb0b2 | ||
|
|
cf95c9664d | ||
|
|
0192eeeb7e | ||
|
|
ed54bcc58f | ||
|
|
9ac7f185f9 | ||
|
|
7de72d3dab | ||
|
|
2e3c998454 | ||
|
|
580afffa7f | ||
|
|
67535e1e1d | ||
|
|
767ea69d2e | ||
|
|
21e1a116e4 | ||
|
|
65fe7779be | ||
|
|
0e7abf0173 | ||
|
|
cca022ac99 | ||
|
|
43e939d06a | ||
|
|
8096268826 | ||
|
|
631b23091d | ||
|
|
09c6476282 | ||
|
|
a768d16c5f | ||
|
|
3834a7ef85 | ||
|
|
606a1aae73 | ||
|
|
340d07ee7a | ||
|
|
12d2cec4d5 | ||
|
|
e93feb49b7 | ||
|
|
dcf8602a0b | ||
|
|
e07c4d11c8 | ||
|
|
b7e1c14192 | ||
|
|
29f44cdac9 | ||
|
|
96be7a4ae3 | ||
|
|
d6bd030a72 | ||
|
|
75047b590f | ||
|
|
a05881df0f | ||
|
|
5f406fce5c | ||
|
|
49c945a037 | ||
|
|
54de20f0b8 | ||
|
|
80b4ab9852 | ||
|
|
acd98aa63c | ||
|
|
0afaab8f2b | ||
|
|
7ded38bc3f | ||
|
|
840676709a | ||
|
|
ee30c52673 | ||
|
|
117a00334f | ||
|
|
1e03debfac | ||
|
|
72137b2fa9 | ||
|
|
5abf967116 | ||
|
|
5d882f465d | ||
|
|
45bdaac833 | ||
|
|
7ae1f990ef | ||
|
|
b526fd1669 | ||
|
|
5e07655f35 | ||
|
|
6fb6afe8d5 | ||
|
|
d6f89052d9 | ||
|
|
e4aa7f5994 | ||
|
|
6e4c65cb6c | ||
|
|
4f091677e2 | ||
|
|
0c05df1162 | ||
|
|
64a745fd34 |
25
.cspell.json
@@ -5,10 +5,13 @@
|
||||
"mdx"
|
||||
],
|
||||
"words": [
|
||||
"acmesolver",
|
||||
"acraccesstoken",
|
||||
"acraccesstokens",
|
||||
"admissionregistration",
|
||||
"alertmanager",
|
||||
"alertmanagers",
|
||||
"anchore",
|
||||
"anthos",
|
||||
"apiextensions",
|
||||
"apimachinery",
|
||||
@@ -33,12 +36,14 @@
|
||||
"blackbox",
|
||||
"buildplan",
|
||||
"builtinpluginloadingoptions",
|
||||
"cachedir",
|
||||
"cadvisor",
|
||||
"cainjector",
|
||||
"CAROOT",
|
||||
"certificaterequest",
|
||||
"certificaterequests",
|
||||
"certificatesigningrequests",
|
||||
"clientset",
|
||||
"clsx",
|
||||
"clusterexternalsecret",
|
||||
"clusterexternalsecrets",
|
||||
@@ -49,8 +54,10 @@
|
||||
"clustersecretstore",
|
||||
"clustersecretstores",
|
||||
"clusterwide",
|
||||
"Cmds",
|
||||
"CNCF",
|
||||
"CODEOWNERS",
|
||||
"configdir",
|
||||
"configmap",
|
||||
"configmapargs",
|
||||
"connectrpc",
|
||||
@@ -69,9 +76,11 @@
|
||||
"deploymentruntimeconfig",
|
||||
"destinationrule",
|
||||
"destinationrules",
|
||||
"devel",
|
||||
"devicecode",
|
||||
"dnsmasq",
|
||||
"dscacheutil",
|
||||
"ecrauthorizationtoken",
|
||||
"ecrauthorizationtokens",
|
||||
"edns",
|
||||
"endpointslices",
|
||||
@@ -90,6 +99,7 @@
|
||||
"fullname",
|
||||
"gatewayclass",
|
||||
"gatewayclasses",
|
||||
"gcraccesstoken",
|
||||
"gcraccesstokens",
|
||||
"gendoc",
|
||||
"generationbehavior",
|
||||
@@ -98,8 +108,10 @@
|
||||
"genproto",
|
||||
"ggnpl",
|
||||
"ghaction",
|
||||
"githubaccesstoken",
|
||||
"githubaccesstokens",
|
||||
"gitops",
|
||||
"GOBIN",
|
||||
"godoc",
|
||||
"golangci",
|
||||
"gomarkdoc",
|
||||
@@ -127,6 +139,7 @@
|
||||
"httproute",
|
||||
"httproutes",
|
||||
"iampolicygenerator",
|
||||
"incpatch",
|
||||
"Infima",
|
||||
"intstr",
|
||||
"isatty",
|
||||
@@ -143,6 +156,7 @@
|
||||
"kubelet",
|
||||
"kubelogin",
|
||||
"kubernetesobjects",
|
||||
"kubeversion",
|
||||
"Kustomization",
|
||||
"Kustomizations",
|
||||
"kustomize",
|
||||
@@ -159,6 +173,7 @@
|
||||
"loadbalancer",
|
||||
"loadrestrictions",
|
||||
"logfmt",
|
||||
"lxnl",
|
||||
"mattn",
|
||||
"mccutchen",
|
||||
"metav",
|
||||
@@ -169,6 +184,7 @@
|
||||
"Multicluster",
|
||||
"mutatingwebhookconfiguration",
|
||||
"mutatingwebhookconfigurations",
|
||||
"mvdan",
|
||||
"mxcl",
|
||||
"myhostname",
|
||||
"myRegistrKeySecretName",
|
||||
@@ -183,9 +199,11 @@
|
||||
"oauthproxy",
|
||||
"objectmap",
|
||||
"objectmeta",
|
||||
"omitempty",
|
||||
"organizationconnect",
|
||||
"orgid",
|
||||
"otelconnect",
|
||||
"outfile",
|
||||
"overriden",
|
||||
"Parentspanid",
|
||||
"patchstrategicmerge",
|
||||
@@ -207,6 +225,7 @@
|
||||
"poddisruptionbudget",
|
||||
"poddisruptionbudgets",
|
||||
"podinfo",
|
||||
"podmonitor",
|
||||
"portmapping",
|
||||
"postgrescluster",
|
||||
"privs",
|
||||
@@ -236,9 +255,11 @@
|
||||
"requestauthentications",
|
||||
"resourcequotas",
|
||||
"retryable",
|
||||
"rogpeppe",
|
||||
"rolebinding",
|
||||
"rootfs",
|
||||
"ropc",
|
||||
"sboms",
|
||||
"seccomp",
|
||||
"secretargs",
|
||||
"SECRETKEY",
|
||||
@@ -272,6 +293,7 @@
|
||||
"systemconnect",
|
||||
"tablewriter",
|
||||
"templatable",
|
||||
"testscript",
|
||||
"thanos",
|
||||
"Tiltfile",
|
||||
"timestamppb",
|
||||
@@ -287,6 +309,7 @@
|
||||
"typemeta",
|
||||
"udev",
|
||||
"uibutton",
|
||||
"Unmarshal",
|
||||
"unstage",
|
||||
"untar",
|
||||
"upbound",
|
||||
@@ -298,12 +321,14 @@
|
||||
"userservice",
|
||||
"validatingwebhookconfiguration",
|
||||
"validatingwebhookconfigurations",
|
||||
"vaultdynamicsecret",
|
||||
"vaultdynamicsecrets",
|
||||
"virtualservice",
|
||||
"virtualservices",
|
||||
"volumeattachments",
|
||||
"wasmplugin",
|
||||
"wasmplugins",
|
||||
"workdir",
|
||||
"workloadentries",
|
||||
"workloadentry",
|
||||
"workloadgroup",
|
||||
|
||||
27
.github/workflows/release.yaml
vendored
@@ -35,6 +35,9 @@ jobs:
|
||||
with:
|
||||
go-version: stable
|
||||
|
||||
- name: Setup Syft
|
||||
uses: anchore/sbom-action/download-syft@1ca97d9028b51809cf6d3c934c3e160716e1b605 # v0.17.5
|
||||
|
||||
# Necessary to run these outside of goreleaser, otherwise
|
||||
# /home/runner/_work/holos/holos/internal/frontend/node_modules/.bin/protoc-gen-connect-query is not in PATH
|
||||
- name: Install Tools
|
||||
@@ -54,11 +57,31 @@ jobs:
|
||||
- name: Git diff
|
||||
run: git diff
|
||||
|
||||
- name: Run GoReleaser
|
||||
- uses: actions/create-github-app-token@v1
|
||||
id: app-token
|
||||
with:
|
||||
owner: ${{ github.repository_owner }}
|
||||
app-id: ${{ vars.GORELEASER_APP_ID }}
|
||||
private-key: ${{ secrets.GORELEASER_APP_PRIVATE_KEY }}
|
||||
|
||||
- name: Run GoReleaser if tag
|
||||
if: github.ref_type == 'tag'
|
||||
uses: goreleaser/goreleaser-action@v5
|
||||
with:
|
||||
distribution: goreleaser
|
||||
version: latest
|
||||
version: '~> v2'
|
||||
args: release --clean
|
||||
env:
|
||||
HOMEBREW_TAP_GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Run GoReleaser if branch
|
||||
if: github.ref_type == 'branch' && github.ref == 'refs/heads/release'
|
||||
uses: goreleaser/goreleaser-action@v5
|
||||
with:
|
||||
distribution: goreleaser
|
||||
version: '~> v2'
|
||||
args: release --clean --nightly
|
||||
env:
|
||||
HOMEBREW_TAP_GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -13,7 +13,7 @@ permissions:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: gha-rs
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
@@ -35,7 +35,7 @@ jobs:
|
||||
uses: azure/setup-helm@v4
|
||||
|
||||
- name: Set up Kubectl
|
||||
uses: azure/setup-kubectl@v3
|
||||
uses: azure/setup-kubectl@v4
|
||||
|
||||
- name: Install Tools
|
||||
run: |
|
||||
@@ -6,7 +6,7 @@
|
||||
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
|
||||
# vim: set ts=2 sw=2 tw=0 fo=cnqoj
|
||||
|
||||
version: 1
|
||||
version: 2
|
||||
|
||||
before:
|
||||
hooks:
|
||||
@@ -25,6 +25,24 @@ builds:
|
||||
- amd64
|
||||
- arm64
|
||||
|
||||
# .goreleaser.yml
|
||||
nightly:
|
||||
# Default: `{{ incpatch .Version }}-{{ .ShortCommit }}-nightly`.
|
||||
# Templates: allowed.
|
||||
version_template: "{{ .Version }}-{{ .ShortCommit }}-devel"
|
||||
|
||||
# Tag name to create if publish_release is enabled.
|
||||
tag_name: devel
|
||||
|
||||
# Whether to publish a release or not.
|
||||
# Only works on GitHub.
|
||||
publish_release: true
|
||||
|
||||
# Whether to delete previous pre-releases for the same `tag_name` when
|
||||
# releasing.
|
||||
# This allows you to keep a single pre-release.
|
||||
keep_single_release: true
|
||||
|
||||
signs:
|
||||
- artifacts: checksum
|
||||
args: ["-u", "code-signing-key@openinfrastructure.co", "--output", "${signature}", "--detach-sign", "${artifact}"]
|
||||
@@ -50,3 +68,39 @@ changelog:
|
||||
exclude:
|
||||
- "^docs:"
|
||||
- "^test:"
|
||||
|
||||
source:
|
||||
enabled: true
|
||||
name_template: '{{ .ProjectName }}_{{ .Version }}_source_code'
|
||||
|
||||
sboms:
|
||||
- id: source
|
||||
artifacts: source
|
||||
documents:
|
||||
- "{{ .ProjectName }}_{{ .Version }}_sbom.spdx.json"
|
||||
|
||||
brews:
|
||||
- name: holos
|
||||
repository:
|
||||
owner: holos-run
|
||||
name: homebrew-tap
|
||||
branch: main
|
||||
token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}"
|
||||
directory: Formula
|
||||
homepage: "https://holos.run"
|
||||
description: "Holos CLI"
|
||||
dependencies:
|
||||
- name: helm
|
||||
type: optional
|
||||
- name: kubectl
|
||||
type: optional
|
||||
install: |
|
||||
bin.install "holos"
|
||||
bash_output = Utils.safe_popen_read(bin/"holos", "completion", "bash")
|
||||
(bash_completion/"holos").write bash_output
|
||||
zsh_output = Utils.safe_popen_read(bin/"holos", "completion", "zsh")
|
||||
(zsh_completion/"holos").write zsh_output
|
||||
fish_output = Utils.safe_popen_read(bin/"holos", "completion", "fish")
|
||||
(fish_completion/"holos.fish").write fish_output
|
||||
test: |
|
||||
system "#{bin}/holos version"
|
||||
|
||||
4
Makefile
@@ -150,6 +150,10 @@ dev-deploy: install image ## deploy to dev
|
||||
website: ## Build website
|
||||
./hack/build-website
|
||||
|
||||
.PHONY: unity
|
||||
unity: ## https://cuelabs.dev/unity/
|
||||
./scripts/unity
|
||||
|
||||
.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)
|
||||
|
||||
145
api/author/v1alpha5/definitions.go
Normal file
@@ -0,0 +1,145 @@
|
||||
// Package author contains a standard set of schemas for component authors to
|
||||
// generate common [core] BuildPlans.
|
||||
//
|
||||
// Holos values stability, flexibility, and composition. This package
|
||||
// intentionally defines only the minimal necessary set of structures.
|
||||
// Component authors are encouraged to define their own structures building on
|
||||
// our example [topics].
|
||||
//
|
||||
// The Holos Maintainers may add definitions to this package if the community
|
||||
// identifies nearly all users must define the exact same structure. Otherwise,
|
||||
// definitions should be added as a customizable example in [topics].
|
||||
//
|
||||
// For example, structures representing a cluster and environment almost always
|
||||
// need to be defined. Their definition varies from one organization to the
|
||||
// next. Therefore, customizable definitions for a cluster and environment are
|
||||
// best maintained in [topics], not standardized in this package.
|
||||
//
|
||||
// [core]: https://holos.run/docs/api/core/
|
||||
// [topics]: https://holos.run/docs/topics/
|
||||
package author
|
||||
|
||||
import core "github.com/holos-run/holos/api/core/v1alpha5"
|
||||
|
||||
//go:generate ../../../hack/gendoc
|
||||
|
||||
// Platform assembles a core Platform in the Resource field for the holos render
|
||||
// platform command. Use the Components field to register components with the
|
||||
// platform.
|
||||
type Platform struct {
|
||||
Name string
|
||||
Components map[NameLabel]core.Component
|
||||
Resource core.Platform
|
||||
}
|
||||
|
||||
// ComponentConfig represents the configuration common to all kinds of
|
||||
// components for use with the holos render component command. All component
|
||||
// kinds may be transformed with [kustomize] configured with the
|
||||
// [KustomizeConfig] field.
|
||||
//
|
||||
// - [Helm] charts.
|
||||
// - [Kubernetes] resources generated from CUE.
|
||||
// - [Kustomize] bases.
|
||||
//
|
||||
// [kustomize]: https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/
|
||||
type ComponentConfig struct {
|
||||
// Name represents the BuildPlan metadata.name field. Used to construct the
|
||||
// fully rendered manifest file path.
|
||||
Name string
|
||||
// Path represents the path to the component producing the BuildPlan.
|
||||
Path string
|
||||
// Parameters are useful to reuse a component with various parameters.
|
||||
// Injected as CUE @tag variables. Parameters with a "holos_" prefix are
|
||||
// reserved for use by the Holos Authors.
|
||||
Parameters map[string]string
|
||||
// OutputBaseDir represents the output base directory used when assembling
|
||||
// artifacts. Useful to organize components by clusters or other parameters.
|
||||
// For example, holos writes resource manifests to
|
||||
// {WriteTo}/{OutputBaseDir}/components/{Name}/{Name}.gen.yaml
|
||||
OutputBaseDir string `cue:"string | *\"\""`
|
||||
|
||||
// Resources represents kubernetes resources mixed into the rendered manifest.
|
||||
Resources core.Resources
|
||||
// KustomizeConfig represents the configuration kustomize.
|
||||
KustomizeConfig KustomizeConfig
|
||||
// Artifacts represents additional artifacts to mix in. Useful for adding
|
||||
// GitOps resources. Each Artifact is unified without modification into the
|
||||
// BuildPlan.
|
||||
Artifacts map[NameLabel]core.Artifact
|
||||
}
|
||||
|
||||
// Helm assembles a BuildPlan rendering a helm chart. Useful to mix in
|
||||
// additional resources from CUE and transform the helm output with kustomize.
|
||||
type Helm struct {
|
||||
ComponentConfig `json:",inline"`
|
||||
|
||||
// Chart represents a Helm chart.
|
||||
Chart core.Chart
|
||||
// Values represents data to marshal into a values.yaml for helm.
|
||||
Values core.Values
|
||||
// EnableHooks enables helm hooks when executing the `helm template` command.
|
||||
EnableHooks bool `cue:"true | *false"`
|
||||
// Namespace sets the helm chart namespace flag if provided.
|
||||
Namespace string `json:",omitempty"`
|
||||
// APIVersions represents the helm template --api-versions flag
|
||||
APIVersions []string `json:",omitempty"`
|
||||
// KubeVersion represents the helm template --kube-version flag
|
||||
KubeVersion string `json:",omitempty"`
|
||||
|
||||
// BuildPlan represents the derived BuildPlan produced for the holos render
|
||||
// component command.
|
||||
BuildPlan core.BuildPlan
|
||||
}
|
||||
|
||||
// Kubernetes assembles a BuildPlan containing inline resources exported from
|
||||
// CUE.
|
||||
type Kubernetes struct {
|
||||
ComponentConfig `json:",inline"`
|
||||
|
||||
// BuildPlan represents the derived BuildPlan produced for the holos render
|
||||
// component command.
|
||||
BuildPlan core.BuildPlan
|
||||
}
|
||||
|
||||
// Kustomize assembles a BuildPlan rendering manifests from a [kustomize]
|
||||
// kustomization.
|
||||
//
|
||||
// [kustomize]: https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/
|
||||
type Kustomize struct {
|
||||
ComponentConfig `json:",inline"`
|
||||
|
||||
// BuildPlan represents the derived BuildPlan produced for the holos render
|
||||
// component command.
|
||||
BuildPlan core.BuildPlan
|
||||
}
|
||||
|
||||
// KustomizeConfig represents the configuration for [kustomize] post processing.
|
||||
// Use the Files field to mix in plain manifest files located in the component
|
||||
// directory. Use the Resources field to mix in manifests from network urls.
|
||||
//
|
||||
// [kustomize]: https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/
|
||||
type KustomizeConfig struct {
|
||||
// Kustomization represents the kustomization used to transform resources.
|
||||
// Note the resources field is internally managed from the Files and Resources fields.
|
||||
Kustomization map[string]any `json:",omitempty"`
|
||||
// Files represents files to copy from the component directory for kustomization.
|
||||
Files map[string]struct{ Source string } `cue:"{[NAME=_]: Source: NAME}"`
|
||||
// Resources represents additional entries to included in the resources list.
|
||||
Resources map[string]struct{ Source string } `cue:"{[NAME=_]: Source: NAME}"`
|
||||
// CommonLabels represents common labels added without including selectors.
|
||||
CommonLabels map[string]string
|
||||
}
|
||||
|
||||
// NameLabel represents the common use case of converting a struct to a list
|
||||
// where the name field of each value unifies with the field name of the outer
|
||||
// struct.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// S: [NameLabel=string]: name: NameLabel
|
||||
// S: jeff: _
|
||||
// S: gary: _
|
||||
// S: nate: _
|
||||
// L: [for x in S {x}]
|
||||
// // L is [{name: "jeff"}, {name: "gary"}, {name: "nate"}]
|
||||
type NameLabel string
|
||||
5
api/author/v1alpha5/header.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
title: Author Schemas
|
||||
description: Standardized schemas for component authors.
|
||||
sidebar_position: 200
|
||||
---
|
||||
@@ -1,4 +1,4 @@
|
||||
---
|
||||
description: Core v1alpha2 schema for advanced use cases.
|
||||
sidebar_position: 996
|
||||
description: Core schema for holos to render a component BuildPlan.
|
||||
sidebar_position: 100
|
||||
---
|
||||
|
||||
5
api/core/v1alpha5/header.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
title: Core Schemas
|
||||
description: BuildPlan defines the holos rendering pipeline.
|
||||
sidebar_position: 100
|
||||
---
|
||||
279
api/core/v1alpha5/types.go
Normal file
@@ -0,0 +1,279 @@
|
||||
// Package core contains schemas for a [Platform] and [BuildPlan]. Holos takes
|
||||
// a [Platform] as input, then iterates over each [Component] to produce a
|
||||
// [BuildPlan]. Holos processes the [BuildPlan] to produce fully rendered
|
||||
// manifests, each an [Artifact].
|
||||
package core
|
||||
|
||||
//go:generate ../../../hack/gendoc
|
||||
|
||||
// BuildPlan represents an implementation of the [rendered manifest pattern].
|
||||
// Holos processes a BuildPlan to produce one or more [Artifact] output files.
|
||||
// BuildPlan artifact files usually contain Kubernetes manifests, but they may
|
||||
// have any content.
|
||||
//
|
||||
// A BuildPlan usually produces two artifacts. One artifact contains a manifest
|
||||
// of resources. A second artifact contains a GitOps resource to manage the
|
||||
// first, usually an ArgoCD Application resource.
|
||||
//
|
||||
// Holos uses CUE to construct a BuildPlan. A future enhancement will support
|
||||
// user defined executables providing a BuildPlan to Holos in the style of an
|
||||
// [external credential provider].
|
||||
//
|
||||
// [rendered manifest pattern]: https://akuity.io/blog/the-rendered-manifests-pattern
|
||||
// [external credential provider]: https://github.com/kubernetes/enhancements/blob/313ad8b59c80819659e1fbf0f165230f633f2b22/keps/sig-auth/541-external-credential-providers/README.md
|
||||
type BuildPlan struct {
|
||||
// Kind represents the type of the resource.
|
||||
Kind string `json:"kind" cue:"\"BuildPlan\""`
|
||||
// APIVersion represents the versioned schema of the resource.
|
||||
APIVersion string `json:"apiVersion" cue:"string | *\"v1alpha5\""`
|
||||
// Metadata represents data about the resource such as the Name.
|
||||
Metadata Metadata `json:"metadata"`
|
||||
// Spec specifies the desired state of the resource.
|
||||
Spec BuildPlanSpec `json:"spec"`
|
||||
// Source reflects the origin of the BuildPlan.
|
||||
Source BuildPlanSource `json:"source,omitempty"`
|
||||
}
|
||||
|
||||
// BuildPlanSpec represents the specification of the [BuildPlan].
|
||||
type BuildPlanSpec struct {
|
||||
// Artifacts represents the artifacts for holos to build.
|
||||
Artifacts []Artifact `json:"artifacts"`
|
||||
// Disabled causes the holos cli to disregard the build plan.
|
||||
Disabled bool `json:"disabled,omitempty"`
|
||||
}
|
||||
|
||||
// BuildPlanSource reflects the origin of a [BuildPlan]. Useful to save a build
|
||||
// plan to a file, then re-generate it without needing to process a [Platform]
|
||||
// component collection.
|
||||
type BuildPlanSource struct {
|
||||
// Component reflects the component that produced the build plan.
|
||||
Component Component `json:"component,omitempty"`
|
||||
}
|
||||
|
||||
// Artifact represents one fully rendered manifest produced by a [Transformer]
|
||||
// sequence, which transforms a [Generator] collection. A [BuildPlan] produces
|
||||
// an [Artifact] collection.
|
||||
//
|
||||
// Each Artifact produces one manifest file artifact. Generator Output values
|
||||
// are used as Transformer Inputs. The Output field of the final [Transformer]
|
||||
// should have the same value as the Artifact field.
|
||||
//
|
||||
// When there is more than one [Generator] there must be at least one
|
||||
// [Transformer] to combine outputs into one Artifact. If there is a single
|
||||
// Generator, it may directly produce the Artifact output.
|
||||
//
|
||||
// An Artifact is processed concurrently with other artifacts in the same
|
||||
// [BuildPlan]. An Artifact should not use an output from another Artifact as
|
||||
// an input. Each [Generator] may also run concurrently. Each [Transformer] is
|
||||
// executed sequentially starting after all generators have completed.
|
||||
//
|
||||
// Output fields are write-once. It is an error for multiple Generators or
|
||||
// Transformers to produce the same Output value within the context of a
|
||||
// [BuildPlan].
|
||||
type Artifact struct {
|
||||
Artifact FilePath `json:"artifact,omitempty"`
|
||||
Generators []Generator `json:"generators,omitempty"`
|
||||
Transformers []Transformer `json:"transformers,omitempty"`
|
||||
Skip bool `json:"skip,omitempty"`
|
||||
}
|
||||
|
||||
// Generator generates Kubernetes resources. [Helm] and [Resources] are the
|
||||
// most commonly used, often paired together to mix-in resources to an
|
||||
// unmodified Helm chart. A simple [File] generator is also available for use
|
||||
// with the [Kustomize] transformer.
|
||||
//
|
||||
// Each Generator in an [Artifact] must have a distinct Output value for a
|
||||
// [Transformer] to reference.
|
||||
//
|
||||
// 1. [Resources] - Generates resources from CUE code.
|
||||
// 2. [Helm] - Generates rendered yaml from a [Chart].
|
||||
// 3. [File] - Generates data by reading a file from the component directory.
|
||||
type Generator struct {
|
||||
// Kind represents the kind of generator. Must be Resources, Helm, or File.
|
||||
Kind string `json:"kind" cue:"\"Resources\" | \"Helm\" | \"File\""`
|
||||
// Output represents a file for a Transformer or Artifact to consume.
|
||||
Output FilePath `json:"output"`
|
||||
// Resources generator. Ignored unless kind is Resources. Resources are
|
||||
// stored as a two level struct. The top level key is the Kind of resource,
|
||||
// e.g. Namespace or Deployment. The second level key is an arbitrary
|
||||
// InternalLabel. The third level is a map[string]any representing the
|
||||
// Resource.
|
||||
Resources Resources `json:"resources,omitempty"`
|
||||
// Helm generator. Ignored unless kind is Helm.
|
||||
Helm Helm `json:"helm,omitempty"`
|
||||
// File generator. Ignored unless kind is File.
|
||||
File File `json:"file,omitempty"`
|
||||
}
|
||||
|
||||
// Resource represents one kubernetes api object.
|
||||
type Resource map[string]any
|
||||
|
||||
// Resources represents Kubernetes resources. Most commonly used to mix
|
||||
// resources into the [BuildPlan] generated from CUE, but may be generated from
|
||||
// elsewhere.
|
||||
type Resources map[Kind]map[InternalLabel]Resource
|
||||
|
||||
// File represents a simple single file copy [Generator]. Useful with a
|
||||
// [Kustomize] [Transformer] to process plain manifest files stored in the
|
||||
// component directory. Multiple File generators may be used to transform
|
||||
// multiple resources.
|
||||
type File struct {
|
||||
// Source represents a file sub-path relative to the component path.
|
||||
Source FilePath `json:"source"`
|
||||
}
|
||||
|
||||
// Helm represents a [Chart] manifest [Generator].
|
||||
type Helm struct {
|
||||
// Chart represents a helm chart to manage.
|
||||
Chart Chart `json:"chart"`
|
||||
// Values represents values for holos to marshal into values.yaml when
|
||||
// rendering the chart.
|
||||
Values Values `json:"values"`
|
||||
// EnableHooks enables helm hooks when executing the `helm template` command.
|
||||
EnableHooks bool `json:"enableHooks,omitempty"`
|
||||
// Namespace represents the helm namespace flag
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
// APIVersions represents the helm template --api-versions flag
|
||||
APIVersions []string `json:"apiVersions,omitempty"`
|
||||
// KubeVersion represents the helm template --kube-version flag
|
||||
KubeVersion string `json:"kubeVersion,omitempty"`
|
||||
}
|
||||
|
||||
// Values represents [Helm] Chart values generated from CUE.
|
||||
type Values map[string]any
|
||||
|
||||
// Chart represents a [Helm] Chart.
|
||||
type Chart struct {
|
||||
// Name represents the chart name.
|
||||
Name string `json:"name"`
|
||||
// Version represents the chart version.
|
||||
Version string `json:"version"`
|
||||
// Release represents the chart release when executing helm template.
|
||||
Release string `json:"release"`
|
||||
// Repository represents the repository to fetch the chart from.
|
||||
Repository Repository `json:"repository,omitempty"`
|
||||
}
|
||||
|
||||
// Repository represents a [Helm] [Chart] repository.
|
||||
type Repository struct {
|
||||
Name string `json:"name"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
// Transformer combines multiple inputs from prior [Generator] or [Transformer]
|
||||
// outputs into one output. [Kustomize] is the most commonly used transformer.
|
||||
// A simple [Join] is also supported for use with plain manifest files.
|
||||
//
|
||||
// 1. [Kustomize] - Patch and transform the output from prior generators or
|
||||
// transformers. See [Introduction to Kustomize].
|
||||
// 2. [Join] - Concatenate multiple prior outputs into one output.
|
||||
//
|
||||
// [Introduction to Kustomize]: https://kubectl.docs.kubernetes.io/guides/config_management/introduction/
|
||||
type Transformer struct {
|
||||
// Kind represents the kind of transformer. Must be Kustomize, or Join.
|
||||
Kind string `json:"kind" cue:"\"Kustomize\" | \"Join\""`
|
||||
// Inputs represents the files to transform. The Output of prior Generators
|
||||
// and Transformers.
|
||||
Inputs []FilePath `json:"inputs"`
|
||||
// Output represents a file for a subsequent Transformer or Artifact to
|
||||
// consume.
|
||||
Output FilePath `json:"output"`
|
||||
// Kustomize transformer. Ignored unless kind is Kustomize.
|
||||
Kustomize Kustomize `json:"kustomize,omitempty"`
|
||||
// Join transformer. Ignored unless kind is Join.
|
||||
Join Join `json:"join,omitempty"`
|
||||
}
|
||||
|
||||
// Join represents a [Transformer] using [bytes.Join] to concatenate multiple
|
||||
// inputs into one output with a separator. Useful for combining output from
|
||||
// [Helm] and [Resources] together into one [Artifact] when [Kustomize] is
|
||||
// otherwise unnecessary.
|
||||
//
|
||||
// [bytes.Join]: https://pkg.go.dev/bytes#Join
|
||||
type Join struct {
|
||||
Separator string `json:"separator" cue:"string | *\"---\\n\""`
|
||||
}
|
||||
|
||||
// Kustomize represents a kustomization [Transformer].
|
||||
type Kustomize struct {
|
||||
// Kustomization represents the decoded kustomization.yaml file
|
||||
Kustomization Kustomization `json:"kustomization"`
|
||||
// Files holds file contents for kustomize, e.g. patch files.
|
||||
Files FileContentMap `json:"files,omitempty"`
|
||||
}
|
||||
|
||||
// Kustomization represents a kustomization.yaml file for use with the
|
||||
// [Kustomize] [Transformer]. Untyped to avoid tightly coupling holos to
|
||||
// kubectl versions which was a problem for the Flux maintainers. Type checking
|
||||
// is expected to happen in CUE against the kubectl version the user prefers.
|
||||
type Kustomization map[string]any
|
||||
|
||||
// FileContent represents file contents.
|
||||
type FileContent string
|
||||
|
||||
// FileContentMap represents a mapping of file paths to file contents.
|
||||
type FileContentMap map[FilePath]FileContent
|
||||
|
||||
// FilePath represents a file path.
|
||||
type FilePath string
|
||||
|
||||
// InternalLabel is an arbitrary unique identifier internal to holos itself.
|
||||
// The holos cli is expected to never write a InternalLabel value to rendered
|
||||
// output files, therefore use a InternalLabel when the identifier must be
|
||||
// unique and internal. Defined as a type for clarity and type checking.
|
||||
type InternalLabel string
|
||||
|
||||
// Kind is a discriminator. Defined as a type for clarity and type checking.
|
||||
type Kind string
|
||||
|
||||
// Metadata represents data about the resource such as the Name.
|
||||
type Metadata struct {
|
||||
// Name represents the resource name.
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// Platform represents a platform to manage. A Platform specifies a [Component]
|
||||
// collection and integrates the components together into a holistic platform.
|
||||
// Holos iterates over the [Component] collection producing a [BuildPlan] for
|
||||
// each, which holos then executes to render manifests.
|
||||
//
|
||||
// Inspect a Platform resource holos would process by executing:
|
||||
//
|
||||
// cue export --out yaml ./platform
|
||||
type Platform struct {
|
||||
// Kind is a string value representing the resource.
|
||||
Kind string `json:"kind" cue:"\"Platform\""`
|
||||
// APIVersion represents the versioned schema of this resource.
|
||||
APIVersion string `json:"apiVersion" cue:"string | *\"v1alpha5\""`
|
||||
// Metadata represents data about the resource such as the Name.
|
||||
Metadata Metadata `json:"metadata"`
|
||||
|
||||
// Spec represents the platform specification.
|
||||
Spec PlatformSpec `json:"spec"`
|
||||
}
|
||||
|
||||
// PlatformSpec represents the platform specification.
|
||||
type PlatformSpec struct {
|
||||
// Components represents a collection of holos components to manage.
|
||||
Components []Component `json:"components"`
|
||||
}
|
||||
|
||||
// Component represents the complete context necessary to produce a [BuildPlan]
|
||||
// from a path containing parameterized CUE configuration.
|
||||
type Component struct {
|
||||
// Name represents the name of the component. Injected as the tag variable
|
||||
// "holos_component_name".
|
||||
Name string `json:"name"`
|
||||
// Path represents the path of the component relative to the platform root.
|
||||
// Injected as the tag variable "holos_component_path".
|
||||
Path string `json:"path"`
|
||||
// WriteTo represents the holos render component --write-to flag. If empty,
|
||||
// the default value for the --write-to flag is used.
|
||||
WriteTo string `json:"writeTo,omitempty"`
|
||||
// Parameters represent user defined input variables to produce various
|
||||
// [BuildPlan] resources from one component path. Injected as CUE @tag
|
||||
// variables. Parameters with a "holos_" prefix are reserved for use by the
|
||||
// Holos Authors. Multiple environments are a prime example of an input
|
||||
// parameter that should always be user defined, never defined by Holos.
|
||||
Parameters map[string]string `json:"parameters,omitempty"`
|
||||
}
|
||||
@@ -2,8 +2,10 @@ package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
cue "cuelang.org/go/cmd/cue/cmd"
|
||||
"github.com/holos-run/holos/internal/cli"
|
||||
"github.com/rogpeppe/go-internal/testscript"
|
||||
)
|
||||
@@ -11,11 +13,42 @@ import (
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(testscript.RunMain(m, map[string]func() int{
|
||||
"holos": cli.MakeMain(),
|
||||
"cue": cue.Main,
|
||||
}))
|
||||
}
|
||||
|
||||
func TestGetSecrets(t *testing.T) {
|
||||
testscript.Run(t, testscript.Params{
|
||||
Dir: "testdata",
|
||||
})
|
||||
func TestGuides_v1alpha4(t *testing.T) {
|
||||
testscript.Run(t, params(filepath.Join("v1alpha4", "guides")))
|
||||
}
|
||||
func TestGuides_v1alpha5(t *testing.T) {
|
||||
testscript.Run(t, params(filepath.Join("v1alpha5", "guides")))
|
||||
}
|
||||
|
||||
func TestSchemas_v1alpha5(t *testing.T) {
|
||||
testscript.Run(t, params(filepath.Join("v1alpha5", "schemas")))
|
||||
}
|
||||
|
||||
func TestIssues_v1alpha5(t *testing.T) {
|
||||
testscript.Run(t, params(filepath.Join("v1alpha5", "issues")))
|
||||
}
|
||||
|
||||
func TestCLI(t *testing.T) {
|
||||
testscript.Run(t, params("cli"))
|
||||
}
|
||||
|
||||
func params(dir string) testscript.Params {
|
||||
return testscript.Params{
|
||||
Dir: filepath.Join("tests", dir),
|
||||
RequireExplicitExec: true,
|
||||
RequireUniqueNames: os.Getenv("HOLOS_WORKDIR_ROOT") == "",
|
||||
WorkdirRoot: os.Getenv("HOLOS_WORKDIR_ROOT"),
|
||||
UpdateScripts: os.Getenv("HOLOS_UPDATE_SCRIPTS") != "",
|
||||
Setup: func(env *testscript.Env) error {
|
||||
// Just like cmd/cue/cmd.TestScript, set up separate cache and config dirs per test.
|
||||
env.Setenv("CUE_CACHE_DIR", filepath.Join(env.WorkDir, "tmp/cachedir"))
|
||||
configDir := filepath.Join(env.WorkDir, "tmp/configdir")
|
||||
env.Setenv("CUE_CONFIG_DIR", configDir)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
34
cmd/holos/testdata/constraints.txt
vendored
@@ -1,34 +0,0 @@
|
||||
# Want support for intermediary constraints
|
||||
exec holos build ./foo/... --log-level debug
|
||||
stdout '^bf2bc7f9-9ba0-4f9e-9bd2-9a205627eb0b$'
|
||||
|
||||
-- platform.config.json --
|
||||
{}
|
||||
-- cue.mod --
|
||||
package holos
|
||||
-- foo/constraints.cue --
|
||||
package holos
|
||||
|
||||
metadata: name: "jeff"
|
||||
-- foo/bar/bar.cue --
|
||||
package holos
|
||||
|
||||
spec: components: KubernetesObjectsList: [
|
||||
#KubernetesObjects & {
|
||||
apiObjectMap: foo: bar: "bf2bc7f9-9ba0-4f9e-9bd2-9a205627eb0b"
|
||||
}
|
||||
]
|
||||
-- schema.cue --
|
||||
package holos
|
||||
|
||||
_cluster: string @tag(cluster, string)
|
||||
_platform_config: string @tag(platform_config, string)
|
||||
|
||||
#KubernetesObjects: {
|
||||
apiVersion: "holos.run/v1alpha1"
|
||||
kind: "KubernetesObjects"
|
||||
apiObjectMap: {...}
|
||||
}
|
||||
|
||||
apiVersion: "holos.run/v1alpha1"
|
||||
kind: "BuildPlan"
|
||||
20
cmd/holos/testdata/issue15_cue_errors.txt
vendored
@@ -1,20 +0,0 @@
|
||||
# Want cue errors to show files and lines
|
||||
! exec holos build .
|
||||
stderr 'apiObjectMap.foo.bar: cannot convert incomplete value'
|
||||
stderr '/component.cue:\d+:\d+$'
|
||||
|
||||
-- platform.config.json --
|
||||
{}
|
||||
-- cue.mod --
|
||||
package holos
|
||||
-- component.cue --
|
||||
package holos
|
||||
|
||||
_cluster: string @tag(cluster, string)
|
||||
_platform_config: string @tag(platform_config, string)
|
||||
|
||||
apiVersion: "holos.run/v1alpha1"
|
||||
kind: "BuildPlan"
|
||||
spec: components: KubernetesObjectsList: [{apiObjectMap: foo: bar: _baz}]
|
||||
|
||||
_baz: string
|
||||
61
cmd/holos/testdata/issue25_apiobjects_cue.txt
vendored
@@ -1,61 +0,0 @@
|
||||
# Want kube api objects in the apiObjects output.
|
||||
exec holos build .
|
||||
stdout '^kind: SecretStore$'
|
||||
stdout '# Source: CUE apiObjects.SecretStore.default'
|
||||
|
||||
-- platform.config.json --
|
||||
{}
|
||||
-- cue.mod --
|
||||
package holos
|
||||
-- component.cue --
|
||||
package holos
|
||||
|
||||
apiVersion: "holos.run/v1alpha1"
|
||||
kind: "BuildPlan"
|
||||
spec: components: KubernetesObjectsList: [{apiObjectMap: #APIObjects.apiObjectMap}]
|
||||
|
||||
_cluster: string @tag(cluster, string)
|
||||
_platform_config: string @tag(platform_config, string)
|
||||
|
||||
#SecretStore: {
|
||||
kind: string
|
||||
metadata: name: string
|
||||
}
|
||||
|
||||
#APIObjects: {
|
||||
apiObjects: {
|
||||
SecretStore: {
|
||||
default: #SecretStore & { metadata: name: "default" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-- schema.cue --
|
||||
package holos
|
||||
|
||||
// #APIObjects is the output type for api objects produced by cue. A map is used to aid debugging and clarity.
|
||||
import "encoding/yaml"
|
||||
|
||||
#APIObjects: {
|
||||
// apiObjects holds each the api objects produced by cue.
|
||||
apiObjects: {
|
||||
[Kind=_]: {
|
||||
[Name=_]: {
|
||||
kind: Kind
|
||||
metadata: name: Name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// apiObjectsContent holds the marshalled representation of apiObjects
|
||||
apiObjectMap: {
|
||||
for kind, v in apiObjects {
|
||||
"\(kind)": {
|
||||
for name, obj in v {
|
||||
"\(name)": yaml.Marshal(obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
62
cmd/holos/testdata/issue25_apiobjects_helm.txt
vendored
@@ -1,62 +0,0 @@
|
||||
# Want kube api objects in the apiObjects output.
|
||||
exec holos build .
|
||||
stdout '^kind: SecretStore$'
|
||||
stdout '# Source: CUE apiObjects.SecretStore.default'
|
||||
stderr 'skipping helm: no chart name specified'
|
||||
|
||||
-- platform.config.json --
|
||||
{}
|
||||
-- cue.mod --
|
||||
package holos
|
||||
-- component.cue --
|
||||
package holos
|
||||
|
||||
apiVersion: "holos.run/v1alpha1"
|
||||
kind: "BuildPlan"
|
||||
spec: components: HelmChartList: [{apiObjectMap: #APIObjects.apiObjectMap}]
|
||||
|
||||
_cluster: string @tag(cluster, string)
|
||||
_platform_config: string @tag(platform_config, string)
|
||||
|
||||
#SecretStore: {
|
||||
kind: string
|
||||
metadata: name: string
|
||||
}
|
||||
|
||||
#APIObjects: {
|
||||
apiObjects: {
|
||||
SecretStore: {
|
||||
default: #SecretStore & { metadata: name: "default" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-- schema.cue --
|
||||
package holos
|
||||
|
||||
// #APIObjects is the output type for api objects produced by cue. A map is used to aid debugging and clarity.
|
||||
import "encoding/yaml"
|
||||
|
||||
#APIObjects: {
|
||||
// apiObjects holds each the api objects produced by cue.
|
||||
apiObjects: {
|
||||
[Kind=_]: {
|
||||
[Name=_]: {
|
||||
kind: Kind
|
||||
metadata: name: Name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// apiObjectsContent holds the marshalled representation of apiObjects
|
||||
apiObjectMap: {
|
||||
for kind, v in apiObjects {
|
||||
"\(kind)": {
|
||||
for name, obj in v {
|
||||
"\(name)": yaml.Marshal(obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
25
cmd/holos/testdata/issue25_show_object_names.txt
vendored
@@ -1,25 +0,0 @@
|
||||
# Want api object kind and name in errors
|
||||
! exec holos build .
|
||||
stderr 'apiObjects.secretstore.default.foo: field not allowed'
|
||||
|
||||
-- platform.config.json --
|
||||
{}
|
||||
-- cue.mod --
|
||||
package holos
|
||||
-- component.cue --
|
||||
package holos
|
||||
|
||||
apiVersion: "holos.run/v1alpha1"
|
||||
kind: "KubernetesObjects"
|
||||
cluster: string @tag(cluster, string)
|
||||
_platform_config: string @tag(platform_config, string)
|
||||
|
||||
#SecretStore: {
|
||||
metadata: name: string
|
||||
}
|
||||
|
||||
apiObjects: {
|
||||
secretstore: {
|
||||
default: #SecretStore & { foo: "not allowed" }
|
||||
}
|
||||
}
|
||||
289
cmd/holos/testdata/issue33_helm_stderr.txt
vendored
@@ -1,289 +0,0 @@
|
||||
# Want helm errors to show up
|
||||
! exec holos build .
|
||||
stderr 'Error: execution error at \(zitadel/templates/secret_zitadel-masterkey.yaml:2:4\): Either set .Values.zitadel.masterkey xor .Values.zitadel.masterkeySecretName'
|
||||
|
||||
-- platform.config.json --
|
||||
{}
|
||||
-- cue.mod --
|
||||
package holos
|
||||
-- zitadel.cue --
|
||||
package holos
|
||||
|
||||
apiVersion: "holos.run/v1alpha1"
|
||||
kind: "BuildPlan"
|
||||
spec: components: HelmChartList: [_HelmChart]
|
||||
|
||||
_cluster: string @tag(cluster, string)
|
||||
_platform_config: string @tag(platform_config, string)
|
||||
|
||||
_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" }}
|
||||
{{- end }}
|
||||
{{- if .Values.zitadel.masterkey -}}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
type: Opaque
|
||||
metadata:
|
||||
name: zitadel-masterkey
|
||||
{{- with .Values.zitadel.masterkeyAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "zitadel.labels" . | nindent 4 }}
|
||||
stringData:
|
||||
masterkey: {{ .Values.zitadel.masterkey }}
|
||||
{{- end -}}
|
||||
-- vendor/zitadel/Chart.yaml --
|
||||
apiVersion: v2
|
||||
appVersion: v2.46.0
|
||||
description: A Helm chart for ZITADEL
|
||||
icon: https://zitadel.com/zitadel-logo-dark.svg
|
||||
kubeVersion: '>= 1.21.0-0'
|
||||
maintainers:
|
||||
- email: support@zitadel.com
|
||||
name: zitadel
|
||||
url: https://zitadel.com
|
||||
name: zitadel
|
||||
type: application
|
||||
version: 7.9.0
|
||||
-- vendor/zitadel/values.yaml --
|
||||
# Default values for zitadel.
|
||||
zitadel:
|
||||
# The ZITADEL config under configmapConfig is written to a Kubernetes ConfigMap
|
||||
# See all defaults here:
|
||||
# https://github.com/zitadel/zitadel/blob/main/cmd/defaults.yaml
|
||||
configmapConfig:
|
||||
ExternalSecure: true
|
||||
Machine:
|
||||
Identification:
|
||||
Hostname:
|
||||
Enabled: true
|
||||
Webhook:
|
||||
Enabled: false
|
||||
|
||||
# The ZITADEL config under secretConfig is written to a Kubernetes Secret
|
||||
# See all defaults here:
|
||||
# https://github.com/zitadel/zitadel/blob/main/cmd/defaults.yaml
|
||||
secretConfig:
|
||||
|
||||
# Annotations set on secretConfig secret
|
||||
secretConfigAnnotations:
|
||||
helm.sh/hook: pre-install,pre-upgrade
|
||||
helm.sh/hook-delete-policy: before-hook-creation
|
||||
helm.sh/hook-weight: "0"
|
||||
|
||||
# Reference the name of a secret that contains ZITADEL configuration.
|
||||
configSecretName:
|
||||
# The key under which the ZITADEL configuration is located in the secret.
|
||||
configSecretKey: config-yaml
|
||||
|
||||
# ZITADEL uses the masterkey for symmetric encryption.
|
||||
# You can generate it for example with tr -dc A-Za-z0-9 </dev/urandom | head -c 32
|
||||
masterkey: ""
|
||||
# Reference the name of the secret that contains the masterkey. The key should be named "masterkey".
|
||||
# Note: Either zitadel.masterkey or zitadel.masterkeySecretName must be set
|
||||
masterkeySecretName: ""
|
||||
|
||||
# Annotations set on masterkey secret
|
||||
masterkeyAnnotations:
|
||||
helm.sh/hook: pre-install,pre-upgrade
|
||||
helm.sh/hook-delete-policy: before-hook-creation
|
||||
helm.sh/hook-weight: "0"
|
||||
|
||||
# The CA Certificate needed for establishing secure database connections
|
||||
dbSslCaCrt: ""
|
||||
|
||||
# The Secret containing the CA certificate at key ca.crt needed for establishing secure database connections
|
||||
dbSslCaCrtSecret: ""
|
||||
|
||||
# The db admins secret containing the client certificate and key at tls.crt and tls.key needed for establishing secure database connections
|
||||
dbSslAdminCrtSecret: ""
|
||||
|
||||
# The db users secret containing the client certificate and key at tls.crt and tls.key needed for establishing secure database connections
|
||||
dbSslUserCrtSecret: ""
|
||||
|
||||
# Generate a self-signed certificate using an init container
|
||||
# This will also mount the generated files to /etc/tls/ so that you can reference them in the pod.
|
||||
# E.G. KeyPath: /etc/tls/tls.key CertPath: /etc/tls/tls.crt
|
||||
# By default, the SAN DNS names include, localhost, the POD IP address and the POD name. You may include one more by using additionalDnsName like "my.zitadel.fqdn".
|
||||
selfSignedCert:
|
||||
enabled: false
|
||||
additionalDnsName:
|
||||
|
||||
replicaCount: 3
|
||||
|
||||
image:
|
||||
repository: ghcr.io/zitadel/zitadel
|
||||
pullPolicy: IfNotPresent
|
||||
# Overrides the image tag whose default is the chart appVersion.
|
||||
tag: ""
|
||||
|
||||
chownImage:
|
||||
repository: alpine
|
||||
pullPolicy: IfNotPresent
|
||||
tag: "3.19"
|
||||
|
||||
imagePullSecrets: []
|
||||
nameOverride: ""
|
||||
fullnameOverride: ""
|
||||
|
||||
# Annotations to add to the deployment
|
||||
annotations: {}
|
||||
|
||||
# Annotations to add to the configMap
|
||||
configMap:
|
||||
annotations:
|
||||
helm.sh/hook: pre-install,pre-upgrade
|
||||
helm.sh/hook-delete-policy: before-hook-creation
|
||||
helm.sh/hook-weight: "0"
|
||||
|
||||
serviceAccount:
|
||||
# Specifies whether a service account should be created
|
||||
create: true
|
||||
# Annotations to add to the service account
|
||||
annotations:
|
||||
helm.sh/hook: pre-install,pre-upgrade
|
||||
helm.sh/hook-delete-policy: before-hook-creation
|
||||
helm.sh/hook-weight: "0"
|
||||
# The name of the service account to use.
|
||||
# If not set and create is true, a name is generated using the fullname template
|
||||
name: ""
|
||||
|
||||
podAnnotations: {}
|
||||
|
||||
podAdditionalLabels: {}
|
||||
|
||||
podSecurityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
|
||||
securityContext: {}
|
||||
|
||||
# Additional environment variables
|
||||
env:
|
||||
[]
|
||||
# - name: ZITADEL_DATABASE_POSTGRES_HOST
|
||||
# valueFrom:
|
||||
# secretKeyRef:
|
||||
# name: postgres-pguser-postgres
|
||||
# key: host
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
# If service type is "ClusterIP", this can optionally be set to a fixed IP address.
|
||||
clusterIP: ""
|
||||
port: 8080
|
||||
protocol: http2
|
||||
annotations: {}
|
||||
scheme: HTTP
|
||||
|
||||
ingress:
|
||||
enabled: false
|
||||
className: ""
|
||||
annotations: {}
|
||||
hosts:
|
||||
- host: localhost
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
tls: []
|
||||
|
||||
resources: {}
|
||||
|
||||
nodeSelector: {}
|
||||
|
||||
tolerations: []
|
||||
|
||||
affinity: {}
|
||||
|
||||
topologySpreadConstraints: []
|
||||
|
||||
initJob:
|
||||
# Once ZITADEL is installed, the initJob can be disabled.
|
||||
enabled: true
|
||||
annotations:
|
||||
helm.sh/hook: pre-install,pre-upgrade
|
||||
helm.sh/hook-delete-policy: before-hook-creation
|
||||
helm.sh/hook-weight: "1"
|
||||
resources: {}
|
||||
backoffLimit: 5
|
||||
activeDeadlineSeconds: 300
|
||||
extraContainers: []
|
||||
podAnnotations: {}
|
||||
# Available init commands :
|
||||
# "": initialize ZITADEL instance (without skip anything)
|
||||
# database: initialize only the database
|
||||
# grant: set ALL grant to user
|
||||
# user: initialize only the database user
|
||||
# zitadel: initialize ZITADEL internals (skip "create user" and "create database")
|
||||
command: ""
|
||||
|
||||
setupJob:
|
||||
annotations:
|
||||
helm.sh/hook: pre-install,pre-upgrade
|
||||
helm.sh/hook-delete-policy: before-hook-creation
|
||||
helm.sh/hook-weight: "2"
|
||||
resources: {}
|
||||
activeDeadlineSeconds: 300
|
||||
extraContainers: []
|
||||
podAnnotations: {}
|
||||
additionalArgs:
|
||||
- "--init-projections=true"
|
||||
machinekeyWriter:
|
||||
image:
|
||||
repository: bitnami/kubectl
|
||||
tag: ""
|
||||
resources: {}
|
||||
|
||||
readinessProbe:
|
||||
enabled: true
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 5
|
||||
failureThreshold: 3
|
||||
|
||||
livenessProbe:
|
||||
enabled: true
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 5
|
||||
failureThreshold: 3
|
||||
|
||||
startupProbe:
|
||||
enabled: true
|
||||
periodSeconds: 1
|
||||
failureThreshold: 30
|
||||
|
||||
metrics:
|
||||
enabled: false
|
||||
serviceMonitor:
|
||||
# If true, the chart creates a ServiceMonitor that is compatible with Prometheus Operator
|
||||
# https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#monitoring.coreos.com/v1.ServiceMonitor.
|
||||
# The Prometheus community Helm chart installs this operator
|
||||
# https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack#kube-prometheus-stack
|
||||
enabled: false
|
||||
honorLabels: false
|
||||
honorTimestamps: true
|
||||
|
||||
pdb:
|
||||
enabled: false
|
||||
# these values are used for the PDB and are mutally exclusive
|
||||
minAvailable: 1
|
||||
# maxUnavailable: 1
|
||||
annotations: {}
|
||||
@@ -1,39 +0,0 @@
|
||||
# Kustomize is a supported holos component kind
|
||||
exec holos render component --cluster-name=mycluster . --log-level=debug
|
||||
|
||||
# Want generated output
|
||||
cmp want.yaml deploy/clusters/mycluster/components/kstest/kstest.gen.yaml
|
||||
|
||||
-- platform.config.json --
|
||||
{}
|
||||
-- cue.mod --
|
||||
package holos
|
||||
-- component.cue --
|
||||
package holos
|
||||
|
||||
_cluster: string @tag(cluster, string)
|
||||
_platform_config: string @tag(platform_config, string)
|
||||
|
||||
apiVersion: "holos.run/v1alpha1"
|
||||
kind: "BuildPlan"
|
||||
spec: components: KustomizeBuildList: [{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
|
||||
metadata:
|
||||
name: test
|
||||
namespace: mynamespace
|
||||
@@ -1,17 +0,0 @@
|
||||
# https://github.com/holos-run/holos/issues/72
|
||||
# Want holos to fail on unknown fields to catch typos and aid refactors
|
||||
! exec holos build .
|
||||
stderr 'unknown field \\"TypoKubernetesObjectsList\\"'
|
||||
|
||||
-- platform.config.json --
|
||||
{}
|
||||
-- cue.mod --
|
||||
package holos
|
||||
-- component.cue --
|
||||
package holos
|
||||
_cluster: string @tag(cluster, string)
|
||||
_platform_config: string @tag(platform_config, string)
|
||||
|
||||
apiVersion: "holos.run/v1alpha1"
|
||||
kind: "BuildPlan"
|
||||
spec: components: TypoKubernetesObjectsList: []
|
||||
2
cmd/holos/tests/cli/first-impression.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
# https://github.com/holos-run/holos/issues/334
|
||||
exec holos
|
||||
15042
cmd/holos/tests/v1alpha4/guides/helm.txt
Normal file
14953
cmd/holos/tests/v1alpha5/guides/helm.txt
Normal file
38
cmd/holos/tests/v1alpha5/issues/helm-pull-errors.txt
Normal file
@@ -0,0 +1,38 @@
|
||||
# https://github.com/holos-run/holos/issues/332
|
||||
env HOME=$WORK
|
||||
# Mock with a stub helm command
|
||||
env PATH=$WORK/bin:$PATH
|
||||
chmod 755 bin/helm
|
||||
# Initialize the platform
|
||||
exec holos init platform v1alpha5 --force
|
||||
# when helm update returns an error
|
||||
! exec holos render platform ./platform
|
||||
# holos should log the helm error to stderr
|
||||
stderr 'Error: chart "podinfo" matching 0.0.0 not found in podinfo index'
|
||||
-- bin/helm --
|
||||
#! /bin/bash
|
||||
echo 'Error: chart "podinfo" matching 0.0.0 not found in podinfo index' >&2
|
||||
exit 2
|
||||
-- platform/podinfo.cue --
|
||||
package holos
|
||||
|
||||
Platform: Components: podinfo: {
|
||||
name: "podinfo"
|
||||
path: "components/podinfo"
|
||||
}
|
||||
-- components/podinfo/podinfo.cue --
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
holos: HelmChart.BuildPlan
|
||||
|
||||
HelmChart: #Helm & {
|
||||
Name: "podinfo"
|
||||
Chart: {
|
||||
version: "0.0.0"
|
||||
repository: {
|
||||
name: "podinfo"
|
||||
url: "https://stefanprodan.github.io/podinfo"
|
||||
}
|
||||
}
|
||||
}
|
||||
144
cmd/holos/tests/v1alpha5/schemas/capabilities.txt
Normal file
@@ -0,0 +1,144 @@
|
||||
# https://github.com/holos-run/holos/issues/330
|
||||
exec holos init platform v1alpha5 --force
|
||||
exec helm template ./components/capabilities/vendor/0.1.0/capabilities
|
||||
cmp stdout want/helm-template.yaml
|
||||
exec holos render platform ./platform
|
||||
# When no capabilities are specified
|
||||
cmp deploy/components/capabilities/capabilities.gen.yaml want/when-no-capabilities-specified.yaml
|
||||
# With APIVersions specified
|
||||
cmp deploy/components/specified/specified.gen.yaml want/with-capabilities-specified.yaml
|
||||
# With KubeVersion specified
|
||||
cmp deploy/components/kubeversion1/kubeversion1.gen.yaml want/with-kubeversion-specified.yaml
|
||||
# With both APIVersions and KubeVersion specified
|
||||
cmp deploy/components/kubeversion2/kubeversion2.gen.yaml want/with-both-specified.yaml
|
||||
-- want/with-both-specified.yaml --
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations:
|
||||
kubeVersion: v1.20.0
|
||||
name: has-foo-v1
|
||||
spec:
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
protocol: TCP
|
||||
targetPort: http
|
||||
-- want/with-kubeversion-specified.yaml --
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations:
|
||||
kubeVersion: v1.20.0
|
||||
name: has-foo-v1beta1
|
||||
spec:
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
protocol: TCP
|
||||
targetPort: http
|
||||
-- want/when-no-capabilities-specified.yaml --
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations:
|
||||
kubeVersion: v1.31.0
|
||||
name: has-foo-v1beta1
|
||||
spec:
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
protocol: TCP
|
||||
targetPort: http
|
||||
-- want/with-capabilities-specified.yaml --
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations:
|
||||
kubeVersion: v1.31.0
|
||||
name: has-foo-v1
|
||||
spec:
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
protocol: TCP
|
||||
targetPort: http
|
||||
-- platform/capabilities.cue --
|
||||
package holos
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
Platform: Components: capabilities: {
|
||||
name: "capabilities"
|
||||
path: "components/capabilities"
|
||||
}
|
||||
Platform: Components: specified: {
|
||||
name: "specified"
|
||||
path: "components/capabilities"
|
||||
parameters: apiVersions: json.Marshal(["foo/v1","bar/v1"])
|
||||
}
|
||||
Platform: Components: kubeversion1: {
|
||||
name: "kubeversion1"
|
||||
path: "components/capabilities"
|
||||
parameters: kubeVersion: "v1.20.0"
|
||||
}
|
||||
Platform: Components: kubeversion2: {
|
||||
name: "kubeversion2"
|
||||
path: "components/capabilities"
|
||||
parameters: kubeVersion: "v1.20.0"
|
||||
parameters: apiVersions: json.Marshal(["foo/v1","bar/v1"])
|
||||
}
|
||||
-- components/capabilities/capabilities.cue --
|
||||
package holos
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
holos: Component.BuildPlan
|
||||
|
||||
Component: #Helm & {
|
||||
Name: string @tag(holos_component_name, type=string)
|
||||
Chart: name: "capabilities"
|
||||
Chart: version: "0.1.0"
|
||||
_APIVersions: string | *"[]" @tag(apiVersions, type=string)
|
||||
APIVersions: json.Unmarshal(_APIVersions)
|
||||
KubeVersion: string | *"v1.31.0" @tag(kubeVersion, type=string)
|
||||
}
|
||||
-- components/capabilities/vendor/0.1.0/capabilities/Chart.yaml --
|
||||
apiVersion: v2
|
||||
name: capabilities
|
||||
description: A Helm chart for Kubernetes
|
||||
type: application
|
||||
version: 0.1.0
|
||||
appVersion: "1.16.0"
|
||||
-- components/capabilities/vendor/0.1.0/capabilities/templates/service.yaml --
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
{{- if .Capabilities.APIVersions.Has "foo/v1" }}
|
||||
name: has-foo-v1
|
||||
{{- else }}
|
||||
name: has-foo-v1beta1
|
||||
{{- end }}
|
||||
annotations:
|
||||
kubeVersion: {{ .Capabilities.KubeVersion }}
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
-- want/helm-template.yaml --
|
||||
---
|
||||
# Source: capabilities/templates/service.yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: has-foo-v1beta1
|
||||
annotations:
|
||||
kubeVersion: v1.31.0
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
52
cmd/holos/tests/v1alpha5/schemas/kubernetes.txt
Normal file
@@ -0,0 +1,52 @@
|
||||
# author.#Kubernetes
|
||||
|
||||
# Start in an empty directory.
|
||||
cd $WORK
|
||||
|
||||
# Generate the directory structure we're going to work in.
|
||||
exec holos generate platform v1alpha5 --force
|
||||
|
||||
# Platforms are empty by default.
|
||||
exec holos render platform ./platform
|
||||
stderr -count=1 '^rendered platform'
|
||||
|
||||
# When author.#Kubernetes is empty
|
||||
exec holos cue export --expression holos --out=yaml ./components/empty
|
||||
cmp stdout want.txt
|
||||
|
||||
-- components/empty/empty.cue --
|
||||
package holos
|
||||
|
||||
Kubernetes: #Kubernetes & {}
|
||||
holos: Kubernetes.BuildPlan
|
||||
-- want.txt --
|
||||
kind: BuildPlan
|
||||
apiVersion: v1alpha5
|
||||
metadata:
|
||||
name: no-name
|
||||
spec:
|
||||
artifacts:
|
||||
- artifact: components/no-name/no-name.gen.yaml
|
||||
generators:
|
||||
- kind: Resources
|
||||
output: resources.gen.yaml
|
||||
resources: {}
|
||||
transformers:
|
||||
- kind: Kustomize
|
||||
inputs:
|
||||
- resources.gen.yaml
|
||||
output: components/no-name/no-name.gen.yaml
|
||||
kustomize:
|
||||
kustomization:
|
||||
labels:
|
||||
- includeSelectors: false
|
||||
pairs: {}
|
||||
resources:
|
||||
- resources.gen.yaml
|
||||
kind: Kustomization
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
source:
|
||||
component:
|
||||
name: no-name
|
||||
path: no-path
|
||||
parameters: {}
|
||||
@@ -80,33 +80,62 @@ The bank front end web service is managed by the
|
||||
refers to the organization display name in `schema.gen.cue`.
|
||||
|
||||
<Tabs groupId="F5B546EB-566F-4B83-84C3-C55B40F55555">
|
||||
<TabItem value="schema.gen.cue" label="schema.gen.cue">
|
||||
<TabItem value="schema.cue" label="schema.cue">
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
import api "github.com/holos-run/holos/api/author/v1alpha3"
|
||||
import api "github.com/holos-run/holos/api/author/v1alpha4"
|
||||
|
||||
// Define the default organization name
|
||||
// highlight-next-line
|
||||
#Organization: DisplayName: string | *"Bank of Holos"
|
||||
#Organization: Name: string | *"bank-of-holos"
|
||||
|
||||
#Organization: api.#OrganizationStrict
|
||||
#Platform: api.#Platform
|
||||
#Fleets: api.#StandardFleets
|
||||
|
||||
_ComponentConfig: {
|
||||
Resources: #Resources
|
||||
ArgoConfig: #ArgoConfig
|
||||
// Define the default organization name.
|
||||
_Organization: api.#OrganizationStrict & {
|
||||
DisplayName: string | *"Bank of Holos"
|
||||
Name: string | *"bank-of-holos"
|
||||
Domain: string | *"holos.localhost"
|
||||
}
|
||||
|
||||
#Helm: api.#Helm & _ComponentConfig
|
||||
#Kustomize: api.#Kustomize & _ComponentConfig
|
||||
#Kubernetes: api.#Kubernetes & _ComponentConfig
|
||||
// Projects represents a way to organize components into projects with owners.
|
||||
// https://holos.run/docs/api/author/v1alpha4/#Projects
|
||||
_Projects: api.#Projects
|
||||
|
||||
#ArgoConfig: api.#ArgoConfig & {
|
||||
ClusterName: _ClusterName
|
||||
// ArgoConfig represents the configuration of ArgoCD Application resources for
|
||||
// each component.
|
||||
// https://holos.run/docs/api/author/v1alpha4/#ArgoConfig
|
||||
_ArgoConfig: api.#ArgoConfig
|
||||
|
||||
#ComponentConfig: api.#ComponentConfig & {
|
||||
Name: _Tags.name
|
||||
Component: _Tags.component
|
||||
Cluster: _Tags.cluster
|
||||
ArgoConfig: _ArgoConfig & {
|
||||
if _Tags.project != "no-project" {
|
||||
AppProject: _Tags.project
|
||||
}
|
||||
}
|
||||
Resources: #Resources
|
||||
|
||||
// Mix in project labels if the project is defined by the platform.
|
||||
if _Tags.project != "no-project" {
|
||||
CommonLabels: _Projects[_Tags.project].CommonLabels
|
||||
}
|
||||
}
|
||||
|
||||
// https://holos.run/docs/api/author/v1alpha4/#Kubernetes
|
||||
#Kubernetes: close({
|
||||
#ComponentConfig
|
||||
api.#Kubernetes
|
||||
})
|
||||
|
||||
// https://holos.run/docs/api/author/v1alpha4/#Kustomize
|
||||
#Kustomize: close({
|
||||
#ComponentConfig
|
||||
api.#Kustomize
|
||||
})
|
||||
|
||||
// https://holos.run/docs/api/author/v1alpha4/#Helm
|
||||
#Helm: close({
|
||||
#ComponentConfig
|
||||
api.#Helm
|
||||
})
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="projects/bank-of-holos/frontend/components/bank-frontend/bank-frontend.cue" label="projects/bank-of-holos/frontend/components/bank-frontend/bank-frontend.cue">
|
||||
@@ -117,215 +146,214 @@ package holos
|
||||
(#Kubernetes & Objects).BuildPlan
|
||||
|
||||
let Objects = {
|
||||
Name: "bank-frontend"
|
||||
Namespace: #BankOfHolos.Frontend.Namespace
|
||||
Name: "bank-frontend"
|
||||
Namespace: _BankOfHolos.Frontend.Namespace
|
||||
|
||||
// Ensure resources go in the correct namespace
|
||||
Resources: [_]: [_]: metadata: namespace: Namespace
|
||||
// Ensure resources go in the correct namespace
|
||||
Resources: [_]: [_]: metadata: namespace: Namespace
|
||||
|
||||
// https://github.com/GoogleCloudPlatform/bank-of-anthos/blob/release/v0.6.5/kubernetes-manifests/frontend.yaml
|
||||
Resources: {
|
||||
Service: frontend: {
|
||||
metadata: name: "frontend"
|
||||
metadata: labels: {
|
||||
application: "bank-of-holos"
|
||||
environment: "development"
|
||||
team: "frontend"
|
||||
tier: "web"
|
||||
}
|
||||
spec: {
|
||||
selector: {
|
||||
app: "frontend"
|
||||
application: "bank-of-holos"
|
||||
environment: "development"
|
||||
team: "frontend"
|
||||
tier: "web"
|
||||
}
|
||||
_ports: http: {
|
||||
name: "http"
|
||||
port: 80
|
||||
targetPort: 8080
|
||||
protocol: "TCP"
|
||||
}
|
||||
ports: [for x in _ports {x}]
|
||||
}
|
||||
}
|
||||
// https://github.com/GoogleCloudPlatform/bank-of-anthos/blob/release/v0.6.5/kubernetes-manifests/frontend.yaml
|
||||
Resources: {
|
||||
Service: frontend: {
|
||||
metadata: name: "frontend"
|
||||
metadata: labels: {
|
||||
application: "bank-of-holos"
|
||||
environment: "development"
|
||||
team: "frontend"
|
||||
tier: "web"
|
||||
}
|
||||
spec: {
|
||||
selector: {
|
||||
app: "frontend"
|
||||
application: "bank-of-holos"
|
||||
environment: "development"
|
||||
team: "frontend"
|
||||
tier: "web"
|
||||
}
|
||||
_ports: http: {
|
||||
name: "http"
|
||||
port: 80
|
||||
targetPort: 8080
|
||||
protocol: "TCP"
|
||||
}
|
||||
ports: [for x in _ports {x}]
|
||||
}
|
||||
}
|
||||
|
||||
Deployment: frontend: {
|
||||
metadata: name: "frontend"
|
||||
metadata: labels: {
|
||||
application: "bank-of-holos"
|
||||
environment: "development"
|
||||
team: "frontend"
|
||||
tier: "web"
|
||||
}
|
||||
spec: {
|
||||
selector: matchLabels: {
|
||||
app: "frontend"
|
||||
application: "bank-of-holos"
|
||||
environment: "development"
|
||||
team: "frontend"
|
||||
tier: "web"
|
||||
}
|
||||
template: {
|
||||
metadata: labels: {
|
||||
app: "frontend"
|
||||
application: "bank-of-holos"
|
||||
environment: "development"
|
||||
team: "frontend"
|
||||
tier: "web"
|
||||
}
|
||||
spec: {
|
||||
securityContext: {
|
||||
seccompProfile: type: "RuntimeDefault"
|
||||
fsGroup: 1000
|
||||
runAsGroup: 1000
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
}
|
||||
serviceAccountName: "bank-of-holos"
|
||||
terminationGracePeriodSeconds: 5
|
||||
containers: [{
|
||||
env: [{
|
||||
name: "BANK_NAME"
|
||||
// highlight-next-line
|
||||
value: #Organization.DisplayName
|
||||
}, {
|
||||
name: "ENV_PLATFORM"
|
||||
value: "local"
|
||||
}, {
|
||||
name: "VERSION"
|
||||
value: "v0.6.5"
|
||||
}, {
|
||||
name: "PORT"
|
||||
value: "8080"
|
||||
}, {
|
||||
name: "ENABLE_TRACING"
|
||||
value: "false"
|
||||
}, {
|
||||
name: "SCHEME"
|
||||
value: "https"
|
||||
}, {
|
||||
name: "LOG_LEVEL"
|
||||
value: "info"
|
||||
}, {
|
||||
name: "DEFAULT_USERNAME"
|
||||
valueFrom: configMapKeyRef: {
|
||||
key: "DEMO_LOGIN_USERNAME"
|
||||
name: "demo-data-config"
|
||||
}
|
||||
}, {
|
||||
name: "DEFAULT_PASSWORD"
|
||||
valueFrom: configMapKeyRef: {
|
||||
key: "DEMO_LOGIN_PASSWORD"
|
||||
name: "demo-data-config"
|
||||
}
|
||||
}, {
|
||||
name: "REGISTERED_OAUTH_CLIENT_ID"
|
||||
valueFrom: configMapKeyRef: {
|
||||
key: "DEMO_OAUTH_CLIENT_ID"
|
||||
name: "oauth-config"
|
||||
optional: true
|
||||
}
|
||||
}, {
|
||||
name: "ALLOWED_OAUTH_REDIRECT_URI"
|
||||
valueFrom: configMapKeyRef: {
|
||||
key: "DEMO_OAUTH_REDIRECT_URI"
|
||||
name: "oauth-config"
|
||||
optional: true
|
||||
}
|
||||
}]
|
||||
envFrom: [{
|
||||
configMapRef: name: "environment-config"
|
||||
}, {
|
||||
configMapRef: name: "service-api-config"
|
||||
}]
|
||||
image: "us-central1-docker.pkg.dev/bank-of-anthos-ci/bank-of-anthos/frontend:v0.6.5@sha256:d72050f70d12383e4434ad04d189b681dc625f696087ddf0b5df641645c9dafa"
|
||||
livenessProbe: {
|
||||
httpGet: {
|
||||
path: "/ready"
|
||||
port: 8080
|
||||
}
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 15
|
||||
timeoutSeconds: 30
|
||||
}
|
||||
name: "front"
|
||||
readinessProbe: {
|
||||
httpGet: {
|
||||
path: "/ready"
|
||||
port: 8080
|
||||
}
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 10
|
||||
}
|
||||
resources: {
|
||||
limits: {
|
||||
cpu: "250m"
|
||||
memory: "128Mi"
|
||||
}
|
||||
requests: {
|
||||
cpu: "100m"
|
||||
memory: "64Mi"
|
||||
}
|
||||
}
|
||||
securityContext: {
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities: drop: ["all"]
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
}
|
||||
volumeMounts: [{
|
||||
mountPath: "/tmp"
|
||||
name: "tmp"
|
||||
}, {
|
||||
mountPath: "/tmp/.ssh"
|
||||
name: "publickey"
|
||||
readOnly: true
|
||||
}]
|
||||
}]
|
||||
volumes: [
|
||||
{
|
||||
emptyDir: {}
|
||||
name: "tmp"
|
||||
},
|
||||
{
|
||||
name: "publickey"
|
||||
secret: {
|
||||
items: [{key: "jwtRS256.key.pub", path: "publickey"}]
|
||||
secretName: "jwt-key"
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Deployment: frontend: {
|
||||
metadata: name: "frontend"
|
||||
metadata: labels: {
|
||||
application: "bank-of-holos"
|
||||
environment: "development"
|
||||
team: "frontend"
|
||||
tier: "web"
|
||||
}
|
||||
spec: {
|
||||
selector: matchLabels: {
|
||||
app: "frontend"
|
||||
application: "bank-of-holos"
|
||||
environment: "development"
|
||||
team: "frontend"
|
||||
tier: "web"
|
||||
}
|
||||
template: {
|
||||
metadata: labels: {
|
||||
app: "frontend"
|
||||
application: "bank-of-holos"
|
||||
environment: "development"
|
||||
team: "frontend"
|
||||
tier: "web"
|
||||
}
|
||||
spec: {
|
||||
securityContext: {
|
||||
seccompProfile: type: "RuntimeDefault"
|
||||
fsGroup: 1000
|
||||
runAsGroup: 1000
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
}
|
||||
serviceAccountName: "bank-of-holos"
|
||||
terminationGracePeriodSeconds: 5
|
||||
containers: [{
|
||||
env: [{
|
||||
name: "BANK_NAME"
|
||||
value: _Organization.DisplayName
|
||||
}, {
|
||||
name: "ENV_PLATFORM"
|
||||
value: "local"
|
||||
}, {
|
||||
name: "VERSION"
|
||||
value: "v0.6.5"
|
||||
}, {
|
||||
name: "PORT"
|
||||
value: "8080"
|
||||
}, {
|
||||
name: "ENABLE_TRACING"
|
||||
value: "false"
|
||||
}, {
|
||||
name: "SCHEME"
|
||||
value: "https"
|
||||
}, {
|
||||
name: "LOG_LEVEL"
|
||||
value: "info"
|
||||
}, {
|
||||
name: "DEFAULT_USERNAME"
|
||||
valueFrom: configMapKeyRef: {
|
||||
key: "DEMO_LOGIN_USERNAME"
|
||||
name: "demo-data-config"
|
||||
}
|
||||
}, {
|
||||
name: "DEFAULT_PASSWORD"
|
||||
valueFrom: configMapKeyRef: {
|
||||
key: "DEMO_LOGIN_PASSWORD"
|
||||
name: "demo-data-config"
|
||||
}
|
||||
}, {
|
||||
name: "REGISTERED_OAUTH_CLIENT_ID"
|
||||
valueFrom: configMapKeyRef: {
|
||||
key: "DEMO_OAUTH_CLIENT_ID"
|
||||
name: "oauth-config"
|
||||
optional: true
|
||||
}
|
||||
}, {
|
||||
name: "ALLOWED_OAUTH_REDIRECT_URI"
|
||||
valueFrom: configMapKeyRef: {
|
||||
key: "DEMO_OAUTH_REDIRECT_URI"
|
||||
name: "oauth-config"
|
||||
optional: true
|
||||
}
|
||||
}]
|
||||
envFrom: [{
|
||||
configMapRef: name: "environment-config"
|
||||
}, {
|
||||
configMapRef: name: "service-api-config"
|
||||
}]
|
||||
image: "us-central1-docker.pkg.dev/bank-of-anthos-ci/bank-of-anthos/frontend:v0.6.5@sha256:d72050f70d12383e4434ad04d189b681dc625f696087ddf0b5df641645c9dafa"
|
||||
livenessProbe: {
|
||||
httpGet: {
|
||||
path: "/ready"
|
||||
port: 8080
|
||||
}
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 15
|
||||
timeoutSeconds: 30
|
||||
}
|
||||
name: "front"
|
||||
readinessProbe: {
|
||||
httpGet: {
|
||||
path: "/ready"
|
||||
port: 8080
|
||||
}
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 10
|
||||
}
|
||||
resources: {
|
||||
limits: {
|
||||
cpu: "250m"
|
||||
memory: "128Mi"
|
||||
}
|
||||
requests: {
|
||||
cpu: "100m"
|
||||
memory: "64Mi"
|
||||
}
|
||||
}
|
||||
securityContext: {
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities: drop: ["all"]
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
}
|
||||
volumeMounts: [{
|
||||
mountPath: "/tmp"
|
||||
name: "tmp"
|
||||
}, {
|
||||
mountPath: "/tmp/.ssh"
|
||||
name: "publickey"
|
||||
readOnly: true
|
||||
}]
|
||||
}]
|
||||
volumes: [
|
||||
{
|
||||
emptyDir: {}
|
||||
name: "tmp"
|
||||
},
|
||||
{
|
||||
name: "publickey"
|
||||
secret: {
|
||||
items: [{key: "jwtRS256.key.pub", path: "publickey"}]
|
||||
secretName: "jwt-key"
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Allow HTTPRoutes in the ingress gateway namespace to reference Services
|
||||
// in this namespace.
|
||||
ReferenceGrant: grant: #ReferenceGrant & {
|
||||
metadata: namespace: Namespace
|
||||
}
|
||||
// Allow HTTPRoutes in the ingress gateway namespace to reference Services
|
||||
// in this namespace.
|
||||
ReferenceGrant: grant: _ReferenceGrant & {
|
||||
metadata: namespace: Namespace
|
||||
}
|
||||
|
||||
// Include shared resources
|
||||
#BankOfHolos.Resources
|
||||
}
|
||||
// Include shared resources
|
||||
_BankOfHolos.Resources
|
||||
}
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Line 6 of the `schema.gen.cue` file defines the _default_ value for
|
||||
`#Organization.DisplayName` by using `string | *"..."`. In CUE, the `*`
|
||||
Line 7 of the `schema.cue` file defines the _default_ value for
|
||||
`_Organization.DisplayName` by using `string | *"..."`. In CUE, the `*`
|
||||
asterisk character denotes a [default value].
|
||||
|
||||
Line 78 of the `bank-frontend.cue` file refers to `#Organization.DisplayName` to
|
||||
Line 78 of the `bank-frontend.cue` file refers to `_Organization.DisplayName` to
|
||||
configure the front end web container.
|
||||
|
||||
Let's change the name of the bank by defining a new value for
|
||||
`#Organization.DisplayName` at the root of the configuration. Create
|
||||
`_Organization.DisplayName` at the root of the configuration. Create
|
||||
`projects/organization.cue` with the following content.
|
||||
|
||||
<Tabs groupId="B386181F-EBE7-469D-8CB5-37631067669B">
|
||||
@@ -333,7 +361,7 @@ Let's change the name of the bank by defining a new value for
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
#Organization: DisplayName: "The Holistic-Bank"
|
||||
_Organization: DisplayName: "The Holistic-Bank"
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
@@ -348,18 +376,11 @@ holos render platform ./platform
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
#Organization.DisplayName: 2 errors in empty disjunction:
|
||||
#Organization.DisplayName: conflicting values "Bank of Holos" and "The Holistic-Bank":
|
||||
/bank-of-holos/projects/organization.cue:3:29
|
||||
/bank-of-holos/schema.gen.cue:6:39
|
||||
// highlight-next-line
|
||||
#Organization.DisplayName: invalid value "The Holistic-Bank" (out of bound =~"^[0-9A-Za-z][0-9A-Za-z ]{2,61}[0-9A-Za-z]$"):
|
||||
/bank-of-holos/cue.mod/gen/github.com/holos-run/holos/api/author/v1alpha3/definitions_go_gen.cue:203:25
|
||||
/bank-of-holos/cue.mod/gen/github.com/holos-run/holos/api/author/v1alpha3/definitions_go_gen.cue:188:15
|
||||
/bank-of-holos/cue.mod/gen/github.com/holos-run/holos/api/author/v1alpha3/definitions_go_gen.cue:203:15
|
||||
/bank-of-holos/projects/organization.cue:3:29
|
||||
/bank-of-holos/schema.gen.cue:6:29
|
||||
could not run: could not render component: exit status 1 at internal/render/platform.go:50
|
||||
could not run: could not marshal json projects/platform/components/istio/cni: cue: marshal error: _Organization.DisplayName: 2 errors in empty disjunction: (and 2 more errors) at internal/builder/builder.go:63
|
||||
_Organization.DisplayName: _Organization.DisplayName: 2 errors in empty disjunction: (and 2 more errors)
|
||||
could not run: could not marshal json projects/platform/components/argocd/crds: cue: marshal error: _Organization.DisplayName: 2 errors in empty disjunction: (and 2 more errors) at internal/builder/builder.go:63
|
||||
_Organization.DisplayName: _Organization.DisplayName: 2 errors in empty disjunction: (and 2 more errors)
|
||||
could not run: could not render component: exit status 1 at builder/v1alpha4/builder.go:95
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
@@ -386,7 +407,7 @@ Let's try again, this time replacing the hyphen with a space.
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
#Organization: DisplayName: "The Holistic Bank"
|
||||
_Organization: DisplayName: "The Holistic Bank"
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
@@ -130,23 +130,23 @@ package holos
|
||||
|
||||
// Platform wide definitions
|
||||
// highlight-next-line
|
||||
#Migration: Namespace: "migration"
|
||||
_Migration: Namespace: "migration"
|
||||
|
||||
// Register namespaces
|
||||
// highlight-next-line
|
||||
#Namespaces: (#Migration.Namespace): _
|
||||
_Namespaces: (_Migration.Namespace): _
|
||||
|
||||
// Register projects
|
||||
// highlight-next-line
|
||||
#AppProjects: migration: _
|
||||
_AppProjects: migration: _
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Each of the highlighted lines has a specific purpose.
|
||||
|
||||
- Line 4 defines the `#Migration` CUE struct. The team that currently owns the
|
||||
migration project defines this struct.
|
||||
- Line 4 defines the `_Migration` hidden field. The team owning the migration
|
||||
project manages this struct.
|
||||
- Line 7 registers the namespace with the `namespaces` component owned by the
|
||||
platform team. The `_` value indicates the value is defined elsewhere in CUE.
|
||||
In this case, the platform team defines what a Namespace is.
|
||||
@@ -208,9 +208,9 @@ Changes not staged for commit:
|
||||
(use "git add <file>..." to update what will be committed)
|
||||
(use "git restore <file>..." to discard changes in working directory)
|
||||
// highlight-next-line
|
||||
modified: deploy/clusters/workload/components/app-projects/app-projects.gen.yaml
|
||||
modified: deploy/clusters/local/components/app-projects/app-projects.gen.yaml
|
||||
// highlight-next-line
|
||||
modified: deploy/clusters/workload/components/namespaces/namespaces.gen.yaml
|
||||
modified: deploy/clusters/local/components/namespaces/namespaces.gen.yaml
|
||||
|
||||
Untracked files:
|
||||
(use "git add <file>..." to include in what will be committed)
|
||||
@@ -230,15 +230,14 @@ git diff deploy
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```diff
|
||||
diff --git a/deploy/clusters/workload/components/app-projects/app-projects.gen.yaml b/deploy/clusters/workload/components/app-projects/app-projects.gen.yaml
|
||||
diff --git a/deploy/clusters/local/components/app-projects/app-projects.gen.yaml b/deploy/clusters/local/components/app-projects/app-projects.gen.yaml
|
||||
index bdc8371..42cb01a 100644
|
||||
--- a/deploy/clusters/workload/components/app-projects/app-projects.gen.yaml
|
||||
+++ b/deploy/clusters/workload/components/app-projects/app-projects.gen.yaml
|
||||
--- a/deploy/clusters/local/components/app-projects/app-projects.gen.yaml
|
||||
+++ b/deploy/clusters/local/components/app-projects/app-projects.gen.yaml
|
||||
@@ -50,6 +50,23 @@ spec:
|
||||
sourceRepos:
|
||||
- '*'
|
||||
---
|
||||
+# Source: CUE apiObjects.AppProject.migration
|
||||
+apiVersion: argoproj.io/v1alpha1
|
||||
+kind: AppProject
|
||||
+metadata:
|
||||
@@ -255,19 +254,17 @@ index bdc8371..42cb01a 100644
|
||||
+ sourceRepos:
|
||||
+ - '*'
|
||||
+---
|
||||
# Source: CUE apiObjects.AppProject.platform
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: AppProject
|
||||
diff --git a/deploy/clusters/workload/components/namespaces/namespaces.gen.yaml b/deploy/clusters/workload/components/namespaces/namespaces.gen.yaml
|
||||
diff --git a/deploy/clusters/local/components/namespaces/namespaces.gen.yaml b/deploy/clusters/local/components/namespaces/namespaces.gen.yaml
|
||||
index de96ab9..7ddd870 100644
|
||||
--- a/deploy/clusters/workload/components/namespaces/namespaces.gen.yaml
|
||||
+++ b/deploy/clusters/workload/components/namespaces/namespaces.gen.yaml
|
||||
--- a/deploy/clusters/local/components/namespaces/namespaces.gen.yaml
|
||||
+++ b/deploy/clusters/local/components/namespaces/namespaces.gen.yaml
|
||||
@@ -62,3 +62,11 @@ metadata:
|
||||
kubernetes.io/metadata.name: istio-system
|
||||
kind: Namespace
|
||||
apiVersion: v1
|
||||
+---
|
||||
+# Source: CUE apiObjects.Namespace.migration
|
||||
+metadata:
|
||||
+ name: migration
|
||||
+ labels:
|
||||
@@ -351,37 +348,33 @@ import ks "sigs.k8s.io/kustomize/api/types"
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
// highlight-next-line
|
||||
(#Helm & Chart).BuildPlan
|
||||
_Helm.BuildPlan
|
||||
|
||||
let Chart = {
|
||||
// highlight-next-line
|
||||
Name: "podinfo"
|
||||
// highlight-next-line
|
||||
Namespace: #Migration.Namespace
|
||||
_Helm: #Helm & {
|
||||
// highlight-next-line
|
||||
Name: "podinfo"
|
||||
// highlight-next-line
|
||||
Namespace: _Migration.Namespace
|
||||
|
||||
Chart: {
|
||||
version: "6.6.2"
|
||||
repository: {
|
||||
name: "podinfo"
|
||||
url: "https://stefanprodan.github.io/podinfo"
|
||||
}
|
||||
}
|
||||
Chart: {
|
||||
version: "6.6.2"
|
||||
repository: {
|
||||
name: "podinfo"
|
||||
url: "https://stefanprodan.github.io/podinfo"
|
||||
}
|
||||
}
|
||||
|
||||
// Necessary to ensure the resources go to the correct namespace.
|
||||
// highlight-next-line
|
||||
EnableKustomizePostProcessor: true
|
||||
// highlight-next-line
|
||||
KustomizeFiles: "kustomization.yaml": ks.#Kustomization & {
|
||||
namespace: Namespace
|
||||
}
|
||||
KustomizeConfig: Kustomization: ks.#Kustomization & {
|
||||
// highlight-next-line
|
||||
namespace: Namespace
|
||||
}
|
||||
|
||||
// Allow the platform team to route traffic into our namespace.
|
||||
// highlight-next-line
|
||||
Resources: ReferenceGrant: grant: #ReferenceGrant & {
|
||||
metadata: namespace: Namespace
|
||||
}
|
||||
// Allow the platform team to route traffic into our namespace.
|
||||
Resources: ReferenceGrant: grant: _ReferenceGrant & {
|
||||
// highlight-next-line
|
||||
metadata: namespace: Namespace
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
@@ -403,16 +396,16 @@ component, `podinfo/podinfo.cue`, but `holos` doesn't enforce this convention.
|
||||
**Line 10**: We use the same namespace we registered with the `namespaces`
|
||||
component as the value we pass to Helm. This is a good example of Holos
|
||||
offering safety and consistency with CUE, if we change the value of
|
||||
`#Migration.Namespace`, multiple components stay consistent.
|
||||
`_Migration.Namespace`, multiple components stay consistent.
|
||||
|
||||
**Lines 20-21**: Unfortunately, the Helm chart doesn't set the
|
||||
**Lines 21**: Unfortunately, the Helm chart doesn't set the
|
||||
`metadata.namespace` field for the resources it generates, which creates a
|
||||
security problem. The resources will be created in the wrong namespace. We
|
||||
don't want to modify the upstream chart because it creates a maintenance burden.
|
||||
We solve the problem by having Holos post-process the Helm output with
|
||||
Kustomize. This ensures all resources go into the correct namespace.
|
||||
|
||||
**Lines 27**: The migration team grants the platform team permission to route
|
||||
**Lines 26**: The migration team grants the platform team permission to route
|
||||
traffic into the `migration` Namespace using a [ReferenceGrant].
|
||||
|
||||
:::note
|
||||
@@ -463,11 +456,12 @@ following content.
|
||||
package holos
|
||||
|
||||
// Manage on workload clusters only
|
||||
for Cluster in #Fleets.workload.clusters {
|
||||
#Platform: Components: "\(Cluster.name)/podinfo": {
|
||||
path: "projects/migration/components/podinfo"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
for Cluster in _Fleets.workload.clusters {
|
||||
_Platform: Components: "\(Cluster.name)/podinfo": {
|
||||
name: "podinfo"
|
||||
component: "projects/migration/components/podinfo"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
@@ -492,7 +486,7 @@ package holos
|
||||
|
||||
// Assign ArgoCD Applications to the migration AppProject
|
||||
// highlight-next-line
|
||||
#ArgoConfig: AppProject: #AppProjects.migration.metadata.name
|
||||
_ArgoConfig: AppProject: _AppProjects.migration.metadata.name
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
@@ -501,7 +495,7 @@ This file provides consistency and safety in a number of ways:
|
||||
|
||||
1. All components under `projects/migration/` will automatically have their
|
||||
ArgoCD Application assigned to the migration `AppProject`.
|
||||
2. `holos render platform` errors out if `#AppProjects.migration` is not
|
||||
2. `holos render platform` errors out if `_AppProjects.migration` is not
|
||||
defined, we defined it in `projects/migration.cue`
|
||||
3. The platform team is responsible for managing the `AppProject` resource
|
||||
itself, the team doing the migration refers to the `metadata.name` field defined
|
||||
@@ -561,14 +555,14 @@ git status
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
On branch main
|
||||
On branch jeff/291-consistent-fields
|
||||
Changes to be committed:
|
||||
(use "git restore --staged <file>..." to unstage)
|
||||
new file: deploy/clusters/workload/components/podinfo/podinfo.gen.yaml
|
||||
new file: deploy/clusters/workload/gitops/podinfo.application.gen.yaml
|
||||
new file: platform/migration-podinfo.cue
|
||||
new file: projects/migration/app-project.cue
|
||||
new file: projects/migration/components/podinfo/podinfo.cue
|
||||
new file: deploy/clusters/local/components/podinfo/podinfo.gen.yaml
|
||||
new file: deploy/clusters/local/gitops/podinfo.gen.yaml
|
||||
new file: platform/migration-podinfo.cue
|
||||
new file: projects/migration/app-project.cue
|
||||
new file: projects/migration/components/podinfo/podinfo.cue
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
@@ -578,25 +572,26 @@ in a new manifest for the Helm output along with an ArgoCD Application for
|
||||
GitOps. Here's what they look like:
|
||||
|
||||
<Tabs groupId="0F2B3066-B57F-466E-A27F-A603C1803E11">
|
||||
<TabItem value="deploy/clusters/workload/gitops/podinfo.application.gen.yaml" label="podinfo.application.gen.yaml">
|
||||
<TabItem value="deploy/clusters/local/gitops/podinfo.gen.yaml" label="podinfo.gen.yaml">
|
||||
```yaml showLineNumbers
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
labels:
|
||||
holos.run/component.name: podinfo
|
||||
name: podinfo
|
||||
namespace: argocd
|
||||
spec:
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
# highlight-next-line
|
||||
project: migration
|
||||
source:
|
||||
path: ./deploy/clusters/workload/components/podinfo
|
||||
path: deploy/clusters/local/components/podinfo
|
||||
repoURL: https://github.com/holos-run/bank-of-holos
|
||||
targetRevision: main
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="deploy/clusters/workload/components/podinfo/podinfo.gen.yaml" label="podinfo.gen.yaml">
|
||||
<TabItem value="deploy/clusters/local/components/podinfo/podinfo.gen.yaml" label="podinfo.gen.yaml">
|
||||
```yaml showLineNumbers
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
@@ -605,9 +600,10 @@ metadata:
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: podinfo
|
||||
app.kubernetes.io/version: 6.6.2
|
||||
argocd.argoproj.io/instance: podinfo
|
||||
helm.sh/chart: podinfo-6.6.2
|
||||
holos.run/component.name: podinfo
|
||||
name: podinfo
|
||||
# highlight-next-line
|
||||
namespace: migration
|
||||
spec:
|
||||
ports:
|
||||
@@ -621,6 +617,8 @@ spec:
|
||||
targetPort: grpc
|
||||
selector:
|
||||
app.kubernetes.io/name: podinfo
|
||||
argocd.argoproj.io/instance: podinfo
|
||||
holos.run/component.name: podinfo
|
||||
type: ClusterIP
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
@@ -630,15 +628,18 @@ metadata:
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: podinfo
|
||||
app.kubernetes.io/version: 6.6.2
|
||||
argocd.argoproj.io/instance: podinfo
|
||||
helm.sh/chart: podinfo-6.6.2
|
||||
holos.run/component.name: podinfo
|
||||
name: podinfo
|
||||
# highlight-next-line
|
||||
namespace: migration
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: podinfo
|
||||
argocd.argoproj.io/instance: podinfo
|
||||
holos.run/component.name: podinfo
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
maxUnavailable: 1
|
||||
@@ -650,6 +651,8 @@ spec:
|
||||
prometheus.io/scrape: "true"
|
||||
labels:
|
||||
app.kubernetes.io/name: podinfo
|
||||
argocd.argoproj.io/instance: podinfo
|
||||
holos.run/component.name: podinfo
|
||||
spec:
|
||||
containers:
|
||||
- command:
|
||||
@@ -714,6 +717,23 @@ spec:
|
||||
volumes:
|
||||
- emptyDir: {}
|
||||
name: data
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: ReferenceGrant
|
||||
metadata:
|
||||
labels:
|
||||
argocd.argoproj.io/instance: podinfo
|
||||
holos.run/component.name: podinfo
|
||||
name: istio-ingress
|
||||
namespace: migration
|
||||
spec:
|
||||
from:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: HTTPRoute
|
||||
namespace: istio-ingress
|
||||
to:
|
||||
- group: ""
|
||||
kind: Service
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
@@ -730,10 +750,10 @@ git commit -m 'register the migration project podinfo component with the platfor
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
[main] register the migration project podinfo component with the platform
|
||||
5 files changed, 167 insertions(+)
|
||||
create mode 100644 deploy/clusters/workload/components/podinfo/podinfo.gen.yaml
|
||||
create mode 100644 deploy/clusters/workload/gitops/podinfo.application.gen.yaml
|
||||
[main 31197e2] register the migration project podinfo component with the platform
|
||||
5 files changed, 205 insertions(+)
|
||||
create mode 100644 deploy/clusters/local/components/podinfo/podinfo.gen.yaml
|
||||
create mode 100644 deploy/clusters/local/gitops/podinfo.gen.yaml
|
||||
create mode 100644 platform/migration-podinfo.cue
|
||||
create mode 100644 projects/migration/app-project.cue
|
||||
create mode 100644 projects/migration/components/podinfo/podinfo.cue
|
||||
@@ -777,9 +797,9 @@ platform as a whole. Bank of Holos uses [HTTPRoute] routes from the new Gateway
|
||||
API. The company the bank acquired uses older Ingress resources from earlier
|
||||
Kubernetes versions.
|
||||
|
||||
The platform team at the bank defines a `#HTTPRoutes` struct for other teams at
|
||||
the bank to register with. The `#HTTPRoutes` struct is similar to the
|
||||
`#Namespaces` and `#AppProjects` structs we've already seen.
|
||||
The platform team at the bank defines a `_HTTPRoutes` struct for other teams at
|
||||
the bank to register with. The `_HTTPRoutes` struct is similar to the
|
||||
`_Namespaces` and `_AppProjects` structs we've already seen.
|
||||
|
||||
As a member of the migration team, we'll add the file
|
||||
`projects/migration-routes.cue` to expose the service we're migrating.
|
||||
@@ -791,17 +811,15 @@ Go ahead and create this file (if it hasn't been created previously) with the fo
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
let Podinfo = {
|
||||
podinfo: {
|
||||
port: 9898
|
||||
namespace: #Migration.Namespace
|
||||
}
|
||||
}
|
||||
|
||||
// Route migration-podinfo.example.com to port 9898 of Service podinfo in the
|
||||
// migration namespace.
|
||||
// highlight-next-line
|
||||
#HTTPRoutes: "migration-podinfo": _backendRefs: Podinfo
|
||||
_HTTPRoutes: "migration-podinfo": _backendRefs: {
|
||||
podinfo: {
|
||||
port: 9898
|
||||
namespace: _Migration.Namespace
|
||||
}
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="projects/httproutes.cue" label="projects/httproutes.cue">
|
||||
@@ -810,44 +828,45 @@ package holos
|
||||
|
||||
import v1 "gateway.networking.k8s.io/httproute/v1"
|
||||
|
||||
// #HTTPRoutes defines managed HTTPRoute resources for the platform. These
|
||||
// resources are managed in the istio-ingress namespace. Other components
|
||||
// define the routes they need close to the root of configuration.
|
||||
// Struct containing HTTPRoute configurations. These resources are managed in
|
||||
// the istio-ingress namespace. Other components define the routes they need
|
||||
// close to the root of configuration.
|
||||
_HTTPRoutes: #HTTPRoutes
|
||||
|
||||
// #HTTPRoutes defines the schema of managed HTTPRoute resources for the
|
||||
// platform.
|
||||
#HTTPRoutes: {
|
||||
// For the guides, we simplify this down to a flat namespace.
|
||||
// highlight-next-line
|
||||
[Name=string]: v1.#HTTPRoute & {
|
||||
let HOST = Name + "." + #Organization.Domain
|
||||
// For the guides, we simplify this down to a flat namespace.
|
||||
[Name=string]: v1.#HTTPRoute & {
|
||||
let HOST = Name + "." + _Organization.Domain
|
||||
|
||||
// highlight-next-line
|
||||
_backendRefs: [NAME=string]: {
|
||||
name: NAME
|
||||
namespace: string
|
||||
port: number | *80
|
||||
}
|
||||
_backendRefs: [NAME=string]: {
|
||||
name: NAME
|
||||
namespace: string
|
||||
port: number | *80
|
||||
}
|
||||
|
||||
metadata: name: Name
|
||||
metadata: namespace: #Istio.Gateway.Namespace
|
||||
metadata: labels: app: Name
|
||||
spec: hostnames: [HOST]
|
||||
spec: parentRefs: [{
|
||||
name: "default"
|
||||
namespace: metadata.namespace
|
||||
}]
|
||||
spec: rules: [
|
||||
{
|
||||
matches: [{path: {type: "PathPrefix", value: "/"}}]
|
||||
// highlight-next-line
|
||||
backendRefs: [for x in _backendRefs {x}]
|
||||
},
|
||||
]
|
||||
}
|
||||
metadata: name: Name
|
||||
metadata: namespace: _Istio.Gateway.Namespace
|
||||
metadata: labels: app: Name
|
||||
spec: hostnames: [HOST]
|
||||
spec: parentRefs: [{
|
||||
name: "default"
|
||||
namespace: metadata.namespace
|
||||
}]
|
||||
spec: rules: [
|
||||
{
|
||||
matches: [{path: {type: "PathPrefix", value: "/"}}]
|
||||
backendRefs: [for x in _backendRefs {x}]
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
In this file we're adding a field to the `#HTTPRoutes` struct the platform team
|
||||
In this file we're adding a field to the `_HTTPRoutes` struct the platform team
|
||||
defined for us.
|
||||
|
||||
You might be wondering how we knew all of these fields to put into this file.
|
||||
@@ -861,8 +880,9 @@ The most important things the migration team takes away from this file are:
|
||||
|
||||
1. The platform team requires a `gateway.networking.k8s.io/httproute/v1`
|
||||
`HTTPRoute`.
|
||||
2. Line 13 uses a [hidden field] so we can provide backend references as a struct instead of a list.
|
||||
3. Line 30 uses a [comprehension] to convert the struct to a list.
|
||||
2. Line 17 uses a [hidden field] so we can provide backend references as a
|
||||
struct instead of a list.
|
||||
3. Line 34 uses a [comprehension] to convert the struct to a list.
|
||||
|
||||
We can look up the spec for the fields we need to provide in the Gateway API
|
||||
reference documentation for [HTTPRoute].
|
||||
@@ -928,10 +948,10 @@ git diff
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```diff
|
||||
diff --git a/deploy/clusters/workload/components/httproutes/httproutes.gen.yaml b/deploy/clusters/workload/components/httproutes/httproutes.gen.yaml
|
||||
diff --git a/deploy/clusters/local/components/httproutes/httproutes.gen.yaml b/deploy/clusters/local/components/httproutes/httproutes.gen.yaml
|
||||
index 06f7c91..349e070 100644
|
||||
--- a/deploy/clusters/workload/components/httproutes/httproutes.gen.yaml
|
||||
+++ b/deploy/clusters/workload/components/httproutes/httproutes.gen.yaml
|
||||
--- a/deploy/clusters/local/components/httproutes/httproutes.gen.yaml
|
||||
+++ b/deploy/clusters/local/components/httproutes/httproutes.gen.yaml
|
||||
@@ -47,3 +47,28 @@ spec:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
@@ -961,7 +981,6 @@ index 06f7c91..349e070 100644
|
||||
+ - path:
|
||||
+ type: PathPrefix
|
||||
+ value: /
|
||||
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
@@ -1044,7 +1063,7 @@ in the `bank-of-holos` repository after resetting your cluster following the
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/workload/components/namespaces/namespaces.gen.yaml
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/local/components/namespaces/namespaces.gen.yaml
|
||||
namespace/argocd serverside-applied
|
||||
namespace/bank-backend serverside-applied
|
||||
namespace/bank-frontend serverside-applied
|
||||
@@ -1054,17 +1073,17 @@ namespace/external-secrets serverside-applied
|
||||
namespace/istio-ingress serverside-applied
|
||||
namespace/istio-system serverside-applied
|
||||
namespace/migration serverside-applied
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/workload/components/argocd-crds/argocd-crds.gen.yaml
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/local/components/argocd-crds/argocd-crds.gen.yaml
|
||||
customresourcedefinition.apiextensions.k8s.io/applications.argoproj.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/applicationsets.argoproj.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/appprojects.argoproj.io serverside-applied
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/workload/components/gateway-api/gateway-api.gen.yaml
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/local/components/gateway-api/gateway-api.gen.yaml
|
||||
customresourcedefinition.apiextensions.k8s.io/gatewayclasses.gateway.networking.k8s.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/gateways.gateway.networking.k8s.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/grpcroutes.gateway.networking.k8s.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/httproutes.gateway.networking.k8s.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/referencegrants.gateway.networking.k8s.io serverside-applied
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/workload/components/external-secrets-crds/external-secrets-crds.gen.yaml
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/local/components/external-secrets-crds/external-secrets-crds.gen.yaml
|
||||
customresourcedefinition.apiextensions.k8s.io/acraccesstokens.generators.external-secrets.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/clusterexternalsecrets.external-secrets.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/clustersecretstores.external-secrets.io serverside-applied
|
||||
@@ -1126,7 +1145,7 @@ customresourcedefinition.apiextensions.k8s.io/wasmplugins.extensions.istio.io co
|
||||
customresourcedefinition.apiextensions.k8s.io/webhooks.generators.external-secrets.io condition met
|
||||
customresourcedefinition.apiextensions.k8s.io/workloadentries.networking.istio.io condition met
|
||||
customresourcedefinition.apiextensions.k8s.io/workloadgroups.networking.istio.io condition met
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/workload/components/external-secrets/external-secrets.gen.yaml
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/local/components/external-secrets/external-secrets.gen.yaml
|
||||
serviceaccount/external-secrets-cert-controller serverside-applied
|
||||
serviceaccount/external-secrets serverside-applied
|
||||
serviceaccount/external-secrets-webhook serverside-applied
|
||||
@@ -1146,7 +1165,7 @@ deployment.apps/external-secrets serverside-applied
|
||||
deployment.apps/external-secrets-webhook serverside-applied
|
||||
validatingwebhookconfiguration.admissionregistration.k8s.io/secretstore-validate serverside-applied
|
||||
validatingwebhookconfiguration.admissionregistration.k8s.io/externalsecret-validate serverside-applied
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/workload/components/cert-manager/cert-manager.gen.yaml
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/local/components/cert-manager/cert-manager.gen.yaml
|
||||
serviceaccount/cert-manager-cainjector serverside-applied
|
||||
serviceaccount/cert-manager serverside-applied
|
||||
serviceaccount/cert-manager-webhook serverside-applied
|
||||
@@ -1192,11 +1211,11 @@ deployment.apps/cert-manager serverside-applied
|
||||
deployment.apps/cert-manager-webhook serverside-applied
|
||||
mutatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook serverside-applied
|
||||
validatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook serverside-applied
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/workload/components/local-ca/local-ca.gen.yaml
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/local/components/local-ca/local-ca.gen.yaml
|
||||
clusterissuer.cert-manager.io/local-ca serverside-applied
|
||||
+ kubectl wait --for=condition=Ready clusterissuer/local-ca --timeout=30s
|
||||
clusterissuer.cert-manager.io/local-ca condition met
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/workload/components/argocd/argocd.gen.yaml
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/local/components/argocd/argocd.gen.yaml
|
||||
serviceaccount/argocd-application-controller serverside-applied
|
||||
serviceaccount/argocd-applicationset-controller serverside-applied
|
||||
serviceaccount/argocd-notifications-controller serverside-applied
|
||||
@@ -1243,13 +1262,13 @@ deployment.apps/argocd-server serverside-applied
|
||||
statefulset.apps/argocd-application-controller serverside-applied
|
||||
job.batch/argocd-redis-secret-init serverside-applied
|
||||
referencegrant.gateway.networking.k8s.io/istio-ingress serverside-applied
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/workload/components/app-projects/app-projects.gen.yaml
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/local/components/app-projects/app-projects.gen.yaml
|
||||
appproject.argoproj.io/bank-backend serverside-applied
|
||||
appproject.argoproj.io/bank-frontend serverside-applied
|
||||
appproject.argoproj.io/bank-security serverside-applied
|
||||
appproject.argoproj.io/migration serverside-applied
|
||||
appproject.argoproj.io/platform serverside-applied
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/workload/components/istio-base/istio-base.gen.yaml
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/local/components/istio-base/istio-base.gen.yaml
|
||||
customresourcedefinition.apiextensions.k8s.io/authorizationpolicies.security.istio.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/destinationrules.networking.istio.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/envoyfilters.networking.istio.io serverside-applied
|
||||
@@ -1266,7 +1285,7 @@ customresourcedefinition.apiextensions.k8s.io/workloadentries.networking.istio.i
|
||||
customresourcedefinition.apiextensions.k8s.io/workloadgroups.networking.istio.io serverside-applied
|
||||
serviceaccount/istio-reader-service-account serverside-applied
|
||||
validatingwebhookconfiguration.admissionregistration.k8s.io/istiod-default-validator serverside-applied
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/workload/components/istiod/istiod.gen.yaml
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/local/components/istiod/istiod.gen.yaml
|
||||
serviceaccount/istiod serverside-applied
|
||||
role.rbac.authorization.k8s.io/istiod serverside-applied
|
||||
clusterrole.rbac.authorization.k8s.io/istio-reader-clusterrole-istio-system serverside-applied
|
||||
@@ -1284,7 +1303,7 @@ poddisruptionbudget.policy/istiod serverside-applied
|
||||
horizontalpodautoscaler.autoscaling/istiod serverside-applied
|
||||
mutatingwebhookconfiguration.admissionregistration.k8s.io/istio-sidecar-injector serverside-applied
|
||||
validatingwebhookconfiguration.admissionregistration.k8s.io/istio-validator-istio-system serverside-applied
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/workload/components/istio-cni/istio-cni.gen.yaml
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/local/components/istio-cni/istio-cni.gen.yaml
|
||||
serviceaccount/istio-cni serverside-applied
|
||||
configmap/istio-cni-config serverside-applied
|
||||
clusterrole.rbac.authorization.k8s.io/istio-cni serverside-applied
|
||||
@@ -1296,20 +1315,20 @@ clusterrolebinding.rbac.authorization.k8s.io/istio-cni-ambient serverside-applie
|
||||
daemonset.apps/istio-cni-node serverside-applied
|
||||
+ kubectl wait --for=condition=Ready pod -l k8s-app=istio-cni-node --timeout=300s -n istio-system
|
||||
pod/istio-cni-node-7kfbh condition met
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/workload/components/istio-ztunnel/istio-ztunnel.gen.yaml
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/local/components/istio-ztunnel/istio-ztunnel.gen.yaml
|
||||
serviceaccount/ztunnel serverside-applied
|
||||
daemonset.apps/ztunnel serverside-applied
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/workload/components/istio-gateway/istio-gateway.gen.yaml
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/local/components/istio-gateway/istio-gateway.gen.yaml
|
||||
certificate.cert-manager.io/gateway-cert serverside-applied
|
||||
gateway.gateway.networking.k8s.io/default serverside-applied
|
||||
serviceaccount/default-istio serverside-applied
|
||||
+ kubectl wait --for=condition=Ready pod -l istio.io/gateway-name=default --timeout=300s -n istio-ingress
|
||||
pod/default-istio-54598d985b-69wmr condition met
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/workload/components/httproutes/httproutes.gen.yaml
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/local/components/httproutes/httproutes.gen.yaml
|
||||
httproute.gateway.networking.k8s.io/argocd serverside-applied
|
||||
httproute.gateway.networking.k8s.io/bank serverside-applied
|
||||
httproute.gateway.networking.k8s.io/migration-podinfo serverside-applied
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/workload/components/bank-secrets/bank-secrets.gen.yaml
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/local/components/bank-secrets/bank-secrets.gen.yaml
|
||||
configmap/jwt-key-writer serverside-applied
|
||||
job.batch/jwt-key-writer serverside-applied
|
||||
role.rbac.authorization.k8s.io/jwt-key-reader serverside-applied
|
||||
@@ -1319,7 +1338,7 @@ rolebinding.rbac.authorization.k8s.io/jwt-key-writer serverside-applied
|
||||
serviceaccount/jwt-key-writer serverside-applied
|
||||
+ kubectl wait --for=condition=complete job.batch/jwt-key-writer -n bank-security --timeout=300s
|
||||
job.batch/jwt-key-writer condition met
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/workload/components/bank-backend-config/bank-backend-config.gen.yaml
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/local/components/bank-backend-config/bank-backend-config.gen.yaml
|
||||
configmap/demo-data-config serverside-applied
|
||||
configmap/environment-config serverside-applied
|
||||
configmap/service-api-config serverside-applied
|
||||
@@ -1327,30 +1346,30 @@ externalsecret.external-secrets.io/jwt-key serverside-applied
|
||||
referencegrant.gateway.networking.k8s.io/istio-ingress serverside-applied
|
||||
secretstore.external-secrets.io/bank-security serverside-applied
|
||||
serviceaccount/bank-of-holos serverside-applied
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/workload/components/bank-accounts-db/bank-accounts-db.gen.yaml
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/local/components/bank-accounts-db/bank-accounts-db.gen.yaml
|
||||
configmap/accounts-db-config serverside-applied
|
||||
service/accounts-db serverside-applied
|
||||
statefulset.apps/accounts-db serverside-applied
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/workload/components/bank-ledger-db/bank-ledger-db.gen.yaml
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/local/components/bank-ledger-db/bank-ledger-db.gen.yaml
|
||||
configmap/ledger-db-config serverside-applied
|
||||
service/ledger-db serverside-applied
|
||||
statefulset.apps/ledger-db serverside-applied
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/workload/components/bank-contacts/bank-contacts.gen.yaml
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/local/components/bank-contacts/bank-contacts.gen.yaml
|
||||
deployment.apps/contacts serverside-applied
|
||||
service/contacts serverside-applied
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/workload/components/bank-balance-reader/bank-balance-reader.gen.yaml
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/local/components/bank-balance-reader/bank-balance-reader.gen.yaml
|
||||
deployment.apps/balancereader serverside-applied
|
||||
service/balancereader serverside-applied
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/workload/components/bank-userservice/bank-userservice.gen.yaml
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/local/components/bank-userservice/bank-userservice.gen.yaml
|
||||
deployment.apps/userservice serverside-applied
|
||||
service/userservice serverside-applied
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/workload/components/bank-ledger-writer/bank-ledger-writer.gen.yaml
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/local/components/bank-ledger-writer/bank-ledger-writer.gen.yaml
|
||||
deployment.apps/ledgerwriter serverside-applied
|
||||
service/ledgerwriter serverside-applied
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/workload/components/bank-transaction-history/bank-transaction-history.gen.yaml
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/local/components/bank-transaction-history/bank-transaction-history.gen.yaml
|
||||
deployment.apps/transactionhistory serverside-applied
|
||||
service/transactionhistory serverside-applied
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/workload/components/bank-frontend/bank-frontend.gen.yaml
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/local/components/bank-frontend/bank-frontend.gen.yaml
|
||||
configmap/demo-data-config serverside-applied
|
||||
configmap/environment-config serverside-applied
|
||||
configmap/service-api-config serverside-applied
|
||||
@@ -1360,7 +1379,7 @@ referencegrant.gateway.networking.k8s.io/istio-ingress serverside-applied
|
||||
secretstore.external-secrets.io/bank-security serverside-applied
|
||||
service/frontend serverside-applied
|
||||
serviceaccount/bank-of-holos serverside-applied
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/workload/gitops
|
||||
+ kubectl apply --server-side=true -f deploy/clusters/local/gitops
|
||||
application.argoproj.io/app-projects serverside-applied
|
||||
application.argoproj.io/argocd-crds serverside-applied
|
||||
application.argoproj.io/argocd serverside-applied
|
||||
@@ -461,8 +461,9 @@ values into both charts to configure them in lock step.
|
||||
|
||||
<Tabs groupId="740ABBEB-7A03-4B53-9CD5-4B8C5680172F">
|
||||
<TabItem value="projects/blackbox.schema.cue" label="Blackbox Schema">
|
||||
```txt
|
||||
projects/blackbox.schema.cue
|
||||
```bash
|
||||
mkdir -p projects
|
||||
touch projects/blackbox.schema.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
@@ -498,9 +499,7 @@ Add the CUE configuration to manage the prometheus Helm Chart component.
|
||||
|
||||
```bash
|
||||
mkdir -p projects/platform/components/prometheus
|
||||
```
|
||||
```txt
|
||||
projects/platform/components/prometheus/prometheus.cue
|
||||
touch projects/platform/components/prometheus/prometheus.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
@@ -527,8 +526,9 @@ the platform directory.
|
||||
|
||||
<Tabs groupId="FF5FF6C6-181D-4071-8BCF-5C8E0663C028">
|
||||
<TabItem value="platform/prometheus.cue" label="Platform">
|
||||
```txt
|
||||
platform/prometheus.cue
|
||||
```bash
|
||||
mkdir -p platform
|
||||
touch platform/prometheus.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
@@ -553,8 +553,8 @@ holos render platform ./platform
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
cached prometheus 25.27.0
|
||||
rendered prometheus for cluster local in 1.900449291s
|
||||
rendered platform in 1.900581125s
|
||||
rendered prometheus for cluster local in 1.600449291s
|
||||
rendered platform in 1.600581125s
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="deploy/clusters/local/components/prometheus/prometheus.gen.yaml" label="prometheus.gen.yaml">
|
||||
@@ -2041,9 +2041,7 @@ Add the CUE configuration to manage the blackbox Helm Chart component.
|
||||
|
||||
```bash
|
||||
mkdir -p projects/platform/components/blackbox
|
||||
```
|
||||
```txt
|
||||
projects/platform/components/blackbox/blackbox.cue
|
||||
touch projects/platform/components/blackbox/blackbox.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
@@ -2070,8 +2068,9 @@ _Helm: #Helm & {
|
||||
Register the blackbox chart with the platform by adding the following file to
|
||||
the platform directory.
|
||||
|
||||
```txt
|
||||
platform/blackbox.cue
|
||||
```bash
|
||||
mkdir -p platform
|
||||
touch platform/blackbox.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
@@ -2292,9 +2291,10 @@ First for prometheus.
|
||||
<Tabs groupId="5062EB93-F5AA-4038-9CF8-67A5ECA085FD">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
cue import -p holos -o- -l '_Helm: Values:' \
|
||||
projects/platform/components/prometheus/vendor/25.27.0/prometheus/values.yaml \
|
||||
> projects/platform/components/prometheus/values.cue
|
||||
cue import --package holos \
|
||||
--path '_Helm: Values:' \
|
||||
--outfile projects/platform/components/prometheus/values.cue \
|
||||
projects/platform/components/prometheus/vendor/25.27.0/prometheus/values.yaml
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="values.cue">
|
||||
@@ -3648,9 +3648,10 @@ Then for blackbox.
|
||||
<Tabs groupId="843D706B-5BE0-46FE-978F-EA17BC1AD932">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
cue import -p holos -o- -l '_Helm: Values:' \
|
||||
projects/platform/components/blackbox/vendor/9.0.1/prometheus-blackbox-exporter/values.yaml \
|
||||
> projects/platform/components/blackbox/values.cue
|
||||
cue import --package holos \
|
||||
--path '_Helm: Values:' \
|
||||
--outfile projects/platform/components/blackbox/values.cue
|
||||
projects/platform/components/blackbox/vendor/9.0.1/prometheus-blackbox-exporter/values.yaml
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="values.cue">
|
||||
@@ -4168,12 +4169,8 @@ lock step.
|
||||
|
||||
<Tabs groupId="B3A011D0-2D13-4DA8-B963-92115E734085">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
git diff
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output" default>
|
||||
```diff
|
||||
patch -p1 <<EOF
|
||||
--- a/projects/platform/components/blackbox/values.cue
|
||||
+++ b/projects/platform/components/blackbox/values.cue
|
||||
@@ -2,6 +2,9 @@ package holos
|
||||
@@ -4186,15 +4183,15 @@ git diff
|
||||
global: {
|
||||
//# Global image registry to use if it needs to be overriden for some specific use cases (e.g local registries, custom images, ...)
|
||||
//#
|
||||
@@ -196,7 +196,7 @@ _Helm: {
|
||||
annotations: {}
|
||||
labels: {}
|
||||
type: "ClusterIP"
|
||||
- port: 9115
|
||||
+ port: _blackbox.port
|
||||
ipDualStack: {
|
||||
enabled: false
|
||||
ipFamilies: ["IPv6", "IPv4"]
|
||||
@@ -193,7 +196,7 @@ _Helm: {
|
||||
annotations: {}
|
||||
labels: {}
|
||||
type: "ClusterIP"
|
||||
- port: 9115
|
||||
+ port: _blackbox.port
|
||||
ipDualStack: {
|
||||
enabled: false
|
||||
ipFamilies: ["IPv6", "IPv4"]
|
||||
--- a/projects/platform/components/prometheus/values.cue
|
||||
+++ b/projects/platform/components/prometheus/values.cue
|
||||
@@ -1084,7 +1084,7 @@ _Helm: {
|
||||
@@ -4206,6 +4203,13 @@ git diff
|
||||
}, {
|
||||
source_labels: ["__param_target"]
|
||||
target_label: "instance"
|
||||
EOF
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output" default>
|
||||
```txt
|
||||
patching file 'projects/platform/components/blackbox/values.cue'
|
||||
patching file 'projects/platform/components/prometheus/values.cue'
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
@@ -4308,11 +4312,10 @@ git diff
|
||||
- __address__
|
||||
target_label: __param_target
|
||||
- - replacement: blackbox
|
||||
+ - replacement: blackbox:6115
|
||||
+ - replacement: blackbox:9115
|
||||
target_label: __address__
|
||||
- source_labels:
|
||||
- __param_target
|
||||
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
@@ -4498,12 +4501,8 @@ render platform` command fails immediately with a clear validation error.
|
||||
|
||||
<Tabs groupId="BFCF4FCA-33EB-45D8-8D36-CDD80E54C819">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
git diff
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```diff
|
||||
patch -p1 <<EOF
|
||||
--- a/projects/blackbox.schema.cue
|
||||
+++ b/projects/blackbox.schema.cue
|
||||
@@ -10,6 +10,6 @@ package holos
|
||||
@@ -4514,7 +4513,12 @@ git diff
|
||||
+ host: "this is not valid"
|
||||
port: 6115
|
||||
}
|
||||
|
||||
EOF
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
patching file 'projects/blackbox.schema.cue'
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
@@ -4539,6 +4543,13 @@ could not run: could not render component: exit status 1 at builder/v1alpha4/bui
|
||||
|
||||

|
||||
|
||||
Undo the invalid change.
|
||||
|
||||
```bash
|
||||
git restore projects/blackbox.schema.cue
|
||||
rm -f projects/blackbox.schema.cue.orig
|
||||
```
|
||||
|
||||
### Httpbin Kustomization
|
||||
|
||||
We need to manage [httpbin] so we can achieve the goal of probing a simple
|
||||
@@ -4556,10 +4567,7 @@ components.
|
||||
<TabItem value="projects/platform/components/httpbin/httpbin.cue" label="Component">
|
||||
```bash
|
||||
mkdir -p projects/platform/components/httpbin
|
||||
```
|
||||
|
||||
```txt
|
||||
projects/platform/components/httpbin/httpbin.cue
|
||||
touch projects/platform/components/httpbin/httpbin.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
@@ -4571,9 +4579,10 @@ _Kustomize.BuildPlan
|
||||
|
||||
// https://github.com/mccutchen/go-httpbin/blob/v2.15.0/kustomize/README.md
|
||||
_Kustomize: #Kustomize & {
|
||||
KustomizeConfig: Resources: "github.com/mccutchen/go-httpbin/kustomize": _
|
||||
KustomizeConfig: Files: "resources.yaml": _
|
||||
KustomizeConfig: Kustomization: {
|
||||
commonLabels: "app.kubernetes.io/name": "httpbin"
|
||||
images: [{name: "mccutchen/go-httpbin"}]
|
||||
_patches: probe: {
|
||||
target: kind: "Service"
|
||||
target: name: "httpbin"
|
||||
@@ -4586,6 +4595,55 @@ _Kustomize: #Kustomize & {
|
||||
patches: [for x in _patches {x}]
|
||||
}
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="projects/platform/components/httpbin/resources.yaml" label="resources.yaml">
|
||||
Add a plain `resources.yaml` file containing resources for kustomize to process.
|
||||
:::important
|
||||
Holos knows this file is part of the BuildPlan from the `KustomizeConfig:
|
||||
Files: "resources.yaml": _` line in the Component.
|
||||
:::
|
||||
```bash
|
||||
mkdir -p projects/platform/components/httpbin
|
||||
touch projects/platform/components/httpbin/resources.yaml
|
||||
```
|
||||
```yaml showLineNumbers
|
||||
# https://github.com/mccutchen/go-httpbin/blob/v2.15.0/kustomize/resources.yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: httpbin
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: httpbin
|
||||
image: mccutchen/go-httpbin
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
protocol: TCP
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /status/200
|
||||
port: http
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /status/200
|
||||
port: http
|
||||
resources: {}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: httpbin
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
appProtocol: http
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
@@ -4595,7 +4653,8 @@ Register the component with the platform.
|
||||
<Tabs groupId="CBD42BC2-38C3-46E2-9F4D-B21D8E909BAC">
|
||||
<TabItem value="platform/httpbin.cue" label="Platform">
|
||||
```txt
|
||||
platform/httpbin.cue
|
||||
mkdir -p platform
|
||||
touch platform/httpbin.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
@@ -4765,6 +4824,7 @@ deployment.apps/httpbin created
|
||||
Port forward to the prometheus web interface.
|
||||
|
||||
```bash
|
||||
kubectl wait --for=condition=Available deployment/prometheus-server --timeout=300s
|
||||
kubectl -n default port-forward svc/prometheus-server 8081:80
|
||||
```
|
||||
|
||||
|
Before Width: | Height: | Size: 690 KiB After Width: | Height: | Size: 690 KiB |
|
Before Width: | Height: | Size: 997 KiB After Width: | Height: | Size: 997 KiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 287 KiB After Width: | Height: | Size: 287 KiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 1009 KiB After Width: | Height: | Size: 1009 KiB |
|
Before Width: | Height: | Size: 617 KiB After Width: | Height: | Size: 617 KiB |
|
Before Width: | Height: | Size: 706 KiB After Width: | Height: | Size: 706 KiB |
|
Before Width: | Height: | Size: 794 KiB After Width: | Height: | Size: 794 KiB |
@@ -72,7 +72,7 @@ go install github.com/holos-run/holos/cmd/holos@latest
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
go: downloading github.com/holos-run/holos v0.95.1
|
||||
go: downloading github.com/holos-run/holos v0.97.2
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
@@ -138,12 +138,10 @@ workflow.
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
#ArgoConfig: {
|
||||
Enabled: true
|
||||
// highlight-next-line
|
||||
RepoURL: "https://github.com/holos-run/bank-of-holos"
|
||||
_ArgoConfig: {
|
||||
Enabled: true
|
||||
RepoURL: "https://github.com/jeffmccune/bank-of-holos"
|
||||
}
|
||||
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
@@ -154,16 +152,17 @@ Change the RepoURL to the URL of your fork. For example:
|
||||
<TabItem value="command" label="projects/argocd-config.cue">
|
||||
```diff showLineNumbers
|
||||
diff --git a/projects/argocd-config.cue b/projects/argocd-config.cue
|
||||
index 5264f48..0214e99 100644
|
||||
index 1291a31..ff3bbfb 100644
|
||||
--- a/projects/argocd-config.cue
|
||||
+++ b/projects/argocd-config.cue
|
||||
@@ -2,5 +2,5 @@ package holos
|
||||
|
||||
#ArgoConfig: {
|
||||
Enabled: true
|
||||
- RepoURL: "https://github.com/holos-run/bank-of-holos"
|
||||
+ RepoURL: "https://github.com/jeffmccune/bank-of-holos"
|
||||
|
||||
_ArgoConfig: {
|
||||
Enabled: true
|
||||
- RepoURL: "https://github.com/holos-run/bank-of-holos"
|
||||
+ RepoURL: "https://github.com/jeffmccune/bank-of-holos"
|
||||
}
|
||||
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
@@ -228,38 +227,36 @@ git status
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
On branch main
|
||||
Your branch is up to date with 'origin/main'.
|
||||
|
||||
On branch jeff/291-consistent-fields
|
||||
Changes not staged for commit:
|
||||
(use "git add <file>..." to update what will be committed)
|
||||
(use "git restore <file>..." to discard changes in working directory)
|
||||
modified: deploy/clusters/workload/gitops/app-projects.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/argocd-crds.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/argocd.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/bank-accounts-db.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/bank-backend-config.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/bank-balance-reader.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/bank-contacts.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/bank-frontend.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/bank-ledger-db.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/bank-ledger-writer.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/bank-secrets.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/bank-transaction-history.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/bank-userservice.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/cert-manager.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/external-secrets-crds.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/external-secrets.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/gateway-api.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/httproutes.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/istio-base.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/istio-cni.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/istio-gateway.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/istio-ztunnel.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/istiod.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/local-ca.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/namespaces.gen.yaml
|
||||
modified: projects/argocd-config.cue
|
||||
modified: deploy/clusters/local/gitops/app-projects.gen.yaml
|
||||
modified: deploy/clusters/local/gitops/argocd-crds.gen.yaml
|
||||
modified: deploy/clusters/local/gitops/argocd.gen.yaml
|
||||
modified: deploy/clusters/local/gitops/bank-accounts-db.gen.yaml
|
||||
modified: deploy/clusters/local/gitops/bank-backend-config.gen.yaml
|
||||
modified: deploy/clusters/local/gitops/bank-balance-reader.gen.yaml
|
||||
modified: deploy/clusters/local/gitops/bank-contacts.gen.yaml
|
||||
modified: deploy/clusters/local/gitops/bank-frontend.gen.yaml
|
||||
modified: deploy/clusters/local/gitops/bank-ledger-db.gen.yaml
|
||||
modified: deploy/clusters/local/gitops/bank-ledger-writer.gen.yaml
|
||||
modified: deploy/clusters/local/gitops/bank-secrets.gen.yaml
|
||||
modified: deploy/clusters/local/gitops/bank-transaction-history.gen.yaml
|
||||
modified: deploy/clusters/local/gitops/bank-userservice.gen.yaml
|
||||
modified: deploy/clusters/local/gitops/cert-manager.gen.yaml
|
||||
modified: deploy/clusters/local/gitops/external-secrets-crds.gen.yaml
|
||||
modified: deploy/clusters/local/gitops/external-secrets.gen.yaml
|
||||
modified: deploy/clusters/local/gitops/gateway-api.gen.yaml
|
||||
modified: deploy/clusters/local/gitops/httproutes.gen.yaml
|
||||
modified: deploy/clusters/local/gitops/istio-base.gen.yaml
|
||||
modified: deploy/clusters/local/gitops/istio-cni.gen.yaml
|
||||
modified: deploy/clusters/local/gitops/istio-gateway.gen.yaml
|
||||
modified: deploy/clusters/local/gitops/istio-ztunnel.gen.yaml
|
||||
modified: deploy/clusters/local/gitops/istiod.gen.yaml
|
||||
modified: deploy/clusters/local/gitops/local-ca.gen.yaml
|
||||
modified: deploy/clusters/local/gitops/namespaces.gen.yaml
|
||||
modified: projects/argocd-config.cue
|
||||
|
||||
no changes added to commit (use "git add" and/or "git commit -a")
|
||||
```
|
||||
@@ -272,22 +269,23 @@ the changed `spec.source.repoURL` field.
|
||||
<Tabs groupId="665E5402-FB42-4975-B654-3922EE73EE07">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
git diff deploy/clusters/workload/gitops/bank-frontend.gen.yaml
|
||||
git diff deploy/clusters/local/gitops/bank-frontend.gen.yaml
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```diff showLineNumbers
|
||||
diff --git a/deploy/clusters/workload/gitops/bank-frontend.gen.yaml b/deploy/clusters/workload/gitops/bank-frontend.gen.yaml
|
||||
index 3a3dec0..22e21bb 100644
|
||||
--- a/deploy/clusters/workload/gitops/bank-frontend.gen.yaml
|
||||
+++ b/deploy/clusters/workload/gitops/bank-frontend.gen.yaml
|
||||
diff --git a/deploy/clusters/local/gitops/bank-frontend.gen.yaml b/deploy/clusters/local/gitops/bank-frontend.gen.yaml
|
||||
index e07d5ea..14cc71c 100644
|
||||
--- a/deploy/clusters/local/gitops/bank-frontend.gen.yaml
|
||||
+++ b/deploy/clusters/local/gitops/bank-frontend.gen.yaml
|
||||
@@ -11,5 +11,5 @@ spec:
|
||||
project: default
|
||||
project: bank-frontend
|
||||
source:
|
||||
path: deploy/clusters/workload/components/bank-frontend
|
||||
path: deploy/clusters/local/components/bank-frontend
|
||||
- repoURL: https://github.com/holos-run/bank-of-holos
|
||||
+ repoURL: https://github.com/jeffmccune/bank-of-holos
|
||||
targetRevision: main
|
||||
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
@@ -328,35 +326,34 @@ like this.
|
||||
|
||||
```mermaid
|
||||
---
|
||||
title: Figure 1 - Render Pipeline
|
||||
title: Figure 1 - v1alpha4 Rendered Manifest Pipeline
|
||||
---
|
||||
graph LR
|
||||
PS[<a href="/docs/api/author/v1alpha3/#Platform">Platform</a>]
|
||||
HC[<a href="/docs/api/author/v1alpha3/#ComponentFields">Components</a>]
|
||||
BP[<a href="/docs/api/core/v1alpha3#BuildPlan">BuildPlan</a>]
|
||||
Platform[<a href="/docs/api/author/v1alpha4/#Platform">Platform</a>]
|
||||
Component[<a href="/docs/api/author/v1alpha4/#ComponentConfig">Components</a>]
|
||||
|
||||
H[<a href="/docs/api/author/v1alpha3/#Helm">Helm</a>]
|
||||
K[<a href="/docs/api/author/v1alpha3/#Kustomize">Kustomize</a>]
|
||||
O[<a href="/docs/api/author/v1alpha3/#Kubernetes">Kubernetes</a>]
|
||||
Helm[<a href="/docs/api/author/v1alpha4/#Helm">Helm</a>]
|
||||
Kustomize[<a href="/docs/api/author/v1alpha4/#Kustomize">Kustomize</a>]
|
||||
Kubernetes[<a href="/docs/api/author/v1alpha4/#Kubernetes">Kubernetes</a>]
|
||||
|
||||
P[<a href="/docs/api/core/v1alpha3#Kustomize">Kustomize</a>]
|
||||
Y[Kubernetes <br/>Resources]
|
||||
G[GitOps <br/>Resource]
|
||||
FS[Local Files]
|
||||
BuildPlan[<a href="/docs/api/core/v1alpha4/#buildplan">BuildPlan</a>]
|
||||
|
||||
C[Kube API Server]
|
||||
ResourcesArtifact[<a href="/docs/api/core/v1alpha4/#artifact">Resources<br/>Artifact</a>]
|
||||
GitOpsArtifact[<a href="/docs/api/core/v1alpha4/#artifact">GitOps<br/>Artifact</a>]
|
||||
|
||||
PS --> HC --> BP
|
||||
BP --> H --> P
|
||||
BP --> K --> P
|
||||
BP --> O --> P
|
||||
Generators[<a href="/docs/api/core/v1alpha4/#generators">Generators</a>]
|
||||
Transformers[<a href="/docs/api/core/v1alpha4/#transformer">Transformers</a>]
|
||||
Files[Manifest<br/>Files]
|
||||
|
||||
P --> Y --> FS
|
||||
P --> G --> FS
|
||||
Platform --> Component
|
||||
Component --> Helm --> BuildPlan
|
||||
Component --> Kubernetes --> BuildPlan
|
||||
Component --> Kustomize --> BuildPlan
|
||||
|
||||
FS --> ArgoCD --> C
|
||||
FS --> Flux --> C
|
||||
FS --> kubectl --> C
|
||||
BuildPlan --> ResourcesArtifact --> Generators
|
||||
BuildPlan --> GitOpsArtifact --> Generators
|
||||
|
||||
Generators --> Transformers --> Files
|
||||
```
|
||||
|
||||
### Why do we render the platform? {#why-render-the-platform}
|
||||
@@ -407,14 +404,14 @@ files for now, they behave the same as these two.
|
||||
package holos
|
||||
|
||||
// Manage the Component on every Cluster in the Platform
|
||||
for Fleet in #Fleets {
|
||||
for Fleet in _Fleets {
|
||||
for Cluster in Fleet.clusters {
|
||||
#Platform: Components: "\(Cluster.name):argocd-crds": {
|
||||
_Platform: Components: "\(Cluster.name):argocd-crds": {
|
||||
name: "argocd-crds"
|
||||
component: "projects/platform/components/argocd/crds"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
#Platform: Components: "\(Cluster.name):argocd": {
|
||||
_Platform: Components: "\(Cluster.name):argocd": {
|
||||
name: "argocd"
|
||||
component: "projects/platform/components/argocd/argocd"
|
||||
cluster: Cluster.name
|
||||
@@ -428,14 +425,14 @@ for Fleet in #Fleets {
|
||||
package holos
|
||||
|
||||
// Manage the component on every cluster in the platform
|
||||
for Fleet in #Fleets {
|
||||
for Fleet in _Fleets {
|
||||
for Cluster in Fleet.clusters {
|
||||
#Platform: Components: "\(Cluster.name):external-secrets-crds": {
|
||||
_Platform: Components: "\(Cluster.name):external-secrets-crds": {
|
||||
name: "external-secrets-crds"
|
||||
component: "projects/platform/components/external-secrets-crds"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
#Platform: Components: "\(Cluster.name):external-secrets": {
|
||||
_Platform: Components: "\(Cluster.name):external-secrets": {
|
||||
name: "external-secrets"
|
||||
component: "projects/platform/components/external-secrets"
|
||||
cluster: Cluster.name
|
||||
@@ -488,7 +485,7 @@ understand how the rest of the CUE files in the platform directory behave.
|
||||
|
||||
:::tip
|
||||
Each CUE file in the platform directory adds components to the
|
||||
`#Platform.Components` struct.
|
||||
`_Platform.Components` struct.
|
||||
:::
|
||||
|
||||
The final file in the directory is responsible for producing the Platform spec.
|
||||
@@ -501,17 +498,17 @@ package holos
|
||||
|
||||
import api "github.com/holos-run/holos/api/author/v1alpha4"
|
||||
|
||||
#Platform: api.#Platform & {
|
||||
Name: "guide"
|
||||
_Platform: api.#Platform & {
|
||||
Name: "default"
|
||||
}
|
||||
|
||||
// Render a Platform resource for holos to process
|
||||
#Platform.Resource
|
||||
_Platform.Resource
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This file provides the value of the `#Platform.Resource` field, the platform
|
||||
This file provides the value of the `_Platform.Resource` field, the platform
|
||||
spec, to `holos`.
|
||||
|
||||
Let's take a look at that Output value:
|
||||
@@ -527,29 +524,84 @@ cue export --out yaml ./platform
|
||||
kind: Platform
|
||||
apiVersion: v1alpha4
|
||||
metadata:
|
||||
name: guide
|
||||
name: default
|
||||
spec:
|
||||
components: # This is a trimmed list for readability.
|
||||
components:
|
||||
- name: httproutes
|
||||
component: projects/platform/components/httproutes
|
||||
cluster: local
|
||||
- name: istio-gateway
|
||||
component: projects/platform/components/istio/gateway
|
||||
cluster: local
|
||||
- name: istio-base
|
||||
component: projects/platform/components/istio/base
|
||||
cluster: local
|
||||
- name: istiod
|
||||
component: projects/platform/components/istio/istiod
|
||||
cluster: local
|
||||
- name: istio-cni
|
||||
component: projects/platform/components/istio/cni
|
||||
cluster: local
|
||||
- name: istio-ztunnel
|
||||
component: projects/platform/components/istio/ztunnel
|
||||
cluster: local
|
||||
- name: app-projects
|
||||
component: projects/platform/components/app-projects
|
||||
cluster: local
|
||||
- name: argocd-crds
|
||||
component: projects/platform/components/argocd/crds
|
||||
cluster: local
|
||||
- name: argocd
|
||||
component: projects/platform/components/argocd/argocd
|
||||
cluster: local
|
||||
- name: bank-secrets
|
||||
component: projects/bank-of-holos/security/components/bank-secrets
|
||||
cluster: workload
|
||||
model: {}
|
||||
cluster: local
|
||||
- name: bank-frontend
|
||||
component: projects/bank-of-holos/frontend/components/bank-frontend
|
||||
cluster: workload
|
||||
model: {}
|
||||
cluster: local
|
||||
- name: bank-backend-config
|
||||
component: projects/bank-of-holos/backend/components/bank-backend-config
|
||||
cluster: workload
|
||||
model: {}
|
||||
cluster: local
|
||||
- name: bank-accounts-db
|
||||
component: projects/bank-of-holos/backend/components/bank-accounts-db
|
||||
cluster: workload
|
||||
model: {}
|
||||
cluster: local
|
||||
- name: bank-userservice
|
||||
component: projects/bank-of-holos/backend/components/bank-userservice
|
||||
cluster: workload
|
||||
model: {}
|
||||
cluster: local
|
||||
- name: bank-ledger-db
|
||||
component: projects/bank-of-holos/backend/components/bank-ledger-db
|
||||
cluster: local
|
||||
- name: bank-ledger-writer
|
||||
component: projects/bank-of-holos/backend/components/bank-ledger-writer
|
||||
cluster: local
|
||||
- name: bank-balance-reader
|
||||
component: projects/bank-of-holos/backend/components/bank-balance-reader
|
||||
cluster: local
|
||||
- name: bank-transaction-history
|
||||
component: projects/bank-of-holos/backend/components/bank-transaction-history
|
||||
cluster: local
|
||||
- name: bank-contacts
|
||||
component: projects/bank-of-holos/backend/components/bank-contacts
|
||||
cluster: local
|
||||
- name: cert-manager
|
||||
component: projects/platform/components/cert-manager
|
||||
cluster: local
|
||||
- name: external-secrets-crds
|
||||
component: projects/platform/components/external-secrets-crds
|
||||
cluster: local
|
||||
- name: external-secrets
|
||||
component: projects/platform/components/external-secrets
|
||||
cluster: local
|
||||
- name: gateway-api
|
||||
component: projects/platform/components/gateway-api
|
||||
cluster: local
|
||||
- name: local-ca
|
||||
component: projects/platform/components/local-ca
|
||||
cluster: local
|
||||
- name: namespaces
|
||||
component: projects/platform/components/namespaces
|
||||
cluster: local
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
@@ -600,23 +652,26 @@ start working with the cert-manager component.
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
(#Helm & Chart).BuildPlan
|
||||
_HelmChart.BuildPlan
|
||||
|
||||
let Chart = {
|
||||
_HelmChart: #Helm & {
|
||||
Name: "cert-manager"
|
||||
Namespace: #CertManager.Namespace
|
||||
Namespace: _CertManager.Namespace
|
||||
|
||||
Chart: {
|
||||
version: #CertManager.Version
|
||||
version: _CertManager.Version
|
||||
repository: {
|
||||
name: "jetstack"
|
||||
url: "https://charts.jetstack.io"
|
||||
}
|
||||
}
|
||||
EnableHooks: true
|
||||
|
||||
Values: {
|
||||
installCRDs: true
|
||||
Values: #Values & {
|
||||
crds: enabled: true
|
||||
startupapicheck: enabled: false
|
||||
// https://github.com/cert-manager/cert-manager/issues/6716
|
||||
global: leaderElection: namespace: Namespace
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -625,14 +680,19 @@ let Chart = {
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// Platform wide configuration
|
||||
#CertManager: {
|
||||
Version: "1.15.3"
|
||||
Version: string
|
||||
Namespace: string
|
||||
}
|
||||
|
||||
// Platform wide configuration
|
||||
_CertManager: {
|
||||
Version: "v1.16.1"
|
||||
Namespace: "cert-manager"
|
||||
}
|
||||
|
||||
// Register the namespace
|
||||
#Namespaces: (#CertManager.Namespace): _
|
||||
_Namespaces: (_CertManager.Namespace): _
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
@@ -640,15 +700,13 @@ package holos
|
||||
This file introduces a few new concepts.
|
||||
|
||||
1. Line 4 indicates this component produces a BuildPlan that wraps a Helm Chart.
|
||||
2. On line 6 `let` binds a name to an expression for the current scope. The
|
||||
current file in this case.
|
||||
3. Notice Chart is referenced on line 4 before it's bound on line 6. **Order is
|
||||
irrelevant in CUE**. Complex changes are simpler and easier when we don't have
|
||||
to think about order.
|
||||
4. The chart version and namespace are defined in a different file closer to the
|
||||
root, `projects/cert-manager.cue`
|
||||
5. We define Helm values in CUE to take advantage of strong type checking and
|
||||
manage multiple Helm charts consistently with platform wide values.
|
||||
2. Notice `_HelmChart` is referenced on line 4 before it's defined on line 6.
|
||||
**Order is irrelevant in CUE**. Complex changes are simpler and easier when we
|
||||
don't have to think about order.
|
||||
3. Line 8 and 11: The chart version and namespace are defined in a different
|
||||
file closer to the root, `projects/cert-manager.cue`
|
||||
4. Line 19: Helm values are defined in CUE to take advantage of strong type
|
||||
checking and manage multiple Helm charts consistently with the same values.
|
||||
|
||||
Let's take a look at the BuildPlan that results from the CUE configuration
|
||||
described above.
|
||||
@@ -675,16 +733,280 @@ spec:
|
||||
helm:
|
||||
chart:
|
||||
name: cert-manager
|
||||
version: 1.15.3
|
||||
version: v1.16.1
|
||||
release: cert-manager
|
||||
repository:
|
||||
name: jetstack
|
||||
url: https://charts.jetstack.io
|
||||
values:
|
||||
installCRDs: true
|
||||
global:
|
||||
imagePullSecrets: []
|
||||
commonLabels: {}
|
||||
priorityClassName: ""
|
||||
rbac:
|
||||
create: true
|
||||
aggregateClusterRoles: true
|
||||
podSecurityPolicy:
|
||||
enabled: false
|
||||
useAppArmor: true
|
||||
logLevel: 2
|
||||
leaderElection:
|
||||
namespace: cert-manager
|
||||
installCRDs: false
|
||||
crds:
|
||||
enabled: true
|
||||
keep: true
|
||||
replicaCount: 1
|
||||
strategy: {}
|
||||
podDisruptionBudget:
|
||||
enabled: false
|
||||
featureGates: ""
|
||||
maxConcurrentChallenges: 60
|
||||
image:
|
||||
repository: quay.io/jetstack/cert-manager-controller
|
||||
pullPolicy: IfNotPresent
|
||||
clusterResourceNamespace: ""
|
||||
namespace: ""
|
||||
serviceAccount:
|
||||
create: true
|
||||
automountServiceAccountToken: true
|
||||
enableCertificateOwnerRef: false
|
||||
config: {}
|
||||
dns01RecursiveNameservers: ""
|
||||
dns01RecursiveNameserversOnly: false
|
||||
disableAutoApproval: false
|
||||
approveSignerNames:
|
||||
- issuers.cert-manager.io/*
|
||||
- clusterissuers.cert-manager.io/*
|
||||
extraArgs: []
|
||||
extraEnv: []
|
||||
resources: {}
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
containerSecurityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
readOnlyRootFilesystem: true
|
||||
volumes: []
|
||||
volumeMounts: []
|
||||
podLabels: {}
|
||||
hostAliases: []
|
||||
nodeSelector:
|
||||
kubernetes.io/os: linux
|
||||
ingressShim: {}
|
||||
affinity: {}
|
||||
tolerations: []
|
||||
topologySpreadConstraints: []
|
||||
livenessProbe:
|
||||
enabled: true
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 15
|
||||
successThreshold: 1
|
||||
failureThreshold: 8
|
||||
enableServiceLinks: false
|
||||
prometheus:
|
||||
enabled: true
|
||||
servicemonitor:
|
||||
enabled: false
|
||||
prometheusInstance: default
|
||||
targetPort: 9402
|
||||
path: /metrics
|
||||
interval: 60s
|
||||
scrapeTimeout: 30s
|
||||
labels: {}
|
||||
annotations: {}
|
||||
honorLabels: false
|
||||
endpointAdditionalProperties: {}
|
||||
podmonitor:
|
||||
enabled: false
|
||||
prometheusInstance: default
|
||||
path: /metrics
|
||||
interval: 60s
|
||||
scrapeTimeout: 30s
|
||||
labels: {}
|
||||
annotations: {}
|
||||
honorLabels: false
|
||||
endpointAdditionalProperties: {}
|
||||
webhook:
|
||||
replicaCount: 1
|
||||
timeoutSeconds: 30
|
||||
config: {}
|
||||
strategy: {}
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
containerSecurityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
readOnlyRootFilesystem: true
|
||||
podDisruptionBudget:
|
||||
enabled: false
|
||||
validatingWebhookConfiguration:
|
||||
namespaceSelector:
|
||||
matchExpressions:
|
||||
- key: cert-manager.io/disable-validation
|
||||
operator: NotIn
|
||||
values:
|
||||
- "true"
|
||||
mutatingWebhookConfiguration:
|
||||
namespaceSelector: {}
|
||||
extraArgs: []
|
||||
extraEnv: []
|
||||
featureGates: ""
|
||||
resources: {}
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
readinessProbe:
|
||||
failureThreshold: 3
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
nodeSelector:
|
||||
kubernetes.io/os: linux
|
||||
affinity: {}
|
||||
tolerations: []
|
||||
topologySpreadConstraints: []
|
||||
podLabels: {}
|
||||
serviceLabels: {}
|
||||
serviceIPFamilyPolicy: ""
|
||||
serviceIPFamilies: []
|
||||
image:
|
||||
repository: quay.io/jetstack/cert-manager-webhook
|
||||
pullPolicy: IfNotPresent
|
||||
serviceAccount:
|
||||
create: true
|
||||
automountServiceAccountToken: true
|
||||
securePort: 10250
|
||||
hostNetwork: false
|
||||
serviceType: ClusterIP
|
||||
url: {}
|
||||
networkPolicy:
|
||||
enabled: false
|
||||
ingress:
|
||||
- from:
|
||||
- ipBlock:
|
||||
cidr: 0.0.0.0/0
|
||||
egress:
|
||||
- ports:
|
||||
- port: 80
|
||||
protocol: TCP
|
||||
- port: 443
|
||||
protocol: TCP
|
||||
- port: 53
|
||||
protocol: TCP
|
||||
- port: 53
|
||||
protocol: UDP
|
||||
- port: 6443
|
||||
protocol: TCP
|
||||
to:
|
||||
- ipBlock:
|
||||
cidr: 0.0.0.0/0
|
||||
volumes: []
|
||||
volumeMounts: []
|
||||
enableServiceLinks: false
|
||||
cainjector:
|
||||
enabled: true
|
||||
replicaCount: 1
|
||||
config: {}
|
||||
strategy: {}
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
containerSecurityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
readOnlyRootFilesystem: true
|
||||
podDisruptionBudget:
|
||||
enabled: false
|
||||
extraArgs: []
|
||||
extraEnv: []
|
||||
featureGates: ""
|
||||
resources: {}
|
||||
nodeSelector:
|
||||
kubernetes.io/os: linux
|
||||
affinity: {}
|
||||
tolerations: []
|
||||
topologySpreadConstraints: []
|
||||
podLabels: {}
|
||||
serviceLabels: {}
|
||||
image:
|
||||
repository: quay.io/jetstack/cert-manager-cainjector
|
||||
pullPolicy: IfNotPresent
|
||||
serviceAccount:
|
||||
create: true
|
||||
automountServiceAccountToken: true
|
||||
volumes: []
|
||||
volumeMounts: []
|
||||
enableServiceLinks: false
|
||||
acmesolver:
|
||||
image:
|
||||
repository: quay.io/jetstack/cert-manager-acmesolver
|
||||
pullPolicy: IfNotPresent
|
||||
startupapicheck:
|
||||
enabled: false
|
||||
enableHooks: false
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
containerSecurityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
readOnlyRootFilesystem: true
|
||||
timeout: 1m
|
||||
backoffLimit: 4
|
||||
jobAnnotations:
|
||||
helm.sh/hook: post-install
|
||||
helm.sh/hook-weight: "1"
|
||||
helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
|
||||
extraArgs:
|
||||
- -v
|
||||
extraEnv: []
|
||||
resources: {}
|
||||
nodeSelector:
|
||||
kubernetes.io/os: linux
|
||||
affinity: {}
|
||||
tolerations: []
|
||||
podLabels: {}
|
||||
image:
|
||||
repository: quay.io/jetstack/cert-manager-startupapicheck
|
||||
pullPolicy: IfNotPresent
|
||||
rbac:
|
||||
annotations:
|
||||
helm.sh/hook: post-install
|
||||
helm.sh/hook-weight: "-5"
|
||||
helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
|
||||
serviceAccount:
|
||||
create: true
|
||||
annotations:
|
||||
helm.sh/hook: post-install
|
||||
helm.sh/hook-weight: "-5"
|
||||
helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
|
||||
automountServiceAccountToken: true
|
||||
volumes: []
|
||||
volumeMounts: []
|
||||
enableServiceLinks: false
|
||||
extraObjects: []
|
||||
creator: helm
|
||||
enabled: true
|
||||
enableHooks: true
|
||||
namespace: cert-manager
|
||||
- kind: Resources
|
||||
output: resources.gen.yaml
|
||||
@@ -711,6 +1033,7 @@ spec:
|
||||
namespace: cert-manager
|
||||
commonLabels:
|
||||
holos.run/component.name: cert-manager
|
||||
argocd.argoproj.io/instance: cert-manager
|
||||
resources:
|
||||
- combined.gen.yaml
|
||||
- artifact: clusters/no-cluster/gitops/cert-manager.gen.yaml
|
||||
@@ -728,7 +1051,7 @@ spec:
|
||||
spec:
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
project: default
|
||||
project: platform
|
||||
source:
|
||||
path: deploy/clusters/no-cluster/components/cert-manager
|
||||
repoURL: https://github.com/jeffmccune/bank-of-holos
|
||||
|
Before Width: | Height: | Size: 934 KiB After Width: | Height: | Size: 934 KiB |
|
Before Width: | Height: | Size: 703 KiB After Width: | Height: | Size: 703 KiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 1014 KiB After Width: | Height: | Size: 1014 KiB |
|
Before Width: | Height: | Size: 728 KiB After Width: | Height: | Size: 728 KiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 1014 KiB After Width: | Height: | Size: 1014 KiB |
|
Before Width: | Height: | Size: 854 KiB After Width: | Height: | Size: 854 KiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 624 KiB After Width: | Height: | Size: 624 KiB |
|
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 116 KiB |
@@ -1,6 +1,5 @@
|
||||
---
|
||||
description: Holos Documentation
|
||||
slug: /
|
||||
description: Introduction
|
||||
---
|
||||
|
||||
# Introduction
|
||||
690
doc/md.archive/technical-overview.mdx
Normal file
@@ -0,0 +1,690 @@
|
||||
---
|
||||
slug: technical-overview
|
||||
title: Technical Overview
|
||||
description: Learn how Holos makes it easier for platform teams to integrate software into their platform.
|
||||
---
|
||||
|
||||
<head>
|
||||
<meta property="og:title" content="Technical Overview | Holos" />
|
||||
<meta property="og:image" content="/img/cards/technical-overview.png" />
|
||||
</head>
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
## Overview
|
||||
|
||||
Holos makes it easier for platform teams to integrate software into their
|
||||
platform. Existing tools in the Kubernetes ecosystem are narrowly focused on
|
||||
application management. Holos takes a holistic approach, focusing on the broad
|
||||
integration layer where applications are joined into the platform. Holos
|
||||
improves cross team collaboration through well defined, typed structures at the
|
||||
integration layer. These definitions provide golden paths for other teams to
|
||||
easily integrate their own services into the platform.
|
||||
|
||||
{/* truncate */}
|
||||
|
||||
## The Problem
|
||||
|
||||
Platform teams need to develop and maintain significant glue code to integrate
|
||||
Helm charts and YAML manifests into a platform built on Kubernetes. This glue
|
||||
code is often implemented with home grown umbrella charts and scripts.
|
||||
Maintaining these charts and scripts takes time and effort that could otherwise
|
||||
be spent improving the platform. The need for each organization to develop and
|
||||
maintain this glue code indicates a gap in the Kubernetes ecosystem. Holos is a
|
||||
Go command line tool leveraging [CUE] to fill this gap.
|
||||
|
||||
## Key Features
|
||||
|
||||
1. Holos enables teams to provide simple definitions for other teams to use as golden paths.
|
||||
2. Define integrations in [CUE] with strong type checking. No more text templates or bash scripts.
|
||||
3. Simplify complex integration. Order does not matter. Validation is early and quick.
|
||||
4. Reuse your existing Helm charts and Kustomize bases.
|
||||
5. Implement the [rendered manifests pattern]. Changes are clearly visible platform-wide.
|
||||
6. Fully render manifests to plain files. Use your existing GitOps tools and processes.
|
||||
7. Post-process with Kustomize from CUE instead of plain text files. Customize your Kustomizations.
|
||||
8. Mix in resources to Helm charts and Kustomize bases, for example ExternalSecrets.
|
||||
9. Render all of Helm, Kustomize, CUE, JSON, and YAML consistently with the same process.
|
||||
|
||||
## Rendering Pipeline
|
||||
|
||||
```mermaid
|
||||
---
|
||||
title: Figure 1 - v1alpha4 Rendered Manifest Pipeline
|
||||
---
|
||||
graph LR
|
||||
Platform[<a href="/docs/api/author/v1alpha4/#Platform">Platform</a>]
|
||||
Component[<a href="/docs/api/author/v1alpha4/#ComponentConfig">Components</a>]
|
||||
|
||||
Helm[<a href="/docs/api/author/v1alpha4/#Helm">Helm</a>]
|
||||
Kustomize[<a href="/docs/api/author/v1alpha4/#Kustomize">Kustomize</a>]
|
||||
Kubernetes[<a href="/docs/api/author/v1alpha4/#Kubernetes">Kubernetes</a>]
|
||||
|
||||
BuildPlan[<a href="/docs/api/core/v1alpha4/#buildplan">BuildPlan</a>]
|
||||
|
||||
ResourcesArtifact[<a href="/docs/api/core/v1alpha4/#artifact">Resources<br/>Artifact</a>]
|
||||
GitOpsArtifact[<a href="/docs/api/core/v1alpha4/#artifact">GitOps<br/>Artifact</a>]
|
||||
|
||||
Generators[<a href="/docs/api/core/v1alpha4/#generators">Generators</a>]
|
||||
Transformers[<a href="/docs/api/core/v1alpha4/#transformer">Transformers</a>]
|
||||
Files[Manifest<br/>Files]
|
||||
|
||||
Platform --> Component
|
||||
Component --> Helm --> BuildPlan
|
||||
Component --> Kubernetes --> BuildPlan
|
||||
Component --> Kustomize --> BuildPlan
|
||||
|
||||
BuildPlan --> ResourcesArtifact --> Generators
|
||||
BuildPlan --> GitOpsArtifact --> Generators
|
||||
|
||||
Generators --> Transformers --> Files
|
||||
```
|
||||
|
||||
## Use Case
|
||||
|
||||
One of the development teams at the fictional Bank of Holos wants to deploy a
|
||||
simple web app for an experimental project they're working on.
|
||||
|
||||
The platform team at the bank wants to build a simple golden path for teams to
|
||||
provision projects consistently and easily in compliance with the bank's
|
||||
policies.
|
||||
|
||||
### Platform Team
|
||||
|
||||
The platform team builds a golden path for development teams to register their
|
||||
project with the platform. In compliance with bank policy, the platform team
|
||||
needs to manage important security resources for each new project. All of these
|
||||
resources can be derived from only 3 pieces of information.
|
||||
|
||||
1. The name of the project the dev team is working on.
|
||||
2. The name of the team who currently owns the project.
|
||||
3. The services, if any, the project is exposing.
|
||||
|
||||
The platform team defines a structure for the dev team to register this
|
||||
information. This structure provides the golden path for the dev team.
|
||||
|
||||
The development team registers their experimental project, creatively named
|
||||
"experiment" by submitting a pull request that contains this information.
|
||||
|
||||
<Tabs groupId="EB9C9AF1-F1AA-4189-B746-A5B8E3043F87">
|
||||
<TabItem value="projects/experiment.cue" label="projects/experiment.cue">
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// The development team registers a project name.
|
||||
_Projects: experiment: {
|
||||
// The project owner must be named.
|
||||
Owner: Name: "dev-team"
|
||||
// Expose Service podinfo at https://podinfo.example.com
|
||||
Hostnames: podinfo: Port: 9898
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
The platform team uses these three pieces of information to derive all of the
|
||||
platform resources necessary to support the development team.
|
||||
|
||||
1. **Namespace** for the project resources.
|
||||
2. **RoleBinding** to grant the dev team access to the project namespace.
|
||||
3. **SecretStore** which implements the secret management policy for the bank.
|
||||
4. **ReferenceGrant** to expose the project services through the Gateway API.
|
||||
5. **HTTPRoutes** to expose the project services, if any.
|
||||
6. **AppProject** to deploy and manage the project Applications with ArgoCD.
|
||||
7. **Common Labels** to ensure every resource is labeled for resource accounting.
|
||||
|
||||
Rendering the platform generates fully rendered manifests for all of these
|
||||
resources. These manifests are derived from the three pieces of information the
|
||||
dev team provided.
|
||||
|
||||
Note the platform team must manage these resources across multiple namespaces.
|
||||
The first four reside in the project namespace owned by the dev team. The
|
||||
HTTPRoute and AppProject go into two namespaces managed by the platform team.
|
||||
Holos makes it easier for the platform team to organize these resources into
|
||||
different components with different owners.
|
||||
|
||||
:::important
|
||||
Holos supports [CODEOWNERS] by clearly defining the teams responsible for each
|
||||
platform component.
|
||||
:::
|
||||
|
||||
<Tabs groupId="2E46EA1C-B118-44BF-AE20-752E8D1CE131">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render platform ./platform
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
rendered httproutes for cluster overview in 177.823625ms
|
||||
rendered app-projects for cluster overview in 180.946834ms
|
||||
rendered projects for cluster overview in 181.98725ms
|
||||
rendered namespaces for cluster overview in 182.30725ms
|
||||
rendered platform in 182.31075ms
|
||||
```
|
||||
:::tip
|
||||
If you'd like to try this for yourself, `cd` into [examples/tech-overview] and
|
||||
render the platform.
|
||||
:::
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
The fully rendered manifests are written into the `deploy/` directory organized
|
||||
by cluster and component for GitOps.
|
||||
|
||||
<Tabs groupId="07FBE14E-E9EA-437B-9FA1-C6D8806524AD">
|
||||
<TabItem value="deploy/clusters/local/components/namespaces/namespaces.gen.yaml" label="namespaces">
|
||||
```
|
||||
cat deploy/clusters/local/components/namespaces/namespaces.gen.yaml
|
||||
```
|
||||
```yaml showLineNumbers
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
labels:
|
||||
argocd.argoproj.io/instance: namespaces
|
||||
example.com/owner.email: sg-dev-team@example.com
|
||||
example.com/owner.name: dev-team
|
||||
example.com/project.name: experiment
|
||||
holos.run/component.name: namespaces
|
||||
kubernetes.io/metadata.name: experiment
|
||||
name: experiment
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="deploy/clusters/local/components/projects/projects.gen.yaml" label="projects">
|
||||
```
|
||||
cat deploy/clusters/local/components/projects/projects.gen.yaml
|
||||
```
|
||||
```yaml showLineNumbers
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
labels:
|
||||
argocd.argoproj.io/instance: projects
|
||||
example.com/owner.email: sg-dev-team@example.com
|
||||
example.com/owner.name: dev-team
|
||||
example.com/project.name: experiment
|
||||
holos.run/component.name: projects
|
||||
name: admin
|
||||
namespace: experiment
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: admin
|
||||
subjects:
|
||||
- apiGroup: rbac.authorization.k8s.io
|
||||
kind: Group
|
||||
name: oidc:sg-dev-team@example.com
|
||||
---
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: SecretStore
|
||||
metadata:
|
||||
labels:
|
||||
argocd.argoproj.io/instance: projects
|
||||
example.com/owner.email: sg-dev-team@example.com
|
||||
example.com/owner.name: dev-team
|
||||
example.com/project.name: experiment
|
||||
holos.run/component.name: projects
|
||||
name: default
|
||||
namespace: experiment
|
||||
spec:
|
||||
provider:
|
||||
kubernetes:
|
||||
auth:
|
||||
token:
|
||||
bearerToken:
|
||||
key: token
|
||||
name: eso-reader
|
||||
remoteNamespace: experiment
|
||||
server:
|
||||
caBundle: LS0tLS1CRUd...QVRFLS0tLS0K
|
||||
url: https://management.example.com:6443
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: ReferenceGrant
|
||||
metadata:
|
||||
labels:
|
||||
argocd.argoproj.io/instance: projects
|
||||
example.com/owner.email: sg-dev-team@example.com
|
||||
example.com/owner.name: dev-team
|
||||
example.com/project.name: experiment
|
||||
holos.run/component.name: projects
|
||||
name: istio-ingress
|
||||
namespace: experiment
|
||||
spec:
|
||||
from:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: HTTPRoute
|
||||
namespace: istio-ingress
|
||||
to:
|
||||
- group: ""
|
||||
kind: Service
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="deploy/clusters/local/components/httproutes/httproutes.gen.yaml" label="httproutes">
|
||||
```
|
||||
cat deploy/clusters/local/components/httproutes/httproutes.gen.yaml
|
||||
```
|
||||
```yaml showLineNumbers
|
||||
apiVersion: gateway.networking.k8s.io/v1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
labels:
|
||||
argocd.argoproj.io/instance: httproutes
|
||||
example.com/owner.email: sg-dev-team@example.com
|
||||
example.com/owner.name: dev-team
|
||||
example.com/project.name: experiment
|
||||
holos.run/component.name: httproutes
|
||||
name: podinfo.example.com
|
||||
namespace: istio-ingress
|
||||
spec:
|
||||
hostnames:
|
||||
- podinfo.example.com
|
||||
parentRefs:
|
||||
- name: default
|
||||
namespace: istio-ingress
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: podinfo
|
||||
namespace: experiment
|
||||
port: 9898
|
||||
matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
The rendered manifests are derived from the project registration information by
|
||||
definitions implemented by the platform team. The [Author API] provides a
|
||||
[Project] schema, but does not define an implementation. The platform team
|
||||
implements the [Project] schema by adding a `_Projects` struct to manage
|
||||
resources according to bank policies.
|
||||
|
||||
:::important
|
||||
The Author API is intended as a convenient, ergonomic reference for component
|
||||
authors. Definitions **are not** confined to the Author API.
|
||||
:::
|
||||
|
||||
The following example shows how the platform team wrote the `_Projects`
|
||||
definition to derive the Namespace from the project registration provided by the
|
||||
dev team.
|
||||
|
||||
<Tabs groupId="5732727B-295E-46E1-B851-F8A1C5D7DF88">
|
||||
<TabItem value="projects/platform/components/namespaces/namespaces.cue" label="Namespaces Component">
|
||||
```txt
|
||||
projects/platform/components/namespaces/namespaces.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
_Kubernetes: #Kubernetes & {
|
||||
Name: "namespaces"
|
||||
Resources: Namespace: _Namespaces
|
||||
}
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
_Kubernetes.BuildPlan
|
||||
```
|
||||
|
||||
1. This is the namespaces component which manages a collection of Namespace resources derived from the project registration data shown in the second tab.
|
||||
2. Line 5 manages a Namespace for each value of the `#Namespaces` struct. See the second tab for how the platform team defines this structure.
|
||||
</TabItem>
|
||||
<TabItem value="projects/projects.cue" label="Projects Definition">
|
||||
```txt
|
||||
projects/projects.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
import api "github.com/holos-run/holos/api/author/v1alpha4"
|
||||
|
||||
// Projects defines the structure other teams register with to manage project
|
||||
// resources. The platform team defines the schema, development teams provide
|
||||
// the values.
|
||||
_Projects: api.#Projects & {
|
||||
[NAME=string]: {
|
||||
Name: NAME
|
||||
// The platform team requires the development teams to indicate an owner of
|
||||
// the project.
|
||||
Owner: Name: string
|
||||
// The default value for the owner email address is derived from the owner
|
||||
// name, but development teams can provide a different email address if
|
||||
// needed.
|
||||
Owner: Email: string | *"sg-\(Owner.Name)@\(_Organization.Domain)"
|
||||
// The platform team constrains the project to a single namespace.
|
||||
Namespaces: close({(NAME): Name: NAME})
|
||||
// The platform team constrains the exposed services to the project
|
||||
// namespace.
|
||||
Hostnames: [HOST=string]: {
|
||||
Name: HOST
|
||||
Namespace: Namespaces[NAME].Name
|
||||
Service: HOST
|
||||
Port: number | *80
|
||||
}
|
||||
|
||||
CommonLabels: {
|
||||
"\(_Organization.Domain)/project.name": Name
|
||||
"\(_Organization.Domain)/owner.name": Owner.Name
|
||||
"\(_Organization.Domain)/owner.email": Owner.Email
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for Project in _Projects {
|
||||
// Register project namespaces with the namespaces component.
|
||||
_Namespaces: {
|
||||
for Namespace in Project.Namespaces {
|
||||
(Namespace.Name): metadata: labels: Project.CommonLabels
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
1. On lines 8-35 the platform team derives most fields from the project name (line 9), and the owner name (line 13). The purpose is to fill in the remaining fields defined by the Author API.
|
||||
2. Line 13 The dev team is expected to provide a concrete owner name, indicated by the `string` value.
|
||||
3. Line 17 The platform team provides a default value for the email address. The project team may define a different value.
|
||||
4. Line 19 The Author API allows a project to have many namespaces. The platform team constrains this down to one namespace per project by closing the struct. The namespace name must be the same as the project name.
|
||||
5. Lines 22-27 The platform team derives values for a Gateway API [BackendObjectReference] from the hostname provided by the project team. These values are used later to build HTTPRoutes to expose their service.
|
||||
6. Lines 30-32 Common labels are derived to mix into resources associated with this project.
|
||||
7. Lines 37-44 The platform team adds a namespace with common labels for each project to the struct we saw in the first tab.
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
The RoleBinding, SecretScore, and ReferenceGrant are managed in the
|
||||
[projects](https://github.com/holos-run/bank-of-holos/blob/v0.4.1/examples/tech-overview/projects/platform/components/projects/projects.cue)
|
||||
component, similar to the previous namespaces example.
|
||||
The HTTPRoute is managed separately in the
|
||||
[httproutes](https://github.com/holos-run/bank-of-holos/blob/v0.4.1/examples/tech-overview/projects/platform/components/httproutes/httproutes.cue)
|
||||
component.
|
||||
|
||||
All components are registered with the platform in the
|
||||
[platform](https://github.com/holos-run/bank-of-holos/tree/v0.4.1/examples/tech-overview/platform)
|
||||
directory.
|
||||
|
||||
:::important
|
||||
Multiple components, potentially owned by different teams, derive fully rendered
|
||||
resources from the same three project values. The dev team added these three
|
||||
values to the `_Projects` struct. The platform team wrote the definition to
|
||||
integrate software according to bank policies. CUE powers this _unified_
|
||||
platform configuration model.
|
||||
:::
|
||||
|
||||
:::tip
|
||||
Components map 1:1 to ArgoCD Applications or Flux Kustomizations.
|
||||
:::
|
||||
|
||||
### Development Team
|
||||
|
||||
The development team has the platform resources they need, but they still need
|
||||
to deploy their container. The development team submits a pull request adding
|
||||
the following two files to deploy their existing Helm chart.
|
||||
|
||||
<Tabs groupId="7AD1DDA9-8001-462B-8BE0-D9410EB51233">
|
||||
<TabItem value="projects/experiment/components/podinfo/podinfo.cue" label="Helm Component">
|
||||
```txt
|
||||
projects/experiment/components/podinfo/podinfo.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
_HelmChart.BuildPlan
|
||||
|
||||
_HelmChart: #Helm & {
|
||||
Name: "podinfo"
|
||||
Chart: {
|
||||
version: "6.6.2"
|
||||
repository: {
|
||||
name: "podinfo"
|
||||
url: "https://stefanprodan.github.io/podinfo"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
This file represents a Helm chart component to add to the platform. The second
|
||||
tab registers this component with the platform.
|
||||
</TabItem>
|
||||
<TabItem value="platform/podinfo.cue" label="Component Registration">
|
||||
```
|
||||
platform/podinfo.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// Manage the component on every workload Cluster, but not management clusters.
|
||||
for Cluster in _Fleets.workload.clusters {
|
||||
_Platform: Components: "\(Cluster.name):podinfo": {
|
||||
name: "podinfo"
|
||||
component: "projects/experiment/components/podinfo"
|
||||
cluster: Cluster.name
|
||||
tags: project: "experiment"
|
||||
}
|
||||
}
|
||||
```
|
||||
This file registers the component with the platform. When the platform is
|
||||
rendered the dev team's Helm chart will be rendered on all workload clusters
|
||||
across the platform.
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
The project tag links the component to the same field of the `_Projects` struct.
|
||||
|
||||
:::important
|
||||
You can add your own key=value tags in your platform specification to inject
|
||||
values into components. This feature is useful to reuse one component path for
|
||||
several environments or customers.
|
||||
:::
|
||||
|
||||
Once the dev team's component is registered, rendering the platform will render
|
||||
their component.
|
||||
|
||||
<Tabs groupId="1BAF7AD2-BBCD-4797-A3A6-55A626732845">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render platform ./platform
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
rendered namespaces for cluster overview in 185.64075ms
|
||||
rendered app-projects for cluster overview in 186.729292ms
|
||||
rendered httproutes for cluster overview in 195.222833ms
|
||||
rendered projects for cluster overview in 195.217125ms
|
||||
// highlight-next-line
|
||||
rendered podinfo for cluster overview in 195.830042ms
|
||||
rendered platform in 195.90275ms
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
<Tabs groupId="77BF500B-105A-4AB4-A615-DEC19F501AE1">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
cat deploy/clusters/local/components/podinfo/podinfo.gen.yaml
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```yaml showLineNumbers
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: podinfo
|
||||
app.kubernetes.io/version: 6.6.2
|
||||
argocd.argoproj.io/instance: podinfo
|
||||
example.com/owner.email: sg-dev-team@example.com
|
||||
example.com/owner.name: dev-team
|
||||
example.com/project.name: experiment
|
||||
helm.sh/chart: podinfo-6.6.2
|
||||
holos.run/component.name: podinfo
|
||||
name: podinfo
|
||||
spec:
|
||||
ports:
|
||||
- name: http
|
||||
port: 9898
|
||||
protocol: TCP
|
||||
targetPort: http
|
||||
- name: grpc
|
||||
port: 9999
|
||||
protocol: TCP
|
||||
targetPort: grpc
|
||||
selector:
|
||||
app.kubernetes.io/name: podinfo
|
||||
argocd.argoproj.io/instance: podinfo
|
||||
example.com/owner.email: sg-dev-team@example.com
|
||||
example.com/owner.name: dev-team
|
||||
example.com/project.name: experiment
|
||||
holos.run/component.name: podinfo
|
||||
type: ClusterIP
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: podinfo
|
||||
app.kubernetes.io/version: 6.6.2
|
||||
argocd.argoproj.io/instance: podinfo
|
||||
example.com/owner.email: sg-dev-team@example.com
|
||||
example.com/owner.name: dev-team
|
||||
example.com/project.name: experiment
|
||||
helm.sh/chart: podinfo-6.6.2
|
||||
holos.run/component.name: podinfo
|
||||
name: podinfo
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: podinfo
|
||||
argocd.argoproj.io/instance: podinfo
|
||||
example.com/owner.email: sg-dev-team@example.com
|
||||
example.com/owner.name: dev-team
|
||||
example.com/project.name: experiment
|
||||
holos.run/component.name: podinfo
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
maxUnavailable: 1
|
||||
type: RollingUpdate
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
prometheus.io/port: "9898"
|
||||
prometheus.io/scrape: "true"
|
||||
labels:
|
||||
app.kubernetes.io/name: podinfo
|
||||
argocd.argoproj.io/instance: podinfo
|
||||
example.com/owner.email: sg-dev-team@example.com
|
||||
example.com/owner.name: dev-team
|
||||
example.com/project.name: experiment
|
||||
holos.run/component.name: podinfo
|
||||
spec:
|
||||
containers:
|
||||
- command:
|
||||
- ./podinfo
|
||||
- --port=9898
|
||||
- --cert-path=/data/cert
|
||||
- --port-metrics=9797
|
||||
- --grpc-port=9999
|
||||
- --grpc-service-name=podinfo
|
||||
- --level=info
|
||||
- --random-delay=false
|
||||
- --random-error=false
|
||||
env:
|
||||
- name: PODINFO_UI_COLOR
|
||||
value: '#34577c'
|
||||
image: ghcr.io/stefanprodan/podinfo:6.6.2
|
||||
imagePullPolicy: IfNotPresent
|
||||
livenessProbe:
|
||||
exec:
|
||||
command:
|
||||
- podcli
|
||||
- check
|
||||
- http
|
||||
- localhost:9898/healthz
|
||||
failureThreshold: 3
|
||||
initialDelaySeconds: 1
|
||||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 5
|
||||
name: podinfo
|
||||
ports:
|
||||
- containerPort: 9898
|
||||
name: http
|
||||
protocol: TCP
|
||||
- containerPort: 9797
|
||||
name: http-metrics
|
||||
protocol: TCP
|
||||
- containerPort: 9999
|
||||
name: grpc
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
exec:
|
||||
command:
|
||||
- podcli
|
||||
- check
|
||||
- http
|
||||
- localhost:9898/readyz
|
||||
failureThreshold: 3
|
||||
initialDelaySeconds: 1
|
||||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 5
|
||||
resources:
|
||||
limits: null
|
||||
requests:
|
||||
cpu: 1m
|
||||
memory: 16Mi
|
||||
volumeMounts:
|
||||
- mountPath: /data
|
||||
name: data
|
||||
terminationGracePeriodSeconds: 30
|
||||
volumes:
|
||||
- emptyDir: {}
|
||||
name: data
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Note the rendered Helm chart resources have consistent project labels. The
|
||||
platform team added a constraint to the project so all Helm charts are post
|
||||
processed with Kustomize to add these common labels. The platform team
|
||||
accomplishes this by adding a constraint in the project directory. This can be
|
||||
seen in
|
||||
[schema.cue](https://github.com/holos-run/bank-of-holos/blob/v0.4.1/schema.cue#L35-L38)
|
||||
where the platform team configures all component kinds for the platform.
|
||||
|
||||
We've covered how the platform team provides a golden path for development teams
|
||||
to register their projects by defining a Projects structure. We've also covered
|
||||
how the development team deploys their existing Helm chart onto the platform.
|
||||
|
||||
## Support & Resources
|
||||
|
||||
1. See our [Quickstart] guide to get started with Holos.
|
||||
2. Check out our other [Guides] which cover specific topics.
|
||||
3. Refer to the [Author API] when writing components.
|
||||
4. Consider the [Core API] if you need to do something more advanced than the Author API supports.
|
||||
5. Community and commercial [Support] is available.
|
||||
6. [Discussions Forum](https://github.com/holos-run/holos/discussions)
|
||||
|
||||
[Support]: /docs/support/
|
||||
[Guides]: /docs/guides/
|
||||
[API Reference]: /docs/api/
|
||||
[Quickstart]: /docs/quickstart/
|
||||
[CUE]: https://cuelang.org/
|
||||
[Author API]: /docs/api/author/
|
||||
[Core API]: /docs/api/core/
|
||||
[Open Infrastructure Services]: https://openinfrastructure.co/
|
||||
[Why are we templating YAML]: https://hn.algolia.com/?dateRange=all&page=0&prefix=false&query=https%3A%2F%2Fleebriggs.co.uk%2Fblog%2F2019%2F02%2F07%2Fwhy-are-we-templating-yaml&sort=byDate&type=story
|
||||
[Holos]: https://holos.run/
|
||||
[Quickstart]: /docs/quickstart/
|
||||
[rendered manifests pattern]: https://akuity.io/blog/the-rendered-manifests-pattern/
|
||||
[examples/tech-overview]: https://github.com/holos-run/bank-of-holos/tree/v0.2.0/examples/tech-overview
|
||||
[BackendObjectReference]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io%2fv1.BackendObjectReference
|
||||
[CODEOWNERS]: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
|
||||
[Project]: /docs/api/author/v1alpha3/#Project
|
||||
10
doc/md/api.mdx
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
slug: api
|
||||
description: Schema Reference
|
||||
---
|
||||
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
|
||||
# Schema Reference
|
||||
|
||||
<DocCardList />
|
||||
@@ -1,5 +1,179 @@
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
---
|
||||
title: Author Schemas
|
||||
description: Standardized schemas for component authors.
|
||||
sidebar_position: 200
|
||||
---
|
||||
<!-- Code generated by gomarkdoc. DO NOT EDIT -->
|
||||
|
||||
# Author API
|
||||
|
||||
<DocCardList />
|
||||
```go
|
||||
import "github.com/holos-run/holos/api/author/v1alpha5"
|
||||
```
|
||||
|
||||
Package author contains a standard set of schemas for component authors to generate common [core](<https://holos.run/docs/api/core/>) BuildPlans.
|
||||
|
||||
Holos values stability, flexibility, and composition. This package intentionally defines only the minimal necessary set of structures. Component authors are encouraged to define their own structures building on our example [topics](<https://holos.run/docs/topics/>).
|
||||
|
||||
The Holos Maintainers may add definitions to this package if the community identifies nearly all users must define the exact same structure. Otherwise, definitions should be added as a customizable example in [topics](<https://holos.run/docs/topics/>).
|
||||
|
||||
For example, structures representing a cluster and environment almost always need to be defined. Their definition varies from one organization to the next. Therefore, customizable definitions for a cluster and environment are best maintained in [topics](<https://holos.run/docs/topics/>), not standardized in this package.
|
||||
|
||||
## Index
|
||||
|
||||
- [type ComponentConfig](<#ComponentConfig>)
|
||||
- [type Helm](<#Helm>)
|
||||
- [type Kubernetes](<#Kubernetes>)
|
||||
- [type Kustomize](<#Kustomize>)
|
||||
- [type KustomizeConfig](<#KustomizeConfig>)
|
||||
- [type NameLabel](<#NameLabel>)
|
||||
- [type Platform](<#Platform>)
|
||||
|
||||
|
||||
<a name="ComponentConfig"></a>
|
||||
## type ComponentConfig {#ComponentConfig}
|
||||
|
||||
ComponentConfig represents the configuration common to all kinds of components for use with the holos render component command. All component kinds may be transformed with [kustomize](<https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/>) configured with the [KustomizeConfig](<#KustomizeConfig>) field.
|
||||
|
||||
- [Helm](<#Helm>) charts.
|
||||
- [Kubernetes](<#Kubernetes>) resources generated from CUE.
|
||||
- [Kustomize](<#Kustomize>) bases.
|
||||
|
||||
```go
|
||||
type ComponentConfig struct {
|
||||
// Name represents the BuildPlan metadata.name field. Used to construct the
|
||||
// fully rendered manifest file path.
|
||||
Name string
|
||||
// Path represents the path to the component producing the BuildPlan.
|
||||
Path string
|
||||
// Parameters are useful to reuse a component with various parameters.
|
||||
// Injected as CUE @tag variables. Parameters with a "holos_" prefix are
|
||||
// reserved for use by the Holos Authors.
|
||||
Parameters map[string]string
|
||||
// OutputBaseDir represents the output base directory used when assembling
|
||||
// artifacts. Useful to organize components by clusters or other parameters.
|
||||
// For example, holos writes resource manifests to
|
||||
// {WriteTo}/{OutputBaseDir}/components/{Name}/{Name}.gen.yaml
|
||||
OutputBaseDir string `cue:"string | *\"\""`
|
||||
|
||||
// Resources represents kubernetes resources mixed into the rendered manifest.
|
||||
Resources core.Resources
|
||||
// KustomizeConfig represents the configuration kustomize.
|
||||
KustomizeConfig KustomizeConfig
|
||||
// Artifacts represents additional artifacts to mix in. Useful for adding
|
||||
// GitOps resources. Each Artifact is unified without modification into the
|
||||
// BuildPlan.
|
||||
Artifacts map[NameLabel]core.Artifact
|
||||
}
|
||||
```
|
||||
|
||||
<a name="Helm"></a>
|
||||
## type Helm {#Helm}
|
||||
|
||||
Helm assembles a BuildPlan rendering a helm chart. Useful to mix in additional resources from CUE and transform the helm output with kustomize.
|
||||
|
||||
```go
|
||||
type Helm struct {
|
||||
ComponentConfig `json:",inline"`
|
||||
|
||||
// Chart represents a Helm chart.
|
||||
Chart core.Chart
|
||||
// Values represents data to marshal into a values.yaml for helm.
|
||||
Values core.Values
|
||||
// EnableHooks enables helm hooks when executing the `helm template` command.
|
||||
EnableHooks bool `cue:"true | *false"`
|
||||
// Namespace sets the helm chart namespace flag if provided.
|
||||
Namespace string `json:",omitempty"`
|
||||
// APIVersions represents the helm template --api-versions flag
|
||||
APIVersions []string `json:",omitempty"`
|
||||
// KubeVersion represents the helm template --kube-version flag
|
||||
KubeVersion string `json:",omitempty"`
|
||||
|
||||
// BuildPlan represents the derived BuildPlan produced for the holos render
|
||||
// component command.
|
||||
BuildPlan core.BuildPlan
|
||||
}
|
||||
```
|
||||
|
||||
<a name="Kubernetes"></a>
|
||||
## type Kubernetes {#Kubernetes}
|
||||
|
||||
Kubernetes assembles a BuildPlan containing inline resources exported from CUE.
|
||||
|
||||
```go
|
||||
type Kubernetes struct {
|
||||
ComponentConfig `json:",inline"`
|
||||
|
||||
// BuildPlan represents the derived BuildPlan produced for the holos render
|
||||
// component command.
|
||||
BuildPlan core.BuildPlan
|
||||
}
|
||||
```
|
||||
|
||||
<a name="Kustomize"></a>
|
||||
## type Kustomize {#Kustomize}
|
||||
|
||||
Kustomize assembles a BuildPlan rendering manifests from a [kustomize](<https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/>) kustomization.
|
||||
|
||||
```go
|
||||
type Kustomize struct {
|
||||
ComponentConfig `json:",inline"`
|
||||
|
||||
// BuildPlan represents the derived BuildPlan produced for the holos render
|
||||
// component command.
|
||||
BuildPlan core.BuildPlan
|
||||
}
|
||||
```
|
||||
|
||||
<a name="KustomizeConfig"></a>
|
||||
## type KustomizeConfig {#KustomizeConfig}
|
||||
|
||||
KustomizeConfig represents the configuration for [kustomize](<https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/>) post processing. Use the Files field to mix in plain manifest files located in the component directory. Use the Resources field to mix in manifests from network urls.
|
||||
|
||||
```go
|
||||
type KustomizeConfig struct {
|
||||
// Kustomization represents the kustomization used to transform resources.
|
||||
// Note the resources field is internally managed from the Files and Resources fields.
|
||||
Kustomization map[string]any `json:",omitempty"`
|
||||
// Files represents files to copy from the component directory for kustomization.
|
||||
Files map[string]struct{ Source string } `cue:"{[NAME=_]: Source: NAME}"`
|
||||
// Resources represents additional entries to included in the resources list.
|
||||
Resources map[string]struct{ Source string } `cue:"{[NAME=_]: Source: NAME}"`
|
||||
// CommonLabels represents common labels added without including selectors.
|
||||
CommonLabels map[string]string
|
||||
}
|
||||
```
|
||||
|
||||
<a name="NameLabel"></a>
|
||||
## type NameLabel {#NameLabel}
|
||||
|
||||
NameLabel represents the common use case of converting a struct to a list where the name field of each value unifies with the field name of the outer struct.
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
S: [NameLabel=string]: name: NameLabel
|
||||
S: jeff: _
|
||||
S: gary: _
|
||||
S: nate: _
|
||||
L: [for x in S {x}]
|
||||
// L is [{name: "jeff"}, {name: "gary"}, {name: "nate"}]
|
||||
```
|
||||
|
||||
```go
|
||||
type NameLabel string
|
||||
```
|
||||
|
||||
<a name="Platform"></a>
|
||||
## type Platform {#Platform}
|
||||
|
||||
Platform assembles a core Platform in the Resource field for the holos render platform command. Use the Components field to register components with the platform.
|
||||
|
||||
```go
|
||||
type Platform struct {
|
||||
Name string
|
||||
Components map[NameLabel]core.Component
|
||||
Resource core.Platform
|
||||
}
|
||||
```
|
||||
|
||||
Generated by [gomarkdoc](<https://github.com/princjef/gomarkdoc>)
|
||||
|
||||
@@ -1,5 +1,416 @@
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
---
|
||||
title: Core Schemas
|
||||
description: BuildPlan defines the holos rendering pipeline.
|
||||
sidebar_position: 100
|
||||
---
|
||||
<!-- Code generated by gomarkdoc. DO NOT EDIT -->
|
||||
|
||||
# Core API
|
||||
|
||||
<DocCardList />
|
||||
```go
|
||||
import "github.com/holos-run/holos/api/core/v1alpha5"
|
||||
```
|
||||
|
||||
Package core contains schemas for a [Platform](<#Platform>) and [BuildPlan](<#BuildPlan>). Holos takes a [Platform](<#Platform>) as input, then iterates over each [Component](<#Component>) to produce a [BuildPlan](<#BuildPlan>). Holos processes the [BuildPlan](<#BuildPlan>) to produce fully rendered manifests, each an [Artifact](<#Artifact>).
|
||||
|
||||
## Index
|
||||
|
||||
- [type Artifact](<#Artifact>)
|
||||
- [type BuildPlan](<#BuildPlan>)
|
||||
- [type BuildPlanSource](<#BuildPlanSource>)
|
||||
- [type BuildPlanSpec](<#BuildPlanSpec>)
|
||||
- [type Chart](<#Chart>)
|
||||
- [type Component](<#Component>)
|
||||
- [type File](<#File>)
|
||||
- [type FileContent](<#FileContent>)
|
||||
- [type FileContentMap](<#FileContentMap>)
|
||||
- [type FilePath](<#FilePath>)
|
||||
- [type Generator](<#Generator>)
|
||||
- [type Helm](<#Helm>)
|
||||
- [type InternalLabel](<#InternalLabel>)
|
||||
- [type Join](<#Join>)
|
||||
- [type Kind](<#Kind>)
|
||||
- [type Kustomization](<#Kustomization>)
|
||||
- [type Kustomize](<#Kustomize>)
|
||||
- [type Metadata](<#Metadata>)
|
||||
- [type Platform](<#Platform>)
|
||||
- [type PlatformSpec](<#PlatformSpec>)
|
||||
- [type Repository](<#Repository>)
|
||||
- [type Resource](<#Resource>)
|
||||
- [type Resources](<#Resources>)
|
||||
- [type Transformer](<#Transformer>)
|
||||
- [type Values](<#Values>)
|
||||
|
||||
|
||||
<a name="Artifact"></a>
|
||||
## type Artifact {#Artifact}
|
||||
|
||||
Artifact represents one fully rendered manifest produced by a [Transformer](<#Transformer>) sequence, which transforms a [Generator](<#Generator>) collection. A [BuildPlan](<#BuildPlan>) produces an [Artifact](<#Artifact>) collection.
|
||||
|
||||
Each Artifact produces one manifest file artifact. Generator Output values are used as Transformer Inputs. The Output field of the final [Transformer](<#Transformer>) should have the same value as the Artifact field.
|
||||
|
||||
When there is more than one [Generator](<#Generator>) there must be at least one [Transformer](<#Transformer>) to combine outputs into one Artifact. If there is a single Generator, it may directly produce the Artifact output.
|
||||
|
||||
An Artifact is processed concurrently with other artifacts in the same [BuildPlan](<#BuildPlan>). An Artifact should not use an output from another Artifact as an input. Each [Generator](<#Generator>) may also run concurrently. Each [Transformer](<#Transformer>) is executed sequentially starting after all generators have completed.
|
||||
|
||||
Output fields are write\-once. It is an error for multiple Generators or Transformers to produce the same Output value within the context of a [BuildPlan](<#BuildPlan>).
|
||||
|
||||
```go
|
||||
type Artifact struct {
|
||||
Artifact FilePath `json:"artifact,omitempty"`
|
||||
Generators []Generator `json:"generators,omitempty"`
|
||||
Transformers []Transformer `json:"transformers,omitempty"`
|
||||
Skip bool `json:"skip,omitempty"`
|
||||
}
|
||||
```
|
||||
|
||||
<a name="BuildPlan"></a>
|
||||
## type BuildPlan {#BuildPlan}
|
||||
|
||||
BuildPlan represents an implementation of the [rendered manifest pattern](<https://akuity.io/blog/the-rendered-manifests-pattern>). Holos processes a BuildPlan to produce one or more [Artifact](<#Artifact>) output files. BuildPlan artifact files usually contain Kubernetes manifests, but they may have any content.
|
||||
|
||||
A BuildPlan usually produces two artifacts. One artifact contains a manifest of resources. A second artifact contains a GitOps resource to manage the first, usually an ArgoCD Application resource.
|
||||
|
||||
Holos uses CUE to construct a BuildPlan. A future enhancement will support user defined executables providing a BuildPlan to Holos in the style of an [external credential provider](<https://github.com/kubernetes/enhancements/blob/313ad8b59c80819659e1fbf0f165230f633f2b22/keps/sig-auth/541-external-credential-providers/README.md>).
|
||||
|
||||
```go
|
||||
type BuildPlan struct {
|
||||
// Kind represents the type of the resource.
|
||||
Kind string `json:"kind" cue:"\"BuildPlan\""`
|
||||
// APIVersion represents the versioned schema of the resource.
|
||||
APIVersion string `json:"apiVersion" cue:"string | *\"v1alpha5\""`
|
||||
// Metadata represents data about the resource such as the Name.
|
||||
Metadata Metadata `json:"metadata"`
|
||||
// Spec specifies the desired state of the resource.
|
||||
Spec BuildPlanSpec `json:"spec"`
|
||||
// Source reflects the origin of the BuildPlan.
|
||||
Source BuildPlanSource `json:"source,omitempty"`
|
||||
}
|
||||
```
|
||||
|
||||
<a name="BuildPlanSource"></a>
|
||||
## type BuildPlanSource {#BuildPlanSource}
|
||||
|
||||
BuildPlanSource reflects the origin of a [BuildPlan](<#BuildPlan>). Useful to save a build plan to a file, then re\-generate it without needing to process a [Platform](<#Platform>) component collection.
|
||||
|
||||
```go
|
||||
type BuildPlanSource struct {
|
||||
// Component reflects the component that produced the build plan.
|
||||
Component Component `json:"component,omitempty"`
|
||||
}
|
||||
```
|
||||
|
||||
<a name="BuildPlanSpec"></a>
|
||||
## type BuildPlanSpec {#BuildPlanSpec}
|
||||
|
||||
BuildPlanSpec represents the specification of the [BuildPlan](<#BuildPlan>).
|
||||
|
||||
```go
|
||||
type BuildPlanSpec struct {
|
||||
// Artifacts represents the artifacts for holos to build.
|
||||
Artifacts []Artifact `json:"artifacts"`
|
||||
// Disabled causes the holos cli to disregard the build plan.
|
||||
Disabled bool `json:"disabled,omitempty"`
|
||||
}
|
||||
```
|
||||
|
||||
<a name="Chart"></a>
|
||||
## type Chart {#Chart}
|
||||
|
||||
Chart represents a [Helm](<#Helm>) Chart.
|
||||
|
||||
```go
|
||||
type Chart struct {
|
||||
// Name represents the chart name.
|
||||
Name string `json:"name"`
|
||||
// Version represents the chart version.
|
||||
Version string `json:"version"`
|
||||
// Release represents the chart release when executing helm template.
|
||||
Release string `json:"release"`
|
||||
// Repository represents the repository to fetch the chart from.
|
||||
Repository Repository `json:"repository,omitempty"`
|
||||
}
|
||||
```
|
||||
|
||||
<a name="Component"></a>
|
||||
## type Component {#Component}
|
||||
|
||||
Component represents the complete context necessary to produce a [BuildPlan](<#BuildPlan>) from a path containing parameterized CUE configuration.
|
||||
|
||||
```go
|
||||
type Component struct {
|
||||
// Name represents the name of the component. Injected as the tag variable
|
||||
// "holos_component_name".
|
||||
Name string `json:"name"`
|
||||
// Path represents the path of the component relative to the platform root.
|
||||
// Injected as the tag variable "holos_component_path".
|
||||
Path string `json:"path"`
|
||||
// WriteTo represents the holos render component --write-to flag. If empty,
|
||||
// the default value for the --write-to flag is used.
|
||||
WriteTo string `json:"writeTo,omitempty"`
|
||||
// Parameters represent user defined input variables to produce various
|
||||
// [BuildPlan] resources from one component path. Injected as CUE @tag
|
||||
// variables. Parameters with a "holos_" prefix are reserved for use by the
|
||||
// Holos Authors. Multiple environments are a prime example of an input
|
||||
// parameter that should always be user defined, never defined by Holos.
|
||||
Parameters map[string]string `json:"parameters,omitempty"`
|
||||
}
|
||||
```
|
||||
|
||||
<a name="File"></a>
|
||||
## type File {#File}
|
||||
|
||||
File represents a simple single file copy [Generator](<#Generator>). Useful with a [Kustomize](<#Kustomize>) [Transformer](<#Transformer>) to process plain manifest files stored in the component directory. Multiple File generators may be used to transform multiple resources.
|
||||
|
||||
```go
|
||||
type File struct {
|
||||
// Source represents a file sub-path relative to the component path.
|
||||
Source FilePath `json:"source"`
|
||||
}
|
||||
```
|
||||
|
||||
<a name="FileContent"></a>
|
||||
## type FileContent {#FileContent}
|
||||
|
||||
FileContent represents file contents.
|
||||
|
||||
```go
|
||||
type FileContent string
|
||||
```
|
||||
|
||||
<a name="FileContentMap"></a>
|
||||
## type FileContentMap {#FileContentMap}
|
||||
|
||||
FileContentMap represents a mapping of file paths to file contents.
|
||||
|
||||
```go
|
||||
type FileContentMap map[FilePath]FileContent
|
||||
```
|
||||
|
||||
<a name="FilePath"></a>
|
||||
## type FilePath {#FilePath}
|
||||
|
||||
FilePath represents a file path.
|
||||
|
||||
```go
|
||||
type FilePath string
|
||||
```
|
||||
|
||||
<a name="Generator"></a>
|
||||
## type Generator {#Generator}
|
||||
|
||||
Generator generates Kubernetes resources. [Helm](<#Helm>) and [Resources](<#Resources>) are the most commonly used, often paired together to mix\-in resources to an unmodified Helm chart. A simple [File](<#File>) generator is also available for use with the [Kustomize](<#Kustomize>) transformer.
|
||||
|
||||
Each Generator in an [Artifact](<#Artifact>) must have a distinct Output value for a [Transformer](<#Transformer>) to reference.
|
||||
|
||||
1. [Resources](<#Resources>) \- Generates resources from CUE code.
|
||||
2. [Helm](<#Helm>) \- Generates rendered yaml from a [Chart](<#Chart>).
|
||||
3. [File](<#File>) \- Generates data by reading a file from the component directory.
|
||||
|
||||
```go
|
||||
type Generator struct {
|
||||
// Kind represents the kind of generator. Must be Resources, Helm, or File.
|
||||
Kind string `json:"kind" cue:"\"Resources\" | \"Helm\" | \"File\""`
|
||||
// Output represents a file for a Transformer or Artifact to consume.
|
||||
Output FilePath `json:"output"`
|
||||
// Resources generator. Ignored unless kind is Resources. Resources are
|
||||
// stored as a two level struct. The top level key is the Kind of resource,
|
||||
// e.g. Namespace or Deployment. The second level key is an arbitrary
|
||||
// InternalLabel. The third level is a map[string]any representing the
|
||||
// Resource.
|
||||
Resources Resources `json:"resources,omitempty"`
|
||||
// Helm generator. Ignored unless kind is Helm.
|
||||
Helm Helm `json:"helm,omitempty"`
|
||||
// File generator. Ignored unless kind is File.
|
||||
File File `json:"file,omitempty"`
|
||||
}
|
||||
```
|
||||
|
||||
<a name="Helm"></a>
|
||||
## type Helm {#Helm}
|
||||
|
||||
Helm represents a [Chart](<#Chart>) manifest [Generator](<#Generator>).
|
||||
|
||||
```go
|
||||
type Helm struct {
|
||||
// Chart represents a helm chart to manage.
|
||||
Chart Chart `json:"chart"`
|
||||
// Values represents values for holos to marshal into values.yaml when
|
||||
// rendering the chart.
|
||||
Values Values `json:"values"`
|
||||
// EnableHooks enables helm hooks when executing the `helm template` command.
|
||||
EnableHooks bool `json:"enableHooks,omitempty"`
|
||||
// Namespace represents the helm namespace flag
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
// APIVersions represents the helm template --api-versions flag
|
||||
APIVersions []string `json:"apiVersions,omitempty"`
|
||||
// KubeVersion represents the helm template --kube-version flag
|
||||
KubeVersion string `json:"kubeVersion,omitempty"`
|
||||
}
|
||||
```
|
||||
|
||||
<a name="InternalLabel"></a>
|
||||
## type InternalLabel {#InternalLabel}
|
||||
|
||||
InternalLabel is an arbitrary unique identifier internal to holos itself. The holos cli is expected to never write a InternalLabel value to rendered output files, therefore use a InternalLabel when the identifier must be unique and internal. Defined as a type for clarity and type checking.
|
||||
|
||||
```go
|
||||
type InternalLabel string
|
||||
```
|
||||
|
||||
<a name="Join"></a>
|
||||
## type Join {#Join}
|
||||
|
||||
Join represents a [Transformer](<#Transformer>) using [bytes.Join](<https://pkg.go.dev/bytes#Join>) to concatenate multiple inputs into one output with a separator. Useful for combining output from [Helm](<#Helm>) and [Resources](<#Resources>) together into one [Artifact](<#Artifact>) when [Kustomize](<#Kustomize>) is otherwise unnecessary.
|
||||
|
||||
```go
|
||||
type Join struct {
|
||||
Separator string `json:"separator" cue:"string | *\"---\\n\""`
|
||||
}
|
||||
```
|
||||
|
||||
<a name="Kind"></a>
|
||||
## type Kind {#Kind}
|
||||
|
||||
Kind is a discriminator. Defined as a type for clarity and type checking.
|
||||
|
||||
```go
|
||||
type Kind string
|
||||
```
|
||||
|
||||
<a name="Kustomization"></a>
|
||||
## type Kustomization {#Kustomization}
|
||||
|
||||
Kustomization represents a kustomization.yaml file for use with the [Kustomize](<#Kustomize>) [Transformer](<#Transformer>). Untyped to avoid tightly coupling holos to kubectl versions which was a problem for the Flux maintainers. Type checking is expected to happen in CUE against the kubectl version the user prefers.
|
||||
|
||||
```go
|
||||
type Kustomization map[string]any
|
||||
```
|
||||
|
||||
<a name="Kustomize"></a>
|
||||
## type Kustomize {#Kustomize}
|
||||
|
||||
Kustomize represents a kustomization [Transformer](<#Transformer>).
|
||||
|
||||
```go
|
||||
type Kustomize struct {
|
||||
// Kustomization represents the decoded kustomization.yaml file
|
||||
Kustomization Kustomization `json:"kustomization"`
|
||||
// Files holds file contents for kustomize, e.g. patch files.
|
||||
Files FileContentMap `json:"files,omitempty"`
|
||||
}
|
||||
```
|
||||
|
||||
<a name="Metadata"></a>
|
||||
## type Metadata {#Metadata}
|
||||
|
||||
Metadata represents data about the resource such as the Name.
|
||||
|
||||
```go
|
||||
type Metadata struct {
|
||||
// Name represents the resource name.
|
||||
Name string `json:"name"`
|
||||
}
|
||||
```
|
||||
|
||||
<a name="Platform"></a>
|
||||
## type Platform {#Platform}
|
||||
|
||||
Platform represents a platform to manage. A Platform specifies a [Component](<#Component>) collection and integrates the components together into a holistic platform. Holos iterates over the [Component](<#Component>) collection producing a [BuildPlan](<#BuildPlan>) for each, which holos then executes to render manifests.
|
||||
|
||||
Inspect a Platform resource holos would process by executing:
|
||||
|
||||
```
|
||||
cue export --out yaml ./platform
|
||||
```
|
||||
|
||||
```go
|
||||
type Platform struct {
|
||||
// Kind is a string value representing the resource.
|
||||
Kind string `json:"kind" cue:"\"Platform\""`
|
||||
// APIVersion represents the versioned schema of this resource.
|
||||
APIVersion string `json:"apiVersion" cue:"string | *\"v1alpha5\""`
|
||||
// Metadata represents data about the resource such as the Name.
|
||||
Metadata Metadata `json:"metadata"`
|
||||
|
||||
// Spec represents the platform specification.
|
||||
Spec PlatformSpec `json:"spec"`
|
||||
}
|
||||
```
|
||||
|
||||
<a name="PlatformSpec"></a>
|
||||
## type PlatformSpec {#PlatformSpec}
|
||||
|
||||
PlatformSpec represents the platform specification.
|
||||
|
||||
```go
|
||||
type PlatformSpec struct {
|
||||
// Components represents a collection of holos components to manage.
|
||||
Components []Component `json:"components"`
|
||||
}
|
||||
```
|
||||
|
||||
<a name="Repository"></a>
|
||||
## type Repository {#Repository}
|
||||
|
||||
Repository represents a [Helm](<#Helm>) [Chart](<#Chart>) repository.
|
||||
|
||||
```go
|
||||
type Repository struct {
|
||||
Name string `json:"name"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
```
|
||||
|
||||
<a name="Resource"></a>
|
||||
## type Resource {#Resource}
|
||||
|
||||
Resource represents one kubernetes api object.
|
||||
|
||||
```go
|
||||
type Resource map[string]any
|
||||
```
|
||||
|
||||
<a name="Resources"></a>
|
||||
## type Resources {#Resources}
|
||||
|
||||
Resources represents Kubernetes resources. Most commonly used to mix resources into the [BuildPlan](<#BuildPlan>) generated from CUE, but may be generated from elsewhere.
|
||||
|
||||
```go
|
||||
type Resources map[Kind]map[InternalLabel]Resource
|
||||
```
|
||||
|
||||
<a name="Transformer"></a>
|
||||
## type Transformer {#Transformer}
|
||||
|
||||
Transformer combines multiple inputs from prior [Generator](<#Generator>) or [Transformer](<#Transformer>) outputs into one output. [Kustomize](<#Kustomize>) is the most commonly used transformer. A simple [Join](<#Join>) is also supported for use with plain manifest files.
|
||||
|
||||
1. [Kustomize](<#Kustomize>) \- Patch and transform the output from prior generators or transformers. See [Introduction to Kustomize](<https://kubectl.docs.kubernetes.io/guides/config_management/introduction/>).
|
||||
2. [Join](<#Join>) \- Concatenate multiple prior outputs into one output.
|
||||
|
||||
```go
|
||||
type Transformer struct {
|
||||
// Kind represents the kind of transformer. Must be Kustomize, or Join.
|
||||
Kind string `json:"kind" cue:"\"Kustomize\" | \"Join\""`
|
||||
// Inputs represents the files to transform. The Output of prior Generators
|
||||
// and Transformers.
|
||||
Inputs []FilePath `json:"inputs"`
|
||||
// Output represents a file for a subsequent Transformer or Artifact to
|
||||
// consume.
|
||||
Output FilePath `json:"output"`
|
||||
// Kustomize transformer. Ignored unless kind is Kustomize.
|
||||
Kustomize Kustomize `json:"kustomize,omitempty"`
|
||||
// Join transformer. Ignored unless kind is Join.
|
||||
Join Join `json:"join,omitempty"`
|
||||
}
|
||||
```
|
||||
|
||||
<a name="Values"></a>
|
||||
## type Values {#Values}
|
||||
|
||||
Values represents [Helm](<#Helm>) Chart values generated from CUE.
|
||||
|
||||
```go
|
||||
type Values map[string]any
|
||||
```
|
||||
|
||||
Generated by [gomarkdoc](<https://github.com/princjef/gomarkdoc>)
|
||||
|
||||
26
doc/md/support.mdx
Normal file
@@ -0,0 +1,26 @@
|
||||
---
|
||||
description: Get Support for Holos
|
||||
slug: support
|
||||
sidebar_position: 2000
|
||||
---
|
||||
|
||||
# Support
|
||||
|
||||
## Community Support
|
||||
|
||||
You can ask questions in our community forums in [GitHub
|
||||
Discussions](https://github.com/holos-run/holos/discussions),
|
||||
[Discord](https://discord.gg/JgDVbNpye7), or [Google
|
||||
Groups](https://groups.google.com/g/holos-discuss).
|
||||
|
||||
## Commercial Support and Services
|
||||
|
||||
### Open Infrastructure Services
|
||||
|
||||
[Open Infrastructure Services] are the primary stewards of Holos. Contact Open
|
||||
Infrastructure Services for training, support, and services related to Holos,
|
||||
platform engineering, and cloud infrastructure automation.
|
||||
|
||||
Please email holos-support@openinfrastructure.co for more information.
|
||||
|
||||
[Open Infrastructure Services]: https://openinfrastructure.co/
|
||||
15
doc/md/topics.mdx
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
slug: /topics
|
||||
title: Topics
|
||||
description: Stand alone topics that often come up when using Holos.
|
||||
---
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
|
||||
# Topics
|
||||
|
||||
This section has self-contained articles related to various topics that come up
|
||||
when writing platform configuration code with Holos.
|
||||
|
||||
---
|
||||
|
||||
<DocCardList />
|
||||
18
doc/md/topics/architecture.mdx
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
description: Architecture diagrams.
|
||||
slug: architecture
|
||||
sidebar_position: 90
|
||||
---
|
||||
|
||||
import RenderPlatformDiagram from '@site/src/diagrams/render-platform-sequence.mdx';
|
||||
import RenderComponentDiagram from '@site/src/diagrams/render-component-sequence.mdx';
|
||||
|
||||
# Architecture
|
||||
|
||||
## Platform Rendering Sequence
|
||||
|
||||
<RenderPlatformDiagram />
|
||||
|
||||
## Component Rendering Sequence
|
||||
|
||||
<RenderComponentDiagram />
|
||||