Compare commits

..

1 Commits

Author SHA1 Message Date
Jeff McCune
27e5846a4c Changes we discuessed at Zipper on 7/17 2024-07-18 07:57:47 -07:00
1178 changed files with 159461 additions and 167680 deletions

View File

@@ -5,157 +5,48 @@
"mdx"
],
"words": [
"admissionregistration",
"apiextensions",
"applicationset",
"argoproj",
"authcode",
"authorizationpolicies",
"authpolicy",
"authproxy",
"authroutes",
"buildplan",
"cainjector",
"CAROOT",
"certificaterequests",
"certificatesigningrequests",
"clsx",
"clusterissuer",
"clusterissuers",
"clusterrole",
"clusterrolebinding",
"configmap",
"cookiesecret",
"coredns",
"corev",
"CRD's",
"crds",
"creds",
"crossplane",
"cuecontext",
"cuelang",
"customresourcedefinition",
"daemonset",
"destinationrules",
"devicecode",
"dnsmasq",
"dscacheutil",
"entgo",
"envoyfilters",
"errgroup",
"fctr",
"fieldmaskpb",
"flushcache",
"gatewayclasses",
"gendoc",
"ggnpl",
"ghaction",
"gitops",
"godoc",
"golangci",
"goreleaser",
"grpcreflect",
"grpcroutes",
"grpcurl",
"holos",
"holoslogger",
"horizontalpodautoscaler",
"httpbin",
"httproute",
"httproutes",
"Infima",
"isatty",
"istiod",
"jbrx",
"jetstack",
"Jsonnet",
"killall",
"kubeadm",
"kubeconfig",
"kubelogin",
"Kustomization",
"Kustomizations",
"kustomize",
"ldflags",
"leaderelection",
"libnss",
"loadbalancer",
"mattn",
"mccutchen",
"mindmap",
"mktemp",
"msqbn",
"mtls",
"Multicluster",
"mutatingwebhookconfiguration",
"mxcl",
"myhostname",
"nameserver",
"organizationconnect",
"orgid",
"otelconnect",
"Parentspanid",
"pcjc",
"peerauthentications",
"pflag",
"pipefail",
"PKCE",
"platformconnect",
"poddisruptionbudget",
"podinfo",
"portmapping",
"promhttp",
"protobuf",
"protojson",
"proxyconfigs",
"Pulumi",
"putenv",
"qjbp",
"quickstart",
"referencegrant",
"referencegrants",
"requestauthentications",
"retryable",
"rolebinding",
"ropc",
"seccomp",
"SECRETKEY",
"secretstores",
"serverlb",
"serverside",
"serviceaccount",
"serviceentries",
"spanid",
"spiffe",
"startupapicheck",
"stefanprodan",
"structpb",
"subjectaccessreviews",
"svclb",
"systemconnect",
"tablewriter",
"Tiltfile",
"timestamppb",
"Timoni",
"tlsclientconfig",
"tokencache",
"Tokener",
"Traceid",
"traefik",
"uibutton",
"untar",
"Upsert",
"urandom",
"usecases",
"userconnect",
"userdata",
"validatingwebhookconfiguration",
"virtualservices",
"wasmplugins",
"workloadentries",
"workloadgroups",
"zerolog",
"zitadel",
"ztunnel"
"zitadel"
]
}

View File

@@ -1,57 +0,0 @@
name: Dev Deploy
on:
push:
branches: ['main', 'dev-deploy']
jobs:
deploy:
name: Deploy
runs-on: ubuntu-latest
steps:
## Not needed on ubuntu-latest
# - name: Provide GPG and Git
# run: sudo apt update && sudo apt -qq -y install gnupg git curl zip unzip tar bzip2 make jq
## Not needed on ubuntu-latest
# - name: Provide Holos Dependencies
# run: |
# sudo mkdir -p -m 755 /etc/apt/keyrings
# curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
# sudo chmod 644 /etc/apt/keyrings/kubernetes-apt-keyring.gpg
# echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
# sudo chmod 644 /etc/apt/sources.list.d/kubernetes.list
# sudo apt update
# sudo apt install -qq -y kubectl
# curl -fsSL -o- https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
# Must come after git executable is provided
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-go@v5
with:
go-version: '1.22.x'
- uses: ko-build/setup-ko@v0.7
env:
KO_DOCKER_REPO: quay.io/holos-run/holos
- name: Setup SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.DEPLOY_SSH_PRIVATE_KEY }}" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
ssh-keyscan github.com >> ~/.ssh/known_hosts
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
- name: make dev-deploy
env:
auth_user: holos-run+pusher
auth_token: ${{ secrets.QUAY_TOKEN }}
run: |
echo "${auth_token}" | ko login quay.io --username "${auth_user}" --password-stdin
make dev-deploy

View File

@@ -1,30 +0,0 @@
name: golangci-lint
on:
push:
branches:
- main
- test
pull_request:
types: [opened, synchronize]
permissions:
# Required: allow read access to the content for analysis.
contents: read
# Optional: allow read access to pull request. Use with `only-new-issues` option.
pull-requests: read
# Optional: allow write access to checks to allow the action to annotate code in the PR.
checks: write
jobs:
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: stable
- name: golangci-lint
uses: golangci/golangci-lint-action@v6
with:
version: v1.60

View File

@@ -13,9 +13,9 @@ permissions:
contents: read
jobs:
lint:
golangci:
name: lint
runs-on: ubuntu-latest
runs-on: gha-rs
steps:
- name: Checkout code
uses: actions/checkout@v4
@@ -30,13 +30,16 @@ jobs:
with:
go-version: stable
## Not needed on ubuntu-latest
# - name: Install Packages
# run: sudo apt update && sudo apt -qq -y install git curl zip unzip tar bzip2 make
- name: Install Packages
run: sudo apt update && sudo apt -qq -y install git curl zip unzip tar bzip2 make
- name: Install Tools
run: make tools
run: |
set -x
make tools
- name: Lint
# golangci-lint runs in a separate workflow.
run: make lint -o golangci-lint
- name: golangci-lint
uses: golangci/golangci-lint-action@v4
with:
version: latest
skip-pkg-cache: true

View File

@@ -12,12 +12,11 @@ permissions:
jobs:
goreleaser:
runs-on: ubuntu-latest
runs-on: gha-rs
steps:
## Not needed on ubuntu-latest
# Must come before Checkout, otherwise goreleaser fails
# - name: Provide GPG and Git
# run: sudo apt update && sudo apt -qq -y install gnupg git curl zip unzip tar bzip2 make
- name: Provide GPG and Git
run: sudo apt update && sudo apt -qq -y install gnupg git curl zip unzip tar bzip2 make
# Must come after git executable is provided
- name: Checkout

2
.gitignore vendored
View File

@@ -1,4 +1,5 @@
/bin/
vendor/
.idea/
coverage.out
/dist/
@@ -6,7 +7,6 @@ coverage.out
/deploy/
.vscode/
tmp/
.DS_*
# In case we run through the tutorial in this directory.
/holos-k3d/

View File

@@ -1,13 +0,0 @@
# Refer to https://ko.build/configuration/#overriding-go-build-settings
builds:
- id: holos
dir: .
main: ./cmd/holos
env:
- GOPRIVATE=github.com/holos-run/\*
ldflags:
- -s
- -w
- -X
# Makefile provides GIT_DETAIL and GIT_SUFFIX.
- github.com/holos-run/holos/version.GitDescribe={{.Env.GIT_DETAIL}}{{.Env.GIT_SUFFIX}}

View File

@@ -48,16 +48,13 @@ bumpmajor: ## Bump the major version.
show-version: ## Print the full version.
@echo $(VERSION)
.PHONY: tag
tag: ## Tag a release
git tag v$(VERSION)
.PHONY: tidy
tidy: ## Tidy go module.
go mod tidy
.PHONY: fmt
fmt: ## Format code.
cd docs/examples && cue fmt ./...
cd internal/generate/platforms && cue fmt ./...
go fmt ./...
@@ -92,14 +89,11 @@ clean: ## Clean executables.
test: ## Run tests.
scripts/test
.PHONY: golangci-lint
golangci-lint:
golangci-lint run
.PHONY: lint
lint: golangci-lint ## Run linters.
lint: ## Run linters.
buf lint
cd internal/frontend/holos && ng lint
golangci-lint run
./hack/cspell
.PHONY: coverage
@@ -123,28 +117,25 @@ go-deps: ## tool versions pinned in tools.go
go install honnef.co/go/tools/cmd/staticcheck
go install golang.org/x/tools/cmd/godoc
go install github.com/princjef/gomarkdoc/cmd/gomarkdoc
go install github.com/google/ko
# curl https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | bash
.PHONY: frontend-deps
frontend-deps: ## Install Angular deps for go generate
cd internal/frontend/holos && npm install
cd internal/frontend/holos && npm install --save-dev @bufbuild/buf @connectrpc/protoc-gen-connect-es
cd internal/frontend/holos && npm install @connectrpc/connect @connectrpc/connect-web @bufbuild/protobuf
# https://github.com/connectrpc/connect-query-es/blob/1350b6f07b6aead81793917954bdb1cc3ce09df9/packages/protoc-gen-connect-query/README.md?plain=1#L23
cd internal/frontend/holos && npm install --save-dev @connectrpc/protoc-gen-connect-query @bufbuild/protoc-gen-es
cd internal/frontend/holos && npm install @connectrpc/connect-query @bufbuild/protobuf
.PHONY: website-deps
website-deps: ## Install Docusaurus deps for go generate
cd doc/website && npm install
.PHONY: image # refer to .ko.yaml as well
image: ## Container image build for workflows/publish.yaml
KO_DOCKER_REPO=$(DOCKER_REPO) GIT_DETAIL=$(GIT_DETAIL) GIT_SUFFIX=$(GIT_SUFFIX) ko build --platform=all --bare ./cmd/holos --tags $(GIT_DETAIL)$(GIT_SUFFIX) --tags latest
.PHONY: prod-deploy
prod-deploy: install image ## deploy to PROD
GIT_DETAIL=$(GIT_DETAIL) GIT_SUFFIX=$(GIT_SUFFIX) bash ./hack/deploy
.PHONY: dev-deploy
dev-deploy: install image ## deploy to dev
GIT_DETAIL=$(GIT_DETAIL) GIT_SUFFIX=$(GIT_SUFFIX) bash ./hack/deploy-dev
.PHONY: image
image: build ## Docker image build
docker build . -t ${DOCKER_REPO}:v$(shell ./bin/holos --version)
docker push ${DOCKER_REPO}:v$(shell ./bin/holos --version)
.PHONY: website
website: ## Build website

View File

@@ -1,4 +1,4 @@
## Holos - A Holistic Development Platform
## Holos - A Holostic Development Platform
<img width="50%"
align="right"
@@ -9,27 +9,24 @@ Building and maintaining a software development platform is a complex and time
consuming endeavour. Organizations often dedicate a team of 3-4 who need 6-12
months to build the platform.
Holos is a tool and a reference platform to reduce the complexity and speed up
Holos is a tool and a reference platform to reduce the compexity and speed up
the process of building a modern, cloud native software development platform.
- **Accelerate new projects** - Reduce time to market and operational complexity by starting your new project on top of the Holos reference platform.
- **Modernize existing projects** - Incrementally incorporate your existing platform services into Holos for simpler integration.
- **Unified configuration model** - Increase safety and reduce the risk of config changes with CUE.
- **First class Helm and Kustomize support** - Leverage and reuse your existing investment in existing configuration tools such as Helm and Kustomize.
- **Modern Authentication and Authorization** - Holos seamlessly integrates platform identity and access management with zero-trust beyond corp style authorization policy.
- **Accelerate new projects** - Reduce time to market and operational complexity by starting your new project on top of the Holos reference platform.
- **Modernize existing projects** - Incrementally incorporate your existing platform services into Holos for simpler integration.
- **Unified configuration model** - Increase safety and reduce the risk of config changes with CUE.
- **First class Helm and Kustomize support** - Leverage and reuse your existing investment in existing configuration tools such as Helm and Kustomize.
- **Modern Authentication and Authorization** - Holos seamlessly integrates platform identity and access mangement with zero-trust beyond corp style authorization policy.
## Quick Installation
```console
go install github.com/holos-run/holos/cmd/holos@latest
```
## Docs and Support
The documentation for developing and using Holos is available at: https://holos.run
The documentation for developing and using Holos is avaialble at: https://holos.run
For discussion and support, [open a discussion](https://github.com/orgs/holos-run/discussions/new/choose).
## License
Holos is licensed under Apache 2.0 as found in the [LICENSE file](LICENSE).

View File

@@ -9,7 +9,7 @@ if os.getenv('TILT_WRAPPER') != '1':
fail("could not run, ./hack/tilt/bin/tilt was not used to start tilt")
# Resource ids
holos_backend = 'Holos Server'
holos_backend = 'Holos Backend'
compile_id = 'Go Build'
# Default Registry.
@@ -61,10 +61,8 @@ docker_build_with_restart(
entrypoint=[
'/app/bin/holos.linux',
'server',
'--log-format=text',
'--oidc-issuer=https://login.holos.run',
'--oidc-audience=275804490387516853@holos_quickstart', # auth proxy
'--oidc-audience=270319630705329162@holos_platform', # holos cli
'--oidc-audience=275571128859132936',
],
dockerfile='./Dockerfile',
only=['./bin'],

View File

@@ -1,47 +0,0 @@
package v1alpha3
import "google.golang.org/protobuf/types/known/structpb"
// 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.
//
// A InternalLabel is useful to convert a CUE struct to a list, for example
// producing a list of [APIObject] resources from an [APIObjectMap]. A CUE
// struct using InternalLabel keys is guaranteed to not lose data when rendering
// output because a InternalLabel is expected to never be written to the final
// output.
type InternalLabel string
// Kind is a kubernetes api object kind. Defined as a type for clarity and type
// checking.
type Kind string
// APIObject represents the most basic generic form of a single kubernetes api
// object. Represented as a JSON object internally for compatibility between
// tools, for example loading from CUE.
type APIObject structpb.Struct
// APIObjectMap represents the marshalled yaml representation of kubernetes api
// objects. Do not produce an APIObjectMap directly, instead use [APIObjects]
// to produce the marshalled yaml representation from CUE data, then provide the
// result to [Component].
type APIObjectMap map[Kind]map[InternalLabel]string
// APIObjects represents Kubernetes API objects defined directly from CUE code.
// Useful to mix in resources to any kind of [Component], for example
// adding an ExternalSecret resource to a [HelmChart].
//
// [Kind] must be the resource kind, e.g. Deployment or Service.
//
// [InternalLabel] is an arbitrary internal identifier to uniquely identify the resource
// within the context of a `holos` command. Holos will never write the
// intermediate label to rendered output.
//
// Refer to [Component] which accepts an [APIObjectMap] field provided by
// [APIObjects].
type APIObjects struct {
APIObjects map[Kind]map[InternalLabel]APIObject `json:"apiObjects"`
APIObjectMap APIObjectMap `json:"apiObjectMap"`
}

View File

@@ -1,52 +0,0 @@
package v1alpha3
// FilePath represents a file path.
type FilePath string
// FileContent represents file contents.
type FileContent string
// FileContentMap represents a mapping of file paths to file contents.
type FileContentMap map[FilePath]FileContent
// BuildPlan represents a build plan for the holos cli to execute. The purpose
// of a BuildPlan is to define one or more [Component] kinds. For example a
// [HelmChart], [KustomizeBuild], or [KubernetesObjects].
//
// A BuildPlan usually has an additional empty [KubernetesObjects] for the
// purpose of using the [Component] DeployFiles field to deploy an ArgoCD
// or Flux gitops resource for the holos component.
type BuildPlan struct {
Kind string `json:"kind" cue:"\"BuildPlan\""`
APIVersion string `json:"apiVersion" cue:"string | *\"v1alpha3\""`
Spec BuildPlanSpec `json:"spec"`
}
// BuildPlanSpec represents the specification of the build plan.
type BuildPlanSpec struct {
// Disabled causes the holos cli to take no action over the [BuildPlan].
Disabled bool `json:"disabled,omitempty"`
// Components represents multiple [HolosComponent] kinds to manage.
Components BuildPlanComponents `json:"components,omitempty"`
}
type BuildPlanComponents struct {
Resources map[InternalLabel]KubernetesObjects `json:"resources,omitempty"`
KubernetesObjectsList []KubernetesObjects `json:"kubernetesObjectsList,omitempty"`
HelmChartList []HelmChart `json:"helmChartList,omitempty"`
KustomizeBuildList []KustomizeBuild `json:"kustomizeBuildList,omitempty"`
}
// Kustomize represents resources necessary to execute a kustomize build.
// Intended for at least two use cases:
//
// 1. Process a [KustomizeBuild] [Component] which represents raw yaml
// file resources in a holos component directory.
// 2. Post process a [HelmChart] [Component] to inject istio, patch jobs,
// add custom labels, etc...
type Kustomize struct {
// KustomizeFiles holds file contents for kustomize, e.g. patch files.
KustomizeFiles FileContentMap `json:"kustomizeFiles,omitempty"`
// ResourcesFile is the file name used for api objects in kustomization.yaml
ResourcesFile string `json:"resourcesFile,omitempty"`
}

View File

@@ -1,43 +0,0 @@
package v1alpha3
// Component defines the fields common to all holos component kinds. Every
// holos component kind should embed Component.
type Component struct {
// Kind is a string value representing the resource this object represents.
Kind string `json:"kind"`
// APIVersion represents the versioned schema of this representation of an object.
APIVersion string `json:"apiVersion" cue:"\"v1alpha3\""`
// Metadata represents data about the holos component such as the Name.
Metadata Metadata `json:"metadata"`
// APIObjectMap holds the marshalled representation of api objects. Useful to
// mix in resources to each Component type, for example adding an
// ExternalSecret to a [HelmChart] Component. Refer to [APIObjects].
APIObjectMap APIObjectMap `json:"apiObjectMap,omitempty"`
// DeployFiles represents file paths relative to the cluster deploy directory
// with the value representing the file content. Intended for defining the
// ArgoCD Application resource or Flux Kustomization resource from within CUE,
// but may be used to render any file related to the build plan from CUE.
DeployFiles FileContentMap `json:"deployFiles,omitempty"`
// Kustomize represents a kubectl kustomize build post-processing step.
Kustomize `json:"kustomize,omitempty"`
// Skip causes holos to take no action regarding this component.
Skip bool `json:"skip" cue:"bool | *false"`
}
// Metadata represents data about the object such as the Name.
type Metadata struct {
// Name represents the name of the holos component.
Name string `json:"name"`
// Namespace is the primary namespace of the holos component. A holos
// component may manage resources in multiple namespaces, in this case
// consider setting the component namespace to default.
//
// This field is optional because not all resources require a namespace,
// particularly CRDs and DeployFiles functionality.
// +optional
Namespace string `json:"namespace,omitempty"`
}

View File

@@ -1,11 +0,0 @@
package v1alpha3
const (
APIVersion = "v1alpha3"
BuildPlanKind = "BuildPlan"
HelmChartKind = "HelmChart"
// ChartDir is the directory name created in the holos component directory to cache a chart.
ChartDir = "vendor"
// ResourcesFile is the file name used to store component output when post-processing with kustomize.
ResourcesFile = "resources.yaml"
)

View File

@@ -1,26 +0,0 @@
// Package v1alpha3 contains the core API contract between the holos cli and CUE
// configuration code. Platform designers, operators, and software developers
// use this API to write configuration in CUE which `holos` loads. The overall
// shape of the API defines imperative actions `holos` should carry out to
// render the complete yaml that represents a Platform.
//
// [Platform] defines the complete configuration of a platform. With the holos
// reference platform this takes the shape of one management cluster and at
// least two workload cluster. Each cluster has multiple [Component]
// resources applied to it.
//
// Each holos component path, e.g. `components/namespaces` produces exactly one
// [BuildPlan] which in turn contains a set of [Component] kinds.
//
// The primary kinds of [Component] are:
//
// 1. [HelmChart] to render config from a helm chart.
// 2. [KustomizeBuild] to render config from [Kustomize]
// 3. [KubernetesObjects] to render [APIObjects] defined directly in CUE
// configuration.
//
// Note that Holos operates as a data pipeline, so the output of a [HelmChart]
// may be provided to [Kustomize] for post-processing.
package v1alpha3
//go:generate ../../../hack/gendoc

View File

@@ -1,38 +0,0 @@
package v1alpha3
// HelmChart represents a holos component which wraps around an upstream helm
// chart. Holos orchestrates helm by providing values obtained from CUE,
// renders the output using `helm template`, then post-processes the helm output
// yaml using the general functionality provided by [Component], for
// example [Kustomize] post-rendering and mixing in additional kubernetes api
// objects.
type HelmChart struct {
Component `json:",inline"`
Kind string `json:"kind" cue:"\"HelmChart\""`
// Chart represents a helm chart to manage.
Chart Chart `json:"chart"`
// ValuesContent represents the values.yaml file holos passes to the `helm
// template` command.
ValuesContent string `json:"valuesContent"`
// EnableHooks enables helm hooks when executing the `helm template` command.
EnableHooks bool `json:"enableHooks" cue:"bool | *false"`
}
// 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"`
}

View File

@@ -1,10 +0,0 @@
package v1alpha3
const KubernetesObjectsKind = "KubernetesObjects"
// KubernetesObjects represents a [Component] composed of Kubernetes API
// objects provided directly from CUE using [APIObjects].
type KubernetesObjects struct {
Component `json:",inline"`
Kind string `json:"kind" cue:"\"KubernetesObjects\""`
}

View File

@@ -1,8 +0,0 @@
package v1alpha3
// KustomizeBuild represents a [Component] that renders plain yaml files in
// the holos component directory using `kubectl kustomize build`.
type KustomizeBuild struct {
Component `json:",inline"`
Kind string `json:"kind" cue:"\"KustomizeBuild\""`
}

View File

@@ -1,44 +0,0 @@
package v1alpha3
import "google.golang.org/protobuf/types/known/structpb"
// Platform represents a platform to manage. A Platform resource informs holos
// which components to build. The platform resource also acts as a container
// for the platform model form values provided by the PlatformService. The
// primary use case is to collect the cluster names, cluster types, platform
// model, and holos components to build into one resource.
type Platform struct {
// Kind is a string value representing the resource this object represents.
Kind string `json:"kind" cue:"\"Platform\""`
// APIVersion represents the versioned schema of this representation of an object.
APIVersion string `json:"apiVersion" cue:"string | *\"v1alpha3\""`
// Metadata represents data about the object such as the Name.
Metadata PlatformMetadata `json:"metadata"`
// Spec represents the specification.
Spec PlatformSpec `json:"spec"`
}
type PlatformMetadata struct {
// Name represents the Platform name.
Name string `json:"name"`
}
// PlatformSpec represents the specification of a Platform. Think of a platform
// specification as a list of platform components to apply to a list of
// kubernetes clusters combined with the user-specified Platform Model.
type PlatformSpec struct {
// Model represents the platform model holos gets from from the
// PlatformService.GetPlatform rpc method and provides to CUE using a tag.
Model structpb.Struct `json:"model" cue:"{...}"`
// Components represents a list of holos components to manage.
Components []PlatformSpecComponent `json:"components"`
}
// PlatformSpecComponent represents a holos component to build or render.
type PlatformSpecComponent struct {
// Path is the path of the component relative to the platform root.
Path string `json:"path"`
// Cluster is the cluster name to provide when rendering the component.
Cluster string `json:"cluster"`
}

View File

@@ -1,163 +0,0 @@
// Package v1alpha3 contains CUE definitions intended as convenience wrappers
// around the core data types defined in package core. The purpose of these
// wrappers is to make life easier for platform engineers by reducing boiler
// plate code and generating component build plans in a consistent manner.
package v1alpha3
import (
core "github.com/holos-run/holos/api/core/v1alpha3"
"google.golang.org/protobuf/types/known/structpb"
)
//go:generate ../../../hack/gendoc
// Component represents the fields common the different kinds of component. All
// components have a name, support mixing in resources, and produce a BuildPlan.
type ComponentFields struct {
// Name represents the Component name.
Name string
// Resources are kubernetes api objects to mix into the output.
Resources map[string]any
// ArgoConfig represents the ArgoCD GitOps configuration for this Component.
ArgoConfig ArgoConfig
// BuildPlan represents the derived BuildPlan for the Holos cli to render.
BuildPlan core.BuildPlan
}
// Helm provides a BuildPlan via the Output field which contains one HelmChart
// from package core. Useful as a convenience wrapper to render a HelmChart
// with optional mix-in resources and Kustomization post-processing.
type Helm struct {
ComponentFields `json:",inline"`
// Version represents the chart version.
Version string
// Namespace represents the helm namespace option when rendering the chart.
Namespace string
// Repo represents the chart repository
Repo struct {
Name string `json:"name"`
URL string `json:"url"`
}
// Values represents data to marshal into a values.yaml for helm.
Values interface{} `cue:"{...}"`
// Chart represents the derived HelmChart for inclusion in the BuildPlan
// Output field value. The default HelmChart field values are derived from
// other Helm field values and should be sufficient for most use cases.
Chart core.HelmChart
// EnableKustomizePostProcessor processes helm output with kustomize if true.
EnableKustomizePostProcessor bool `cue:"true | *false"`
// KustomizeFiles represents additional files to include in a Kustomization
// resources list. Useful to patch helm output. The implementation is a
// struct with filename keys and structs as values. Holos encodes the struct
// value to yaml then writes the result to the filename key. Component
// authors may then reference the filename in the kustomization.yaml resources
// or patches lists.
// Requires EnableKustomizePostProcessor: true.
KustomizeFiles map[string]any `cue:"{[string]: {...}}"`
// KustomizePatches represents patches to apply to the helm output. Requires
// EnableKustomizePostProcessor: true.
KustomizePatches map[core.InternalLabel]any `cue:"{[string]: {...}}"`
// KustomizeResources represents additional resources files to include in the
// kustomize resources list.
KustomizeResources map[string]any `cue:"{[string]: {...}}"`
}
// Kustomize provides a BuildPlan via the Output field which contains one
// KustomizeBuild from package core.
type Kustomize struct {
ComponentFields `json:",inline"`
// Kustomization represents the kustomize build plan for holos to render.
Kustomization core.KustomizeBuild
}
// Kubernetes provides a BuildPlan via the Output field which contains inline
// API Objects provided directly from CUE.
type Kubernetes struct {
ComponentFields `json:",inline"`
// Objects represents the kubernetes api objects for the Component.
Objects core.KubernetesObjects
}
// ArgoConfig represents the ArgoCD GitOps configuration for a Component.
// Useful to define once at the root of the Platform configuration and reuse
// across all Components.
type ArgoConfig struct {
// Enabled causes holos to render an ArgoCD Application resource for GitOps if true.
Enabled bool `cue:"true | *false"`
// ClusterName represents the cluster within the platform the Application
// resource is intended for.
ClusterName string
// DeployRoot represents the path from the git repository root to the `deploy`
// rendering output directory. Used as a prefix for the
// Application.spec.source.path field.
DeployRoot string `cue:"string | *\".\""`
// RepoURL represents the value passed to the Application.spec.source.repoURL
// field.
RepoURL string
// TargetRevision represents the value passed to the
// Application.spec.source.targetRevision field. Defaults to the branch named
// main.
TargetRevision string `cue:"string | *\"main\""`
// AppProject represents the ArgoCD Project to associate the Application with.
AppProject string `cue:"string | *\"default\""`
}
// Cluster represents a cluster managed by the Platform.
type Cluster struct {
// Name represents the cluster name, for example "east1", "west1", or
// "management".
Name string `json:"name"`
// Primary represents if the cluster is marked as the primary among a set of
// candidate clusters. Useful for promotion of database leaders.
Primary bool `json:"primary" cue:"true | *false"`
}
// Fleet represents a named collection of similarly configured Clusters. Useful
// to segregate workload clusters from their management cluster.
type Fleet struct {
Name string `json:"name"`
// Clusters represents a mapping of Clusters by their name.
Clusters map[string]Cluster `json:"clusters" cue:"{[Name=_]: name: Name}"`
}
// StandardFleets represents the standard set of Clusters in a Platform
// segmented into Fleets by their purpose. The management Fleet contains a
// single Cluster, for example a GKE autopilot cluster with no workloads
// deployed for reliability and cost efficiency. The workload Fleet contains
// all other Clusters which contain workloads and sync Secrets from the
// management cluster.
type StandardFleets struct {
// Workload represents a Fleet of zero or more workload Clusters.
Workload Fleet `json:"workload" cue:"{name: \"workload\"}"`
// Management represents a Fleet with one Cluster named management.
Management Fleet `json:"management" cue:"{name: \"management\"}"`
}
// Platform is a convenience structure to produce a core Platform specification
// value in the Output field. Useful to collect components at the root of the
// Platform configuration tree as a struct, which are automatically converted
// into a list for the core Platform spec output.
type Platform struct {
// Name represents the Platform name.
Name string `cue:"string | *\"holos\""`
// Components is a structured map of components to manage by their name.
Components map[string]core.PlatformSpecComponent
// Model represents the Platform model holos gets from from the
// PlatformService.GetPlatform rpc method and provides to CUE using a tag.
Model structpb.Struct `cue:"{...}"`
// Output represents the core Platform spec for the holos cli to iterate over
// and render each listed Component, injecting the Model.
Output core.Platform
// Domain represents the primary domain the Platform operates in. This field
// is intended as a sensible default for component authors to reference and
// platform operators to define.
Domain string `cue:"string | *\"holos.localhost\""`
}

View File

@@ -1,7 +1,6 @@
package v1alpha1
import (
"errors"
"fmt"
"strings"
)
@@ -39,7 +38,7 @@ func (bp *BuildPlan) Validate() error {
errs = append(errs, fmt.Sprintf("apiVersion invalid: want: %s have: %s", APIVersion, bp.APIVersion))
}
if len(errs) > 0 {
return errors.New("invalid BuildPlan: " + strings.Join(errs, ", "))
return fmt.Errorf("invalid BuildPlan: " + strings.Join(errs, ", "))
}
return nil
}

1
cue.mod/module.cue Normal file
View File

@@ -0,0 +1 @@
module: "github.com/holos-run/holos"

View File

@@ -1,5 +0,0 @@
import DocCardList from '@theme/DocCardList';
# API Reference
<DocCardList />

View File

@@ -1,5 +0,0 @@
import DocCardList from '@theme/DocCardList';
# Core API
<DocCardList />

View File

@@ -1,403 +0,0 @@
<!-- Code generated by gomarkdoc. DO NOT EDIT -->
# v1alpha3
```go
import "github.com/holos-run/holos/api/core/v1alpha3"
```
Package v1alpha3 contains the core API contract between the holos cli and CUE configuration code. Platform designers, operators, and software developers use this API to write configuration in CUE which \`holos\` loads. The overall shape of the API defines imperative actions \`holos\` should carry out to render the complete yaml that represents a Platform.
[Platform](<#Platform>) defines the complete configuration of a platform. With the holos reference platform this takes the shape of one management cluster and at least two workload cluster. Each cluster has multiple [Component](<#Component>) resources applied to it.
Each holos component path, e.g. \`components/namespaces\` produces exactly one [BuildPlan](<#BuildPlan>) which in turn contains a set of [Component](<#Component>) kinds.
The primary kinds of [Component](<#Component>) are:
1. [HelmChart](<#HelmChart>) to render config from a helm chart.
2. [KustomizeBuild](<#KustomizeBuild>) to render config from [Kustomize](<#Kustomize>)
3. [KubernetesObjects](<#KubernetesObjects>) to render [APIObjects](<#APIObjects>) defined directly in CUE configuration.
Note that Holos operates as a data pipeline, so the output of a [HelmChart](<#HelmChart>) may be provided to [Kustomize](<#Kustomize>) for post\-processing.
## Index
- [Constants](<#constants>)
- [type APIObject](<#APIObject>)
- [type APIObjectMap](<#APIObjectMap>)
- [type APIObjects](<#APIObjects>)
- [type BuildPlan](<#BuildPlan>)
- [type BuildPlanComponents](<#BuildPlanComponents>)
- [type BuildPlanSpec](<#BuildPlanSpec>)
- [type Chart](<#Chart>)
- [type Component](<#Component>)
- [type FileContent](<#FileContent>)
- [type FileContentMap](<#FileContentMap>)
- [type FilePath](<#FilePath>)
- [type HelmChart](<#HelmChart>)
- [type InternalLabel](<#InternalLabel>)
- [type Kind](<#Kind>)
- [type KubernetesObjects](<#KubernetesObjects>)
- [type Kustomize](<#Kustomize>)
- [type KustomizeBuild](<#KustomizeBuild>)
- [type Metadata](<#Metadata>)
- [type Platform](<#Platform>)
- [type PlatformMetadata](<#PlatformMetadata>)
- [type PlatformSpec](<#PlatformSpec>)
- [type PlatformSpecComponent](<#PlatformSpecComponent>)
- [type Repository](<#Repository>)
## Constants
<a name="APIVersion"></a>
```go
const (
APIVersion = "v1alpha3"
BuildPlanKind = "BuildPlan"
HelmChartKind = "HelmChart"
// ChartDir is the directory name created in the holos component directory to cache a chart.
ChartDir = "vendor"
// ResourcesFile is the file name used to store component output when post-processing with kustomize.
ResourcesFile = "resources.yaml"
)
```
<a name="KubernetesObjectsKind"></a>
```go
const KubernetesObjectsKind = "KubernetesObjects"
```
<a name="APIObject"></a>
## type APIObject {#APIObject}
APIObject represents the most basic generic form of a single kubernetes api object. Represented as a JSON object internally for compatibility between tools, for example loading from CUE.
```go
type APIObject structpb.Struct
```
<a name="APIObjectMap"></a>
## type APIObjectMap {#APIObjectMap}
APIObjectMap represents the marshalled yaml representation of kubernetes api objects. Do not produce an APIObjectMap directly, instead use [APIObjects](<#APIObjects>) to produce the marshalled yaml representation from CUE data, then provide the result to [Component](<#Component>).
```go
type APIObjectMap map[Kind]map[InternalLabel]string
```
<a name="APIObjects"></a>
## type APIObjects {#APIObjects}
APIObjects represents Kubernetes API objects defined directly from CUE code. Useful to mix in resources to any kind of [Component](<#Component>), for example adding an ExternalSecret resource to a [HelmChart](<#HelmChart>).
[Kind](<#Kind>) must be the resource kind, e.g. Deployment or Service.
[InternalLabel](<#InternalLabel>) is an arbitrary internal identifier to uniquely identify the resource within the context of a \`holos\` command. Holos will never write the intermediate label to rendered output.
Refer to [Component](<#Component>) which accepts an [APIObjectMap](<#APIObjectMap>) field provided by [APIObjects](<#APIObjects>).
```go
type APIObjects struct {
APIObjects map[Kind]map[InternalLabel]APIObject `json:"apiObjects"`
APIObjectMap APIObjectMap `json:"apiObjectMap"`
}
```
<a name="BuildPlan"></a>
## type BuildPlan {#BuildPlan}
BuildPlan represents a build plan for the holos cli to execute. The purpose of a BuildPlan is to define one or more [Component](<#Component>) kinds. For example a [HelmChart](<#HelmChart>), [KustomizeBuild](<#KustomizeBuild>), or [KubernetesObjects](<#KubernetesObjects>).
A BuildPlan usually has an additional empty [KubernetesObjects](<#KubernetesObjects>) for the purpose of using the [Component](<#Component>) DeployFiles field to deploy an ArgoCD or Flux gitops resource for the holos component.
```go
type BuildPlan struct {
Kind string `json:"kind" cue:"\"BuildPlan\""`
APIVersion string `json:"apiVersion" cue:"string | *\"v1alpha3\""`
Spec BuildPlanSpec `json:"spec"`
}
```
<a name="BuildPlanComponents"></a>
## type BuildPlanComponents {#BuildPlanComponents}
```go
type BuildPlanComponents struct {
Resources map[InternalLabel]KubernetesObjects `json:"resources,omitempty"`
KubernetesObjectsList []KubernetesObjects `json:"kubernetesObjectsList,omitempty"`
HelmChartList []HelmChart `json:"helmChartList,omitempty"`
KustomizeBuildList []KustomizeBuild `json:"kustomizeBuildList,omitempty"`
}
```
<a name="BuildPlanSpec"></a>
## type BuildPlanSpec {#BuildPlanSpec}
BuildPlanSpec represents the specification of the build plan.
```go
type BuildPlanSpec struct {
// Disabled causes the holos cli to take no action over the [BuildPlan].
Disabled bool `json:"disabled,omitempty"`
// Components represents multiple [HolosComponent] kinds to manage.
Components BuildPlanComponents `json:"components,omitempty"`
}
```
<a name="Chart"></a>
## type Chart {#Chart}
Chart represents a 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 defines the fields common to all holos component kinds. Every holos component kind should embed Component.
```go
type Component struct {
// Kind is a string value representing the resource this object represents.
Kind string `json:"kind"`
// APIVersion represents the versioned schema of this representation of an object.
APIVersion string `json:"apiVersion" cue:"\"v1alpha3\""`
// Metadata represents data about the holos component such as the Name.
Metadata Metadata `json:"metadata"`
// APIObjectMap holds the marshalled representation of api objects. Useful to
// mix in resources to each Component type, for example adding an
// ExternalSecret to a [HelmChart] Component. Refer to [APIObjects].
APIObjectMap APIObjectMap `json:"apiObjectMap,omitempty"`
// DeployFiles represents file paths relative to the cluster deploy directory
// with the value representing the file content. Intended for defining the
// ArgoCD Application resource or Flux Kustomization resource from within CUE,
// but may be used to render any file related to the build plan from CUE.
DeployFiles FileContentMap `json:"deployFiles,omitempty"`
// Kustomize represents a kubectl kustomize build post-processing step.
Kustomize `json:"kustomize,omitempty"`
// Skip causes holos to take no action regarding this component.
Skip bool `json:"skip" cue:"bool | *false"`
}
```
<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="HelmChart"></a>
## type HelmChart {#HelmChart}
HelmChart represents a holos component which wraps around an upstream helm chart. Holos orchestrates helm by providing values obtained from CUE, renders the output using \`helm template\`, then post\-processes the helm output yaml using the general functionality provided by [Component](<#Component>), for example [Kustomize](<#Kustomize>) post\-rendering and mixing in additional kubernetes api objects.
```go
type HelmChart struct {
Component `json:",inline"`
Kind string `json:"kind" cue:"\"HelmChart\""`
// Chart represents a helm chart to manage.
Chart Chart `json:"chart"`
// ValuesContent represents the values.yaml file holos passes to the `helm
// template` command.
ValuesContent string `json:"valuesContent"`
// EnableHooks enables helm hooks when executing the `helm template` command.
EnableHooks bool `json:"enableHooks" cue:"bool | *false"`
}
```
<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](<#InternalLabel>) when the identifier must be unique and internal. Defined as a type for clarity and type checking.
A InternalLabel is useful to convert a CUE struct to a list, for example producing a list of [APIObject](<#APIObject>) resources from an [APIObjectMap](<#APIObjectMap>). A CUE struct using InternalLabel keys is guaranteed to not lose data when rendering output because a InternalLabel is expected to never be written to the final output.
```go
type InternalLabel string
```
<a name="Kind"></a>
## type Kind {#Kind}
Kind is a kubernetes api object kind. Defined as a type for clarity and type checking.
```go
type Kind string
```
<a name="KubernetesObjects"></a>
## type KubernetesObjects {#KubernetesObjects}
KubernetesObjects represents a [Component](<#Component>) composed of Kubernetes API objects provided directly from CUE using [APIObjects](<#APIObjects>).
```go
type KubernetesObjects struct {
Component `json:",inline"`
Kind string `json:"kind" cue:"\"KubernetesObjects\""`
}
```
<a name="Kustomize"></a>
## type Kustomize {#Kustomize}
Kustomize represents resources necessary to execute a kustomize build. Intended for at least two use cases:
1. Process a [KustomizeBuild](<#KustomizeBuild>) [Component](<#Component>) which represents raw yaml file resources in a holos component directory.
2. Post process a [HelmChart](<#HelmChart>) [Component](<#Component>) to inject istio, patch jobs, add custom labels, etc...
```go
type Kustomize struct {
// KustomizeFiles holds file contents for kustomize, e.g. patch files.
KustomizeFiles FileContentMap `json:"kustomizeFiles,omitempty"`
// ResourcesFile is the file name used for api objects in kustomization.yaml
ResourcesFile string `json:"resourcesFile,omitempty"`
}
```
<a name="KustomizeBuild"></a>
## type KustomizeBuild {#KustomizeBuild}
KustomizeBuild represents a [Component](<#Component>) that renders plain yaml files in the holos component directory using \`kubectl kustomize build\`.
```go
type KustomizeBuild struct {
Component `json:",inline"`
Kind string `json:"kind" cue:"\"KustomizeBuild\""`
}
```
<a name="Metadata"></a>
## type Metadata {#Metadata}
Metadata represents data about the object such as the Name.
```go
type Metadata struct {
// Name represents the name of the holos component.
Name string `json:"name"`
// Namespace is the primary namespace of the holos component. A holos
// component may manage resources in multiple namespaces, in this case
// consider setting the component namespace to default.
//
// This field is optional because not all resources require a namespace,
// particularly CRDs and DeployFiles functionality.
// +optional
Namespace string `json:"namespace,omitempty"`
}
```
<a name="Platform"></a>
## type Platform {#Platform}
Platform represents a platform to manage. A Platform resource informs holos which components to build. The platform resource also acts as a container for the platform model form values provided by the PlatformService. The primary use case is to collect the cluster names, cluster types, platform model, and holos components to build into one resource.
```go
type Platform struct {
// Kind is a string value representing the resource this object represents.
Kind string `json:"kind" cue:"\"Platform\""`
// APIVersion represents the versioned schema of this representation of an object.
APIVersion string `json:"apiVersion" cue:"string | *\"v1alpha3\""`
// Metadata represents data about the object such as the Name.
Metadata PlatformMetadata `json:"metadata"`
// Spec represents the specification.
Spec PlatformSpec `json:"spec"`
}
```
<a name="PlatformMetadata"></a>
## type PlatformMetadata {#PlatformMetadata}
```go
type PlatformMetadata struct {
// Name represents the Platform name.
Name string `json:"name"`
}
```
<a name="PlatformSpec"></a>
## type PlatformSpec {#PlatformSpec}
PlatformSpec represents the specification of a Platform. Think of a platform specification as a list of platform components to apply to a list of kubernetes clusters combined with the user\-specified Platform Model.
```go
type PlatformSpec struct {
// Model represents the platform model holos gets from from the
// PlatformService.GetPlatform rpc method and provides to CUE using a tag.
Model structpb.Struct `json:"model" cue:"{...}"`
// Components represents a list of holos components to manage.
Components []PlatformSpecComponent `json:"components"`
}
```
<a name="PlatformSpecComponent"></a>
## type PlatformSpecComponent {#PlatformSpecComponent}
PlatformSpecComponent represents a holos component to build or render.
```go
type PlatformSpecComponent struct {
// Path is the path of the component relative to the platform root.
Path string `json:"path"`
// Cluster is the cluster name to provide when rendering the component.
Cluster string `json:"cluster"`
}
```
<a name="Repository"></a>
## type Repository {#Repository}
Repository represents a helm chart repository.
```go
type Repository struct {
Name string `json:"name"`
URL string `json:"url"`
}
```
Generated by [gomarkdoc](<https://github.com/princjef/gomarkdoc>)

View File

@@ -1,5 +0,0 @@
import DocCardList from '@theme/DocCardList';
# Schema API
<DocCardList />

View File

@@ -1,213 +0,0 @@
<!-- Code generated by gomarkdoc. DO NOT EDIT -->
# v1alpha3
```go
import "github.com/holos-run/holos/api/schema/v1alpha3"
```
Package v1alpha3 contains CUE definitions intended as convenience wrappers around the core data types defined in package core. The purpose of these wrappers is to make life easier for platform engineers by reducing boiler plate code and generating component build plans in a consistent manner.
## Index
- [type ArgoConfig](<#ArgoConfig>)
- [type Cluster](<#Cluster>)
- [type ComponentFields](<#ComponentFields>)
- [type Fleet](<#Fleet>)
- [type Helm](<#Helm>)
- [type Kubernetes](<#Kubernetes>)
- [type Kustomize](<#Kustomize>)
- [type Platform](<#Platform>)
- [type StandardFleets](<#StandardFleets>)
<a name="ArgoConfig"></a>
## type ArgoConfig {#ArgoConfig}
ArgoConfig represents the ArgoCD GitOps configuration for a Component. Useful to define once at the root of the Platform configuration and reuse across all Components.
```go
type ArgoConfig struct {
// Enabled causes holos to render an ArgoCD Application resource for GitOps if true.
Enabled bool `cue:"true | *false"`
// ClusterName represents the cluster within the platform the Application
// resource is intended for.
ClusterName string
// DeployRoot represents the path from the git repository root to the `deploy`
// rendering output directory. Used as a prefix for the
// Application.spec.source.path field.
DeployRoot string `cue:"string | *\".\""`
// RepoURL represents the value passed to the Application.spec.source.repoURL
// field.
RepoURL string
// TargetRevision represents the value passed to the
// Application.spec.source.targetRevision field. Defaults to the branch named
// main.
TargetRevision string `cue:"string | *\"main\""`
// AppProject represents the ArgoCD Project to associate the Application with.
AppProject string `cue:"string | *\"default\""`
}
```
<a name="Cluster"></a>
## type Cluster {#Cluster}
Cluster represents a cluster managed by the Platform.
```go
type Cluster struct {
// Name represents the cluster name, for example "east1", "west1", or
// "management".
Name string `json:"name"`
// Primary represents if the cluster is marked as the primary among a set of
// candidate clusters. Useful for promotion of database leaders.
Primary bool `json:"primary" cue:"true | *false"`
}
```
<a name="ComponentFields"></a>
## type ComponentFields {#ComponentFields}
Component represents the fields common the different kinds of component. All components have a name, support mixing in resources, and produce a BuildPlan.
```go
type ComponentFields struct {
// Name represents the Component name.
Name string
// Resources are kubernetes api objects to mix into the output.
Resources map[string]any
// ArgoConfig represents the ArgoCD GitOps configuration for this Component.
ArgoConfig ArgoConfig
// BuildPlan represents the derived BuildPlan for the Holos cli to render.
BuildPlan core.BuildPlan
}
```
<a name="Fleet"></a>
## type Fleet {#Fleet}
Fleet represents a named collection of similarly configured Clusters. Useful to segregate workload clusters from their management cluster.
```go
type Fleet struct {
Name string `json:"name"`
// Clusters represents a mapping of Clusters by their name.
Clusters map[string]Cluster `json:"clusters" cue:"{[Name=_]: name: Name}"`
}
```
<a name="Helm"></a>
## type Helm {#Helm}
Helm provides a BuildPlan via the Output field which contains one HelmChart from package core. Useful as a convenience wrapper to render a HelmChart with optional mix\-in resources and Kustomization post\-processing.
```go
type Helm struct {
ComponentFields `json:",inline"`
// Version represents the chart version.
Version string
// Namespace represents the helm namespace option when rendering the chart.
Namespace string
// Repo represents the chart repository
Repo struct {
Name string `json:"name"`
URL string `json:"url"`
}
// Values represents data to marshal into a values.yaml for helm.
Values interface{} `cue:"{...}"`
// Chart represents the derived HelmChart for inclusion in the BuildPlan
// Output field value. The default HelmChart field values are derived from
// other Helm field values and should be sufficient for most use cases.
Chart core.HelmChart
// EnableKustomizePostProcessor processes helm output with kustomize if true.
EnableKustomizePostProcessor bool `cue:"true | *false"`
// KustomizeFiles represents additional files to include in a Kustomization
// resources list. Useful to patch helm output. The implementation is a
// struct with filename keys and structs as values. Holos encodes the struct
// value to yaml then writes the result to the filename key. Component
// authors may then reference the filename in the kustomization.yaml resources
// or patches lists.
// Requires EnableKustomizePostProcessor: true.
KustomizeFiles map[string]any `cue:"{[string]: {...}}"`
// KustomizePatches represents patches to apply to the helm output. Requires
// EnableKustomizePostProcessor: true.
KustomizePatches map[core.InternalLabel]any `cue:"{[string]: {...}}"`
// KustomizeResources represents additional resources files to include in the
// kustomize resources list.
KustomizeResources map[string]any `cue:"{[string]: {...}}"`
}
```
<a name="Kubernetes"></a>
## type Kubernetes {#Kubernetes}
Kubernetes provides a BuildPlan via the Output field which contains inline API Objects provided directly from CUE.
```go
type Kubernetes struct {
ComponentFields `json:",inline"`
// Objects represents the kubernetes api objects for the Component.
Objects core.KubernetesObjects
}
```
<a name="Kustomize"></a>
## type Kustomize {#Kustomize}
Kustomize provides a BuildPlan via the Output field which contains one KustomizeBuild from package core.
```go
type Kustomize struct {
ComponentFields `json:",inline"`
// Kustomization represents the kustomize build plan for holos to render.
Kustomization core.KustomizeBuild
}
```
<a name="Platform"></a>
## type Platform {#Platform}
Platform is a convenience structure to produce a core Platform specification value in the Output field. Useful to collect components at the root of the Platform configuration tree as a struct, which are automatically converted into a list for the core Platform spec output.
```go
type Platform struct {
// Name represents the Platform name.
Name string `cue:"string | *\"holos\""`
// Components is a structured map of components to manage by their name.
Components map[string]core.PlatformSpecComponent
// Model represents the Platform model holos gets from from the
// PlatformService.GetPlatform rpc method and provides to CUE using a tag.
Model structpb.Struct `cue:"{...}"`
// Output represents the core Platform spec for the holos cli to iterate over
// and render each listed Component, injecting the Model.
Output core.Platform
// Domain represents the primary domain the Platform operates in. This field
// is intended as a sensible default for component authors to reference and
// platform operators to define.
Domain string `cue:"string | *\"holos.localhost\""`
}
```
<a name="StandardFleets"></a>
## type StandardFleets {#StandardFleets}
StandardFleets represents the standard set of Clusters in a Platform segmented into Fleets by their purpose. The management Fleet contains a single Cluster, for example a GKE autopilot cluster with no workloads deployed for reliability and cost efficiency. The workload Fleet contains all other Clusters which contain workloads and sync Secrets from the management cluster.
```go
type StandardFleets struct {
// Workload represents a Fleet of zero or more workload Clusters.
Workload Fleet `json:"workload" cue:"{name: \"workload\"}"`
// Management represents a Fleet with one Cluster named management.
Management Fleet `json:"management" cue:"{name: \"management\"}"`
}
```
Generated by [gomarkdoc](<https://github.com/princjef/gomarkdoc>)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 728 KiB

View File

@@ -1,6 +0,0 @@
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
# ArgoCD
Coming soon.

View File

@@ -1,3 +0,0 @@
# Backstage
Coming soon.

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +0,0 @@
# Observability
Coming soon.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 624 KiB

View File

@@ -1,687 +0,0 @@
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import Admonition from '@theme/Admonition';
# Try Holos Locally
This guide walks through the process of building and managing a software
development platform with Holos. The k3d platform built in this guide is a
slimmed down version of the larger, more holistic, Holos reference platform.
Holos is different from existing tools in a few important ways.
1. Holos provides a **unified configuration model** purpose built to improve on
unmodified Helm charts, Kustomize bases, or anything else that produces
structured configuration data.
2. Holos all but **eliminates the need to template yaml**, a common source of
frustration and errors in production.
3. Holos platforms are **composable** and have breadth. The toolchain and
techniques scale down to one machine and up to multiple clusters across
multiple regions.
4. The unified configuration model is well suited to a **Zero Trust security
model**. Platform wide policy configuration is easier to manage with Holos.
---
This guide assumes commands are run locally. Capitalized terms have specific
definitions described in the [Glossary](/docs/glossary).
## What you'll need {#Requirements}
You'll need the following tools installed to complete this guide.
1. [holos](/docs/install) - to build the platform.
2. [helm](https://helm.sh/docs/intro/install/) - to render Holos components that wrap upstream Helm charts.
3. [k3d](https://k3d.io/#installation) - to provide a k8s api server.
4. [OrbStack](https://docs.orbstack.dev/install) or [Docker](https://docs.docker.com/get-docker/) - to use k3d.
5. [kubectl](https://kubernetes.io/docs/tasks/tools/) - to interact with the k8s api server.
6. [mkcert](https://github.com/FiloSottile/mkcert?tab=readme-ov-file#installation) - to make trusted TLS certificates.
7. [jq](https://jqlang.github.io/jq/download/) - to fiddle with JSON output.
:::note
Registering an account **is recommended** to try out proper authentication and
authorization in Holos, but you can complete this guide without signing up.
:::
## Goal {#Goal}
By the end of this guide you'll have built the foundation of a software
development platform. The foundation provides Zero Trust security by
holistically integrating off-the-shelf open source software.
1. Istio is configured to authenticate and authorize requests using an OIDC
ID-Token issued by ZITADEL before requests reach backend services.
2. The platform provides single sign-on and role based access control for all
services running on the platform.
This guide strives to keep things neat and tidy. All of the resources are
located in one k3d cluster and one local Git repository. If you want to clean
up at any point, do so with:
```bash
k3d cluster delete workload
rm -rf holos-k3d
```
## Sign In or Out {#Sign-In}
Holos provides integrated authentication and authorization which we'll use in
this guide to protect a service. We recommend registering an account to see
this in action. Registration also enables you to explore the customizable web
form that simplifies complex configuration.
If you opt-out, the platform will be configured to use a fake identity in place
of real id tokens.
<Tabs groupId="registration">
<TabItem value="registered" label="Sign In">
```bash
holos register user
```
</TabItem>
<TabItem value="unregistered" label="Opt Out">
```bash
holos logout
```
</TabItem>
</Tabs>
## Create the Platform {#Create-Platform}
A server-side platform resource in Holos stores the web form used to simplify
platform wide configuration.
First, initialize an empty Git repository:
```bash
mkdir holos-k3d
cd holos-k3d
git init
```
<Tabs groupId="registration">
<TabItem value="registered" label="Signed In">
Use `holos` to make the rpc call to create the server-side platform
resource.
```bash
holos create platform --name k3d --display-name "Try Holos Locally"
```
</TabItem>
<TabItem value="unregistered" label="Signed Out">
Create a blank `platform.metadata.json` file so subsequent holos commands
skip rpc calls.
```bash
touch platform.metadata.json
```
</TabItem>
</Tabs>
### Generate the Platform {#Generate-Platform}
Generate the platform code in the repository root.
```bash
holos generate platform k3d
```
Commit the generated platform config to the repository.
```bash
git add .
git commit -m "holos generate platform k3d - $(holos --version)"
```
### Push the Platform Form
Each Holos platform has a Platform Form used to submit top level, platform-wide
configuration values. The purpose of the form is to validate configuration
values and simplify complicated configurations and integrations.
<Tabs groupId="registration">
<TabItem value="registered" label="Signed In">
Push the Platform Form to publish it. Browse to the printed URL to view the
form.
```bash
holos push platform form .
```
</TabItem>
<TabItem value="unregistered" label="Signed Out">
You will update the Platform Model locally in a later step so there's
nothing to do in this step. Only signed-in users can push a Platform Form
to the Holos web server.
```bash
# holos push platform form .
```
</TabItem>
</Tabs>
The Platform Form is defined locally in `forms/platform/platform-form.cue`.
On the web it looks like:
![Platform Form Default Values](./form-pushed.png)
### Update the Platform Model {#Platform-Model}
Holos needs initial, top level configuration values to render the platform. The
Platform Model is the term we use for these values. In this section you will
configure role based access control by way of updating the Platform Model.
In the k3d platform you're building now, role based access control is
implemented by asserting against the oidc id token subject. Update the form
with the `sub` claim value from your id token. This will ensure only you have
access to platform services.
<Tabs groupId="registration">
<TabItem value="registered" label="Signed In">
Copy and paste the `sub` value into your Platform Form's Subject field.
```bash
holos login --print-claims --log-level=error | jq -r .sub
```
After pasting the `sub` value, click Submit on the form.
</TabItem>
<TabItem value="unregistered" label="Signed Out">
You don't have an id token when you're signed out, so there's nothing for
you to do in this step.
```bash
# holos login --print-claims --log-level=error | jq -r .sub
```
The platform will be configured to assert against the User-Agent header
instead.
</TabItem>
</Tabs>
### Pull the Platform Model {#Pull-the-Platform-Model}
The Platform Model needs to be pulled into the local Git repository after the
form has been submitted. Next, we'll run `holos render` which operates
exclusively on local files.
Holos stores the Platform Model in the `platform.config.json` file. Holos
provides this file as input to CUE when rendering the platform. This file is
intended to be added to version control.
<Tabs groupId="registration">
<TabItem value="registered" label="Signed In">
Pull the updated Platform Model into the local repository.
```bash
holos pull platform model .
git add platform.config.json
git commit -m "Add platform model"
```
</TabItem>
<TabItem value="unregistered" label="Signed Out">
The holos generate platform k3d command created an initial Platform Model in
`platform.config.json`. As a result there's nothing to do in this step.
```bash
# holos pull platform model .
# git add platform.config.json
# git commit -m "Add platform model"
```
</TabItem>
</Tabs>
## Render the Platform {#Render-the-Platform}
Holos has everything necessary to render the platform once the
`platform.config.json` file and the code from `holos generate` are in the
current directory.
Rendering a platform is the process of iterating over each platform component
and rendering it into plain yaml. Holos does not apply the resulting manifests.
Other tools like kubectl, ArgoCD, or Flux are responsible for applying the
manifests.
```bash
holos render platform ./platform
```
The render command writes the manifest files to the `deploy/` directory. Commit
the files so they can be applied via GitOps later.
```bash
git add deploy
git commit -m "holos render platform ./platform"
```
:::info[Don't blink, this is where Holos builds the platform]
It usually takes no more than a few seconds.
Rendering the holos reference platform currently results in about 500K lines of
yaml. In contrast, roughly 80K lines are produced by this slimmed down k3d
platform.
We mention this because the scale doesn't matter as much as it does with other
tools. Manage millions of lines of configuration with Holos the same way this
guide manages thousands. This is made possible by the unique way CUE unifies
all configuration into one single model.
:::
## Configure DNS {#DNS}
Configure your machine to resolve `*.holos.localhost` to your loopback
interface. This is necessary for requests to reach the workload cluster.
<Tabs>
<TabItem value="macos" label="macOS" default>
Cache sudo credentials.
Admin access is necessary to setup a local dnsmasq instance and configure
macOS's DNS resolver.
```bash
sudo -v
```
Resolve *.holos.localhost DNS queries to 127.0.0.1.
```bash
bash ./scripts/local-dns
```
</TabItem>
<TabItem value="linux" label="Linux">
[NSS-myhostname](http://man7.org/linux/man-pages/man8/nss-myhostname.8.html)
ships with many Linux distributions and should resolve *.localhost
automatically to 127.0.0.1.
Otherwise it is installable with:
```bash
sudo apt install libnss-myhostname
```
</TabItem>
<TabItem value="windows" label="Windows">
Ensure the loopback interface has at least the following names in `C:\windows\system32\drivers\etc\hosts`
```
127.0.0.1 httpbin.holos.localhost app.holos.localhost
```
</TabItem>
</Tabs>
## Create the Cluster {#Create-Cluster}
The Workload Cluster is where your applications and services will be deployed.
In production this is usually an EKS, GKE, or AKS cluster.
:::tip
Holos supports all compliant Kubernetes clusters. Holos was developed and tested
on GKE, EKS, Talos, k3s, and Kubeadm clusters.
:::
<Tabs>
<TabItem value="evaluate" label="Try Holos" default>
Use this command when exploring Holos.
```bash
k3d cluster create workload \
--port "443:443@loadbalancer" \
--k3s-arg "--disable=traefik@server:0"
```
</TabItem>
<TabItem value="develop" label="Develop Holos">
Use this command when developing Holos.
```bash
k3d registry create registry.holos.localhost --port 5100
```
```bash
k3d cluster create workload \
--registry-use k3d-registry.holos.localhost:5100 \
--port "443:443@loadbalancer" \
--k3s-arg "--disable=traefik@server:0"
```
</TabItem>
</Tabs>
Traefik is disabled because Istio provides the same functionality.
## Apply the Platform Components {#Apply-Platform-Components}
Use `kubectl` to apply each platform component. In production, it's common to
fully automate this process with ArgoCD, but we use `kubectl` to the same
effect.
### Local CA {#Local-CA}
Holos platforms use cert manager to issue tls certificates. The browser and
tools we're using need to trust these certificates to work together.
Admin access is necessary for `mkcert` to manage the certificate into your trust
stores.
```bash
sudo -v
```
Manage the local CA and copy the CA key to the workload cluster so that cert
manager can manage trusted certificates.
```bash
bash ./scripts/local-ca
```
:::warning
Take care to run the local-ca script each time you create the workload cluster
so that Certificates are issued correctly.
:::
### Service Mesh
The platform service mesh provides an ingress gateway and connectivity useful
for observability, reliability, and security.
#### Namespaces
With Holos, components are automatically added to the namespaces component,
useful for centrally managed policies.
```bash
kubectl apply --server-side=true -f ./deploy/clusters/workload/components/namespaces
```
#### Custom Resource Definitions
```bash
kubectl apply --server-side=true -f ./deploy/clusters/workload/components/gateway-api
kubectl apply --server-side=true -f ./deploy/clusters/workload/components/istio-base
```
#### Cert Manager {#cert-manager}
Apply the cert-manager controller.
```bash
kubectl apply --server-side=true -f ./deploy/clusters/workload/components/cert-manager
```
Apply the ClusterIssuer which issues Certificate resources using the local
certificate authority.
```bash
kubectl -n cert-manager wait pod -l app.kubernetes.io/component=webhook --for=condition=Ready
kubectl apply --server-side=true -f deploy/clusters/workload/components/local-ca
kubectl apply --server-side=true -f deploy/clusters/workload/components/certificates
kubectl -n istio-gateways wait certificate httpbin.holos.localhost --for=condition=Ready
```
:::warning
The certificate will time out before becoming ready if the [local-ca](#Local-CA)
script was not run after the cluster was created.
:::
#### Istio {#Istio}
Istio implements the Service Mesh.
```bash
kubectl apply --server-side=true -f ./deploy/clusters/workload/components/istio-cni
kubectl apply --server-side=true -f ./deploy/clusters/workload/components/istiod
kubectl apply --server-side=true -f ./deploy/clusters/workload/components/gateway
```
Verify the Gateway is programmed and the listeners have been accepted:
```bash
kubectl -n istio-gateways wait gateway default --for=condition=Accepted
```
#### httpbin {#httpbin}
httpbin is a simple backend service useful for end-to-end testing.
```bash
kubectl apply --server-side=true -f deploy/clusters/workload/components/httpbin-backend
kubectl apply --server-side=true -f deploy/clusters/workload/components/httpbin-routes
kubectl -n holos-system wait pod -l app.kubernetes.io/instance=httpbin --for=condition=Ready
```
:::info
Browse to [https://httpbin.holos.localhost/](https://httpbin.holos.localhost/)
to verify end to end connectivity. You should see the httpbin index page.
:::
### Authenticating Proxy
The auth proxy is responsible for authenticating browser requests, handling the
oidc authentication flow, and providing a signed id token to the rest of the
services in the mesh.
#### Cookie Secret
The auth proxy stores session information in an encrypted cookie. Generate a
random cookie encryption Secret and apply.
```bash
LC_ALL=C tr -dc A-Za-z0-9 </dev/urandom \
| head -c 32 \
| kubectl create secret generic "authproxy" \
--from-file=cookiesecret=/dev/stdin \
--dry-run=client -o yaml \
| kubectl apply -n istio-gateways -f-
```
#### Deployment
The auth proxy Deployment receives requests from web browsers and responds with
an authentication decision.
```bash
kubectl apply --server-side=true -f deploy/clusters/workload/components/authproxy
kubectl apply --server-side=true -f deploy/clusters/workload/components/authroutes
```
<Tabs groupId="registration">
<TabItem value="registered" label="Signed In">
<Admonition type="info">
Verify authentication is working by browsing to
[https://httpbin.holos.localhost/holos/authproxy](https://httpbin.holos.localhost/holos/authproxy).
We want a simple `Authenticated` response.
<Admonition type="tip">
You may need to refresh the page a few times while the platform configures
itself.
</Admonition>
</Admonition>
Istio will respond with `no healthy upstream` until the pod becomes ready.
Wait for the pod to become ready with:
```bash
kubectl -n holos-system wait pod -l app.kubernetes.io/instance=httpbin --for=condition=Ready
```
Once authenticated, visit
[https://httpbin.holos.localhost/holos/authproxy/userinfo](https://httpbin.holos.localhost/holos/authproxy/userinfo)
which returns a subset of claims from your id token.
<Admonition type="warning">
If you get `Unauthorized` instead of a json response body, make sure you
[authenticated](https://httpbin.holos.localhost/holos/authproxy) first.
</Admonition>
```json
{
"user": "275552236589843464",
"email": "demo@holos.run",
"preferredUsername": "demo"
}
```
</TabItem>
<TabItem value="unregistered" label="Signed Out">
The auth proxy will always try to sign you in when you are signed out, so
there isn't much to do here. Please do take a moment to glance at the
Signed In tab to see how this would work if you were signed in.
The `k3d` platform relies on `https://login.holos.run` to issue id tokens.
Authorization has been configured against fake request headers instead of
the real `x-oidc-id-token` header.
</TabItem>
</Tabs>
### Authorization Policy
Configure authorization policies using attributes of the authenticated request.
Authorization policies route web requests through the auth proxy and then
validate all requests against the `x-oidc-id-token` header.
```bash
kubectl apply --server-side=true -f deploy/clusters/workload/components/authpolicy
```
Istio make take a few seconds to program the Gateway with the
AuthorizationPolicy resources.
## Try out Zero Trust
A basic Zero Trust security model is now in place. The platform authenticates
and authorizes requests before they reach the backend service.
### Browser
<Tabs groupId="registration">
<TabItem value="registered" label="Signed In">
The platform has been configured to authorize requests with a `x-oidc-id-token` header.
1. Verify authentication is working by browsing to [https://httpbin.holos.localhost/dump/request](https://httpbin.holos.localhost/dump/request).
- Refresh the page a few times.
- The `httpbin` backend pods should echo back the `x-oidc-id-token`
header injected by the auth proxy.
2. Note the `x-oidc-id-token` header is not sent by your browser but is
received by the backend service.
- This design reduces the risk of exposing id tokens in the browser.
- Browser request size remains constant as more claims are added to id
tokens.
- Reliability improves because id tokens often overflow request header
buffers when they pass through middle boxes across the internet.
</TabItem>
<TabItem value="unregistered" label="Signed Out">
The platform has been configured to authorize requests with a `User-Agent: anonymous` header.
1. Open an incognito window (Cmd+Shift+N) to verify the platform is
enforcing the authorization policy.
2. Browse to
[https://httpbin.holos.localhost/dump/request](https://httpbin.holos.localhost/dump/request)
you should be redirected to the sign in page by the auth proxy.
- You **do not** need to register or sign in.
- This step verifies the platform is redirecting unauthenticated
requests to the identity provider.
- Navigate back or close and re-open an incognito window.
3. Set your `User-Agent` header to `anonymous` using your browser developer tools.
- For Chrome the process is described
[here](https://developer.chrome.com/docs/devtools/device-mode/override-user-agent#override_the_user_agent_string).
- The purpose is to simulate an authenticated request.
4. Browse to
[https://httpbin.holos.localhost/dump/request](https://httpbin.holos.localhost/dump/request).
- The platform should allow the request through to the backend pod.
- `httpbin` should echo back your request which should contain `User-Agent: anonymous`.
</TabItem>
</Tabs>
### Command Line
Verify unauthenticated requests are blocked by default outside the browser.
```bash
curl -I https://httpbin.holos.localhost/dump/request
```
You should receive a `HTTP/2 302` response that redirects to `location:
https://login.holos.run` to start the oauth login flow.
Next, verify authenticated requests are allowed.
<Tabs groupId="registration">
<TabItem value="registered" label="Signed In">
The platform is configured to authenticate the id token present in the
`x-oidc-id-token` header.
💡 It also works with `grpcurl`.
```bash
curl -H x-oidc-id-token:$(holos token) https://httpbin.holos.localhost/dump/request
```
</TabItem>
<TabItem value="unregistered" label="Signed Out">
The platform is configured to authorize any request with `User-Agent:
anonymous` in place of validating the oidc id token.
💡 Take a moment to click the Signed In tab, I don't want you to miss how
cool `$(holos token)` is.
```bash
curl -A anonymous https://httpbin.holos.localhost/dump/request
```
</TabItem>
</Tabs>
You should receive a response showing the request headers the backend received.
:::tip
Note how the platform secures both web browser and command line api access to
the backend httpbin service. httpbin itself has no authentication or
authorization functionality.
:::
## Summary
Thank you for taking the time to try out Holos. In this guide, you built the
foundation of a software development platform that:
1. Provides a unified configuration model with CUE that
- Supports unmodified Helm Charts, Kustomize Kustomizations, plain YAML.
- Provides a web form to pass top level parameters.
2. Reduces errors by eliminating the need to template unstructured text.
3. Is composable and scales down to a local machine.
4. Provides an way to safely configure broad authentication and authorization
policy.
## Next Steps
Dive deeper with the following resources that build on the foundation you have now.
1. Explore the [Rendering Process](/docs/concepts#rendering) in Holos.
2. Dive deeper into the [Platform Manifests](./platform-manifests) rendered in this guide.
3. Deploy [ArgoCD](../argocd) onto the foundation you built.
4. Deploy [Backstage](../backstage) as a portal to the integrated platform components.
## Clean-Up
If you'd like to clean up the resources you created in this guide, remove them
with:
```bash
k3d cluster delete workload
rm -rf holos-k3d
```

View File

@@ -1,137 +0,0 @@
# Platform Manifests
This document provides an example of how Holos uses CUE and Helm to unify and
render the platform configuration. It refers to the manifests rendered in the
Try Holos Locally guide.
Take a moment to review the manifests `holos` rendered to build the platform.
### ArgoCD Application
Note the Git URL in the Platform Model is used to derive the ArgoCD
`Application` resource for all of the platform components.
```yaml
# deploy/clusters/workload/gitops/namespaces.application.gen.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: namespaces
namespace: argocd
spec:
destination:
server: https://kubernetes.default.svc
project: default
source:
# highlight-next-line
path: /deploy/clusters/workload/components/namespaces
# highlight-next-line
repoURL: https://github.com/holos-run/holos-k3d.git
# highlight-next-line
targetRevision: HEAD
```
One ArgoCD `Application` resource is produced for each Holos component by
default. The CUE definition which produces the rendered output is defined in
`buildplan.cue` around line 222.
:::tip
Note how CUE does not use error-prone text templates, the language is well
specified and typed which reduces errors when unifying the configuration with
the Platform Model in the following `#Argo` definition.
:::
```cue
// buildplan.cue
// #Argo represents an argocd Application resource for each component, written
// using the #HolosComponent.deployFiles field.
#Argo: {
ComponentName: string
Application: app.#Application & {
metadata: name: ComponentName
metadata: namespace: "argocd"
spec: {
destination: server: "https://kubernetes.default.svc"
project: "default"
source: {
// highlight-next-line
path: "\(_Platform.Model.argocd.deployRoot)/deploy/clusters/\(_ClusterName)/components/\(ComponentName)"
// highlight-next-line
repoURL: _Platform.Model.argocd.repoURL
// highlight-next-line
targetRevision: _Platform.Model.argocd.targetRevision
}
}
}
// deployFiles represents the output files to write along side the component.
deployFiles: "clusters/\(_ClusterName)/gitops/\(ComponentName).application.gen.yaml": yaml.Marshal(Application)
}
```
### Helm Chart
The `cert-manger` component renders using the upstream Helm chart. The build
plan that defines the helm chart to use along with the values to provide looks
like the following.
:::tip
Holos fully supports your existing Helm charts. Consider leveraging `holos` as
an alternative to umbrella charts.
:::
```cue
// components/cert-manager/cert-manager.cue
package holos
// Produce a helm chart build plan.
(#Helm & Chart).Output
let Chart = {
Name: "cert-manager"
Version: "1.14.5"
Namespace: "cert-manager"
Repo: name: "jetstack"
Repo: url: "https://charts.jetstack.io"
// highlight-next-line
Values: {
installCRDs: true
startupapicheck: enabled: false
// Must not use kube-system on gke autopilot. GKE Warden blocks access.
// highlight-next-line
global: leaderElection: namespace: Namespace
// https://cloud.google.com/kubernetes-engine/docs/concepts/autopilot-resource-requests#min-max-requests
resources: requests: {
cpu: "250m"
memory: "512Mi"
"ephemeral-storage": "100Mi"
}
// highlight-next-line
webhook: resources: Values.resources
// highlight-next-line
cainjector: resources: Values.resources
// highlight-next-line
startupapicheck: resource: Values.resources
// https://cloud.google.com/kubernetes-engine/docs/how-to/autopilot-spot-pods
nodeSelector: {
"kubernetes.io/os": "linux"
if _ClusterName == "management" {
"cloud.google.com/gke-spot": "true"
}
}
webhook: nodeSelector: Values.nodeSelector
cainjector: nodeSelector: Values.nodeSelector
startupapicheck: nodeSelector: Values.nodeSelector
}
}
```

View File

@@ -1,3 +0,0 @@
# Backstory
Holos is a tool intended to lighten the burden of managing Kubernetes resources. In 2020 we set out to develop a holistic platform composed from open source cloud native components. We quickly became frustrated with how each of the major components packaged and distributed their software in a different way. Many projects choose to distribute their software with Helm charts, while others provide plain yaml files and Kustomize bases. The popular Kube Prometheus Stack project provides Jsonnet to render and update Kubernetes yaml manifests.

View File

@@ -2,87 +2,16 @@
This page describes the terms used within the context of Holos.
## Platform
In Holos, a Platform is a comprehensive environment configured using the
Kubernetes resource model. It extends beyond traditional Kubernetes
functionality by integrating cloud resources through Crossplane, allowing for a
unified management approach across both Kubernetes and cloud infrastructure. A
Platform typically consists of one Management Cluster, which handles control and
secret management, and one or more Workload Clusters, where application
workloads are deployed and run. This architecture enables a consistent and
scalable approach to managing diverse resources and services within the
cloud-native ecosystem.
## Management Cluster
In the context of Holos, a Management Cluster is a special Kubernetes cluster
that hosts Kubernetes controllers. For example, cert-manager, Cluster api, and
Crossplane. A management cluster manages a single platform. The primary
function of this cluster is to securely store and manage secrets, ensuring the
secure handling of sensitive information such as credentials, API keys, and
other confidential data. The Management Cluster serves as a centralized and
secure control plane for the platform, facilitating the orchestration and
management of other components.
## Workload Cluster
In Holos, a Workload Cluster is a Kubernetes cluster designed to host and run
application workloads. Unlike the Management Cluster, which focuses on control
and secret management, Workload Clusters are dedicated to executing the actual
applications and services. These clusters can vary in size and configuration
based on the specific needs of the applications they support. Workload Clusters
leverage Kubernetes' orchestration capabilities to manage the deployment,
scaling, and operation of containerized applications, providing a flexible and
scalable environment for running production workloads within the platform.
## Platform Form
In Holos, a Platform Form is a customizable web form defined by JSON data. Each
platform within Holos has a unique Platform Form, which serves as an interface
for configuring and managing the platform's settings and resources. Platform
engineers can customize the Platform Form by modifying the underlying CUE
(Configuration Unified Engine) code, allowing for tailored configurations that
meet specific requirements. This flexibility enables platform engineers to
create a user-friendly and specific interface for managing the platform's
components and operations.
## Platform Model
In Holos, the Platform Model represents the collection of values submitted
through the Platform Form. It encapsulates the specific configuration details
and settings defined by the platform engineers, serving as the blueprint for the
platform's setup and operation. The Platform Model is essential for translating
the customized options and parameters from the Platform Form into actionable
configurations within the Holos ecosystem, ensuring that the platform operates
according to the specified requirements and guidelines.
## Secret Store
In Holos, a SecretStore is a repository for securely storing and managing
sensitive data such as passwords, API keys, and other confidential information.
It is compatible with any secret store supported by the External Secrets
Operator. By default, the management cluster serves as the SecretStore to
minimize dependencies and simplify the architecture. This setup ensures that
secrets are managed in a secure and centralized manner, aligning with the
overall security framework of the platform.
## Service Mesh
In Holos, a Service Mesh is a dedicated infrastructure layer for managing,
observing, and securing service-to-service communications within a microservices
architecture. It typically includes features such as load balancing, traffic
routing, service discovery, and security policies like mutual TLS and access
control. The Service Mesh abstracts these functionalities away from the
application code, providing a centralized control plane for managing the
interactions between microservices. This facilitates better observability,
resilience, and security in complex, distributed environments.
## Zero Trust
In the context of Holos and broader security practices, Zero Trust is a security
model that assumes no implicit trust is granted to any user, system, or
component inside or outside the network. Instead, every request for access is
treated as potentially malicious, and verification is required at every stage.
This model enforces strict identity verification, continuous monitoring, and
least-privilege access policies.

View File

@@ -1,5 +0,0 @@
import DocCardList from '@theme/DocCardList';
# Guides
<DocCardList />

View File

@@ -1,277 +0,0 @@
---
description: Build a local Cluster to use with these guides.
slug: /guides/local-cluster
sidebar_position: 300
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import Admonition from '@theme/Admonition';
# Local Cluster
In this guide we'll set up a local k3d cluster to apply and explore the
configuration described in our other guides. After completing this guide you'll
have a standard Kubernetes API server with proper DNS and TLS certificates.
You'll be able to easily reset the cluster to a known good state to iterate on
your own Platform.
The [Concepts](/docs/concepts) page defines capitalized terms such as Platform
and Component.
## Reset the Cluster
If you've already followed this guide, reset the cluster by running the
following commands. Skip this section if you're creating a cluster for the
first time.
First, delete the cluster.
<Tabs groupId="k3d-cluster-delete">
<TabItem value="command" label="Command">
```bash
k3d cluster delete workload
```
</TabItem>
<TabItem value="output" label="Output">
```txt showLineNumbers
INFO[0000] Deleting cluster 'workload'
INFO[0000] Deleting cluster network 'k3d-workload'
INFO[0000] Deleting 1 attached volumes...
INFO[0000] Removing cluster details from default kubeconfig...
INFO[0000] Removing standalone kubeconfig file (if there is one)...
INFO[0000] Successfully deleted cluster workload!
```
</TabItem>
</Tabs>
Then create the cluster again.
<Tabs groupId="k3d-cluster-create">
<TabItem value="command" label="Command">
```bash
k3d cluster create workload \
--registry-use k3d-registry.holos.localhost:5100 \
--port "443:443@loadbalancer" \
--k3s-arg "--disable=traefik@server:0"
```
</TabItem>
<TabItem value="output" label="Output">
```txt showLineNumbers
INFO[0000] portmapping '443:443' targets the loadbalancer: defaulting to [servers:*:proxy agents:*:proxy]
INFO[0000] Prep: Network
INFO[0000] Created network 'k3d-workload'
INFO[0000] Created image volume k3d-workload-images
INFO[0000] Starting new tools node...
INFO[0000] Starting node 'k3d-workload-tools'
INFO[0001] Creating node 'k3d-workload-server-0'
INFO[0001] Creating LoadBalancer 'k3d-workload-serverlb'
INFO[0001] Using the k3d-tools node to gather environment information
INFO[0001] HostIP: using network gateway 172.17.0.1 address
INFO[0001] Starting cluster 'workload'
INFO[0001] Starting servers...
INFO[0001] Starting node 'k3d-workload-server-0'
INFO[0003] All agents already running.
INFO[0003] Starting helpers...
INFO[0003] Starting node 'k3d-workload-serverlb'
INFO[0009] Injecting records for hostAliases (incl. host.k3d.internal) and for 3 network members into CoreDNS configmap...
INFO[0012] Cluster 'workload' created successfully!
INFO[0012] You can now use it like this:
kubectl cluster-info
```
</TabItem>
</Tabs>
Finally, add your trusted certificate authority.
<Tabs groupId="apply-local-ca">
<TabItem value="command" label="Command">
```bash
kubectl apply --server-side=true -f "$(mkcert -CAROOT)/namespace.yaml"
kubectl apply --server-side=true -n cert-manager -f "$(mkcert -CAROOT)/local-ca.yaml"
```
</TabItem>
<TabItem value="output" label="Output">
```txt showLineNumbers
namespace/cert-manager serverside-applied
secret/local-ca serverside-applied
```
</TabItem>
</Tabs>
You're back to the same state as the first time you completed this guide.
## What you'll need {#requirements}
You'll need the following tools installed to complete this guide.
1. [holos](/docs/install) - to build the platform.
2. [helm](https://helm.sh/docs/intro/install/) - to render Holos components that wrap upstream Helm charts.
3. [k3d](https://k3d.io/#installation) - to provide a k8s api server.
4. [OrbStack](https://docs.orbstack.dev/install) or [Docker](https://docs.docker.com/get-docker/) - to use k3d.
5. [kubectl](https://kubernetes.io/docs/tasks/tools/) - to interact with the k8s api server.
6. [mkcert](https://github.com/FiloSottile/mkcert?tab=readme-ov-file#installation) - to make trusted TLS certificates.
7. [jq](https://jqlang.github.io/jq/download/) - to fiddle with JSON output.
## Configure DNS {#configure-dns}
Configure your machine to resolve `*.holos.localhost` to your loopback
interface. This is necessary for requests to reach the workload cluster. Save
this script to a file and execute it.
```bash showLineNumbers
#! /bin/bash
#
set -euo pipefail
tmpdir="$(mktemp -d)"
finish() {
[[ -d "$tmpdir" ]] && rm -rf "$tmpdir"
}
trap finish EXIT
cd "$tmpdir"
brew install dnsmasq
cat <<EOF >"$(brew --prefix)/etc/dnsmasq.d/holos.localhost.conf"
# Refer to https://holos.run/docs/tutorial/local/k3d/
address=/holos.localhost/127.0.0.1
EOF
if [[ -r /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist ]]; then
echo "dnsmasq already configured"
else
sudo cp "$(brew list dnsmasq | grep 'dnsmasq.plist$')" \
/Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
sudo launchctl unload /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
sudo launchctl load /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
dscacheutil -flushcache
echo "dnsmasq configured"
fi
sudo mkdir -p /etc/resolver
sudo tee /etc/resolver/holos.localhost <<EOF
domain holos.localhost
nameserver 127.0.0.1
EOF
sudo killall -HUP mDNSResponder
echo "all done."
```
## Create the Cluster {#create-the-cluster}
The Workload Cluster is where your applications and services will be deployed.
In production this is usually an EKS, GKE, or AKS cluster.
:::tip
Holos supports all compliant Kubernetes clusters. Holos was developed and tested
on GKE, EKS, Talos, k3s, and Kubeadm clusters.
:::
Create a local registry to speed up image builds and pulls.
```bash
k3d registry create registry.holos.localhost --port 5100
```
Create the workload cluster configured to use the local registry.
```bash
k3d cluster create workload \
--registry-use k3d-registry.holos.localhost:5100 \
--port "443:443@loadbalancer" \
--k3s-arg "--disable=traefik@server:0"
```
Traefik is disabled because Istio provides the same functionality.
## Setup Root CA {#setup-root-ca}
Platforms most often use cert-manager to issue tls certificates. The browser
and tools we're using need to trust these certificates to work together.
Generate a local, trusted root certificate authority with the following script.
Admin access is necessary for `mkcert` to manage the certificate into your trust
stores.
```bash
sudo -v
```
Manage the local CA and copy the CA key to the workload cluster so that cert
manager can manage trusted certificates.
Save this script to a file and execute it to configure a trusted certificate
authority.
```bash showLineNumbers
#! /bin/bash
#
set -euo pipefail
mkcert --install
tmpdir="$(mktemp -d)"
finish() {
[[ -d "$tmpdir" ]] && rm -rf "$tmpdir"
}
trap finish EXIT
cd "$tmpdir"
# Create the local CA Secret with ca.crt, tls.crt, tls.key
mkdir local-ca
cd local-ca
CAROOT="$(mkcert -CAROOT)"
cp -p "${CAROOT}/rootCA.pem" ca.crt
cp -p "${CAROOT}/rootCA.pem" tls.crt
cp -p "${CAROOT}/rootCA-key.pem" tls.key
kubectl create secret generic --from-file=. --dry-run=client -o yaml local-ca > ../local-ca.yaml
echo 'type: kubernetes.io/tls' >> ../local-ca.yaml
cd ..
cat <<EOF > namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
labels:
kubernetes.io/metadata.name: cert-manager
name: cert-manager
spec:
finalizers:
- kubernetes
EOF
kubectl apply --server-side=true -f namespace.yaml
kubectl apply -n cert-manager --server-side=true -f local-ca.yaml
# Save the Secret to easily reset the cluster later.
install -m 0644 namespace.yaml "${CAROOT}/namespace.yaml"
install -m 0600 local-ca.yaml "${CAROOT}/local-ca.yaml"
```
:::warning
Take care to run the local-ca script each time you create the workload cluster
so that Certificates are issued correctly.
:::
## Clean Up {#clean-up}
If you'd like to clean up the resources you created in this guide, remove them
with:
```bash
k3d cluster delete workload
```
## Next Steps
Now that you have a real cluster, apply and explore the manifests Holos renders
in the [Quickstart](/docs/quickstart) guide.

View File

@@ -1,106 +0,0 @@
---
description: Self service platform resource management for project teams.
slug: /guides/manage-a-project
sidebar_position: 200
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import Admonition from '@theme/Admonition';
# Manage a Project
In this guide we'll explore how Holos easily, safely, and consistently manages
platform resources for teams to develop the projects they're working on.
Intended Audience: Platform Engineers and Software Engineers.
Goal is to demonstrate how the platform team can consistently, easily, and
safely provide platform resources to software engineers.
Assumption is software engineers have a container they want to deploy onto the
platform and make accessible. We'll use httpbin as a stand-in for the dev
team's container.
Project is roughly equivalent to Dev Team for the purpose of this guide, but in
practice multiple teams work on a given project over the lifetime of the
project, so we structure the files into projects instead of teams.
## What you'll need {#requirements}
You'll need the following tools installed to complete this guide.
1. [holos](/docs/install) - to build the Platform.
2. [helm](https://helm.sh/docs/intro/install/) - to render Helm Components.
3. [kubectl](https://kubernetes.io/docs/tasks/tools/) - to render Kustomize Components.
If you'd like to apply the manifests we render in this guide complete the
following optional, but recommended, steps.
a. Complete the [Local Cluster] guide to set up a local cluster to work with.
b. You'll need a GitHub account to fork the repository associated with this
guide.
## Fork the Guide Repository
<Tabs groupId="fork">
<TabItem value="command" label="Command">
```bash
```
</TabItem>
<TabItem value="output" label="Output">
```txt showLineNumbers
```
</TabItem>
</Tabs>
This guide assumes you will run commands from the root directory of this
repository unless stated otherwise.
[Quickstart]: /docs/quickstart
[Local Cluster]: /docs/guides/local-cluster
## Render the Platform
So we can build the basic platform. Don't dwell on the platform bits.
## Apply the Manifests
Deploy ArgoCD, but not any of the Application resources.
## Browse to ArgoCD
Note there is nothing here yet.
## Switch to your Fork
Note all of the Applications change consistently.
## Apply the Applications
Note how ArgoCD takes over management, no longer need to k apply.
## Create a Project
Project is a conceptual, not technical, thing in Holos. Mainly about how components are laid out in the filesystem tree.
We use a schematic built into holos as an example, the platform team could use the same or provide a similar template and instructions for development teams to self-serve.
## Render the Platform
Notice:
1. Project is registered with the platform at the root.
2. HTTPRoute and Namespace resources are added close to the root in `projects`
3. Deployment and Service resources are added at the leaf in `projects/httpbin/backend`
## Update the image tag
Add a basic schematic to demonstrate this. May need to add two new flags for image url and image tag to the generate subcommand, but should just be two new fields on the struct.
## Dive Deeper
Set the stage for constraints. Ideas: Limit what resources can be added,
namespaces can be operated in, enforce labels, etc...
Simple, consistent, easy constraints.

View File

@@ -1,724 +0,0 @@
---
description: Try Holos with this quick start guide.
slug: /quickstart
sidebar_position: 100
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import Admonition from '@theme/Admonition';
# Quickstart
In this guide, you'll experience how Holos makes the process of operating a
Platform safer, easier, and more consistent. We'll use Holos to manage a
vendor-provided Helm chart as a Component. Next, we'll mix in our own custom
resources to manage the Component with GitOps. Finally, you'll see how Holos
makes it safer and easier to maintain software over time by surfacing the exact
changes that will be applied when upgrading the vendor's chart to a new version,
before they are actually made.
The [Concepts](/docs/concepts) page defines capitalized terms such as Platform
and Component.
## What you'll need {#requirements}
You'll need the following tools installed to complete this guide.
1. [holos](/docs/install) - to build the Platform.
2. [helm](https://helm.sh/docs/intro/install/) - to render Holos Components that
wrap upstream Helm charts.
Optionally, if you'd like to apply the rendered manifests to a real Cluster,
first complete the [Local Cluster Guide](/docs/guides/local-cluster).
## Install Holos
Install Holos with the following command or other methods listed on the
[Installation](/docs/install/) page.
```bash
go install github.com/holos-run/holos/cmd/holos@latest
```
## Create a Git Repository
Start by initializing an empty Git repository. Holos operates on local files
stored in a Git repository.
<Tabs groupId="init">
<TabItem value="command" label="Command">
```bash
mkdir holos-quickstart
cd holos-quickstart
git init
```
</TabItem>
<TabItem value="output" label="Output">
```txt
Initialized empty Git repository in /holos-quickstart/.git/
```
</TabItem>
</Tabs>
This guide assumes you will run commands from the root directory of the Git
repository unless stated otherwise.
## Generate the Platform {#Generate-Platform}
Generate the Platform code in the repository root. A Platform refers to the
entire set of software holistically integrated to provide a software development
platform for your organization. In this guide, the Platform will include a
single Component to demonstrate how the concepts fit together.
```bash
holos generate platform quickstart
```
Commit the generated platform config to the repository.
<Tabs groupId="commit-platform">
<TabItem value="command" label="Command">
```bash
git add .
git commit -m "holos generate platform quickstart - $(holos --version)"
```
</TabItem>
<TabItem value="output" label="Output">
```txt
[main (root-commit) 0b17b7f] holos generate platform quickstart
213 files changed, 72349 insertions(+)
...
```
</TabItem>
</Tabs>
## Generate a Component {#generate-component}
The platform you generated is currently empty. Run the following command to
generate the CUE code that defines a Helm Component.
<Tabs groupId="gen-podinfo">
<TabItem value="command" label="Command">
```bash
holos generate component podinfo --component-version 6.6.1
```
</TabItem>
<TabItem value="output" label="Output">
```txt
generated component
```
</TabItem>
</Tabs>
The --component-version 6.6.1 flag intentionally installs an older release.
You'll see how Holos assists with software upgrades later in this guide.
The generate component command creates two files: a leaf file,
`components/podinfo/podinfo.gen.cue`, and a root file, `podinfo.gen.cue`. Holos
leverages the fact that [order is
irrelevant](https://cuelang.org/docs/tour/basics/order-irrelevance/) in CUE to
register the component with the Platform by adding a file to the root of the Git
repository. The second file defines the component in the leaf component
directory.
<Tabs groupId="podinfo-files">
<TabItem value="components/podinfo/podinfo.gen.cue" label="Leaf">
`components/podinfo/podinfo.gen.cue`
```cue showLineNumbers
package holos
// Produce a helm chart build plan.
(#Helm & Chart).Output
let Chart = {
Name: "podinfo"
Version: "6.6.1"
Namespace: "default"
Repo: name: "podinfo"
Repo: url: "https://stefanprodan.github.io/podinfo"
Values: {}
}
```
</TabItem>
<TabItem value="podinfo.gen.cue" label="Root">
`podinfo.gen.cue`
```cue showLineNumbers
package holos
// Manage podinfo on workload clusters only
for Cluster in #Fleets.workload.clusters {
#Platform: Components: "\(Cluster.name)/podinfo": {
path: "components/podinfo"
cluster: Cluster.name
}
}
```
</TabItem>
</Tabs>
In this example, we provide the minimal information needed to manage the Helm
chart: the name, version, Kubernetes namespace for deployment, and the chart
repository location.
This chart deploys cleanly without any values provided, but we include an empty
Values struct to show how Holos improves consistency and safety in Helm by
leveraging the strong type-checking in CUE. You can safely pass shared values,
such as the organizations domain name, to all Components across all clusters in
the Platform by defining them at the root of the configuration.
Commit the generated component config to the repository.
<Tabs groupId="commit-component">
<TabItem value="command" label="Command">
```bash
git add .
git commit -m "holos generate component podinfo - $(holos --version)"
```
</TabItem>
<TabItem value="output" label="Output">
```txt
[main cc0e90c] holos generate component podinfo
2 files changed, 24 insertions(+)
create mode 100644 components/podinfo/podinfo.gen.cue
create mode 100644 podinfo.gen.cue
```
</TabItem>
</Tabs>
## Render the Component
You can render individual components without adding them to a Platform, which is
helpful when developing a new component.
<Tabs groupId="render-podinfo">
<TabItem value="command" label="Command">
```bash
holos render component ./components/podinfo --cluster-name=default
```
</TabItem>
<TabItem value="output" label="Output">
```txt
cached
rendered podinfo
```
</TabItem>
</Tabs>
First, the command caches the Helm chart locally to speed up subsequent
renderings. Then, the command runs Helm to produce the output and writes it into
the deploy directory.
<Tabs groupId="tree-podinfo">
<TabItem value="command" label="Command">
```bash
tree deploy
```
</TabItem>
<TabItem value="output" label="Output">
```txt
deploy
└── clusters
└── default
└── components
└── podinfo
└── podinfo.gen.yaml
5 directories, 1 file
```
</TabItem>
</Tabs>
The component deploys to one cluster named `default`. In practice, the same
component is often deployed to multiple clusters, such as `east` and `west` to
provide redundancy and increase availability.
:::tip
This example is equivalent to running `helm template` on the chart and saving
the output to a file. Holos simplifies this task, making it safer and more
consistent when managing many charts.
:::
## Mix in an ArgoCD Application
We've seen how Holos works with Helm, but we haven't yet explored how Holos
makes it easier to consistently and safely manage all of the software in a
Platform.
Holos allows you to easily mix in resources that differentiate your Platform.
We'll use this feature to mix in an ArgoCD [Application][application] to manage
the podinfo Component with GitOps. We'll define this configuration in a way that
can be automatically and consistently reused across all future Components added
to the Platform.
Create a new file named `argocd.cue` in the root of your Git repository with the
following contents:
<Tabs groupId="argocd-config">
<TabItem value="command" label="argocd.cue">
```cue showLineNumbers
package holos
#ArgoConfig: {
Enabled: true
RepoURL: "https://github.com/holos-run/holos-quickstart-guide"
}
```
</TabItem>
</Tabs>
:::tip
If you plan to apply the rendered output to a real cluster, change the
`example.com` RepoURL to the URL of the Git repository you created in this
guide. You don't need to change the example if you're just exploring Holos by
inspecting the rendered output without applying it to a live cluster.
:::
With this file in place, render the component again.
<Tabs groupId="render-podinfo-argocd">
<TabItem value="command" label="Command">
```bash
holos render component ./components/podinfo --cluster-name=default
```
</TabItem>
<TabItem value="output" label="Output">
```txt
wrote deploy file
rendered gitops/podinfo
rendered podinfo
```
</TabItem>
</Tabs>
Holos uses the locally cached chart to improve performance and reliability. It
then renders the Helm template output along with an ArgoCD Application resource
for GitOps.
:::tip
By defining the ArgoCD configuration at the root, we again take advantage of the
fact that [order is
irrelevant](https://cuelang.org/docs/tour/basics/order-irrelevance/) in CUE.
:::
Defining the configuration at the root ensures all future leaf Components take
the ArgoCD configuration and render an Application manifest for GitOps
management.
<Tabs groupId="tree-podinfo-argocd">
<TabItem value="command" label="Command">
```bash
tree deploy
```
</TabItem>
<TabItem value="output" label="Output">
```txt
deploy
└── clusters
└── default
├── components
│   └── podinfo
│   └── podinfo.gen.yaml
└── gitops
└── podinfo.application.gen.yaml
6 directories, 2 files
```
</TabItem>
</Tabs>
Notice the new `podinfo.application.gen.yaml` file created by enabling ArgoCD in
the Helm component. The Application resource in the file looks like this:
<Tabs groupId="podinfo-application">
<TabItem value="file" label="podinfo.application.gen.yaml">
```yaml showLineNumbers
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: podinfo
namespace: argocd
spec:
destination:
server: https://kubernetes.default.svc
project: default
source:
path: ./deploy/clusters/default/components/podinfo
repoURL: https://example.com/holos-quickstart.git
targetRevision: main
```
</TabItem>
</Tabs>
:::tip
Holos generates a similar Application resource for every additional Component
added to your Platform.
:::
Finally, add and commit the results to your Platform's Git repository.
<Tabs groupId="commit-argo">
<TabItem value="command" label="Command">
```bash
git add .
git commit -m "holos render component ./components/podinfo --cluster-name=default"
```
</TabItem>
<TabItem value="output" label="Output">
```txt
[main f95cef1] holos render component ./components/podinfo --cluster-name=default
3 files changed, 134 insertions(+)
create mode 100644 argocd.cue
create mode 100644 deploy/clusters/default/components/podinfo/podinfo.gen.yaml
create mode 100644 deploy/clusters/default/gitops/podinfo.application.gen.yaml
```
</TabItem>
</Tabs>
In this section, we learned how Holos simplifies mixing resources into
Components, like an ArgoCD Application. Holos ensures consistency by managing an
Application resource for every Component added to the Platform through the
configuration you define in `argocd.cue` at the root of the repository.
## Define Workload Clusters {#workload-clusters}
We've generated a Component to manage podinfo and integrated it with our
Platform, but rendering the Platform doesn't render podinfo. Podinfo isn't
rendered because we haven't assigned any Clusters to the workload Fleet.
Define two new clusters, `east` and `west`, and assign them to the workload
Fleet. Create a new file named `clusters.cue` in the root of your Git repository
with the following contents:
<Tabs groupId="clusters">
<TabItem value="clusters.cue" label="clusters.cue">
```cue showLineNumbers
package holos
// Define two workload clusters for disaster recovery.
#Fleets: workload: clusters: {
// In CUE _ indicates values are defined elsewhere.
east: _
west: _
}
```
</TabItem>
</Tabs>
This example shows how Holos simplifies configuring multiple clusters with
similar configuration by grouping them into a Fleet.
:::tip
Fleets help segment a group of Clusters into one leader and multiple followers
by designating one cluster as the primary. Holos makes it safer, easier, and
more consistent to reconfigure which cluster is the primary. The primary can be
set to automatically restore persistent data from backups, while non-primary
clusters can be configured to automatically replicate from the primary.
Automatic database backup, restore, and streaming replication is an advanced
topic enabled by Cloud Native PG and CUE. Check back for a guide on this and
other Day 2 operations topics.
:::
## Render the Platform {#render-platform}
Render the Platform to render the podinfo Component for each of the workload
clusters.
<Tabs groupId="render-platform">
<TabItem value="command" label="Command">
```bash
holos render platform ./platform
```
</TabItem>
<TabItem value="output" label="Output">
```txt
rendered components/podinfo for cluster west in 99.480792ms
rendered components/podinfo for cluster east in 99.882667ms
```
</TabItem>
</Tabs>
The render platform command iterates over every Cluster in the Fleet and renders
each Component assigned to the Fleet. Notice the two additional subdirectories
created under the deploy directory, one for each cluster: `east` and `west`.
<Tabs groupId="tree-platform">
<TabItem value="command" label="Command">
```bash
tree deploy
```
</TabItem>
<TabItem value="output" label="Output">
```txt
deploy
└── clusters
├── default
│   ├── components
│   │   └── podinfo
│   │   └── podinfo.gen.yaml
│   └── gitops
│   └── podinfo.application.gen.yaml
# highlight-next-line
├── east
│   ├── components
│   │   └── podinfo
│   │   └── podinfo.gen.yaml
│   └── gitops
│   └── podinfo.application.gen.yaml
# highlight-next-line
└── west
├── components
│   └── podinfo
│   └── podinfo.gen.yaml
└── gitops
└── podinfo.application.gen.yaml
14 directories, 6 files
```
</TabItem>
</Tabs>
Holos ensures consistency and safety by defining the ArgoCD Application once,
with strong type checking, at the configuration root.
New Application resources are automatically generated for the `east` and `west`
workload Clusters.
<Tabs groupId="applications">
<TabItem value="east" label="east">
`deploy/clusters/east/gitops/podinfo.application.gen.yaml`
```yaml showLineNumbers
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: podinfo
namespace: argocd
spec:
destination:
server: https://kubernetes.default.svc
project: default
source:
# highlight-next-line
path: ./deploy/clusters/east/components/podinfo
repoURL: https://example.com/holos-quickstart.git
targetRevision: main
```
</TabItem>
<TabItem value="west" label="west">
`deploy/clusters/west/gitops/podinfo.application.gen.yaml`
```yaml showLineNumbers
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: podinfo
namespace: argocd
spec:
destination:
server: https://kubernetes.default.svc
project: default
source:
# highlight-next-line
path: ./deploy/clusters/west/components/podinfo
repoURL: https://example.com/holos-quickstart.git
targetRevision: main
```
</TabItem>
<TabItem value="default" label="default">
`deploy/clusters/default/gitops/podinfo.application.gen.yaml`
```yaml showLineNumbers
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: podinfo
namespace: argocd
spec:
destination:
server: https://kubernetes.default.svc
project: default
source:
# highlight-next-line
path: ./deploy/clusters/default/components/podinfo
repoURL: https://example.com/holos-quickstart.git
targetRevision: main
```
</TabItem>
</Tabs>
Add and commit the rendered Platform and workload Clusters.
<Tabs groupId="commit-render-platform">
<TabItem value="command" label="Command">
```bash
git add .
git commit -m "holos render platform ./platform - $(holos --version)"
```
</TabItem>
<TabItem value="output" label="Output">
```txt
[main 5aebcf5] holos render platform ./platform - 0.93.2
5 files changed, 263 insertions(+)
create mode 100644 clusters.cue
create mode 100644 deploy/clusters/east/components/podinfo/podinfo.gen.yaml
create mode 100644 deploy/clusters/east/gitops/podinfo.application.gen.yaml
create mode 100644 deploy/clusters/west/components/podinfo/podinfo.gen.yaml
create mode 100644 deploy/clusters/west/gitops/podinfo.application.gen.yaml
```
</TabItem>
</Tabs>
## Upgrade a Helm Chart
Holos is designed to ease the burden of Day 2 operations. With Holos, upgrading
software, integrating new software, and making safe platform-wide configuration
changes become easier.
Let's upgrade the podinfo Component to see how this works in practice. First,
update the Component version field to the latest upstream Helm chart version.
<Tabs groupId="gen-podinfo">
<TabItem value="command" label="Command">
```bash
holos generate component podinfo --component-version 6.6.2
```
</TabItem>
<TabItem value="output" label="Output">
```txt
generated component
```
</TabItem>
</Tabs>
Remove the cached chart version.
<Tabs groupId="gen-podinfo">
<TabItem value="command" label="Command">
```bash
rm -rf components/podinfo/vendor
```
</TabItem>
</Tabs>
Now re-render the Platform.
<Tabs groupId="render-platform2">
<TabItem value="command" label="Command">
```bash
holos render platform ./platform
```
</TabItem>
<TabItem value="output" label="Output">
```txt
rendered components/podinfo for cluster east in 327.10475ms
rendered components/podinfo for cluster west in 327.796541ms
```
</TabItem>
</Tabs>
Notice we're still using the upstream chart without modifying it. The Holos
component wraps around the chart to mix in additional resources and integrate
the component with the broader Platform.
## Visualize the Changes
Holos makes it easier to see exactly what changes are made and which resources
will be applied to the API server. By design, Holos operates on local files,
leaving the task of applying them to ecosystem tools like `kubectl` and ArgoCD.
This allows platform operators to inspect changes during code review, or before
committing the change at all.
For example, using `git diff`, we see that the only functional change when
upgrading this Helm chart is the deployment of a new container image tag to each
cluster. Additionally, we can roll out this change gradually by applying it to
the east cluster first, then to the west cluster, limiting the potential blast
radius of a problematic change.
<Tabs groupId="git-diff">
<TabItem value="command" label="Command">
```bash
git diff deploy/clusters/east
```
</TabItem>
<TabItem value="output" label="Output">
```diff showLineNumbers
diff --git a/deploy/clusters/east/components/podinfo/podinfo.gen.yaml b/deploy/clusters/east/components/podinfo/podinfo.gen.yaml
index 7cc3332..8c1647d 100644
--- a/deploy/clusters/east/components/podinfo/podinfo.gen.yaml
+++ b/deploy/clusters/east/components/podinfo/podinfo.gen.yaml
@@ -5,9 +5,9 @@ kind: Service
metadata:
name: podinfo
labels:
- helm.sh/chart: podinfo-6.6.1
+ helm.sh/chart: podinfo-6.6.2
app.kubernetes.io/name: podinfo
- app.kubernetes.io/version: "6.6.1"
+ app.kubernetes.io/version: "6.6.2"
app.kubernetes.io/managed-by: Helm
spec:
type: ClusterIP
@@ -29,9 +29,9 @@ kind: Deployment
metadata:
name: podinfo
labels:
- helm.sh/chart: podinfo-6.6.1
+ helm.sh/chart: podinfo-6.6.2
app.kubernetes.io/name: podinfo
- app.kubernetes.io/version: "6.6.1"
+ app.kubernetes.io/version: "6.6.2"
app.kubernetes.io/managed-by: Helm
spec:
replicas: 1
@@ -53,7 +53,7 @@ spec:
terminationGracePeriodSeconds: 30
containers:
- name: podinfo
# highlight-next-line
- image: "ghcr.io/stefanprodan/podinfo:6.6.1"
# highlight-next-line
+ image: "ghcr.io/stefanprodan/podinfo:6.6.2"
imagePullPolicy: IfNotPresent
command:
- ./podinfo
```
</TabItem>
</Tabs>
:::tip
Holos is designed to surface the _fully rendered_ manifests intended for the
Kubernetes API server, making it easier to see and reason about platform-wide
configuration changes.
:::
## Recap {#recap}
In this quickstart guide, we learned how Holos makes it easier, safer, and more
consistent to manage a Platform composed of multiple Clusters and upstream Helm
charts.
We covered how to:
1. Generate a Git repository for the Platform config.
2. Wrap the unmodified upstream podinfo Helm chart into a Component.
3. Render an individual Component.
4. Mix-in your Platform's unique resources to all Components. For example, ArgoCD Application resources.
5. Define multiple similar, but not identical, workload clusters.
6. Render the manifests for the entire Platform with the `holos render platform` command.
7. Upgrade a Helm chart to the latest version as an important Day 2 task.
8. Visualize and surface the details of planned changes Platform wide.
## Dive Deeper
If you'd like to dive deeper, check out the [Schema API][schema] and [Core
API][core] reference docs. The main difference between the schema and core
packages is that the schema is used by users to write refined CUE, while the
core package is what the schema produces for `holos` to execute. Users rarely
need to interact with the Core API when on the happy path, but can use the core
package as an escape hatch when the happy path doesn't go where you want.
[application]: https://argo-cd.readthedocs.io/en/stable/user-guide/application-specification/
[schema]: /docs/api/schema/v1alpha3/
[core]: /docs/api/core/v1alpha3/

View File

@@ -1,10 +0,0 @@
---
description: Holos Documentation
slug: /
---
# Introduction
:::warning TODO
See [introduction](https://github.com/facebook/docusaurus/blob/main/website/docs/introduction.mdx?plain=1)
:::

View File

@@ -2,8 +2,8 @@
This document captures notes on locally developing Holos.
Follow the steps in [Try Holos Locally](../guides/try-holos), but take care
to select `Develop` tabs when creating the k3d cluster so you have a local
Follow the steps in [Try Holos Locally](/docs/tutorial/local/k3d), but take
care to select `Develop` tabs when creating the k3d cluster so you have a local
registry to push to.
## Apply Resources

View File

@@ -1,3 +1,81 @@
# Architecture
Coming soon.
This page describes the architecture of the Holos reference platform.
## Overview
The reference platform manages three kubernetes clusters by default. One management cluster and two workload clusters.
```mermaid
graph TB
subgraph "Management"
secrets(Secrets)
c1(Controllers)
end
subgraph "Primary"
s1p(Service 1)
s2p(Service 2)
end
subgraph "Standby"
s1s(Service 1)
s2s(Service 2)
end
classDef plain fill:#ddd,stroke:#fff,stroke-width:4px,color:#000;
classDef k8s fill:#326ce5,stroke:#fff,stroke-width:4px,color:#fff;
classDef cluster fill:#fff,stroke:#bbb,stroke-width:2px,color:#326ce5;
class c1,s1p,s2p,s1s,s2s,secrets k8s;
class Management,Primary,Standby cluster;
```
The services in each cluster type are:
:::tip
The management cluster is designed to operate reliably on spot instances. A highly available management cluster typically costs less than a cup of coffee per month to operate.
:::
1. Management Cluster
- **SecretStore** to provide namespace scoped secrets to workload clusters.
- **CertManager** to provision TLS certificates and make them available to workload clusters.
- **ClusterAPI** to provision and manage workload clusters via GitOps. For example, EKS or GKE clusters.
- **Crossplane** to provision and manage cloud resources via GitOps. For example, buckets, managed databases, any other cloud resource.
- **CronJobs** to refresh short lived credentials. For example image pull credentials.
- **ArgoCD** to manage resources within the management cluster via GitOps.
2. Primary Workload Cluster
- **ArgoCD** to continuously deploy your applications and services via GitOps.
- **External Secrets Operator** to synchronize namespace scoped secrets.
- **Istio** to provide a Gateway to expose services.
- **ZITADEL** to provide SSO login for all other services (e.g. ArgoCD, Grafana, Backstage, etc...)
- **PostgreSQL** for in-cluster databases.
- **Backstage** to provide your developer portal into the whole platform.
- **Observability** implemented by Prometheus, Grafana, and Loki to provide monitoring and logging.
- **AuthorizationPolicy** to provide role based access control to all services in the cluster.
3. Standby Workload Cluster
- Identical configuration to the primary cluster.
- May be scaled down to zero to reduce expenses.
- Intended to take the primary cluster role quickly, within minutes, for disaster recovery or regular maintenance purposes.
## Security
### Namespaces
Namespaces are security boundaries in the reference platform. A given namespace is treated as the same security context across multiple clusters following the [SIG Multi-cluster Position](https://github.com/kubernetes/community/blob/dd4c8b704ef1c9c3bfd928c6fa9234276d61ad18/sig-multicluster/namespace-sameness-position-statement.md).
The namespace sameness principle makes role based access control straightforward to manage and comprehend. For example, granting a developer the ability to create secrets in namespace `example` means the developer has the ability to do so in the secret store in the management cluster and also synchronize the secret to the services they own in the workload clusters.
## Data Platform
Holos is designed to work with two distinct types of databases by default:
1. In-cluster PostgresSQL databases for lower cost and rapid development and testing.
2. Out-of-cluster SQL databases for production services, e.g. RDS, CloudSQL, Aurora, Redshift, etc...
:::tip
To simplify maintenance the holos reference platform provisions databases from the most recent backup by default.
:::
In-cluster databases in the holos reference platform automatically save backups to an S3 or GCS bucket. For regular maintenance and disaster recovery, the standby cluster automatically restores databases from the most recent backup in the bucket. This capability makes maintenance much simpler, most maintenance tasks are carried out on the standby cluster which is then promoted to the primary. Software upgrades in particular are intended to be carried out against the standby, verified, then promoted to primary. Once live traffic shifts to the upgraded services in the new primary the previous cluster can be spun down to save cost or upgraded safely in place.

View File

@@ -1,31 +0,0 @@
# Deployment
This document describes how deployment from `main` is configured.
1. Refer to the publish workflow.
2. Uses a SSH deploy key to:
3. Clone the holos-infra repo.
4. Write the image tag to saas/userdata/components/dev-holos-app/images.json
5. Run holos render platform ./platform
6. Commit and push the results.
7. ArgoCD takes over the rollout.
## Credentials
TODO: Lock this down more, the deploy key has too much access to the infra
repository.
```bash
mkdir -p tmp
cd tmp
ssh-keygen -t ed25519 -f holos-infra.key -m pem -C holos-run/holos -N ''
gh secret set DEPLOY_SSH_PRIVATE_KEY < holos-infra.key
gh api --method POST \
-H "Accept: application/vnd.github+json" \
/repos/holos-run/holos-infra/keys \
-f title='holos-run/holos deploy key' \
-f key="$(cat holos-infra.key.pub)" \
-F read_only=false
cd ..
rm -rf tmp
```

View File

@@ -1,10 +0,0 @@
# ZITADEL Backups
Refer to [Schedule backups](https://cloudnative-pg.io/documentation/1.23/backup/#scheduled-backups)
By default ZITADEL is backed up daily to S3. When restoring into a new cluster
of the same name, increment the revision variable to create a new blank folder
for the new cluster WAL. The cluster will not initialize unless the WAL
directory is empty.
The cluster will recovery from the previous rev.

View File

@@ -1,3 +0,0 @@
## Overview
TODO: This runbook needs to be updated to reflect the switch from PGO to CNPG.

View File

@@ -1,3 +0,0 @@
# Postgres Full Backup
Refer to [On-demand backups](https://cloudnative-pg.io/documentation/1.23/backup/#on-demand-backups)

View File

@@ -1,5 +0,0 @@
import DocCardList from '@theme/DocCardList';
# Get Started
<DocCardList />

View File

@@ -1,70 +0,0 @@
---
description: Compare Holos with other tools in the ecosystem.
slug: /comparison
sidebar_position: 300
---
# Comparison
:::tip
Holos is designed to complement and improve, not replace, existing tools in the
cloud native ecosystem.
:::
## Helm
### Chart Users
Describe how things are different when using an upstream helm chart.
### Chart Authors
Describe how things are different when writing a new helm chart.
## Kustomize
TODO
## ArgoCD
TODO
## Flux
TODO
## Timoni
| Aspect | Timoni | Holos | Comment |
| ---------- | -------------------- | -------------------- | ---------------------------------------------------------------------------------------- |
| Language | CUE | CUE | Like Holos, Timoni is also built on CUE. |
| Artifact | OCI Image | Plain YAML Files | The Holos Authors find plain files easier to work with and reason about than OCI images. |
| Outputs to | OCI Image Repository | Local Git repository | Holos is designed for use with existing GitOps tools. |
| Concept | Module | Component | A Timoni Module is analogous to a Holos Component. |
| Concept | Bundle | Platform | A Timoni Bundle is somewhat similar, but smaller in scope to a Holos Platform. |
:::important
The Holos Authors are deeply grateful to Stefan and Timoni for the capability of
importing Kubernetes custom resource definitions into CUE. Without this
functionality, much of the Kubernetes ecosystem would be more difficult to
manage in CUE and therefore in Holos.
:::
## KubeVela
1. Also built on CUE.
2. Intended to create an Application abstraction.
3. Holos prioritizes composition over abstraction.
4. An abstraction of an Application acts as a filter that removes all but the lowest common denominator functionality. The Holos Authors have found this filtering effect to create excessive friction for software developers.
5. Holos focuses instead on composition to empower developers and platform engineers to leverage the unique features and functionality of their software and platform.
## Pulumi
TODO
## Jsonnet
TODO

View File

@@ -1,370 +0,0 @@
---
description: Learn the concepts and domain language Holos uses.
slug: /concepts
sidebar_position: 200
---
# Concepts
## Introduction
This page is intended as a high level conceptual overview of the key concepts in
Holos. Refer to the [Core API](/docs/api/core/) for low level reference
documentation.
Holos is a tool built for platform engineers. The Holos authors share three
core values which guide our design decisions for the tool.
1. Safety
2. Ease of use
3. Consistency
Each of the following concepts are intended to support and strengthen one or
more of these core values. In this way we hope to lighten the burden carried by
platform engineers.
## Concepts
- [Component](<#component>) - The primary building block in Holos, wraps a Helm chart, Kustomize base, or plain resources defined in CUE.
- [Platform](<#platform>) - A collection of Components integrated into a software development platform.
- [Model](<#model>) - Structured data included in the Platform specification, available to all Components. For example, your organization's domain name.
- [Rendering](<#rendering>) - Holos is a tool that makes the process of rendering Kubernetes manifests safer, easier, and consistent.
- [Cluster](<#cluster>) - A Kubernetes cluster. Components are rendered for and applied to a Cluster.
- [Fleet](<#fleet>) - A collection of Clusters with a similar purpose. A Platform is typically composed of two Fleets, one for management the second for workloads.
```mermaid
graph TB
Platform[<a href="#platform">Platform</a>]
Cluster[<a href="#cluster">Cluster</a>]
Fleet[<a href="#fleet">Fleet</a>]
Component[<a href="#component">Component</a>]
Helm[<a href="#component">Helm</a>]
Kustomize[<a href="#component">Kustomize</a>]
CUE[<a href="#component">CUE</a>]
Cluster --> Platform
Fleet --> Cluster
Component --> Fleet
Helm --> Component
Kustomize --> Component
CUE --> Component
```
:::tip
This graph is organized as a tree. We often say configuration at the root
defines the broad Platform. Configuration at a leaf defines a Component of the
Platform. The concept of a tree also reflects the filesystem organization of
the configuration.
:::
<!--
```mermaid
---
title: Figure 1 - Holos Concepts
---
mindmap
root((Holos))
Platform
Components
HelmChart
KustomizeBuild
KubernetesObjects
Model
name: Example Org
domain: example.com
Renders
YAML Files
Kubernetes Manifests
ArgoCD Application
FluxCD Kustomization
```
-->
## Component
A Component is the primary building block when managing software with Holos. A
software project you wish to integrate into your platform, for example ArgoCD,
is managed using one or more components.
The primary Component kinds are:
1. **HelmChart** to render config provided by Helm.
2. **KustomizeBuild** to render config provided by Kustomize.
3. **KubernetesObjects** to render config provided by CUE.
Components are intended to integrate unmodified upstream software releases into
your Platform. In this way, the focus of a Component is more about the unique
differentiating aspects of your platform than the upstream software contained in
the Component.
#### Example HelmChart Component
The ArgoCD Component is a good example of a HelmChart component because it takes
advantage of most of the key features that empower you to focus on the key
differentiators of your unique platform.
Take note of the following key points in this example ArgoCD Component:
1. The Component wraps the ArgoCD Helm Chart in a way that's easy to upgrade and maintain over time.
2. Newer Gateway API resources are mixed-in replacing the older Ingress resource included in the chart.
3. Helm output is passed through Kustomize to configure secure mutual TLS encryption.
4. Helm values are easier and safer to manipulate with CUE instead of text markup.
5. Kustomize is easier and safer to manipulate with CUE instead of text markup.
6. Platform data Model values are easily accessible, for example the OIDC issuer and the organizations's domain name.
The Component wraps around the unmodified upstream ArgoCD helm chart
providing easier upgrades as new versions are released.
Note how the Component facilitates composition by allowing us to mix-in new
functionality from the ecosystem without modifying the upstream chart. The
Platform this Component integrates with uses the new Gateway API, but the
upstream helm chart does not yet support Gateway API. See how the Resources
field is used to mix-in a ReferenceGrant from the Gateway API without modifying
the upstream helm chart.
The Platform uses Istio to implement service to service encryption with mutual
TLS. The Component passes the Helm output to Kustomize to integrate with Istio.
Kustomize is used to patch the argocd-server Deployment resource to inject the
Istio sidecar for mutual TLS.
Helm values are safer and easier to work with in CUE. Note how you can modify
helm values using well defined data instead of manipulating text yaml files.
Similarly, the yaml files used for Kustomize are produced by CUE, which is again
safer and easier because the Kustomize spec has been imported into CUE and is
validated.
Finally, the domain name used by this Platform is easily accessible from the
PlatformSpec which is defined at the root level and made available to all
components integrated into the platform. Similarly, data values shared by all
of the Components that make up ArgoCD is defined in a structure accessible by
each of these components.
```cue
package holos
import (
"encoding/yaml"
"strings"
)
// Produce a helm chart build plan.
(#Helm & Chart).Output
let Chart = {
Name: "argo-cd"
Namespace: "argocd"
Version: "7.1.1"
Chart: chart: release: "argocd"
// The upstream chart uses a Job to create the argocd-redis Secret. Enable
// hooks to enable the Job.
Chart: enableHooks: true
Repo: name: "argocd"
Repo: url: "https://argoproj.github.io/argo-helm"
// Ensure all of our mix-in resources go into the same namespace as the Chart.
Resources: [_]: [_]: metadata: namespace: Namespace
// Grant the Gateway namespace the ability to refer to the backend service
// from HTTPRoute resources.
Resources: ReferenceGrant: (#IstioGatewaysNamespace): #ReferenceGrant
// Pass the helm output through kustomize.
EnableKustomizePostProcessor: true
// Force all resources into the component namespace, some resources in the
// helm chart do not specify the namespace so they will get mis-applied
// when the kubectl (client-go) context is another namespace.
KustomizeFiles: "kustomization.yaml": namespace: Namespace
// Patch the backend with the service mesh sidecar.
KustomizePatches: {
mesh: {
target: {
group: "apps"
version: "v1"
kind: "Deployment"
name: "argocd-server"
}
patch: yaml.Marshal(IstioInject)
}
}
Values: #Values & {
kubeVersionOverride: "1.29.0"
// handled in the argo-crds component
crds: install: false
global: domain: "argocd.\(_Platform.Model.org.domain)"
dex: enabled: false
// the service mesh handles secure mTLS
configs: params: "server.insecure": true
configs: cm: {
"admin.enabled": false
"oidc.config": yaml.Marshal(OIDCConfig)
"users.anonymous.enabled": "false"
}
// Refer to https://argo-cd.readthedocs.io/en/stable/operator-manual/rbac/
let Policy = [
"g, argocd-view, role:readonly",
"g, prod-cluster-view, role:readonly",
"g, prod-cluster-edit, role:readonly",
"g, prod-cluster-admin, role:admin",
]
configs: rbac: "policy.csv": strings.Join(Policy, "\n")
}
}
let IstioInject = [{
op: "add",
path: "/spec/template/metadata/labels/sidecar.istio.io~1inject",
value: "true",
}]
let OIDCConfig = {
name: "Holos Platform"
issuer: _ArgoCD.issuerURL
clientID: _ArgoCD.clientID
requestedScopes: _ArgoCD.scopesList
// Set redirect uri to https://argocd.example.com/pkce/verify
enablePKCEAuthentication: true
// groups is essential for rbac
requestedIDTokenClaims: groups: essential: true
}
```
## Platform
A Platform refers to all of the software and services integrated together to
provide your organization's software development platform. Holos is designed to
manage all of the resources that compose your Platform using the [Kubernetes
Resource Model][krm] (KRM). Nearly all platforms are larger than Kubernetes
itself. For example, your developers likely need a GCS or S3 bucket to store
data. Holos takes advantage of Crossplane to manage resources in a consistent
way.
Holos defines a [Platform][Platform] object which collects multiple Components
together along with organizational data defined by your Model. Consider the
following example, which is a Platform that manages a single Component which
manages namespaces for each cluster in the Platform.
```cue
package holos
import v1 "github.com/holos-run/holos/api/v1alpha2"
v1.#Platform & {
metadata: name: "example"
spec: components: [{
path: "components/namespaces"
cluster: "cluster1"
}]
}
```
This platform is rendered by the command:
```bash
holos render platform ./platform
```
When Holos renders the platform, it iterates over each component, generates and
executes a [BuildPlan][BuildPlan], then writes the fully rendered output of the
component to the filesystem. In this simple example, two files are produced:
1. `deploy/clusters/cluster1/components/namespaces/namespaces.gen.yaml`
2. `deploy/clusters/cluster1/gitops/namespaces.application.gen.yaml`
The first file is a plain kubernetes manifest containing Namespace resources.
The second file is an ArgoCD Application resource to deploy and manage the
resources defined in the first file.
## Model
The Platform Model is where you store top-level data values used throughout
multiple components in your Platform. Your organization's domain name is a
prime example of the kind of data stored in the Model. Many components derive
host names from your organization's domain name. CUE makes this process safe,
easy, and consistent. For example:
```cue
hostname: "argocd.\(_Platform.Model.org.domain)"
```
When Holos renders a Platform, the model is loaded from a JSON file in the local
filesystem. The platform model file is intended to be committed to version
control along with the rest of the Holos Platform and Component code.
Holos additionally provides a web ui and form to make it easy to enter and
validate top level configuration data. You have complete control over the web
form, it's rendered from JSON data defined by CUE. Customizing the web form is
an advanced topic, the key concept to take away is the Model is for top level,
platform-wide data. You control the shape and structure of the Model, and you
have the ability to collect Model values using a simple web form.
## Rendering
Holos uses the Kubernetes resource model to manage configuration. The Holos
command line interface is the primary method you'll use to manage your platform.
Holos uses CUE to provide a unified configuration model of the platform. This
unified configuration is built up from components packaged with Helm, Kustomize,
CUE, or any other tool that can produce Kubernetes resource manifests as output.
This process can be thought of as a data **rendering pipeline**. The key
concept is that Holos will always produce fully rendered output, but delegates
the _application_ of the configuration to other tools like kubectl apply,
ArgoCD, or Flux.
```mermaid
---
title: Figure 2 - Render Pipeline
---
graph LR
PS[<a href="/docs/api/core/v1alpha2#PlatformSpec">PlatformSpec</a>]
BP[<a href="/docs/api/core/v1alpha2#BuildPlan">BuildPlan</a>]
HC[<a href="/docs/api/core/v1alpha2#HolosComponent">Components</a>]
H[<a href="/docs/api/core/v1alpha2#HelmChart">HelmChart</a>]
K[<a href="/docs/api/core/v1alpha2#KustomizeBuild">KustomizeBuild</a>]
O[<a href="/docs/api/core/v1alpha2#KubernetesObjects">KubernetesObjects</a>]
P[<a href="/docs/api/core/v1alpha2#Kustomize">Kustomize</a>]
Y[Kubernetes <br/>Resources]
G[GitOps <br/>Resource]
FS[Local Files]
C[Kube API Server]
PS --> BP --> HC
HC --> H --> P
HC --> K --> P
HC --> O --> P
P --> Y --> FS
P --> G --> FS
FS --> ArgoCD --> C
FS --> Flux --> C
FS --> kubectl --> C
```
## Cluster
A Cluster represents a Kubernetes cluster. One component may be reused across
multiple different Clusters.
## Fleet
A Fleet represents a group of Clusters that share a similar purpose. A Platform
typically has two Fleets, one for management and one for workloads.
[krm]: https://docs.google.com/document/d/1RmHXdLhNbyOWPW_AtnnowaRfGejw-qlKQIuLKQWlwzs/view#heading=h.sa6p0aye4ide
[Platform]: /docs/api/core/v1alpha2/#Platform
[BuildPlan]: /docs/api/core/v1alpha2/#BuildPlan

View File

@@ -1,10 +1,4 @@
---
description: Install the Holos executable.
slug: /install
sidebar_position: 100
---
# Installation
# Install Holos
Holos is distributed as a single file executable.
@@ -24,3 +18,4 @@ go install github.com/holos-run/holos/cmd/holos@latest
- [helm](https://github.com/helm/helm/releases) to fetch and render Helm chart components.
- [kubectl](https://kubernetes.io/docs/tasks/tools/) to [kustomize](https://kustomize.io/) components.

View File

Before

Width:  |  Height:  |  Size: 934 KiB

After

Width:  |  Height:  |  Size: 934 KiB

View File

Before

Width:  |  Height:  |  Size: 703 KiB

After

Width:  |  Height:  |  Size: 703 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

Before

Width:  |  Height:  |  Size: 1014 KiB

After

Width:  |  Height:  |  Size: 1014 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

Before

Width:  |  Height:  |  Size: 1014 KiB

After

Width:  |  Height:  |  Size: 1014 KiB

View File

Before

Width:  |  Height:  |  Size: 854 KiB

After

Width:  |  Height:  |  Size: 854 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

Before

Width:  |  Height:  |  Size: 116 KiB

After

Width:  |  Height:  |  Size: 116 KiB

View File

@@ -0,0 +1,847 @@
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
# Try Holos Locally
Learn how to configure and deploy the Holos reference platform to your local
host with k3d.
---
This guide assumes commands are run from your local host. Capitalized terms
have specific definitions described in the [Glossary](/docs/glossary).
## Requirements
You'll need the following tools installed on your local host to complete this guide.
1. [k3d](https://k3d.io/#installation) - to provide an api server.
2. [Docker](https://docs.docker.com/get-docker/) - to use k3d.
3. [holos](/docs/tutorial/install) - to build the platform.
4. [kubectl](https://kubernetes.io/docs/tasks/tools/) - to interact with the Kubernetes cluster.
5. [helm](https://helm.sh/docs/intro/install/) - to render Holos components that integrate vendor provided Helm charts.
6. [mkcert](https://github.com/FiloSottile/mkcert?tab=readme-ov-file#installation) - for local trusted certificates.
7. [jq](https://jqlang.github.io/jq/download/) - to manipulate json output.
## Outcome
At the end of this guide you'll have built a development platform that provides
Zero Trust security by holistically integrating off-the-shelf components.
1. ArgoCD to review and apply platform configuration changes.
2. Istio service mesh with mTLS encryption.
3. ZITADEL to provide single sign-on identity tokens with multi factor authentication.
The platform running on your local host will configure Istio to authenticate and
authorize requests using an oidc id token issued by ZITADEL _before_ the request
ever reaches ArgoCD.
:::tip
With Holos, developers don't need to write authentication or authorization logic
for many use cases.
:::
Single sign-on and role based access control are provided by the platform itself
for all service running in the platform using standardized policies.
The `k3d` platform is derived from the larger holos reference platform to
provide a smooth on-ramp to evaluate the value Holos offers.
1. Holos wraps unmodified Helm charts provided by software vendors.
2. Holos eliminates the need to template yaml.
3. Holos is composable, scaling down to local host and up to multi-cloud and multi-cluster.
4. The Zero Trust security model implemented by the reference platform.
5. Configuration unification with CUE.
## Register with Holos
Register an account with the Holos web service. This registration is required
to save platform configuration values via a simple web form and to explore how
Holos implements Zero Trust.
```bash
holos register user
```
## Create the Platform
Create the platform, which stores the Platform Form and its values in the Holos
web service. The Platform Form represents the Platform Model.
```bash
holos create platform --name k3d --display-name "Try Holos Locally"
```
## Generate the Platform
Holos builds the platform by building each component of the platform into fully
rendered Kubernetes configuration resources. Generate the source code for the
platform in a blank local directory. This directory is named `holos-infra` by
convention because it represents the Holos managed platform infrastructure.
Create a new Git repository to store the platform code:
```bash
mkdir holos-k3d
cd holos-k3d
git init .
```
Generate the platform code in the current directory:
```bash
holos generate platform k3d
```
Commit the generated platform config to the repository:
```bash
git add .
git commit -m "holos generate platform k3d - $(holos --version)"
```
## Push the Platform Form
TODO: Describe what the Platform Form is. Why is it needed? To get a value
that varies which ArgoCD needs to make you an admin user.
GREAT IDEA: Add a --open to open the URL in the default browser when pushing so it's an obvious call to action.
Gary wasn't sure what to do with the SUB value... More call to action.
Push the Platform Form to the web service to provide top-level configuration
values from which the platform components derive their final configuration.
```bash
holos push platform form .
```
:::important
Visit the printed URL to view the Platform Form.
:::
![Platform Form](./platform-form.png)
:::tip
You have complete control over the form fields and validation rules.
:::
## Submit the Platform Model
Fill out the form and submit the Platform Model.
For the Role Based Access Control section, provide the value of the `sub`
subject claim of your identity to ensure only you have administrative access to
ArgoCD.
```bash
holos login --print-claims | jq -r .sub
```
For the ArgoCD Git repository URL, enter the url of a public repository where
you will push your local `holos-k3d` repository.
TODO: Make it clear the repo needs to be created.
```bash
git remote add origin https://github.com/example/holos-k3d
git push origin HEAD:main
```
## Pull the Platform Model
The Platform Model is the JSON representation of the Platform Form values.
Holos provides the Platform Model to CUE to render the platform configuration to
plain YAML. Configuration that varies is derived from the Platform Model using
CUE.
Pull the Platform Model to your local host to render the platform.
```bash
holos pull platform model .
```
The `platform.config.json` file is intended to be committed to version control.
```bash
git add platform.config.json
git commit -m "Add platform model"
```
TODO: Do not warn people about storing secrets until the advanced doc about customizing the platform form.jj
TODO: Pull out commentary about the reference platform. Only mention the reference platform at the beginning and end.
NATE: Secret Sauce is going from minimal input into a fully rendered platform. Not Zero Trust, not external secrets. Mention the value of deriving the entire unified platform from a simple customizable input form at the beginning and the end.
## Render the Platform
Rendering the platform iterates over each platform component and renders the
component into the final Kubernetes resources that will be sent to the API Server.
```bash
holos render platform ./platform
```
This command writes fully rendered Kubernetes resource yaml to the `deploy/` directory.
:::warning
Do not edit the files in the `deploy` as they will be written over.
:::
Commit the rendered platform configuration for `git diff` later.
```bash
git add deploy
git commit -m "holos render platform ./platform"
```
### Rendering
Holos uses the Kubernetes resource model to manage configuration. The `holos`
command line interface (cli) is the primary method you'll use to manage your
platform. Holos uses CUE to provide a unified configuration model of the
platform which is built from components packaged with Helm, Kustomize, CUE, or
any tool that can produce Kubernetes resources as output. This process can be
thought of as a yaml **rendering pipeline**.
Each component in a platform defines a rendering pipeline shown in Figure 2 to
produce Kubernetes api resources
```mermaid
---
title: Figure 2 - Render Pipeline
---
graph LR
PS[<a href="/docs/api/core/v1alpha2#PlatformSpec">PlatformSpec</a>]
BP[<a href="/docs/api/core/v1alpha2#BuildPlan">BuildPlan</a>]
HC[<a href="/docs/api/core/v1alpha2#HolosComponent">HolosComponent</a>]
H[<a href="/docs/api/core/v1alpha2#HelmChart">HelmChart</a>]
K[<a href="/docs/api/core/v1alpha2#KustomizeBuild">KustomizeBuild</a>]
O[<a href="/docs/api/core/v1alpha2#KubernetesObjects">KubernetesObjects</a>]
P[<a href="/docs/api/core/v1alpha2#Kustomize">Kustomize</a>]
Y[Kubernetes <br>Resources]
G[GitOps <br>Resource]
C[Kube API Server]
PS --> BP --> HC
HC --> H --> P
HC --> K --> P
HC --> O --> P
P --> Y --> C
P --> G --> C
```
The `holos` cli can be thought of as executing a data pipeline. The Platform
Model is the top level input to the pipeline and specifies the ways your
platform varies from other organizations. The `holos` cli takes the Platform
Model as input and executes a series of steps to produce the platform
configuration. The platform configuration output of `holos` are full
Kubernetes API resources, suitable for application to a cluster with `kubectl
apply -f`, or GitOps tools such as ArgoCD or Flux.
## Review the Platform Config
:::tip
This section is optional, included to provide insight into how Holos uses CUE
and Helm to unify and render the platform configuration.
:::
Take a moment to review the platform config `holos` rendered.
### ArgoCD Application
Note the Git URL you entered into the Platform Form is used to derive the ArgoCD
`Application` resource from the Platform Model.
```yaml
# deploy/clusters/workload/gitops/namespaces.application.gen.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: namespaces
namespace: argocd
spec:
destination:
server: https://kubernetes.default.svc
project: default
source:
# highlight-next-line
path: /deploy/clusters/workload/components/namespaces
# highlight-next-line
repoURL: https://github.com/holos-run/holos-k3d
# highlight-next-line
targetRevision: HEAD
```
One ArgoCD `Application` resource is produced for each Holos component by
default. Note the `cert-manger` component renders the output using Helm.
Holos unifies the Application resource using CUE. The CUE definition which
produces the rendered output is defined in `buildplan.cue` around line 222.
:::tip
Note how CUE does not use error-prone text templates, the language is well
specified and typed which reduces errors when unifying the configuration with
the Platform Model in the following `#Argo` definition.
:::
```cue
// buildplan.cue
// #Argo represents an argocd Application resource for each component, written
// using the #HolosComponent.deployFiles field.
#Argo: {
ComponentName: string
Application: app.#Application & {
metadata: name: ComponentName
metadata: namespace: "argocd"
spec: {
destination: server: "https://kubernetes.default.svc"
project: "default"
source: {
// highlight-next-line
path: "\(_Platform.Model.argocd.deployRoot)/deploy/clusters/\(_ClusterName)/components/\(ComponentName)"
// highlight-next-line
repoURL: _Platform.Model.argocd.repoURL
// highlight-next-line
targetRevision: _Platform.Model.argocd.targetRevision
}
}
}
// deployFiles represents the output files to write along side the component.
deployFiles: "clusters/\(_ClusterName)/gitops/\(ComponentName).application.gen.yaml": yaml.Marshal(Application)
}
```
### Helm Chart
Holos uses CUE to safely integrate the unmodified upstream `cert-manager` Helm
chart.
:::tip
Holos fully supports your existing Helm charts. Consider leveraging `holos` as
an safer alternative to umbrella charts.
:::
```cue
// components/cert-manager/cert-manager.cue
package holos
// Produce a helm chart build plan.
(#Helm & Chart).Output
let Chart = {
Name: "cert-manager"
Version: "1.14.5"
Namespace: "cert-manager"
Repo: name: "jetstack"
Repo: url: "https://charts.jetstack.io"
// highlight-next-line
Values: {
installCRDs: true
startupapicheck: enabled: false
// Must not use kube-system on gke autopilot. GKE Warden blocks access.
// highlight-next-line
global: leaderElection: namespace: Namespace
// https://cloud.google.com/kubernetes-engine/docs/concepts/autopilot-resource-requests#min-max-requests
resources: requests: {
cpu: "250m"
memory: "512Mi"
"ephemeral-storage": "100Mi"
}
// highlight-next-line
webhook: resources: Values.resources
// highlight-next-line
cainjector: resources: Values.resources
// highlight-next-line
startupapicheck: resource: Values.resources
// https://cloud.google.com/kubernetes-engine/docs/how-to/autopilot-spot-pods
nodeSelector: {
"kubernetes.io/os": "linux"
if _ClusterName == "management" {
"cloud.google.com/gke-spot": "true"
}
}
webhook: nodeSelector: Values.nodeSelector
cainjector: nodeSelector: Values.nodeSelector
startupapicheck: nodeSelector: Values.nodeSelector
}
}
```
## Create the Workload Cluster
The Workload Cluster is where your applications and services will be deployed.
In production this is usually an EKS, GKE, or AKS cluster.
:::tip
Holos supports any compliant Kubernetes cluster and was developed and tested on
GKE, EKS, Talos, and Kubeadm clusters.
:::
<Tabs>
<TabItem value="evaluate" label="Evaluate" default>
Use this command when evaluating Holos.
```bash
k3d cluster create workload \
--port "443:443@loadbalancer" \
--k3s-arg "--disable=traefik@server:0"
```
</TabItem>
<TabItem value="develop" label="Develop" default>
Use this command when developing Holos.
```bash
k3d registry create registry.holos.localhost --port 5100
```
```bash
k3d cluster create workload \
--registry-use k3d-registry.holos.localhost:5100 \
--port "443:443@loadbalancer" \
--k3s-arg "--disable=traefik@server:0"
```
</TabItem>
</Tabs>
Traefik is disabled because Istio provides the same functionality.
## Local CA
Create and apply the `local-ca` Secret containing the CA private key. This
Secret is necessary to issue certificates trusted by your browser when using the
local k3d platform.
```bash
bash ./scripts/local-ca
```
:::note
Admin access is necessary for `mkcert` to install the newly generated CA cert
into your local host's trust store.
:::
## DNS Setup
Configure your localhost to resolve `*.holos.localhost` to your loopback
interface. This is necessary for your browser requests to reach the k3d
workload cluster.
<Tabs>
<TabItem value="macos" label="macOS" default>
```bash
brew install dnsmasq
```
```bash
cat <<EOF >"$(brew --prefix)/etc/dnsmasq.d/holos.localhost.conf"
# Refer to https://holos.run/docs/tutorial/local/k3d/
address=/holos.localhost/127.0.0.1
EOF
```
```bash
if [[ -r /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist ]]; then
echo "dnsmasq already configured"
else
sudo cp "$(brew list dnsmasq | grep 'dnsmasq.plist$')" \
/Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
sudo launchctl unload /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
sudo launchctl load /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
dscacheutil -flushcache
echo "dnsmasq configured"
fi
```
```bash
sudo mkdir -p /etc/resolver
sudo tee /etc/resolver/holos.localhost <<EOF
domain holos.localhost
nameserver 127.0.0.1
EOF
sudo killall -HUP mDNSResponder
```
</TabItem>
<TabItem value="linux" label="Linux">
[NSS-myhostname](http://man7.org/linux/man-pages/man8/nss-myhostname.8.html)
ships with many Linux distributions and should resolve *.localhost
automatically to 127.0.0.1.
Otherwise it is installable with:
```bash
sudo apt install libnss-myhostname
```
</TabItem>
<TabItem value="windows" label="Windows">
Ensure the loopback interface has at least the following names in `C:\windows\system32\drivers\etc\hosts`
```
127.0.0.1 httpbin.holos.localhost argocd.holos.localhost app.holos.localhost
```
</TabItem>
</Tabs>
## Apply the Platform Components
Use `kubectl` to apply each platform component. In production, it's common to
fully automate this process with ArgoCD, but we use `kubectl` in development
and exploration contexts to the same effect.
### Namespaces
```bash
kubectl apply --server-side=true -f ./deploy/clusters/workload/components/namespaces
```
### Custom Resource Definitions
Services are exposed with standard `HTTPRoute` resources from the Gateway API.
```bash
kubectl apply --server-side=true -f ./deploy/clusters/workload/components/gateway-api
kubectl apply --server-side=true -f ./deploy/clusters/workload/components/istio-base
kubectl apply --server-side=true -f ./deploy/clusters/workload/components/argo-crds
```
### Cert Manager
Apply the ClusterIssuer which issues Certificate resources using the local ca.
```bash
kubectl apply --server-side=true -f ./deploy/clusters/workload/components/cert-manager
kubectl apply --server-side=true -f deploy/clusters/workload/components/local-ca
kubectl apply --server-side=true -f deploy/clusters/workload/components/certificates
```
### Istio
```bash
kubectl apply --server-side=true -f ./deploy/clusters/workload/components/istio-cni
kubectl apply --server-side=true -f ./deploy/clusters/workload/components/istiod
kubectl apply --server-side=true -f ./deploy/clusters/workload/components/gateway
```
Verify the Gateway is programmed and the listeners have been accepted:
```bash
kubectl get -n istio-gateways gateway default -o json \
| jq -r '.status.conditions[].message'
```
```txt
Resource accepted
Resource programmed, assigned to service(s) default-istio.istio-gateways.svc.cluster.local:443
```
### httpbin
httpbin is a simple backend service useful for end-to-end testing.
```bash
kubectl apply --server-side=true -f deploy/clusters/workload/components/httpbin-backend
kubectl apply --server-side=true -f deploy/clusters/workload/components/httpbin-routes
```
:::important
Browse to [https://httpbin.holos.localhost/](https://httpbin.holos.localhost/)
to verify end to end connectivity.
:::
### Cookie Secret
Generate a random cookie encryption Secret and apply.
```bash
LC_ALL=C tr -dc A-Za-z0-9 </dev/urandom \
| head -c 32 \
| kubectl create secret generic "authproxy" \
--from-file=cookiesecret=/dev/stdin \
--dry-run=client -o yaml \
| kubectl apply -n istio-gateways -f-
```
:::tip
The Holos reference platform uses an ExternalSecret to automatically sync this
Secret from your SecretStore.
:::
### Auth Proxy
The auth proxy is responsible for authenticating web browser requests. The auth
proxy provides a standard oidc id token to all services integrated with the
mesh.
```bash
kubectl apply --server-side=true -f deploy/clusters/workload/components/authproxy
kubectl apply --server-side=true -f deploy/clusters/workload/components/authroutes
```
:::important
Verify authentication is working by visiting
[https://httpbin.holos.localhost/holos/authproxy](https://httpbin.holos.localhost/holos/authproxy).
Expect a simple `Authenticated` response.
:::
:::note
Istio will respond with `no healthy upstream` until the pod becomes ready.
:::
Once authenticated, visit
[https://httpbin.holos.localhost/holos/authproxy/userinfo](https://httpbin.holos.localhost/holos/authproxy/userinfo)
which returns a subset of claims from your id token:
```json
{
"user": "275552236589843464",
"email": "demo@holos.run",
"preferredUsername": "demo"
}
```
### Auth Policy
Configure authorization policies using the claims provided in the authenticated
id token.
```bash
kubectl apply --server-side=true -f deploy/clusters/workload/components/authpolicy
```
:::important
Requests to `https://httpbin.holos.localhost` are protected by
AuthorizationPolicy platform resources after applying this component.
:::
### Zero Trust
A basic Zero Trust security model is now in place. Verify authentication is
working by browsing to
[https://httpbin.holos.localhost/dump/request](https://httpbin.holos.localhost/dump/request).
:::note
Istio make take a few seconds to program the Gateway with the
AuthorizationPolicy resources.
:::
:::tip
Note the `x-oidc-id-token` header is not sent by your browser but is received
by the backend service. This design reduces the risk of exposing id tokens.
Requests over the internet are also smaller and more reliable because large id
tokens with may claims are confined to the cluster.
:::
Verify unauthenticated requests are blocked:
```bash
curl https://httpbin.holos.localhost/dump/request
```
Expect a response that redirects to the identity provider.
Verify authenticated requests are allowed:
```bash
curl -H x-oidc-id-token:$(holos token) https://httpbin.holos.localhost/dump/request
```
Expect a response from the backend httpbin service with the id token header the
platform authenticated and authorized.
:::tip
Note how the platform secures both web browser and command line api access to
the backend httpbin service. httpbin itself has no authentication or
authorization functionality.
:::
### ArgoCD
ArgoCD automatically applies resources defined in Git similar to how this guide
uses `kubectl apply`.
Apply controller deployments and supporting resources.
```bash
kubectl apply --server-side=true -f ./deploy/clusters/workload/components/argo-cd
kubectl apply --server-side=true -f ./deploy/clusters/workload/components/argo-authpolicy
kubectl apply --server-side=true -f ./deploy/clusters/workload/components/argo-routes
```
Verify all Pods are running and all containers are ready.
```bash
kubectl get pods -n argocd
```
```txt
NAME READY STATUS RESTARTS AGE
argocd-application-controller-0 1/1 Running 0 10s
argocd-applicationset-controller-578db65fcd-lnn76 1/1 Running 0 10s
argocd-notifications-controller-67c856dbb7-12stk 1/1 Running 0 10s
argocd-redis-698f57d9b9-v4kqs 1/1 Running 0 10s
argocd-redis-secret-init-z5zg8 0/1 Completed 0 10s
argocd-repo-server-69f78dfb8-f6pb7 1/1 Running 0 10s
argocd-server-58f7f4466d-db5fv 2/2 Running 0 10s
```
Browse to [https://argocd.holos.localhost/](https://argocd.holos.localhost/) and
verify you get the ArgoCD login page.
![ArgoCD Login Page](./argocd-login.png)
:::note
Both the platform layer and the ArgoCD application layer performs authentication
and authorization using the same identity provider. Note how the Zero Trust
model provides an additional layer of security without friction.
:::
Login using the SSO button and verify you get to the Applications page.
![ArgoCD Applications](./argocd-apps.png)
### ArgoCD Applications
Apply the Application resources for all of the Holos components that compose the
platform. The Application resources provide drift detection and optional
automatic reconciliation of platform components.
```bash
kubectl apply --server-side=true -f deploy/clusters/workload/gitops
```
Browse to or refresh [https://argocd.holos.localhost/applications](https://argocd.holos.localhost/applications).
![ArgoCD Holos Components](./argocd-apps-2.png)
:::important
If you do not see any applications after refreshing the page ensure the `sub`
value in the Platform Model (`platform.config.json`) is correct and matches
`holos login --print-claims`.
:::
### Sync Applications
Navigate to the [namespaces Application](https://argocd.holos.localhost/applications/argocd/namespaces).
![ArgoCD Out of Sync](./argocd-out-of-sync.png)
Review the differences between the live platform and the git configuration.
![ArgoCD Diff](./argocd-diff.png)
Sync the application to reconcile the differences.
![ArgoCD Sync](./argocd-sync.png)
The Holos components should report Sync OK.
![ArgoCD Sync OK](./argocd-sync-ok.png)
:::tip
Automatic reconciliation is turned off by default.
:::
Optionally enable automatic reconciliation by adding `spec.syncPolicy.automated:
{}` to the `#Argo` definition.
Add the following to `buildplan.site.cue` to avoid `holos generate platform k3d`
writing over the customization.
:::tip
CUE merges definitions located in multiple files. This feature is used to
customize the platform.
:::
```bash
cat <<EOF > buildplan.site.cue
package holos
// Enable automated sync of platform components.
#Argo: Application: spec: syncPolicy: automated: {}
EOF
```
Re-render the platform.
```bash
holos render platform ./platform
```
Add and commit the changes.
```bash
git add .
git commit -m 'enable argocd automatic sync'
git push origin HEAD
```
Apply the new changes.
```bash
kubectl apply --server-side=true -f deploy/clusters/workload/gitops
```
Automatic reconciliation is enabled for all platform components.
![ArgoCD Automatic Sync OK](./argocd-auto-sync-ok.png)
## Summary
TODO
1. Configured the Service Mesh with mTLS.
2. Configured authentication and authorization.
3. Protected a backend service without backend code changes.
4. ArgoCD

Binary file not shown.

After

Width:  |  Height:  |  Size: 558 KiB

View File

@@ -1,34 +1,41 @@
# Website
This website is built using [Docusaurus](https://docusaurus.io/), a modern
static website generator.
This website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator.
## Installation
### Installation
```shell
npm install
```
$ yarn
```
### Local Development
```shell
npm run start
```
$ yarn start
```
This command starts a local development server and opens up a browser window.
Most changes are reflected live without having to restart the server.
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
### Build
```shell
npm run build
```
$ yarn build
```
This command generates static content into the `build` directory and can be
served using any static contents hosting service.
This command generates static content into the `build` directory and can be served using any static contents hosting service.
### Deployment
Deployments are made with Cloudflare Pages. Cloudflare deploys on changes to
the main branch, and Pull Requests get comments with links to preview
environments.
Using SSH:
```
$ USE_SSH=true yarn deploy
```
Not using SSH:
```
$ GIT_USER=<Your GitHub username> yarn deploy
```
If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.

View File

@@ -4,7 +4,7 @@ import type * as Preset from '@docusaurus/preset-classic';
const config: Config = {
title: 'Holos',
tagline: 'The Holistic Package Manager for Cloud Native Applications',
tagline: 'The Platform Operating System',
favicon: 'img/favicon.ico',
// Set the production url of your site here
@@ -34,19 +34,8 @@ const config: Config = {
markdown: {
mermaid: true
},
// TODO: These redirects don't seem to be working, at least with the `npm run
// start` dev server.
plugins: [
[
'@docusaurus/plugin-client-redirects',
{
redirects: [],
},
],
],
themes: ['@docusaurus/theme-mermaid'],
presets: [
[
'classic',
@@ -93,14 +82,19 @@ const config: Config = {
items: [
{
type: 'doc',
docId: 'guides/quickstart',
docId: 'tutorial/local/k3d',
position: 'left',
label: 'Try Holos',
},
{ to: '/docs', label: 'Docs', position: 'left' },
{
type: 'doc',
docId: 'api',
docId: 'intro',
position: 'left',
label: 'Docs',
},
{
type: 'docSidebar',
sidebarId: 'api',
position: 'left',
label: 'API',
},
@@ -125,20 +119,16 @@ const config: Config = {
title: 'Docs',
items: [
{
label: 'Quickstart',
to: '/docs/quickstart',
},
{
label: 'Concepts',
to: '/docs/concepts',
label: 'Try Holos Locally',
to: '/docs/tutorial/local/k3d',
},
{
label: 'Documentation',
to: '/docs',
to: '/docs/intro',
},
{
label: 'API Reference',
to: '/docs/api',
to: '/docs/api/core/v1alpha2',
},
],
},
@@ -147,7 +137,7 @@ const config: Config = {
items: [
{
label: 'Discuss',
href: 'https://github.com/holos-run/holos/discussions',
href: 'https://github.com/orgs/holos-run/discussions',
},
],
},

File diff suppressed because it is too large Load Diff

View File

@@ -15,10 +15,9 @@
"typecheck": "tsc"
},
"dependencies": {
"@docusaurus/core": "^3.5.2",
"@docusaurus/plugin-client-redirects": "^3.5.2",
"@docusaurus/preset-classic": "^3.5.2",
"@docusaurus/theme-mermaid": "^3.5.2",
"@docusaurus/core": "3.4.0",
"@docusaurus/preset-classic": "3.4.0",
"@docusaurus/theme-mermaid": "^3.4.0",
"@mdx-js/react": "^3.0.0",
"clsx": "^2.0.0",
"prism-react-renderer": "^2.3.0",
@@ -26,9 +25,9 @@
"react-dom": "^18.0.0"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "^3.5.2",
"@docusaurus/tsconfig": "^3.5.2",
"@docusaurus/types": "^3.5.2",
"@docusaurus/module-type-aliases": "^3.4.0",
"@docusaurus/tsconfig": "^3.4.0",
"@docusaurus/types": "^3.4.0",
"@wcj/html-to-markdown-cli": "^2.1.1",
"cspell": "^8.10.4",
"html-to-markdown": "^1.0.0",

View File

@@ -12,63 +12,28 @@ import type { SidebarsConfig } from '@docusaurus/plugin-content-docs';
*/
const sidebars: SidebarsConfig = {
doc: [
'introduction',
'intro',
{
label: 'Getting Started',
type: 'category',
collapsed: true,
link: { type: 'doc', id: 'start' },
items: [
{
type: 'autogenerated',
dirName: 'start',
},
],
},
{
label: 'Guides',
type: 'category',
label: 'Tutorial',
collapsed: false,
link: { type: 'doc', id: 'guides' },
items: [
{
type: 'autogenerated',
dirName: 'guides',
},
'tutorial/local/k3d',
],
},
{
label: 'API Reference',
type: 'category',
collapsed: true,
link: { type: 'doc', id: 'api' },
label: 'Reference Platform',
collapsed: false,
items: [
{
label: 'Schema API',
type: 'category',
link: { type: 'doc', id: 'api/schema' },
collapsed: true,
items: [
{
type: 'autogenerated',
dirName: 'api/schema',
},
]
},
{
label: 'Core API',
type: 'category',
link: { type: 'doc', id: 'api/core' },
collapsed: true,
items: [
{
type: 'autogenerated',
dirName: 'api/core',
},
]
},
]
'reference-platform/architecture',
],
},
'glossary',
],
api: [
'api/core/v1alpha2',
'cli',
],
};

View File

@@ -8,50 +8,36 @@ type FeatureItem = {
description: JSX.Element;
};
// TODO: Consider focusing on the three pillars of Safe, Easy, Consistent.
const FeatureList: FeatureItem[] = [
{
title: 'Kustomize Helm',
Svg: require('@site/static/img/base00/undraw_together_re_a8x4.svg').default,
title: 'Zero Trust Security',
Svg: require('@site/static/img/base00/undraw_security_on_re_e491.svg').default,
description: (
<>
Super charge your existing Helm charts by providing well defined,
validated input values, post-processing the output with Kustomize,
and mixing in your own custom resources. All without modifying upstream
charts to alleviate the pain of upgrades.
Spend more time on your business features and less time rebuilding
authentication and authorization. Holos provides zero trust security
with no code needed to protect your services.
</>
),
},
{
title: 'Unified Data Model',
Svg: require('@site/static/img/base00/undraw_fitting_pieces_re_nss7.svg').default,
title: 'Multi-Cloud',
Svg: require('@site/static/img/base00/undraw_cloud_hosting_7xb1.svg').default,
description: (
<>
Unify all of your platform components into one well-defined, strongly
typed data model with CUE. Holos makes it easier and safer to integrate
seamlessly with software distributed with current and future tools that
produce Kubernetes resource manifests.
Avoid vendor lock in, downtime, and price hikes. Holos is designed to
easily deploy workloads into multiple clouds and multiple regions.
</>
),
},
{
title: 'Deep Insights',
Svg: require('@site/static/img/base00/undraw_code_review_re_woeb.svg').default,
title: 'Developer Portal',
Svg: require('@site/static/img/base00/undraw_data_trends_re_2cdy.svg').default,
description: (
<>
Reduce risk and increase confidence in your configuration changes.
Holos offers clear visibility into complete resource configuration
<i>before</i> being applied.
</>
),
},
{
title: 'Interoperable',
Svg: require('@site/static/img/base00/undraw_version_control_re_mg66.svg').default,
description: (
<>
Holos is designed for compatibility with your preferred tools and
processes, for example git diff and code reviews.
Ship high quality code quickly, provide a great developer experience,
and maintain control over your infrastructure with the integrated
Backstage developer portal.
</>
),
},

View File

@@ -4,12 +4,6 @@
* work well for content-centric websites.
*/
/* Enable wrapping by default for mobile */
/* pre code {
white-space: pre-wrap;
overflow-wrap: anywhere;
} */
/* You can override the default Infima variables here. */
:root {
--ifm-link-color: #268bd2;

View File

@@ -21,7 +21,3 @@
align-items: center;
justify-content: center;
}
.divider {
margin: 0 5px;
}

View File

@@ -17,26 +17,19 @@ function HomepageHeader() {
</Heading>
<p className="hero__subtitle">{siteConfig.tagline}</p>
<p className="projectDesc">
Holos adds CUE's type safety, unified structure, and strong validation
features to your current software packages, including Helm and
Kustomize. These features make the experience of integrating software
packages into a holistic platform a pleasant journey.
Holos is a holistic software development platform built from the most
popular open source projects.<br /> Build your developer platform in
no time.
</p>
<div className={styles.buttons}>
<Link
className="button button--secondary button--lg"
to="docs/quickstart">
to="/docs/intro">
Get Started
</Link>
<span className={styles.divider}></span>
<Link
className="button button--primary button--lg"
to="docs/concepts">
Learn More
</Link>
</div>
</div>
</header >
</header>
);
}
@@ -44,8 +37,8 @@ export default function Home(): JSX.Element {
const { siteConfig } = useDocusaurusContext();
return (
<Layout
title={`${siteConfig.title} Package Manager`}
description="Holos adds CUE's type safety, unified structure, and strong validation features to your current software packages, including Helm and Kustomize.">
title={`Hello from ${siteConfig.title}`}
description="Holos provides a software development platform that holistically integrates the most popular cloud native projects.">
<HomepageHeader />
<main>
<HomepageFeatures />

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 8.3 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 7.5 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 8.5 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.9 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 25 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 28 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 34 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 17 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.1 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 18 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 21 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 10 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 40 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 15 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 4.9 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 8.4 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 13 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 7.2 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 13 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 18 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 7.3 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 43 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="581.17725" height="668" viewBox="0 0 581.17725 668" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M248.22582,95.78906h89.68896v73.14404h-89.68896V95.78906Zm87.68896,2h-85.68896v69.14404h85.68896V97.78906Z" fill="#3f3d56"/><rect x="286.81782" y="130.98987" width="70.42636" height="1.99974" transform="translate(181.51001 450.39061) rotate(-88.47361)" fill="#3f3d56"/><rect x="260.34565" y="130.98987" width="70.42636" height="1.99974" transform="translate(155.74299 423.92783) rotate(-88.47361)" fill="#3f3d56"/><rect x="233.87348" y="130.98987" width="70.42636" height="1.99974" transform="translate(129.97597 397.46506) rotate(-88.47361)" fill="#3f3d56"/><path d="M348.72143,167.19043h2v-25.20508l-.72803-.20605c-.60986-.17334-61.65332-17.0542-116.78076,.00732l-.70459,.21777v22.75928h2v-21.28271c51.125-15.53857,107.2041-1.80664,114.21338,.02783v23.68164Z" fill="#3f3d56"/><path d="M233.76635,153.69775c64.82178-17.31445,115.12402-.19727,115.625-.02246l.66016-1.8877c-.50586-.17676-51.35449-17.50244-116.80127-.02246l.51611,1.93262Z" fill="#3f3d56"/><path d="M233.76635,161.05615c64.82178-17.31543,115.12402-.19678,115.625-.02246l.66016-1.8877c-.50586-.17676-51.35449-17.50244-116.80127-.02246l.51611,1.93262Z" fill="#3f3d56"/><path d="M246.74401,244.86805h89.34375v-66.20661l12.40885-10.72828c-38.14672-11.12717-76.76201-11.43174-115.81597-1.65451l14.06337,12.69546v65.89394Z" fill="#657b83"/><path d="M369.00512,238.97021h2v-33.73975l-.72803-.20605c-.82227-.23193-83.0752-22.97705-157.34863,.00732l-.70459,.21777v30.44629h2v-28.97021c69.79443-21.31152,146.50439-2.16113,154.78125,.02686v32.21777Z" fill="#3f3d56"/><path d="M213.48217,220.43018c87.56445-23.39014,155.5166-.25879,156.19287-.02246l.66016-1.8877c-.68164-.23877-69.17871-23.57813-157.36914-.02246l.51611,1.93262Z" fill="#3f3d56"/><path d="M213.48217,230.35742c87.56689-23.39014,155.51611-.25879,156.19287-.02246l.66016-1.8877c-.68164-.23828-69.17871-23.57764-157.36963-.02246l.5166,1.93262Z" fill="#3f3d56"/><path d="M240.95321,96.78906c0,15.53397,27.00976,.40367,48.94007,.40367s50.33076,15.13029,50.33076-.40367-26.05059-39.70833-47.9809-39.70833c-21.93031,0-51.28993,24.17436-51.28993,39.70833Z" fill="#657b83"/><rect x="270.73446" y="43.84462" width="43.01736" height="23.16319" transform="translate(584.48627 110.85243) rotate(-180)" fill="#657b83"/><rect x="288.10685" y="0" width="6.61806" height="47.9809" transform="translate(582.83176 47.9809) rotate(-180)" fill="#657b83"/><path d="M199.59036,667.59633h173.72395l-26.47222-380.53818,34.74479-46.32639c-59.18845-9.46943-119.14115-12.02188-180.34201-3.30903l24.81771,43.01736-26.47222,387.15623Z" fill="#e6e6e6"/><g><rect x="226.06258" y="594.79772" width="31.43576" height="72.79861" transform="translate(483.56093 1262.39405) rotate(-180)" fill="#fff"/><polyline points="280.66154 667.59633 282.31605 584.87064 263.40639 561.70744 242.60772 561.70744 257.49835 586.29047 258.97862 666.78245" fill="#ccc"/></g><g><rect x="301.06258" y="594.79772" width="31.43576" height="72.79861" transform="translate(633.56093 1262.39405) rotate(-180)" fill="#fff"/><polyline points="355.66154 667.59633 357.31605 584.87064 338.40639 561.70744 317.60772 561.70744 332.49835 586.29047 333.97862 666.78245" fill="#ccc"/></g><path d="M434.0852,668h2v-56.8208l-.72803-.20605c-.37207-.10498-37.84863-10.58545-91.42773-15.78418-49.46045-4.7998-123.16992-5.95557-193.44287,15.7915l-.70459,.21777v54.61084h2v-53.13525c69.74414-21.42383,142.84131-20.26025,191.95459-15.49414,49.30518,4.78418,84.88721,14.04346,90.34863,15.51855v55.30176Z" fill="#3f3d56"/><path d="M151.03979,637.34082c83.10986-22.19971,155.81982-21.02441,202.18115-16.12939,50.24316,5.30469,81.22705,15.99951,81.53418,16.10693l.66016-1.8877c-.30859-.10791-31.46045-10.8667-81.91406-16.20068-46.54443-4.92041-119.54102-6.10791-202.97754,16.17822l.51611,1.93262Z" fill="#3f3d56"/><path d="M151.03979,655.34229c83.10986-22.19922,155.81982-21.02441,202.18115-16.12939,50.24316,5.30469,81.22705,15.99951,81.53418,16.10693l.66016-1.8877c-.30859-.10791-31.46045-10.8667-81.91406-16.20068-46.54346-4.9209-119.54102-6.10791-202.97754,16.17822l.51611,1.93262Z" fill="#3f3d56"/><rect x="0" y="665.78223" width="581.17725" height="2" fill="#2f2e41"/></svg>

Before

Width:  |  Height:  |  Size: 4.2 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 27 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="532" height="532" viewBox="0 0 532 532" xmlns:xlink="http://www.w3.org/1999/xlink"><circle cx="270.75986" cy="260.93427" r="86.34897" fill="#ffb6b6"/><polygon points="221.18982 360.05209 217.28876 320.6185 295.18982 306.05209 341.18982 418.05209 261.18982 510.05209 204.18982 398.05209 221.18982 360.05209" fill="#ffb6b6"/><path d="m216.0374,340.35736l17.03111,3.84802s-13.38821-42.45453-8.84396-46.50766c4.54427-4.05316,15.68007,2.33328,15.68007,2.33328l11.70201,13.1199,14.25394-14.51239s15.47495-19.2421,21.53397-24.6463-3.67319-25.46364-3.67319-25.46364c0,0,89.89185-24.23923,56.44299-67.83968,0,0-19.61093-34.18452-25.99734-23.04871-6.38641,11.1358-14.00162-6.55013-14.00162-6.55013l-23.25381,4.42198s-45.89429-27.06042-89.45331,30.82959c-43.55902,57.89003,28.57916,154.01572,28.57916,154.01572h-.00002Z" fill="#2f2e41"/><path d="m433.16003,472.95001c-47.19,38.26001-105.57001,59.04999-167.16003,59.04999-56.23999,0-109.81-17.33997-154.62-49.47998.08002-.84003.16003-1.66998.23004-2.5,1.19-13,2.25-25.64001,2.94995-36.12,2.71002-40.69,97.64001-67.81,97.64001-67.81,0,0,.42999.42999,1.29004,1.17999,5.23999,4.59998,26.50995,21.27997,63.81,25.94,33.25995,4.15997,44.20996-15.57001,47.51996-25.02002,1-2.88,1.30005-4.81,1.30005-4.81l97.63995,46.10999c6.37,9.10004,8.86005,28.70001,9.35004,50.73004.01996.90997.03998,1.81.04999,2.72998Z" fill="#657b83"/><path d="m454.09003,77.91003C403.85004,27.66998,337.05005,0,266,0S128.15002,27.66998,77.91003,77.91003C27.67004,128.15002,0,194.95001,0,266c0,64.85004,23.05005,126.16003,65.29004,174.57001,4.02997,4.63,8.23999,9.14001,12.62,13.52002,1.02997,1.02997,2.07001,2.06,3.12,3.06,2.79999,2.70996,5.65002,5.35999,8.54999,7.92999,1.76001,1.57001,3.54004,3.10999,5.34003,4.62,1.40997,1.19,2.82001,2.35999,4.25,3.51001.02997.02997.04999.04999.07996.07001,3.97003,3.19995,8.01001,6.27997,12.13,9.23999,44.81,32.14001,98.37999,49.47998,154.61998,49.47998,61.59003,0,119.97003-20.78998,167.16003-59.04999,3.84998-3.12,7.62-6.35999,11.32001-9.71002,3.26996-2.95996,6.46997-6.01001,9.60999-9.14996.98999-.98999,1.97998-1.98999,2.95001-3,2.70001-2.78003,5.32001-5.61005,7.88-8.48004,43.37-48.71997,67.07996-110.83997,67.07996-176.60999,0-71.04999-27.66998-137.84998-77.90997-188.08997Zm10.17999,362.20997c-2.5,2.84003-5.06,5.64001-7.67999,8.37-4.08002,4.25-8.28998,8.37-12.64001,12.34003-1.64996,1.52002-3.32001,3-5.01001,4.46997-1.91998,1.67004-3.85999,3.31-5.82996,4.92004-15.53003,12.75-32.54004,23.75-50.73004,32.70996-7.19,3.54999-14.56,6.78003-22.09998,9.67004-29.28998,11.23999-61.08002,17.39996-94.28003,17.39996-32.03998,0-62.75995-5.73999-91.19-16.23999-11.66998-4.29999-22.94995-9.40997-33.77997-15.26001-1.59003-.85999-3.16998-1.72998-4.73999-2.62-8.26001-4.67999-16.25-9.78998-23.91998-15.31-.25-.17999-.51001-.37-.76001-.54999-5.46002-3.94-10.77002-8.09003-15.90002-12.45001-1.88-1.59003-3.73999-3.20001-5.57001-4.84998-2.97998-2.65002-5.89996-5.38-8.75-8.18005-5.39996-5.28998-10.56-10.79999-15.48999-16.52997C26.09003,391.77002,2,331.65002,2,266,2,120.42999,120.43005,2,266,2s264,118.42999,264,264c0,66.66003-24.82996,127.62-65.72998,174.12Z" fill="#3f3d56"/></svg>

Before

Width:  |  Height:  |  Size: 3.1 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 10 KiB

Some files were not shown because too many files have changed in this diff Show More