Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6f39cc6fdc | ||
|
|
e410563f82 | ||
|
|
0a53bef72a | ||
|
|
02a450e597 | ||
|
|
e1222cf367 | ||
|
|
740a3d21a1 | ||
|
|
1114b65a47 | ||
|
|
c9d892eee3 | ||
|
|
4c77eba72b | ||
|
|
a8ae56b08b | ||
|
|
b04837ede2 | ||
|
|
559c8bc79f | ||
|
|
a30335b171 | ||
|
|
108831747a | ||
|
|
c714a2b61e | ||
|
|
1cba383dc1 | ||
|
|
265d5773b8 | ||
|
|
44f8779136 | ||
|
|
4127804092 | ||
|
|
8f424cfabe | ||
|
|
699148abdd | ||
|
|
73f777759e | ||
|
|
8b9070f185 | ||
|
|
1e8861c8b7 | ||
|
|
bdc182f4eb | ||
|
|
4db3fb4ead | ||
|
|
1911c7fe01 | ||
|
|
5e582ec5c6 |
44
.cspell.json
@@ -5,41 +5,59 @@
|
||||
"mdx"
|
||||
],
|
||||
"words": [
|
||||
"admissionregistration",
|
||||
"apiextensions",
|
||||
"applicationset",
|
||||
"argoproj",
|
||||
"authcode",
|
||||
"authorizationpolicies",
|
||||
"authpolicy",
|
||||
"authproxy",
|
||||
"authroutes",
|
||||
"buildplan",
|
||||
"cainjector",
|
||||
"CAROOT",
|
||||
"clsx",
|
||||
"clusterissuer",
|
||||
"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",
|
||||
"ghaction",
|
||||
"gitops",
|
||||
"godoc",
|
||||
"golangci",
|
||||
"goreleaser",
|
||||
"grpcreflect",
|
||||
"grpcroutes",
|
||||
"grpcurl",
|
||||
"holos",
|
||||
"holoslogger",
|
||||
"horizontalpodautoscaler",
|
||||
"httpbin",
|
||||
"httproutes",
|
||||
"Infima",
|
||||
"isatty",
|
||||
"istiod",
|
||||
@@ -56,8 +74,11 @@
|
||||
"libnss",
|
||||
"loadbalancer",
|
||||
"mattn",
|
||||
"mindmap",
|
||||
"mktemp",
|
||||
"msqbn",
|
||||
"Multicluster",
|
||||
"mutatingwebhookconfiguration",
|
||||
"mxcl",
|
||||
"myhostname",
|
||||
"nameserver",
|
||||
@@ -65,23 +86,38 @@
|
||||
"orgid",
|
||||
"otelconnect",
|
||||
"Parentspanid",
|
||||
"peerauthentications",
|
||||
"pflag",
|
||||
"pipefail",
|
||||
"PKCE",
|
||||
"platformconnect",
|
||||
"poddisruptionbudget",
|
||||
"podinfo",
|
||||
"portmapping",
|
||||
"promhttp",
|
||||
"protobuf",
|
||||
"protojson",
|
||||
"proxyconfigs",
|
||||
"Pulumi",
|
||||
"putenv",
|
||||
"quickstart",
|
||||
"referencegrants",
|
||||
"requestauthentications",
|
||||
"retryable",
|
||||
"rolebinding",
|
||||
"ropc",
|
||||
"SECRETKEY",
|
||||
"secretstores",
|
||||
"serverlb",
|
||||
"serverside",
|
||||
"serviceaccount",
|
||||
"serviceentries",
|
||||
"spanid",
|
||||
"spiffe",
|
||||
"startupapicheck",
|
||||
"stefanprodan",
|
||||
"structpb",
|
||||
"svclb",
|
||||
"systemconnect",
|
||||
"tablewriter",
|
||||
"Tiltfile",
|
||||
@@ -99,7 +135,13 @@
|
||||
"usecases",
|
||||
"userconnect",
|
||||
"userdata",
|
||||
"validatingwebhookconfiguration",
|
||||
"virtualservices",
|
||||
"wasmplugins",
|
||||
"workloadentries",
|
||||
"workloadgroups",
|
||||
"zerolog",
|
||||
"zitadel"
|
||||
"zitadel",
|
||||
"ztunnel"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -2,11 +2,6 @@ package v1alpha3
|
||||
|
||||
import "google.golang.org/protobuf/types/known/structpb"
|
||||
|
||||
type PlatformMetadata struct {
|
||||
// Name represents the Platform name.
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// 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
|
||||
@@ -24,13 +19,18 @@ type Platform struct {
|
||||
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"`
|
||||
Model structpb.Struct `json:"model" cue:"{...}"`
|
||||
// Components represents a list of holos components to manage.
|
||||
Components []PlatformSpecComponent `json:"components"`
|
||||
}
|
||||
|
||||
175
api/schema/v1alpha3/definitions.go
Normal file
@@ -0,0 +1,175 @@
|
||||
// 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
|
||||
|
||||
// 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 {
|
||||
// Name represents the Component name.
|
||||
Name string
|
||||
// Version represents the chart version.
|
||||
Version string
|
||||
// Namespace represents the helm namespace option when rendering the chart.
|
||||
Namespace string
|
||||
// Resources are kubernetes api objects to mix into the output.
|
||||
Resources map[string]any
|
||||
|
||||
// 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]: {...}}"`
|
||||
|
||||
// ArgoConfig represents the ArgoCD GitOps configuration for this Component.
|
||||
ArgoConfig ArgoConfig
|
||||
|
||||
// Output represents the derived BuildPlan for the Holos cli to render.
|
||||
Output core.BuildPlan
|
||||
}
|
||||
|
||||
// Resources represents the default schema for a Kubernetes API object resource.
|
||||
// For example, a Service, Namespace or Deployment. The top level key is the
|
||||
// kind of resource so default behavior and strict schema enforcement may be
|
||||
// enforced for the kind. The second level keys are an arbitrary internal
|
||||
// label, which serves as the default value for the resource metadata name
|
||||
// field, but may differ for situations where the same resource kind and name
|
||||
// are managed in different namespaces.
|
||||
//
|
||||
// Refer to [definitions.cue] for the CUE schema definition as an example to
|
||||
// build on when defining your own Components.
|
||||
//
|
||||
// [definitions.cue]: https://github.com/holos-run/holos/blob/main/internal/generate/platforms/cue.mod/pkg/github.com/holos-run/holos/api/schema/v1alpha3/definitions.cue#L9
|
||||
// type Resources map[string]map[string]any
|
||||
|
||||
// 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\""`
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// Kustomize provides a BuildPlan via the Output field which contains one
|
||||
// KustomizeBuild from package core.
|
||||
type Kustomize struct {
|
||||
// Name represents the Component name.
|
||||
Name string
|
||||
|
||||
// Kustomization represents the kustomize build plan for holos to render.
|
||||
Kustomization core.KustomizeBuild
|
||||
|
||||
// Output represents the derived BuildPlan for the Holos cli to render.
|
||||
Output core.BuildPlan
|
||||
}
|
||||
|
||||
// Kubernetes provides a BuildPlan via the Output field which contains inline
|
||||
// API Objects provided directly from CUE.
|
||||
type Kubernetes struct {
|
||||
// Name represents the Component name.
|
||||
Name string
|
||||
// Resources represents the kubernetes api objects for the Component.
|
||||
Resources map[string]any
|
||||
|
||||
// Output represents the derived BuildPlan for the Holos cli to render.
|
||||
Output core.BuildPlan
|
||||
}
|
||||
5
doc/md/api.md
Normal file
@@ -0,0 +1,5 @@
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
|
||||
# API Reference
|
||||
|
||||
<DocCardList />
|
||||
5
doc/md/api/core.md
Normal file
@@ -0,0 +1,5 @@
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
|
||||
# Core API
|
||||
|
||||
<DocCardList />
|
||||
@@ -1,3 +0,0 @@
|
||||
# Core API
|
||||
|
||||
- [v1alpha2](v1alpha2)
|
||||
@@ -368,7 +368,7 @@ PlatformSpec represents the specification of a Platform. Think of a platform spe
|
||||
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"`
|
||||
Model structpb.Struct `json:"model" cue:"{...}"`
|
||||
// Components represents a list of holos components to manage.
|
||||
Components []PlatformSpecComponent `json:"components"`
|
||||
}
|
||||
|
||||
5
doc/md/api/schema.md
Normal file
@@ -0,0 +1,5 @@
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
|
||||
# Schema API
|
||||
|
||||
<DocCardList />
|
||||
205
doc/md/api/schema/v1alpha3.md
Normal file
@@ -0,0 +1,205 @@
|
||||
<!-- 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 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\""`
|
||||
}
|
||||
```
|
||||
|
||||
<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="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 {
|
||||
// Name represents the Component name.
|
||||
Name string
|
||||
// Version represents the chart version.
|
||||
Version string
|
||||
// Namespace represents the helm namespace option when rendering the chart.
|
||||
Namespace string
|
||||
// Resources are kubernetes api objects to mix into the output.
|
||||
Resources map[string]any
|
||||
|
||||
// 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]: {...}}"`
|
||||
|
||||
// ArgoConfig represents the ArgoCD GitOps configuration for this Component.
|
||||
ArgoConfig ArgoConfig
|
||||
|
||||
// Output represents the derived BuildPlan for the Holos cli to render.
|
||||
Output core.BuildPlan
|
||||
}
|
||||
```
|
||||
|
||||
<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 {
|
||||
// Name represents the Component name.
|
||||
Name string
|
||||
// Resources represents the kubernetes api objects for the Component.
|
||||
Resources map[string]any
|
||||
|
||||
// Output represents the derived BuildPlan for the Holos cli to render.
|
||||
Output core.BuildPlan
|
||||
}
|
||||
```
|
||||
|
||||
<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 {
|
||||
// Name represents the Component name.
|
||||
Name string
|
||||
|
||||
// Kustomization represents the kustomize build plan for holos to render.
|
||||
Kustomization core.KustomizeBuild
|
||||
|
||||
// Output represents the derived BuildPlan for the Holos cli to render.
|
||||
Output core.BuildPlan
|
||||
}
|
||||
```
|
||||
|
||||
<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
|
||||
}
|
||||
```
|
||||
|
||||
<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>)
|
||||
|
Before Width: | Height: | Size: 934 KiB After Width: | Height: | Size: 934 KiB |
|
Before Width: | Height: | Size: 703 KiB After Width: | Height: | Size: 703 KiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 1014 KiB After Width: | Height: | Size: 1014 KiB |
|
Before Width: | Height: | Size: 728 KiB After Width: | Height: | Size: 728 KiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 1014 KiB After Width: | Height: | Size: 1014 KiB |
|
Before Width: | Height: | Size: 854 KiB After Width: | Height: | Size: 854 KiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 624 KiB After Width: | Height: | Size: 624 KiB |
|
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 116 KiB |
@@ -671,10 +671,10 @@ foundation of a software development platform that:
|
||||
|
||||
Dive deeper with the following resources that build on the foundation you have now.
|
||||
|
||||
1. Explore the [Rendering Process](/docs/design/rendering) in Holos.
|
||||
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](/docs/guides/argocd) onto the foundation you built.
|
||||
4. Deploy [Backstage](/docs/guides/backstage) as a portal to the integrated platform components.
|
||||
3. Deploy [ArgoCD](../argocd) onto the foundation you built.
|
||||
4. Deploy [Backstage](../backstage) as a portal to the integrated platform components.
|
||||
|
||||
## Clean-Up
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
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](/docs/guides/try-holos/) guide.
|
||||
Try Holos Locally guide.
|
||||
|
||||
Take a moment to review the manifests `holos` rendered to build the platform.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
This document captures notes on locally developing Holos.
|
||||
|
||||
Follow the steps in [Try Holos Locally](/docs/guides/try-holos), but take care
|
||||
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
|
||||
registry to push to.
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
# Rendering
|
||||
|
||||
:::tip
|
||||
|
||||
This document provides a brief overview of the rendering process, a core design
|
||||
element in Holos.
|
||||
|
||||
:::
|
||||
|
||||
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">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
|
||||
```
|
||||
5
doc/md/guides.md
Normal file
@@ -0,0 +1,5 @@
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
|
||||
# Guides
|
||||
|
||||
<DocCardList />
|
||||
799
doc/md/guides/expose-a-service.mdx
Normal file
@@ -0,0 +1,799 @@
|
||||
---
|
||||
description: Use Holos to expose a Service with the Gateway API.
|
||||
slug: /guides/expose-a-service
|
||||
sidebar_position: 200
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
# Expose a Service
|
||||
|
||||
In this guide, you'll learn how to expose a service with Holos using the Gateway
|
||||
API.
|
||||
|
||||
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 Helm Components.
|
||||
3. [kubectl](https://kubernetes.io/docs/tasks/tools/) - to render Kustomize Components.
|
||||
|
||||
Optionally, if you'd like to apply the rendered manifests to a real Cluster,
|
||||
first complete the [localhost Guide](../local-cluster).
|
||||
|
||||
## 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 expose-a-service
|
||||
cd expose-a-service
|
||||
git init
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
Initialized empty Git repository in /expose-a-service/.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}
|
||||
|
||||
Start by generating a platform with one workload Cluster. The `guide` Platform
|
||||
is intended as a starting point for all of our guides.
|
||||
|
||||
<Tabs groupId="generate-platform">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos generate platform guide
|
||||
holos generate component workload-cluster
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
generated component
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
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 guide - $(holos --version)"
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
[main (root-commit) 0b17b7f] holos generate platform guide - 0.93.3
|
||||
213 files changed, 72349 insertions(+)
|
||||
...
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Gateway API
|
||||
|
||||
The Gateway API is an official Kubernetes project focused on L4 and L7 routing .
|
||||
You'll use the custom resources defined by the Gateway API to expose the httpbin
|
||||
service outside of the cluster. The Kubernetes Gateway API does not come
|
||||
installed by default on most Kubernetes clusters, so we need to manage the
|
||||
custom resource definitions (CRDs).
|
||||
|
||||
Run the following command to generate a Component to manage the Gateway API.
|
||||
|
||||
<Tabs groupId="gen-gateway-api">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos generate component gateway-api
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
generated component
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
The command generates two main configuration files, one at the leaf, and another
|
||||
at the root of the tree. At the leaf, the config produces a Kustomize build
|
||||
plan for Holos to render. At the root, the config adds the Component to all
|
||||
Clusters in the Platform.
|
||||
|
||||
Notice the `kustomization.yaml` file at the leaf. This is an unmodified
|
||||
upstream copy of the standard way to install the Gateway API.
|
||||
|
||||
<Tabs groupId="gateway-api-files">
|
||||
<TabItem value="components/gateway-api/gateway-api.cue" label="Leaf">
|
||||
`components/gateway-api/gateway-api.cue`
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// Produce a kubectl kustomize build plan.
|
||||
(#Kustomize & {Name: "gateway-api"}).Output
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="kustomization.yaml" label="kustomization.yaml">
|
||||
`components/gateway-api/kustomization.yaml`
|
||||
```yaml showLineNumbers
|
||||
resources:
|
||||
- standard/gateway.networking.k8s.io_gatewayclasses.yaml
|
||||
- standard/gateway.networking.k8s.io_gateways.yaml
|
||||
- standard/gateway.networking.k8s.io_grpcroutes.yaml
|
||||
- standard/gateway.networking.k8s.io_httproutes.yaml
|
||||
- standard/gateway.networking.k8s.io_referencegrants.yaml
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="gateway-api.gen.cue" label="Root">
|
||||
`gateway-api.gen.cue`
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// Manage on every Cluster in the Platform
|
||||
for Fleet in #Fleets {
|
||||
for Cluster in Fleet.clusters {
|
||||
#Platform: Components: "\(Cluster.name)/gateway-api": {
|
||||
path: "components/gateway-api"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Render the Platform to render the Component for the workload clusters.
|
||||
|
||||
<Tabs groupId="render-platform-gateway">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render platform ./platform
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
rendered components/gateway-api for cluster workload in 279.312292ms
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
:::tip
|
||||
This example is equivalent to running `kubectl kustomize
|
||||
./components/gateway-api` and saving the output to a file. Holos simplifies
|
||||
this task and makes it consistent with Helm and other tools.
|
||||
:::
|
||||
|
||||
Add and commit the Component and rendered Platform.
|
||||
|
||||
<Tabs groupId="commit-gateway-api">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "add gateway-api component"
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
[main 88575a5] add gateway-api component
|
||||
9 files changed, 26907 insertions(+)
|
||||
create mode 100644 components/gateway-api/gateway-api.cue
|
||||
create mode 100644 components/gateway-api/kustomization.yaml
|
||||
create mode 100644 components/gateway-api/standard/gateway.networking.k8s.io_gatewayclasses.yaml
|
||||
create mode 100644 components/gateway-api/standard/gateway.networking.k8s.io_gateways.yaml
|
||||
create mode 100644 components/gateway-api/standard/gateway.networking.k8s.io_grpcroutes.yaml
|
||||
create mode 100644 components/gateway-api/standard/gateway.networking.k8s.io_httproutes.yaml
|
||||
create mode 100644 components/gateway-api/standard/gateway.networking.k8s.io_referencegrants.yaml
|
||||
create mode 100644 deploy/clusters/workload/components/gateway-api/gateway-api.gen.yaml
|
||||
create mode 100644 gateway-api.gen.cue
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Optionally apply the rendered component to your cluster.
|
||||
|
||||
<Tabs groupId="apply-gateway-api">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
kubectl apply --server-side=true -f deploy/clusters/workload/components/gateway-api
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
customresourcedefinition.apiextensions.k8s.io/gatewayclasses.gateway.networking.k8s.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/gateways.gateway.networking.k8s.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/grpcroutes.gateway.networking.k8s.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/httproutes.gateway.networking.k8s.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/referencegrants.gateway.networking.k8s.io serverside-applied
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Namespaces
|
||||
|
||||
We often need to manage namespaces prior to workloads being deployed. This is
|
||||
necessary because a namespace is a security boundary. Holos makes it easier,
|
||||
safer, and more consistent to manage service accounts, role bindings, and
|
||||
secrets prior to deploying workloads into a namespace.
|
||||
|
||||
We'll see how this works with the namespaces component, which offers a mechanism
|
||||
for other components to register their namespaces. The namespaces component
|
||||
initializes each registered namespace, optionally mixing in resources
|
||||
consistently.
|
||||
|
||||
Run the following command to generate the namespaces component.
|
||||
|
||||
<Tabs groupId="gen-namespaces">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos generate component namespaces
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
generated component
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
The command generates two main configuration files like we've seen with other
|
||||
components. One file at the leaf, and another at the root. The leaf uses a
|
||||
Kubernetes build plan to produce resources directly from CUE.
|
||||
|
||||
<Tabs groupId="namespaces-files">
|
||||
<TabItem value="components/namespaces/namespaces.cue" label="Leaf">
|
||||
`components/namespaces/namespaces.cue`
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
let Objects = {
|
||||
Name: "namespaces"
|
||||
// highlight-next-line
|
||||
Resources: Namespace: #Namespaces
|
||||
}
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).Output
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="namespaces.gen.cue" label="Root">
|
||||
`namespaces.gen.cue`
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
import corev1 "k8s.io/api/core/v1"
|
||||
|
||||
// #Namespaces defines all managed namespaces in the Platform.
|
||||
// Holos adopts the sig-multicluster position of namespace sameness.
|
||||
#Namespaces: {
|
||||
// Validate against v1 of the kubernetes core api
|
||||
// highlight-next-line
|
||||
[Name=string]: corev1.#Namespace & {
|
||||
metadata: name: Name
|
||||
}
|
||||
}
|
||||
|
||||
// Manage the Component on every Cluster in the Platform
|
||||
for Fleet in #Fleets {
|
||||
for Cluster in Fleet.clusters {
|
||||
#Platform: Components: "\(Cluster.name)/namespaces": {
|
||||
path: "components/namespaces"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Notice the highlighted line in the leaf file. Resources are managed directly in
|
||||
CUE at the leaf using the Kubernetes component. This is the same mechanism used
|
||||
to mix-in resources to Helm and Kustomize components. The leaf refers to
|
||||
`#Namespaces` defined at the root. At the root `#Namespaces` enforces a
|
||||
constraint: each Namespace must conform to the `k8s.io/api/core/v1`
|
||||
specification.
|
||||
|
||||
:::important
|
||||
We've covered three kinds of components so far. The [Quickstart] guide
|
||||
introduced Helm. We've used Kustomize and Kubernetes in this guide.
|
||||
|
||||
Holos offers a consistent way to manage these different kinds of packaging
|
||||
safely and easily.
|
||||
:::
|
||||
|
||||
- At the **leaf** Holos tailors the component to your platform, mixing
|
||||
in resources and customizing the rendered output.
|
||||
- At the **root** Holos integrates a component with the rest of your platform.
|
||||
|
||||
You'll see this pattern again and again as you build your platform.
|
||||
|
||||
Render the platform to render the component for the workload clusters.
|
||||
|
||||
<Tabs groupId="render-platform-gateway">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render platform ./platform
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
rendered components/namespaces for cluster workload in 72.675292ms
|
||||
rendered components/gateway-api for cluster workload in 259.174583ms
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Add and commit the configuration and rendered manifests.
|
||||
|
||||
<Tabs groupId="commit-gateway-api">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "add namespaces component"
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
[main 1bf0d61] add namespaces component
|
||||
3 files changed, 30 insertions(+)
|
||||
create mode 100644 components/namespaces/namespaces.cue
|
||||
create mode 100644 deploy/clusters/workload/components/namespaces/namespaces.gen.yaml
|
||||
create mode 100644 namespaces.gen.cue
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
`#Namespaces` is currently empty, so the rendered output of
|
||||
`namespaces.gen.yaml` is also empty.
|
||||
|
||||
:::tip
|
||||
Namespaces will be automatically managed as we add more components to the
|
||||
platform over time.
|
||||
:::
|
||||
|
||||
## Istio
|
||||
|
||||
We'll manage Istio to implement the Gateway API so we can expose the httpbin
|
||||
service outside of the cluster.
|
||||
|
||||
Run the following command to generate the istio components.
|
||||
|
||||
<Tabs groupId="gen-istio">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos generate component istio
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
generated component
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
:::important
|
||||
Mix in the `istio-k3d` component if you're applying the rendered manifests to
|
||||
k3d as described in our [Local Cluster] guide.
|
||||
:::
|
||||
|
||||
Skip this step if you aren't using k3d. Istio needs to be configured to refer
|
||||
to the nonstandard cni configuration paths k3d uses.
|
||||
|
||||
<Tabs groupId="gen-istio-k3d">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos generate component istio-k3d
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
generated component
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="file" label="istio-k3d.gen.cue">
|
||||
Holos makes it easier and safer to mix-in this additional configuration at the root.
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// If you are using k3d with the default Flannel CNI, you must append some
|
||||
// values to your installation command, as k3d uses nonstandard locations for
|
||||
// CNI configuration and binaries.
|
||||
//
|
||||
// See https://istio.io/latest/docs/ambient/install/platform-prerequisites/#k3d
|
||||
#Istio: Values: cni: {
|
||||
cniConfDir: "/var/lib/rancher/k3s/agent/etc/cni/net.d"
|
||||
cniBinDir: "/bin"
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Consistent with the other components we've seen, the istio components define
|
||||
configuration at the root and leafs of the tree. Unlike previous components
|
||||
we've generated, this command generated multiple components to manage Istio.
|
||||
|
||||
<Tabs groupId="tree-istio">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
tree components/istio
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
components/istio
|
||||
├── base
|
||||
│ ├── istio-base.cue
|
||||
│ └── values.gen.cue
|
||||
├── cni
|
||||
│ ├── cni.cue
|
||||
│ └── values.gen.cue
|
||||
├── gateway
|
||||
│ ├── gateway.cue
|
||||
│ └── values.gen.cue
|
||||
├── istiod
|
||||
│ ├── istiod.cue
|
||||
│ └── values.gen.cue
|
||||
└── ztunnel
|
||||
├── values.gen.cue
|
||||
└── ztunnel.cue
|
||||
|
||||
6 directories, 10 files
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
These components share the configuration defined at the root in `istio.gen.cue`.
|
||||
|
||||
Let's review how Holos makes it safer and easier to share Helm values defined at
|
||||
the root with the istiod and cni components defined at the leaf.
|
||||
|
||||
1. istiod and cni use version `"1.23.1"` and namespace `"istio-system"` defined at
|
||||
the root.
|
||||
2. The Helm value to configure ambient (sidecar-less) mode is defined once at
|
||||
the root.
|
||||
3. The root adds a constraint to fail validation if the istio system namespace
|
||||
is not `"istio-system"`. Future upgrades are safer with this constraint, if the
|
||||
upstream vendor changes the default in the future the component will fail
|
||||
validation.
|
||||
4. The root registers two Namespaces, `"istio-system"` and `"istio-ingress"`.
|
||||
5. The root manages the components on all workload clusters in the platform.
|
||||
|
||||
<Tabs groupId="istio-files">
|
||||
<TabItem value="istiod.cue" label="istiod">
|
||||
Leaf `components/istio/istiod/istiod.cue`
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
(#Helm & Chart).Output
|
||||
|
||||
let Chart = {
|
||||
Name: "istiod"
|
||||
// highlight-next-line
|
||||
Version: #Istio.Version
|
||||
// highlight-next-line
|
||||
Namespace: #Istio.System.Namespace
|
||||
|
||||
Chart: chart: name: "istiod"
|
||||
|
||||
Repo: name: "istio"
|
||||
Repo: url: "https://istio-release.storage.googleapis.com/charts"
|
||||
|
||||
// highlight-next-line
|
||||
Values: #Istio.Values
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cni.cue" label="cni">
|
||||
Leaf `components/istio/cni/cni.cue`
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
(#Helm & Chart).Output
|
||||
|
||||
let Chart = {
|
||||
Name: "istio-cni"
|
||||
// highlight-next-line
|
||||
Version: #Istio.Version
|
||||
// highlight-next-line
|
||||
Namespace: #Istio.System.Namespace
|
||||
|
||||
Chart: chart: name: "cni"
|
||||
|
||||
Repo: name: "istio"
|
||||
Repo: url: "https://istio-release.storage.googleapis.com/charts"
|
||||
|
||||
// highlight-next-line
|
||||
Values: #Istio.Values
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="istio.gen.cue" label="Root">
|
||||
Root `istio.gen.cue`
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// #Istio represents platform wide configuration
|
||||
#Istio: {
|
||||
// highlight-next-line
|
||||
Version: "1.23.1"
|
||||
// highlight-next-line
|
||||
System: Namespace: "istio-system"
|
||||
Gateway: Namespace: "istio-ingress"
|
||||
|
||||
// Constrain Helm values for safer, easier upgrades and consistency across
|
||||
// platform components.
|
||||
// highlight-next-line
|
||||
Values: global: istioNamespace: System.Namespace
|
||||
|
||||
// Configure ambient mode
|
||||
// highlight-next-line
|
||||
Values: profile: "ambient"
|
||||
}
|
||||
|
||||
// Register the Namespaces
|
||||
#Namespaces: (#Istio.System.Namespace): _
|
||||
#Namespaces: (#Istio.Gateway.Namespace): _
|
||||
|
||||
// Manage istio on workload clusters
|
||||
for Cluster in #Fleets.workload.clusters {
|
||||
#Platform: Components: {
|
||||
"\(Cluster.name)/istio-base": {
|
||||
path: "components/istio/base"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
"\(Cluster.name)/istiod": {
|
||||
path: "components/istio/istiod"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
"\(Cluster.name)/istio-cni": {
|
||||
path: "components/istio/cni"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
"\(Cluster.name)/istio-ztunnel": {
|
||||
path: "components/istio/ztunnel"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
"\(Cluster.name)/istio-gateway": {
|
||||
path: "components/istio/gateway"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
:::tip
|
||||
Many software projects managed by Holos are organized into a collection of
|
||||
components working together, for example to safely manage custom resource
|
||||
definitions, secrets, and policy separately from the workloads that rely on
|
||||
them.
|
||||
:::
|
||||
|
||||
Render the platform to render the istio components for the workload clusters.
|
||||
|
||||
<Tabs groupId="render-platform-istio">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render platform ./platform
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
rendered components/namespaces for cluster workload in 85.490833ms
|
||||
rendered components/istio/ztunnel for cluster workload in 111.784667ms
|
||||
rendered components/istio/cni for cluster workload in 112.362417ms
|
||||
rendered components/istio/base for cluster workload in 113.058ms
|
||||
rendered components/istio/gateway for cluster workload in 119.018208ms
|
||||
rendered components/istio/istiod for cluster workload in 127.736334ms
|
||||
rendered components/gateway-api for cluster workload in 181.922333ms
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Add and commit the configuration and rendered manifests.
|
||||
|
||||
<Tabs groupId="commit-istio">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "add istio"
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
[main aca8ff6] add istio
|
||||
18 files changed, 18955 insertions(+)
|
||||
create mode 100644 components/istio/base/istio-base.cue
|
||||
create mode 100644 components/istio/base/values.gen.cue
|
||||
create mode 100644 components/istio/cni/cni.cue
|
||||
create mode 100644 components/istio/cni/values.gen.cue
|
||||
create mode 100644 components/istio/gateway/gateway.cue
|
||||
create mode 100644 components/istio/gateway/values.gen.cue
|
||||
create mode 100644 components/istio/istiod/istiod.cue
|
||||
create mode 100644 components/istio/istiod/values.gen.cue
|
||||
create mode 100644 components/istio/ztunnel/values.gen.cue
|
||||
create mode 100644 components/istio/ztunnel/ztunnel.cue
|
||||
create mode 100644 deploy/clusters/workload/components/istio-base/istio-base.gen.yaml
|
||||
create mode 100644 deploy/clusters/workload/components/istio-cni/istio-cni.gen.yaml
|
||||
create mode 100644 deploy/clusters/workload/components/istio-gateway/istio-gateway.gen.yaml
|
||||
create mode 100644 deploy/clusters/workload/components/istio-ztunnel/istio-ztunnel.gen.yaml
|
||||
create mode 100644 deploy/clusters/workload/components/istiod/istiod.gen.yaml
|
||||
create mode 100644 istio-k3d.gen.cue
|
||||
create mode 100644 istio.gen.cue
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Optionally apply the rendered component to your cluster.
|
||||
|
||||
<Tabs groupId="apply-istio-namespaces">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
kubectl apply --server-side=true -f deploy/clusters/workload/components/namespaces
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
namespace/istio-ingress serverside-applied
|
||||
namespace/istio-system serverside-applied
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
<Tabs groupId="apply-istio-base">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
kubectl apply --server-side=true -f deploy/clusters/workload/components/istio-base
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
customresourcedefinition.apiextensions.k8s.io/wasmplugins.extensions.istio.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/destinationrules.networking.istio.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/envoyfilters.networking.istio.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/gateways.networking.istio.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/proxyconfigs.networking.istio.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/serviceentries.networking.istio.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/sidecars.networking.istio.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/virtualservices.networking.istio.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/workloadentries.networking.istio.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/workloadgroups.networking.istio.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/authorizationpolicies.security.istio.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/peerauthentications.security.istio.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/requestauthentications.security.istio.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/telemetries.telemetry.istio.io serverside-applied
|
||||
serviceaccount/istio-reader-service-account serverside-applied
|
||||
validatingwebhookconfiguration.admissionregistration.k8s.io/istiod-default-validator serverside-applied
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
<Tabs groupId="apply-istiod">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
kubectl apply --server-side=true -f deploy/clusters/workload/components/istiod
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
poddisruptionbudget.policy/istiod serverside-applied
|
||||
serviceaccount/istiod serverside-applied
|
||||
configmap/istio serverside-applied
|
||||
configmap/istio-sidecar-injector serverside-applied
|
||||
clusterrole.rbac.authorization.k8s.io/istiod-clusterrole-istio-system serverside-applied
|
||||
clusterrole.rbac.authorization.k8s.io/istiod-gateway-controller-istio-system serverside-applied
|
||||
clusterrole.rbac.authorization.k8s.io/istio-reader-clusterrole-istio-system serverside-applied
|
||||
clusterrolebinding.rbac.authorization.k8s.io/istiod-clusterrole-istio-system serverside-applied
|
||||
clusterrolebinding.rbac.authorization.k8s.io/istiod-gateway-controller-istio-system serverside-applied
|
||||
clusterrolebinding.rbac.authorization.k8s.io/istio-reader-clusterrole-istio-system serverside-applied
|
||||
role.rbac.authorization.k8s.io/istiod serverside-applied
|
||||
rolebinding.rbac.authorization.k8s.io/istiod serverside-applied
|
||||
service/istiod serverside-applied
|
||||
deployment.apps/istiod serverside-applied
|
||||
horizontalpodautoscaler.autoscaling/istiod serverside-applied
|
||||
mutatingwebhookconfiguration.admissionregistration.k8s.io/istio-sidecar-injector serverside-applied
|
||||
validatingwebhookconfiguration.admissionregistration.k8s.io/istio-validator-istio-system serverside-applied
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
<Tabs groupId="apply-istio-cni">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
kubectl apply --server-side=true -f deploy/clusters/workload/components/istio-cni
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
serviceaccount/istio-cni serverside-applied
|
||||
configmap/istio-cni-config serverside-applied
|
||||
clusterrole.rbac.authorization.k8s.io/istio-cni serverside-applied
|
||||
clusterrole.rbac.authorization.k8s.io/istio-cni-repair-role serverside-applied
|
||||
clusterrole.rbac.authorization.k8s.io/istio-cni-ambient serverside-applied
|
||||
clusterrolebinding.rbac.authorization.k8s.io/istio-cni serverside-applied
|
||||
clusterrolebinding.rbac.authorization.k8s.io/istio-cni-repair-rolebinding serverside-applied
|
||||
clusterrolebinding.rbac.authorization.k8s.io/istio-cni-ambient serverside-applied
|
||||
daemonset.apps/istio-cni-node serverside-applied
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
<Tabs groupId="apply-istio-ztunnel">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
kubectl apply --server-side=true -f deploy/clusters/workload/components/istio-ztunnel
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
serviceaccount/ztunnel serverside-applied
|
||||
daemonset.apps/ztunnel serverside-applied
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
<Tabs groupId="apply-istio-gateway">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
kubectl apply --server-side=true -f deploy/clusters/workload/components/istio-gateway
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
serviceaccount/gateway serverside-applied
|
||||
role.rbac.authorization.k8s.io/gateway serverside-applied
|
||||
rolebinding.rbac.authorization.k8s.io/gateway serverside-applied
|
||||
service/gateway serverside-applied
|
||||
deployment.apps/gateway serverside-applied
|
||||
horizontalpodautoscaler.autoscaling/gateway serverside-applied
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Make sure all pod containers become ready.
|
||||
|
||||
<Tabs groupId="apply-istio-ready">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
kubectl get pods -A
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
NAMESPACE NAME READY STATUS RESTARTS AGE
|
||||
istio-ingress gateway-6748c5f547-s46pj 1/1 Running 0 26s
|
||||
istio-system istio-cni-node-852nr 1/1 Running 0 2m9s
|
||||
istio-system istiod-5b4d8d4c77-t694z 1/1 Running 0 3m15s
|
||||
istio-system ztunnel-msqbn 1/1 Running 0 63s
|
||||
kube-system coredns-576bfc4dc7-2g4k9 1/1 Running 0 113m
|
||||
kube-system local-path-provisioner-6795b5f9d8-wsz8p 1/1 Running 0 113m
|
||||
kube-system metrics-server-557ff575fb-fctr7 1/1 Running 0 113m
|
||||
kube-system svclb-gateway-5d311af0-fp5mk 3/3 Running 0 26s
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Once all pods are ready, we're ready to manage httpbin so we can route http
|
||||
traffic to it.
|
||||
|
||||
## httpbin
|
||||
|
||||
[Quickstart]: /docs/quickstart
|
||||
[Local Cluster]: /docs/guides/local-cluster
|
||||
277
doc/md/guides/local-cluster.mdx
Normal file
@@ -0,0 +1,277 @@
|
||||
---
|
||||
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 -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.
|
||||
724
doc/md/guides/quickstart.mdx
Normal file
@@ -0,0 +1,724 @@
|
||||
---
|
||||
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 organization’s 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://example.com/holos-quickstart.git"
|
||||
}
|
||||
```
|
||||
</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/
|
||||
10
doc/md/introduction.md
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
description: Holos Documentation
|
||||
slug: /
|
||||
---
|
||||
|
||||
# Introduction
|
||||
|
||||
:::warning TODO
|
||||
See [introduction](https://github.com/facebook/docusaurus/blob/main/website/docs/introduction.mdx?plain=1)
|
||||
:::
|
||||
@@ -1,69 +0,0 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
# Quickstart Guide
|
||||
|
||||
This guide shows you the basics of how Holos. You'll deploy a Helm chart to
|
||||
Kubernetes using a Component to see how Holos makes the process safer, easier,
|
||||
and more consistent.
|
||||
|
||||
## 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 Kubernetes 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.
|
||||
|
||||
## 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
|
||||
```
|
||||
|
||||
## Git repository
|
||||
|
||||
Start by initializing an empty Git repository. Holos is designed to operate
|
||||
against local files 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 commands are run from the root directory of this Git
|
||||
repository unless otherwise stated.
|
||||
|
||||
## Generate the Platform {#Generate-Platform}
|
||||
|
||||
Generate the Platform code in the repository root. A Platform refers to all of
|
||||
the software and services integrated together to provide your organization's
|
||||
software development platform. In this guide the platform will contain a single
|
||||
Component to demonstrate how the concepts fit together.
|
||||
|
||||
```bash
|
||||
holos generate platform quickstart
|
||||
```
|
||||
|
||||
Commit the generated platform config to the repository.
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "holos generate platform quickstart - $(holos --version)"
|
||||
```
|
||||
5
doc/md/start.md
Normal file
@@ -0,0 +1,5 @@
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
|
||||
# Get Started
|
||||
|
||||
<DocCardList />
|
||||
@@ -1,9 +1,14 @@
|
||||
# Comparison with other tools
|
||||
---
|
||||
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.
|
||||
|
||||
Holos is designed to complement and improve, not replace, existing tools in the
|
||||
cloud native ecosystem.
|
||||
:::
|
||||
|
||||
## Helm
|
||||
@@ -30,13 +35,13 @@ 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. |
|
||||
| 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
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
---
|
||||
description: Learn the concepts and domain language Holos uses.
|
||||
slug: /concepts
|
||||
sidebar_position: 200
|
||||
---
|
||||
|
||||
# Concepts
|
||||
|
||||
## Introduction
|
||||
@@ -23,21 +29,34 @@ platform engineers.
|
||||
- [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 BT
|
||||
graph TB
|
||||
Platform[<a href="#platform">Platform</a>]
|
||||
Component[<a href="#component">Components</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>]
|
||||
|
||||
Component --> Platform
|
||||
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
|
||||
@@ -336,6 +355,16 @@ graph LR
|
||||
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
|
||||
@@ -1,3 +1,9 @@
|
||||
---
|
||||
description: Install the Holos executable.
|
||||
slug: /install
|
||||
sidebar_position: 100
|
||||
---
|
||||
|
||||
# Installation
|
||||
|
||||
Holos is distributed as a single file executable.
|
||||
@@ -41,12 +41,7 @@ const config: Config = {
|
||||
[
|
||||
'@docusaurus/plugin-client-redirects',
|
||||
{
|
||||
redirects: [
|
||||
{
|
||||
from: "/docs/tutorial/local/k3d/",
|
||||
to: "/docs/guides/try-holos/",
|
||||
},
|
||||
],
|
||||
redirects: [],
|
||||
},
|
||||
],
|
||||
],
|
||||
@@ -98,19 +93,14 @@ const config: Config = {
|
||||
items: [
|
||||
{
|
||||
type: 'doc',
|
||||
docId: 'quickstart/index',
|
||||
docId: 'guides/quickstart',
|
||||
position: 'left',
|
||||
label: 'Try Holos',
|
||||
},
|
||||
{ to: '/docs', label: 'Docs', position: 'left' },
|
||||
{
|
||||
type: 'doc',
|
||||
docId: 'concepts',
|
||||
position: 'left',
|
||||
label: 'Docs',
|
||||
},
|
||||
{
|
||||
type: 'docSidebar',
|
||||
sidebarId: 'api',
|
||||
docId: 'api',
|
||||
position: 'left',
|
||||
label: 'API',
|
||||
},
|
||||
@@ -135,7 +125,7 @@ const config: Config = {
|
||||
title: 'Docs',
|
||||
items: [
|
||||
{
|
||||
label: 'Get Started',
|
||||
label: 'Quickstart',
|
||||
to: '/docs/quickstart',
|
||||
},
|
||||
{
|
||||
@@ -144,11 +134,11 @@ const config: Config = {
|
||||
},
|
||||
{
|
||||
label: 'Documentation',
|
||||
to: '/docs/intro',
|
||||
to: '/docs',
|
||||
},
|
||||
{
|
||||
label: 'API Reference',
|
||||
to: '/docs/api/core/v1alpha2',
|
||||
to: '/docs/api',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -12,22 +12,63 @@ import type { SidebarsConfig } from '@docusaurus/plugin-content-docs';
|
||||
*/
|
||||
const sidebars: SidebarsConfig = {
|
||||
doc: [
|
||||
'quickstart/index',
|
||||
'concepts',
|
||||
'install',
|
||||
'comparison',
|
||||
],
|
||||
api: [
|
||||
'introduction',
|
||||
{
|
||||
label: 'Core API',
|
||||
label: 'Getting Started',
|
||||
type: 'category',
|
||||
collapsed: true,
|
||||
link: { type: 'doc', id: 'start' },
|
||||
items: [
|
||||
'api/core/v1alpha3',
|
||||
'api/core/v1alpha2',
|
||||
{
|
||||
type: 'autogenerated',
|
||||
dirName: 'start',
|
||||
},
|
||||
],
|
||||
},
|
||||
'cli',
|
||||
{
|
||||
label: 'Guides',
|
||||
type: 'category',
|
||||
collapsed: false,
|
||||
link: { type: 'doc', id: 'guides' },
|
||||
items: [
|
||||
{
|
||||
type: 'autogenerated',
|
||||
dirName: 'guides',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'API Reference',
|
||||
type: 'category',
|
||||
collapsed: true,
|
||||
link: { type: 'doc', id: 'api' },
|
||||
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',
|
||||
},
|
||||
]
|
||||
},
|
||||
]
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
@@ -4,6 +4,12 @@
|
||||
* 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;
|
||||
|
||||
38
doc/website/static/scripts/local-ca
Executable file
@@ -0,0 +1,38 @@
|
||||
#! /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
|
||||
cd ..
|
||||
|
||||
echo 'type: kubernetes.io/tls' >> local-ca.yaml
|
||||
kubectl apply --server-side=true -f- <<EOF
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
labels:
|
||||
kubernetes.io/metadata.name: cert-manager
|
||||
name: cert-manager
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
EOF
|
||||
kubectl apply -n cert-manager --server-side=true -f local-ca.yaml
|
||||
38
doc/website/static/scripts/local-dns
Normal file
@@ -0,0 +1,38 @@
|
||||
#! /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."
|
||||
@@ -75,9 +75,6 @@ func (b *buildPlanWrapper) validate() error {
|
||||
if bp.Kind != v1.BuildPlanKind {
|
||||
errs = append(errs, fmt.Sprintf("kind invalid: want: %s have: %s", v1alpha1.BuildPlanKind, bp.Kind))
|
||||
}
|
||||
if bp.APIVersion != v1.APIVersion {
|
||||
errs = append(errs, fmt.Sprintf("apiVersion invalid: want: %s have: %s", v1.APIVersion, bp.APIVersion))
|
||||
}
|
||||
if len(errs) > 0 {
|
||||
return errors.New("invalid BuildPlan: " + strings.Join(errs, ", "))
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/holos-run/holos/internal/cli/command"
|
||||
"github.com/holos-run/holos/internal/client"
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
"github.com/holos-run/holos/internal/generate"
|
||||
"github.com/holos-run/holos/internal/holos"
|
||||
@@ -35,11 +34,9 @@ func NewPlatform(cfg *holos.Config) *cobra.Command {
|
||||
cmd.Args = cobra.ExactArgs(1)
|
||||
cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Root().Context()
|
||||
clientContext := holos.NewClientContext(ctx)
|
||||
client := client.New(client.NewConfig(cfg))
|
||||
|
||||
for _, name := range args {
|
||||
if err := generate.GeneratePlatform(ctx, client, clientContext.OrgID, name); err != nil {
|
||||
if err := generate.GeneratePlatform(ctx, name); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
}
|
||||
@@ -55,33 +52,13 @@ func NewComponent() *cobra.Command {
|
||||
cmd := command.New("component")
|
||||
cmd.Short = "generate a component from an embedded schematic"
|
||||
|
||||
cmd.AddCommand(NewCueComponent())
|
||||
cmd.AddCommand(NewHelmComponent())
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewHelmComponent() *cobra.Command {
|
||||
cmd := command.New("helm")
|
||||
cmd.Short = "generate a helm component from a schematic"
|
||||
|
||||
for _, name := range generate.HelmComponents() {
|
||||
cmd.AddCommand(makeSchematicCommand("helm", name))
|
||||
for _, name := range generate.Components("v1alpha3") {
|
||||
cmd.AddCommand(makeSchematicCommand("v1alpha3", name))
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewCueComponent() *cobra.Command {
|
||||
cmd := command.New("cue")
|
||||
cmd.Short = "generate a cue component from a schematic"
|
||||
|
||||
for _, name := range generate.CueComponents() {
|
||||
cmd.AddCommand(makeSchematicCommand("cue", name))
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
func makeSchematicCommand(kind, name string) *cobra.Command {
|
||||
cmd := command.New(name)
|
||||
cfg, err := generate.NewSchematic(filepath.Join("components", kind), name)
|
||||
|
||||
@@ -81,22 +81,10 @@ func (s *Schematic) FlagSet() *flag.FlagSet {
|
||||
return fs
|
||||
}
|
||||
|
||||
// CueComponents returns a slice of embedded component schematics or nil if there are none.
|
||||
func CueComponents() []string {
|
||||
entries, err := fs.ReadDir(components, filepath.Join(componentsRoot, "cue"))
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
dirs := make([]string, 0, len(entries))
|
||||
for _, entry := range entries {
|
||||
dirs = append(dirs, entry.Name())
|
||||
}
|
||||
return dirs
|
||||
}
|
||||
|
||||
// HelmComponents returns a slice of embedded component schematics or nil if there are none.
|
||||
func HelmComponents() []string {
|
||||
entries, err := fs.ReadDir(components, filepath.Join(componentsRoot, "helm"))
|
||||
// Components returns a slice of embedded component schematics or nil if there
|
||||
// are none.
|
||||
func Components(name string) []string {
|
||||
entries, err := fs.ReadDir(components, filepath.Join(componentsRoot, name))
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
@@ -131,8 +119,8 @@ func makeRenderFunc[T any](log *slog.Logger, path string, cfg T) func([]byte) *b
|
||||
func GenerateComponent(ctx context.Context, kind string, name string, cfg *Schematic) error {
|
||||
// use name from args to build the source path
|
||||
path := filepath.Join(componentsRoot, kind, name)
|
||||
// use cfg.Name from flags to build the destination path
|
||||
dstPath := filepath.Join(getCwd(ctx), cfg.Name)
|
||||
// write to the current directory.
|
||||
dstPath := filepath.Join(getCwd(ctx))
|
||||
log := logger.FromContext(ctx).With("name", cfg.Name, "path", dstPath)
|
||||
log.DebugContext(ctx, "mkdir")
|
||||
if err := os.MkdirAll(dstPath, os.ModePerm); err != nil {
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
package holos
|
||||
|
||||
// Produce a kubectl kustomize build plan.
|
||||
(#Kustomize & {Name: "gateway-api"}).Output
|
||||
@@ -0,0 +1,6 @@
|
||||
resources:
|
||||
- standard/gateway.networking.k8s.io_gatewayclasses.yaml
|
||||
- standard/gateway.networking.k8s.io_gateways.yaml
|
||||
- standard/gateway.networking.k8s.io_grpcroutes.yaml
|
||||
- standard/gateway.networking.k8s.io_httproutes.yaml
|
||||
- standard/gateway.networking.k8s.io_referencegrants.yaml
|
||||
@@ -0,0 +1,524 @@
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997
|
||||
gateway.networking.k8s.io/bundle-version: v1.1.0
|
||||
gateway.networking.k8s.io/channel: standard
|
||||
creationTimestamp: null
|
||||
name: gatewayclasses.gateway.networking.k8s.io
|
||||
spec:
|
||||
group: gateway.networking.k8s.io
|
||||
names:
|
||||
categories:
|
||||
- gateway-api
|
||||
kind: GatewayClass
|
||||
listKind: GatewayClassList
|
||||
plural: gatewayclasses
|
||||
shortNames:
|
||||
- gc
|
||||
singular: gatewayclass
|
||||
scope: Cluster
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .spec.controllerName
|
||||
name: Controller
|
||||
type: string
|
||||
- jsonPath: .status.conditions[?(@.type=="Accepted")].status
|
||||
name: Accepted
|
||||
type: string
|
||||
- jsonPath: .metadata.creationTimestamp
|
||||
name: Age
|
||||
type: date
|
||||
- jsonPath: .spec.description
|
||||
name: Description
|
||||
priority: 1
|
||||
type: string
|
||||
name: v1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: |-
|
||||
GatewayClass describes a class of Gateways available to the user for creating
|
||||
Gateway resources.
|
||||
|
||||
|
||||
It is recommended that this resource be used as a template for Gateways. This
|
||||
means that a Gateway is based on the state of the GatewayClass at the time it
|
||||
was created and changes to the GatewayClass or associated parameters are not
|
||||
propagated down to existing Gateways. This recommendation is intended to
|
||||
limit the blast radius of changes to GatewayClass or associated parameters.
|
||||
If implementations choose to propagate GatewayClass changes to existing
|
||||
Gateways, that MUST be clearly documented by the implementation.
|
||||
|
||||
|
||||
Whenever one or more Gateways are using a GatewayClass, implementations SHOULD
|
||||
add the `gateway-exists-finalizer.gateway.networking.k8s.io` finalizer on the
|
||||
associated GatewayClass. This ensures that a GatewayClass associated with a
|
||||
Gateway is not deleted while in use.
|
||||
|
||||
|
||||
GatewayClass is a Cluster level resource.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: |-
|
||||
APIVersion defines the versioned schema of this representation of an object.
|
||||
Servers should convert recognized schemas to the latest internal value, and
|
||||
may reject unrecognized values.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind is a string value representing the REST resource this object represents.
|
||||
Servers may infer this from the endpoint the client submits requests to.
|
||||
Cannot be updated.
|
||||
In CamelCase.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: Spec defines the desired state of GatewayClass.
|
||||
properties:
|
||||
controllerName:
|
||||
description: |-
|
||||
ControllerName is the name of the controller that is managing Gateways of
|
||||
this class. The value of this field MUST be a domain prefixed path.
|
||||
|
||||
|
||||
Example: "example.net/gateway-controller".
|
||||
|
||||
|
||||
This field is not mutable and cannot be empty.
|
||||
|
||||
|
||||
Support: Core
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$
|
||||
type: string
|
||||
x-kubernetes-validations:
|
||||
- message: Value is immutable
|
||||
rule: self == oldSelf
|
||||
description:
|
||||
description: Description helps describe a GatewayClass with more details.
|
||||
maxLength: 64
|
||||
type: string
|
||||
parametersRef:
|
||||
description: |-
|
||||
ParametersRef is a reference to a resource that contains the configuration
|
||||
parameters corresponding to the GatewayClass. This is optional if the
|
||||
controller does not require any additional configuration.
|
||||
|
||||
|
||||
ParametersRef can reference a standard Kubernetes resource, i.e. ConfigMap,
|
||||
or an implementation-specific custom resource. The resource can be
|
||||
cluster-scoped or namespace-scoped.
|
||||
|
||||
|
||||
If the referent cannot be found, the GatewayClass's "InvalidParameters"
|
||||
status condition will be true.
|
||||
|
||||
|
||||
A Gateway for this GatewayClass may provide its own `parametersRef`. When both are specified,
|
||||
the merging behavior is implementation specific.
|
||||
It is generally recommended that GatewayClass provides defaults that can be overridden by a Gateway.
|
||||
|
||||
|
||||
Support: Implementation-specific
|
||||
properties:
|
||||
group:
|
||||
description: Group is the group of the referent.
|
||||
maxLength: 253
|
||||
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
|
||||
type: string
|
||||
kind:
|
||||
description: Kind is kind of the referent.
|
||||
maxLength: 63
|
||||
minLength: 1
|
||||
pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
|
||||
type: string
|
||||
name:
|
||||
description: Name is the name of the referent.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
namespace:
|
||||
description: |-
|
||||
Namespace is the namespace of the referent.
|
||||
This field is required when referring to a Namespace-scoped resource and
|
||||
MUST be unset when referring to a Cluster-scoped resource.
|
||||
maxLength: 63
|
||||
minLength: 1
|
||||
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
|
||||
type: string
|
||||
required:
|
||||
- group
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
required:
|
||||
- controllerName
|
||||
type: object
|
||||
status:
|
||||
default:
|
||||
conditions:
|
||||
- lastTransitionTime: "1970-01-01T00:00:00Z"
|
||||
message: Waiting for controller
|
||||
reason: Waiting
|
||||
status: Unknown
|
||||
type: Accepted
|
||||
description: |-
|
||||
Status defines the current state of GatewayClass.
|
||||
|
||||
|
||||
Implementations MUST populate status on all GatewayClass resources which
|
||||
specify their controller name.
|
||||
properties:
|
||||
conditions:
|
||||
default:
|
||||
- lastTransitionTime: "1970-01-01T00:00:00Z"
|
||||
message: Waiting for controller
|
||||
reason: Pending
|
||||
status: Unknown
|
||||
type: Accepted
|
||||
description: |-
|
||||
Conditions is the current status from the controller for
|
||||
this GatewayClass.
|
||||
|
||||
|
||||
Controllers should prefer to publish conditions using values
|
||||
of GatewayClassConditionType for the type of each Condition.
|
||||
items:
|
||||
description: "Condition contains details for one aspect of the current
|
||||
state of this API Resource.\n---\nThis struct is intended for
|
||||
direct use as an array at the field path .status.conditions. For
|
||||
example,\n\n\n\ttype FooStatus struct{\n\t // Represents the
|
||||
observations of a foo's current state.\n\t // Known .status.conditions.type
|
||||
are: \"Available\", \"Progressing\", and \"Degraded\"\n\t //
|
||||
+patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t
|
||||
\ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\"
|
||||
patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
|
||||
\ // other fields\n\t}"
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: |-
|
||||
lastTransitionTime is the last time the condition transitioned from one status to another.
|
||||
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: |-
|
||||
message is a human readable message indicating details about the transition.
|
||||
This may be an empty string.
|
||||
maxLength: 32768
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: |-
|
||||
observedGeneration represents the .metadata.generation that the condition was set based upon.
|
||||
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
|
||||
with respect to the current state of the instance.
|
||||
format: int64
|
||||
minimum: 0
|
||||
type: integer
|
||||
reason:
|
||||
description: |-
|
||||
reason contains a programmatic identifier indicating the reason for the condition's last transition.
|
||||
Producers of specific condition types may define expected values and meanings for this field,
|
||||
and whether the values are considered a guaranteed API.
|
||||
The value should be a CamelCase string.
|
||||
This field may not be empty.
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
||||
type: string
|
||||
status:
|
||||
description: status of the condition, one of True, False, Unknown.
|
||||
enum:
|
||||
- "True"
|
||||
- "False"
|
||||
- Unknown
|
||||
type: string
|
||||
type:
|
||||
description: |-
|
||||
type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||
---
|
||||
Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
|
||||
useful (see .node.status.conditions), the ability to deconflict is important.
|
||||
The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- message
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
maxItems: 8
|
||||
type: array
|
||||
x-kubernetes-list-map-keys:
|
||||
- type
|
||||
x-kubernetes-list-type: map
|
||||
type: object
|
||||
required:
|
||||
- spec
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .spec.controllerName
|
||||
name: Controller
|
||||
type: string
|
||||
- jsonPath: .status.conditions[?(@.type=="Accepted")].status
|
||||
name: Accepted
|
||||
type: string
|
||||
- jsonPath: .metadata.creationTimestamp
|
||||
name: Age
|
||||
type: date
|
||||
- jsonPath: .spec.description
|
||||
name: Description
|
||||
priority: 1
|
||||
type: string
|
||||
name: v1beta1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: |-
|
||||
GatewayClass describes a class of Gateways available to the user for creating
|
||||
Gateway resources.
|
||||
|
||||
|
||||
It is recommended that this resource be used as a template for Gateways. This
|
||||
means that a Gateway is based on the state of the GatewayClass at the time it
|
||||
was created and changes to the GatewayClass or associated parameters are not
|
||||
propagated down to existing Gateways. This recommendation is intended to
|
||||
limit the blast radius of changes to GatewayClass or associated parameters.
|
||||
If implementations choose to propagate GatewayClass changes to existing
|
||||
Gateways, that MUST be clearly documented by the implementation.
|
||||
|
||||
|
||||
Whenever one or more Gateways are using a GatewayClass, implementations SHOULD
|
||||
add the `gateway-exists-finalizer.gateway.networking.k8s.io` finalizer on the
|
||||
associated GatewayClass. This ensures that a GatewayClass associated with a
|
||||
Gateway is not deleted while in use.
|
||||
|
||||
|
||||
GatewayClass is a Cluster level resource.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: |-
|
||||
APIVersion defines the versioned schema of this representation of an object.
|
||||
Servers should convert recognized schemas to the latest internal value, and
|
||||
may reject unrecognized values.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind is a string value representing the REST resource this object represents.
|
||||
Servers may infer this from the endpoint the client submits requests to.
|
||||
Cannot be updated.
|
||||
In CamelCase.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: Spec defines the desired state of GatewayClass.
|
||||
properties:
|
||||
controllerName:
|
||||
description: |-
|
||||
ControllerName is the name of the controller that is managing Gateways of
|
||||
this class. The value of this field MUST be a domain prefixed path.
|
||||
|
||||
|
||||
Example: "example.net/gateway-controller".
|
||||
|
||||
|
||||
This field is not mutable and cannot be empty.
|
||||
|
||||
|
||||
Support: Core
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$
|
||||
type: string
|
||||
x-kubernetes-validations:
|
||||
- message: Value is immutable
|
||||
rule: self == oldSelf
|
||||
description:
|
||||
description: Description helps describe a GatewayClass with more details.
|
||||
maxLength: 64
|
||||
type: string
|
||||
parametersRef:
|
||||
description: |-
|
||||
ParametersRef is a reference to a resource that contains the configuration
|
||||
parameters corresponding to the GatewayClass. This is optional if the
|
||||
controller does not require any additional configuration.
|
||||
|
||||
|
||||
ParametersRef can reference a standard Kubernetes resource, i.e. ConfigMap,
|
||||
or an implementation-specific custom resource. The resource can be
|
||||
cluster-scoped or namespace-scoped.
|
||||
|
||||
|
||||
If the referent cannot be found, the GatewayClass's "InvalidParameters"
|
||||
status condition will be true.
|
||||
|
||||
|
||||
A Gateway for this GatewayClass may provide its own `parametersRef`. When both are specified,
|
||||
the merging behavior is implementation specific.
|
||||
It is generally recommended that GatewayClass provides defaults that can be overridden by a Gateway.
|
||||
|
||||
|
||||
Support: Implementation-specific
|
||||
properties:
|
||||
group:
|
||||
description: Group is the group of the referent.
|
||||
maxLength: 253
|
||||
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
|
||||
type: string
|
||||
kind:
|
||||
description: Kind is kind of the referent.
|
||||
maxLength: 63
|
||||
minLength: 1
|
||||
pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
|
||||
type: string
|
||||
name:
|
||||
description: Name is the name of the referent.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
namespace:
|
||||
description: |-
|
||||
Namespace is the namespace of the referent.
|
||||
This field is required when referring to a Namespace-scoped resource and
|
||||
MUST be unset when referring to a Cluster-scoped resource.
|
||||
maxLength: 63
|
||||
minLength: 1
|
||||
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
|
||||
type: string
|
||||
required:
|
||||
- group
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
required:
|
||||
- controllerName
|
||||
type: object
|
||||
status:
|
||||
default:
|
||||
conditions:
|
||||
- lastTransitionTime: "1970-01-01T00:00:00Z"
|
||||
message: Waiting for controller
|
||||
reason: Waiting
|
||||
status: Unknown
|
||||
type: Accepted
|
||||
description: |-
|
||||
Status defines the current state of GatewayClass.
|
||||
|
||||
|
||||
Implementations MUST populate status on all GatewayClass resources which
|
||||
specify their controller name.
|
||||
properties:
|
||||
conditions:
|
||||
default:
|
||||
- lastTransitionTime: "1970-01-01T00:00:00Z"
|
||||
message: Waiting for controller
|
||||
reason: Pending
|
||||
status: Unknown
|
||||
type: Accepted
|
||||
description: |-
|
||||
Conditions is the current status from the controller for
|
||||
this GatewayClass.
|
||||
|
||||
|
||||
Controllers should prefer to publish conditions using values
|
||||
of GatewayClassConditionType for the type of each Condition.
|
||||
items:
|
||||
description: "Condition contains details for one aspect of the current
|
||||
state of this API Resource.\n---\nThis struct is intended for
|
||||
direct use as an array at the field path .status.conditions. For
|
||||
example,\n\n\n\ttype FooStatus struct{\n\t // Represents the
|
||||
observations of a foo's current state.\n\t // Known .status.conditions.type
|
||||
are: \"Available\", \"Progressing\", and \"Degraded\"\n\t //
|
||||
+patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t
|
||||
\ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\"
|
||||
patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
|
||||
\ // other fields\n\t}"
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: |-
|
||||
lastTransitionTime is the last time the condition transitioned from one status to another.
|
||||
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: |-
|
||||
message is a human readable message indicating details about the transition.
|
||||
This may be an empty string.
|
||||
maxLength: 32768
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: |-
|
||||
observedGeneration represents the .metadata.generation that the condition was set based upon.
|
||||
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
|
||||
with respect to the current state of the instance.
|
||||
format: int64
|
||||
minimum: 0
|
||||
type: integer
|
||||
reason:
|
||||
description: |-
|
||||
reason contains a programmatic identifier indicating the reason for the condition's last transition.
|
||||
Producers of specific condition types may define expected values and meanings for this field,
|
||||
and whether the values are considered a guaranteed API.
|
||||
The value should be a CamelCase string.
|
||||
This field may not be empty.
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
||||
type: string
|
||||
status:
|
||||
description: status of the condition, one of True, False, Unknown.
|
||||
enum:
|
||||
- "True"
|
||||
- "False"
|
||||
- Unknown
|
||||
type: string
|
||||
type:
|
||||
description: |-
|
||||
type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||
---
|
||||
Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
|
||||
useful (see .node.status.conditions), the ability to deconflict is important.
|
||||
The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- message
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
maxItems: 8
|
||||
type: array
|
||||
x-kubernetes-list-map-keys:
|
||||
- type
|
||||
x-kubernetes-list-type: map
|
||||
type: object
|
||||
required:
|
||||
- spec
|
||||
type: object
|
||||
served: true
|
||||
storage: false
|
||||
subresources:
|
||||
status: {}
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: null
|
||||
storedVersions: null
|
||||
@@ -0,0 +1,383 @@
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997
|
||||
gateway.networking.k8s.io/bundle-version: v1.1.0
|
||||
gateway.networking.k8s.io/channel: standard
|
||||
creationTimestamp: null
|
||||
name: referencegrants.gateway.networking.k8s.io
|
||||
spec:
|
||||
group: gateway.networking.k8s.io
|
||||
names:
|
||||
categories:
|
||||
- gateway-api
|
||||
kind: ReferenceGrant
|
||||
listKind: ReferenceGrantList
|
||||
plural: referencegrants
|
||||
shortNames:
|
||||
- refgrant
|
||||
singular: referencegrant
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .metadata.creationTimestamp
|
||||
name: Age
|
||||
type: date
|
||||
deprecated: true
|
||||
deprecationWarning: The v1alpha2 version of ReferenceGrant has been deprecated
|
||||
and will be removed in a future release of the API. Please upgrade to v1beta1.
|
||||
name: v1alpha2
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: |-
|
||||
ReferenceGrant identifies kinds of resources in other namespaces that are
|
||||
trusted to reference the specified kinds of resources in the same namespace
|
||||
as the policy.
|
||||
|
||||
|
||||
Each ReferenceGrant can be used to represent a unique trust relationship.
|
||||
Additional Reference Grants can be used to add to the set of trusted
|
||||
sources of inbound references for the namespace they are defined within.
|
||||
|
||||
|
||||
A ReferenceGrant is required for all cross-namespace references in Gateway API
|
||||
(with the exception of cross-namespace Route-Gateway attachment, which is
|
||||
governed by the AllowedRoutes configuration on the Gateway, and cross-namespace
|
||||
Service ParentRefs on a "consumer" mesh Route, which defines routing rules
|
||||
applicable only to workloads in the Route namespace). ReferenceGrants allowing
|
||||
a reference from a Route to a Service are only applicable to BackendRefs.
|
||||
|
||||
|
||||
ReferenceGrant is a form of runtime verification allowing users to assert
|
||||
which cross-namespace object references are permitted. Implementations that
|
||||
support ReferenceGrant MUST NOT permit cross-namespace references which have
|
||||
no grant, and MUST respond to the removal of a grant by revoking the access
|
||||
that the grant allowed.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: |-
|
||||
APIVersion defines the versioned schema of this representation of an object.
|
||||
Servers should convert recognized schemas to the latest internal value, and
|
||||
may reject unrecognized values.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind is a string value representing the REST resource this object represents.
|
||||
Servers may infer this from the endpoint the client submits requests to.
|
||||
Cannot be updated.
|
||||
In CamelCase.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: Spec defines the desired state of ReferenceGrant.
|
||||
properties:
|
||||
from:
|
||||
description: |-
|
||||
From describes the trusted namespaces and kinds that can reference the
|
||||
resources described in "To". Each entry in this list MUST be considered
|
||||
to be an additional place that references can be valid from, or to put
|
||||
this another way, entries MUST be combined using OR.
|
||||
|
||||
|
||||
Support: Core
|
||||
items:
|
||||
description: ReferenceGrantFrom describes trusted namespaces and
|
||||
kinds.
|
||||
properties:
|
||||
group:
|
||||
description: |-
|
||||
Group is the group of the referent.
|
||||
When empty, the Kubernetes core API group is inferred.
|
||||
|
||||
|
||||
Support: Core
|
||||
maxLength: 253
|
||||
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind is the kind of the referent. Although implementations may support
|
||||
additional resources, the following types are part of the "Core"
|
||||
support level for this field.
|
||||
|
||||
|
||||
When used to permit a SecretObjectReference:
|
||||
|
||||
|
||||
* Gateway
|
||||
|
||||
|
||||
When used to permit a BackendObjectReference:
|
||||
|
||||
|
||||
* GRPCRoute
|
||||
* HTTPRoute
|
||||
* TCPRoute
|
||||
* TLSRoute
|
||||
* UDPRoute
|
||||
maxLength: 63
|
||||
minLength: 1
|
||||
pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
|
||||
type: string
|
||||
namespace:
|
||||
description: |-
|
||||
Namespace is the namespace of the referent.
|
||||
|
||||
|
||||
Support: Core
|
||||
maxLength: 63
|
||||
minLength: 1
|
||||
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
|
||||
type: string
|
||||
required:
|
||||
- group
|
||||
- kind
|
||||
- namespace
|
||||
type: object
|
||||
maxItems: 16
|
||||
minItems: 1
|
||||
type: array
|
||||
to:
|
||||
description: |-
|
||||
To describes the resources that may be referenced by the resources
|
||||
described in "From". Each entry in this list MUST be considered to be an
|
||||
additional place that references can be valid to, or to put this another
|
||||
way, entries MUST be combined using OR.
|
||||
|
||||
|
||||
Support: Core
|
||||
items:
|
||||
description: |-
|
||||
ReferenceGrantTo describes what Kinds are allowed as targets of the
|
||||
references.
|
||||
properties:
|
||||
group:
|
||||
description: |-
|
||||
Group is the group of the referent.
|
||||
When empty, the Kubernetes core API group is inferred.
|
||||
|
||||
|
||||
Support: Core
|
||||
maxLength: 253
|
||||
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind is the kind of the referent. Although implementations may support
|
||||
additional resources, the following types are part of the "Core"
|
||||
support level for this field:
|
||||
|
||||
|
||||
* Secret when used to permit a SecretObjectReference
|
||||
* Service when used to permit a BackendObjectReference
|
||||
maxLength: 63
|
||||
minLength: 1
|
||||
pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
|
||||
type: string
|
||||
name:
|
||||
description: |-
|
||||
Name is the name of the referent. When unspecified, this policy
|
||||
refers to all resources of the specified Group and Kind in the local
|
||||
namespace.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
required:
|
||||
- group
|
||||
- kind
|
||||
type: object
|
||||
maxItems: 16
|
||||
minItems: 1
|
||||
type: array
|
||||
required:
|
||||
- from
|
||||
- to
|
||||
type: object
|
||||
type: object
|
||||
served: false
|
||||
storage: false
|
||||
subresources: {}
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .metadata.creationTimestamp
|
||||
name: Age
|
||||
type: date
|
||||
name: v1beta1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: |-
|
||||
ReferenceGrant identifies kinds of resources in other namespaces that are
|
||||
trusted to reference the specified kinds of resources in the same namespace
|
||||
as the policy.
|
||||
|
||||
|
||||
Each ReferenceGrant can be used to represent a unique trust relationship.
|
||||
Additional Reference Grants can be used to add to the set of trusted
|
||||
sources of inbound references for the namespace they are defined within.
|
||||
|
||||
|
||||
All cross-namespace references in Gateway API (with the exception of cross-namespace
|
||||
Gateway-route attachment) require a ReferenceGrant.
|
||||
|
||||
|
||||
ReferenceGrant is a form of runtime verification allowing users to assert
|
||||
which cross-namespace object references are permitted. Implementations that
|
||||
support ReferenceGrant MUST NOT permit cross-namespace references which have
|
||||
no grant, and MUST respond to the removal of a grant by revoking the access
|
||||
that the grant allowed.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: |-
|
||||
APIVersion defines the versioned schema of this representation of an object.
|
||||
Servers should convert recognized schemas to the latest internal value, and
|
||||
may reject unrecognized values.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind is a string value representing the REST resource this object represents.
|
||||
Servers may infer this from the endpoint the client submits requests to.
|
||||
Cannot be updated.
|
||||
In CamelCase.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: Spec defines the desired state of ReferenceGrant.
|
||||
properties:
|
||||
from:
|
||||
description: |-
|
||||
From describes the trusted namespaces and kinds that can reference the
|
||||
resources described in "To". Each entry in this list MUST be considered
|
||||
to be an additional place that references can be valid from, or to put
|
||||
this another way, entries MUST be combined using OR.
|
||||
|
||||
|
||||
Support: Core
|
||||
items:
|
||||
description: ReferenceGrantFrom describes trusted namespaces and
|
||||
kinds.
|
||||
properties:
|
||||
group:
|
||||
description: |-
|
||||
Group is the group of the referent.
|
||||
When empty, the Kubernetes core API group is inferred.
|
||||
|
||||
|
||||
Support: Core
|
||||
maxLength: 253
|
||||
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind is the kind of the referent. Although implementations may support
|
||||
additional resources, the following types are part of the "Core"
|
||||
support level for this field.
|
||||
|
||||
|
||||
When used to permit a SecretObjectReference:
|
||||
|
||||
|
||||
* Gateway
|
||||
|
||||
|
||||
When used to permit a BackendObjectReference:
|
||||
|
||||
|
||||
* GRPCRoute
|
||||
* HTTPRoute
|
||||
* TCPRoute
|
||||
* TLSRoute
|
||||
* UDPRoute
|
||||
maxLength: 63
|
||||
minLength: 1
|
||||
pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
|
||||
type: string
|
||||
namespace:
|
||||
description: |-
|
||||
Namespace is the namespace of the referent.
|
||||
|
||||
|
||||
Support: Core
|
||||
maxLength: 63
|
||||
minLength: 1
|
||||
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
|
||||
type: string
|
||||
required:
|
||||
- group
|
||||
- kind
|
||||
- namespace
|
||||
type: object
|
||||
maxItems: 16
|
||||
minItems: 1
|
||||
type: array
|
||||
to:
|
||||
description: |-
|
||||
To describes the resources that may be referenced by the resources
|
||||
described in "From". Each entry in this list MUST be considered to be an
|
||||
additional place that references can be valid to, or to put this another
|
||||
way, entries MUST be combined using OR.
|
||||
|
||||
|
||||
Support: Core
|
||||
items:
|
||||
description: |-
|
||||
ReferenceGrantTo describes what Kinds are allowed as targets of the
|
||||
references.
|
||||
properties:
|
||||
group:
|
||||
description: |-
|
||||
Group is the group of the referent.
|
||||
When empty, the Kubernetes core API group is inferred.
|
||||
|
||||
|
||||
Support: Core
|
||||
maxLength: 253
|
||||
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind is the kind of the referent. Although implementations may support
|
||||
additional resources, the following types are part of the "Core"
|
||||
support level for this field:
|
||||
|
||||
|
||||
* Secret when used to permit a SecretObjectReference
|
||||
* Service when used to permit a BackendObjectReference
|
||||
maxLength: 63
|
||||
minLength: 1
|
||||
pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
|
||||
type: string
|
||||
name:
|
||||
description: |-
|
||||
Name is the name of the referent. When unspecified, this policy
|
||||
refers to all resources of the specified Group and Kind in the local
|
||||
namespace.
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
required:
|
||||
- group
|
||||
- kind
|
||||
type: object
|
||||
maxItems: 16
|
||||
minItems: 1
|
||||
type: array
|
||||
required:
|
||||
- from
|
||||
- to
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources: {}
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: null
|
||||
storedVersions: null
|
||||
@@ -0,0 +1,11 @@
|
||||
package holos
|
||||
|
||||
// Manage on every Cluster in the Platform
|
||||
for Fleet in #Fleets {
|
||||
for Cluster in Fleet.clusters {
|
||||
#Platform: Components: "\(Cluster.name)/gateway-api": {
|
||||
path: "components/gateway-api"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "gateway-api",
|
||||
"short": "gateway api custom resource definitions",
|
||||
"long": "Gateway API represents the next generation of Kubernetes Ingress, Load Balancing, and Service Mesh APIs."
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package holos
|
||||
|
||||
// If you are using k3d with the default Flannel CNI, you must append some
|
||||
// values to your installation command, as k3d uses nonstandard locations for
|
||||
// CNI configuration and binaries.
|
||||
//
|
||||
// See https://istio.io/latest/docs/ambient/install/platform-prerequisites/#k3d
|
||||
#Istio: Values: cni: {
|
||||
cniConfDir: "/var/lib/rancher/k3s/agent/etc/cni/net.d"
|
||||
cniBinDir: "/bin"
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "istio-k3d",
|
||||
"short": "configure istio for the k3d flannel cni",
|
||||
"long": "If you are using k3d with the default Flannel CNI, you must append some values to your installation command, as k3d uses nonstandard locations for CNI configuration and binaries. Refer to https://istio.io/latest/docs/ambient/install/platform-prerequisites/#k3d"
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
(#Helm & Chart).Output
|
||||
|
||||
let Chart = {
|
||||
Name: "istio-base"
|
||||
Version: #Istio.Version
|
||||
Namespace: #Istio.System.Namespace
|
||||
|
||||
Chart: chart: name: "base"
|
||||
|
||||
Repo: name: "istio"
|
||||
Repo: url: "https://istio-release.storage.googleapis.com/charts"
|
||||
|
||||
Values: #Istio.Values
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package holos
|
||||
|
||||
// imported from the 1.23.1 base chart
|
||||
// cue import components/istio/base/vendor/base/values.yaml
|
||||
|
||||
#Istio: Values: {
|
||||
// "defaults" is a workaround for Helm limitations. Users should NOT set ".defaults" explicitly, but rather directly set the fields internally.
|
||||
// For instance, instead of `--set defaults.foo=bar`, just set `--set foo=bar`.
|
||||
defaults: {
|
||||
global: {
|
||||
|
||||
// ImagePullSecrets for control plane ServiceAccount, list of secrets in the same namespace
|
||||
// to use for pulling any images in pods that reference this ServiceAccount.
|
||||
// Must be set for any cluster configured with private docker registry.
|
||||
imagePullSecrets: []
|
||||
|
||||
// Used to locate istiod.
|
||||
istioNamespace: "istio-system"
|
||||
externalIstiod: false
|
||||
remotePilotAddress: ""
|
||||
|
||||
// Platform where Istio is deployed. Possible values are: "openshift", "gcp".
|
||||
// An empty value means it is a vanilla Kubernetes distribution, therefore no special
|
||||
// treatment will be considered.
|
||||
platform: ""
|
||||
|
||||
// Setup how istiod Service is configured. See https://kubernetes.io/docs/concepts/services-networking/dual-stack/#services
|
||||
// This is intended only for use with external istiod.
|
||||
ipFamilyPolicy: ""
|
||||
ipFamilies: []
|
||||
}
|
||||
base: {
|
||||
// Used for helm2 to add the CRDs to templates.
|
||||
enableCRDTemplates: false
|
||||
|
||||
// Validation webhook configuration url
|
||||
// For example: https://$remotePilotAddress:15017/validate
|
||||
validationURL: ""
|
||||
// Validation webhook caBundle value. Useful when running pilot with a well known cert
|
||||
validationCABundle: ""
|
||||
|
||||
// For istioctl usage to disable istio config crds in base
|
||||
enableIstioConfigCRDs: true
|
||||
}
|
||||
defaultRevision: "default"
|
||||
experimental: stableValidationPolicy: false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
(#Helm & Chart).Output
|
||||
|
||||
let Chart = {
|
||||
Name: "istio-cni"
|
||||
Version: #Istio.Version
|
||||
Namespace: #Istio.System.Namespace
|
||||
|
||||
Chart: chart: name: "cni"
|
||||
|
||||
Repo: name: "istio"
|
||||
Repo: url: "https://istio-release.storage.googleapis.com/charts"
|
||||
|
||||
Values: #Istio.Values
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
package holos
|
||||
|
||||
// imported from the 1.23.1 cni chart
|
||||
// cue import components/istio/cni/vendor/cni/values.yaml
|
||||
|
||||
#Istio: Values: {
|
||||
// "defaults" is a workaround for Helm limitations. Users should NOT set ".defaults" explicitly, but rather directly set the fields internally.
|
||||
// For instance, instead of `--set defaults.foo=bar`, just set `--set foo=bar`.
|
||||
defaults: {
|
||||
cni: {
|
||||
hub: ""
|
||||
tag: ""
|
||||
variant: ""
|
||||
image: "install-cni"
|
||||
pullPolicy: ""
|
||||
|
||||
// Same as `global.logging.level`, but will override it if set
|
||||
logging: {
|
||||
level: ""
|
||||
}
|
||||
|
||||
// Configuration file to insert istio-cni plugin configuration
|
||||
// by default this will be the first file found in the cni-conf-dir
|
||||
// Example
|
||||
// cniConfFileName: 10-calico.conflist
|
||||
// CNI bin and conf dir override settings
|
||||
// defaults:
|
||||
cniBinDir: "" // Auto-detected based on version; defaults to /opt/cni/bin.
|
||||
cniConfDir: "/etc/cni/net.d"
|
||||
cniConfFileName: ""
|
||||
// This directory must exist on the node, if it does not, consult your container runtime
|
||||
// documentation for the appropriate path.
|
||||
cniNetnsDir: null // Defaults to '/var/run/netns', in minikube/docker/others can be '/var/run/docker/netns'.
|
||||
excludeNamespaces: ["kube-system"]
|
||||
|
||||
// Allows user to set custom affinity for the DaemonSet
|
||||
affinity: {}
|
||||
|
||||
// Custom annotations on pod level, if you need them
|
||||
podAnnotations: {}
|
||||
|
||||
// Deploy the config files as plugin chain (value "true") or as standalone files in the conf dir (value "false")?
|
||||
// Some k8s flavors (e.g. OpenShift) do not support the chain approach, set to false if this is the case
|
||||
chained: true
|
||||
|
||||
// Custom configuration happens based on the CNI provider.
|
||||
// Possible values: "default", "multus"
|
||||
provider: "default"
|
||||
|
||||
// Configure ambient settings
|
||||
ambient: {
|
||||
// If enabled, ambient redirection will be enabled
|
||||
enabled: false
|
||||
// Set ambient config dir path: defaults to /etc/ambient-config
|
||||
configDir: ""
|
||||
// If enabled, and ambient is enabled, DNS redirection will be enabled
|
||||
dnsCapture: false
|
||||
// If enabled, and ambient is enabled, enables ipv6 support
|
||||
ipv6: true
|
||||
}
|
||||
repair: {
|
||||
enabled: true
|
||||
hub: ""
|
||||
tag: ""
|
||||
|
||||
// Repair controller has 3 modes. Pick which one meets your use cases. Note only one may be used.
|
||||
// This defines the action the controller will take when a pod is detected as broken.
|
||||
// labelPods will label all pods with <brokenPodLabelKey>=<brokenPodLabelValue>.
|
||||
// This is only capable of identifying broken pods; the user is responsible for fixing them (generally, by deleting them).
|
||||
// Note this gives the DaemonSet a relatively high privilege, as modifying pod metadata/status can have wider impacts.
|
||||
labelPods: false
|
||||
// deletePods will delete any broken pod. These will then be rescheduled, hopefully onto a node that is fully ready.
|
||||
// Note this gives the DaemonSet a relatively high privilege, as it can delete any Pod.
|
||||
deletePods: false
|
||||
// repairPods will dynamically repair any broken pod by setting up the pod networking configuration even after it has started.
|
||||
// Note the pod will be crashlooping, so this may take a few minutes to become fully functional based on when the retry occurs.
|
||||
// This requires no RBAC privilege, but does require `securityContext.privileged/CAP_SYS_ADMIN`.
|
||||
repairPods: true
|
||||
initContainerName: "istio-validation"
|
||||
brokenPodLabelKey: "cni.istio.io/uninitialized"
|
||||
brokenPodLabelValue: "true"
|
||||
}
|
||||
|
||||
// Set to `type: RuntimeDefault` to use the default profile if available.
|
||||
seccompProfile: {}
|
||||
resources: requests: {
|
||||
cpu: "100m"
|
||||
memory: "100Mi"
|
||||
}
|
||||
resourceQuotas: {
|
||||
enabled: false
|
||||
pods: 5000
|
||||
}
|
||||
|
||||
// The number of pods that can be unavailable during rolling update (see
|
||||
// `updateStrategy.rollingUpdate.maxUnavailable` here:
|
||||
// https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/daemon-set-v1/#DaemonSetSpec).
|
||||
// May be specified as a number of pods or as a percent of the total number
|
||||
// of pods at the start of the update.
|
||||
rollingMaxUnavailable: 1
|
||||
}
|
||||
|
||||
// Revision is set as 'version' label and part of the resource names when installing multiple control planes.
|
||||
revision: ""
|
||||
|
||||
// For Helm compatibility.
|
||||
ownerName: ""
|
||||
global: {
|
||||
// Default hub for Istio images.
|
||||
// Releases are published to docker hub under 'istio' project.
|
||||
// Dev builds from prow are on gcr.io
|
||||
hub: "docker.io/istio"
|
||||
|
||||
// Default tag for Istio images.
|
||||
tag: "1.23.1"
|
||||
|
||||
// Variant of the image to use.
|
||||
// Currently supported are: [debug, distroless]
|
||||
variant: ""
|
||||
|
||||
// Specify image pull policy if default behavior isn't desired.
|
||||
// Default behavior: latest images will be Always else IfNotPresent.
|
||||
imagePullPolicy: ""
|
||||
|
||||
// change cni scope level to control logging out of istio-cni-node DaemonSet
|
||||
logging: {
|
||||
level: "info"
|
||||
}
|
||||
logAsJson: false
|
||||
|
||||
// ImagePullSecrets for all ServiceAccount, list of secrets in the same namespace
|
||||
// to use for pulling any images in pods that reference this ServiceAccount.
|
||||
// For components that don't use ServiceAccounts (i.e. grafana, servicegraph, tracing)
|
||||
// ImagePullSecrets will be added to the corresponding Deployment(StatefulSet) objects.
|
||||
// Must be set for any cluster configured with private docker registry.
|
||||
// - private-registry-key
|
||||
imagePullSecrets: []
|
||||
|
||||
// Default resources allocated
|
||||
defaultResources: {
|
||||
requests: {
|
||||
cpu: "100m"
|
||||
memory: "100Mi"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
(#Helm & Chart).Output
|
||||
|
||||
let Chart = {
|
||||
Name: "istio-gateway"
|
||||
Version: #Istio.Version
|
||||
Namespace: #Istio.Gateway.Namespace
|
||||
|
||||
Chart: chart: name: "gateway"
|
||||
|
||||
Repo: name: "istio"
|
||||
Repo: url: "https://istio-release.storage.googleapis.com/charts"
|
||||
|
||||
Values: #Istio.Values
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
package holos
|
||||
|
||||
// imported from the 1.23.1 gateway chart
|
||||
// cue import components/istio/gateway/vendor/gateway/values.yaml
|
||||
|
||||
#Istio: Values: {
|
||||
// "defaults" is a workaround for Helm limitations. Users should NOT set ".defaults" explicitly, but rather directly set the fields internally.
|
||||
// For instance, instead of `--set defaults.foo=bar`, just set `--set foo=bar`.
|
||||
defaults: {
|
||||
// Name allows overriding the release name. Generally this should not be set
|
||||
name: ""
|
||||
// revision declares which revision this gateway is a part of
|
||||
revision: ""
|
||||
|
||||
// Controls the spec.replicas setting for the Gateway deployment if set.
|
||||
// Otherwise defaults to Kubernetes Deployment default (1).
|
||||
replicaCount: null
|
||||
kind: "Deployment"
|
||||
rbac: {
|
||||
// If enabled, roles will be created to enable accessing certificates from Gateways. This is not needed
|
||||
// when using http://gateway-api.org/.
|
||||
enabled: true
|
||||
}
|
||||
serviceAccount: {
|
||||
// If set, a service account will be created. Otherwise, the default is used
|
||||
create: true
|
||||
// Annotations to add to the service account
|
||||
annotations: {}
|
||||
// The name of the service account to use.
|
||||
// If not set, the release name is used
|
||||
name: ""
|
||||
}
|
||||
podAnnotations: {
|
||||
"prometheus.io/port": "15020"
|
||||
"prometheus.io/scrape": "true"
|
||||
"prometheus.io/path": "/stats/prometheus"
|
||||
"inject.istio.io/templates": "gateway"
|
||||
"sidecar.istio.io/inject": "true"
|
||||
}
|
||||
|
||||
// Define the security context for the pod.
|
||||
// If unset, this will be automatically set to the minimum privileges required to bind to port 80 and 443.
|
||||
// On Kubernetes 1.22+, this only requires the `net.ipv4.ip_unprivileged_port_start` sysctl.
|
||||
securityContext: {}
|
||||
containerSecurityContext: {}
|
||||
service: {
|
||||
// Type of service. Set to "None" to disable the service entirely
|
||||
type: "LoadBalancer"
|
||||
ports: [{
|
||||
name: "status-port"
|
||||
port: 15021
|
||||
protocol: "TCP"
|
||||
targetPort: 15021
|
||||
}, {
|
||||
name: "http2"
|
||||
port: 80
|
||||
protocol: "TCP"
|
||||
targetPort: 80
|
||||
}, {
|
||||
name: "https"
|
||||
port: 443
|
||||
protocol: "TCP"
|
||||
targetPort: 443
|
||||
}]
|
||||
annotations: {}
|
||||
loadBalancerIP: ""
|
||||
loadBalancerSourceRanges: []
|
||||
externalTrafficPolicy: ""
|
||||
externalIPs: []
|
||||
ipFamilyPolicy: ""
|
||||
//# Whether to automatically allocate NodePorts (only for LoadBalancers).
|
||||
// allocateLoadBalancerNodePorts: false
|
||||
ipFamilies: []
|
||||
}
|
||||
resources: {
|
||||
requests: {
|
||||
cpu: "100m"
|
||||
memory: "128Mi"
|
||||
}
|
||||
limits: {
|
||||
cpu: "2000m"
|
||||
memory: "1024Mi"
|
||||
}
|
||||
}
|
||||
autoscaling: {
|
||||
enabled: true
|
||||
minReplicas: 1
|
||||
maxReplicas: 5
|
||||
targetCPUUtilizationPercentage: 80
|
||||
targetMemoryUtilizationPercentage: {}
|
||||
autoscaleBehavior: {}
|
||||
}
|
||||
|
||||
// Pod environment variables
|
||||
env: {}
|
||||
|
||||
// Labels to apply to all resources
|
||||
labels: {}
|
||||
|
||||
// Annotations to apply to all resources
|
||||
annotations: {}
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
topologySpreadConstraints: []
|
||||
affinity: {}
|
||||
|
||||
// If specified, the gateway will act as a network gateway for the given network.
|
||||
networkGateway: ""
|
||||
|
||||
// Specify image pull policy if default behavior isn't desired.
|
||||
// Default behavior: latest images will be Always else IfNotPresent
|
||||
imagePullPolicy: ""
|
||||
imagePullSecrets: []
|
||||
|
||||
// This value is used to configure a Kubernetes PodDisruptionBudget for the gateway.
|
||||
//
|
||||
// By default, the `podDisruptionBudget` is disabled (set to `{}`),
|
||||
// which means that no PodDisruptionBudget resource will be created.
|
||||
//
|
||||
// To enable the PodDisruptionBudget, configure it by specifying the
|
||||
// `minAvailable` or `maxUnavailable`. For example, to set the
|
||||
// minimum number of available replicas to 1, you can update this value as follows:
|
||||
//
|
||||
// podDisruptionBudget:
|
||||
// minAvailable: 1
|
||||
//
|
||||
// Or, to allow a maximum of 1 unavailable replica, you can set:
|
||||
//
|
||||
// podDisruptionBudget:
|
||||
// maxUnavailable: 1
|
||||
//
|
||||
// You can also specify the `unhealthyPodEvictionPolicy` field, and the valid values are `IfHealthyBudget` and `AlwaysAllow`.
|
||||
// For example, to set the `unhealthyPodEvictionPolicy` to `AlwaysAllow`, you can update this value as follows:
|
||||
//
|
||||
// podDisruptionBudget:
|
||||
// minAvailable: 1
|
||||
// unhealthyPodEvictionPolicy: AlwaysAllow
|
||||
//
|
||||
// To disable the PodDisruptionBudget, you can leave it as an empty object `{}`:
|
||||
//
|
||||
// podDisruptionBudget: {}
|
||||
//
|
||||
podDisruptionBudget: {}
|
||||
terminationGracePeriodSeconds: 30
|
||||
|
||||
// A list of `Volumes` added into the Gateway Pods. See
|
||||
// https://kubernetes.io/docs/concepts/storage/volumes/.
|
||||
volumes: []
|
||||
|
||||
// A list of `VolumeMounts` added into the Gateway Pods. See
|
||||
// https://kubernetes.io/docs/concepts/storage/volumes/.
|
||||
volumeMounts: []
|
||||
|
||||
// Configure this to a higher priority class in order to make sure your Istio gateway pods
|
||||
// will not be killed because of low priority class.
|
||||
// Refer to https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass
|
||||
// for more detail.
|
||||
priorityClassName: ""
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
(#Helm & Chart).Output
|
||||
|
||||
let Chart = {
|
||||
Name: "istiod"
|
||||
Version: #Istio.Version
|
||||
Namespace: #Istio.System.Namespace
|
||||
|
||||
Chart: chart: name: "istiod"
|
||||
|
||||
Repo: name: "istio"
|
||||
Repo: url: "https://istio-release.storage.googleapis.com/charts"
|
||||
|
||||
Values: #Istio.Values
|
||||
}
|
||||
@@ -0,0 +1,539 @@
|
||||
package holos
|
||||
|
||||
// imported from the 1.23.1 istiod chart
|
||||
// cue import components/istio/istiod/vendor/istiod/values.yaml
|
||||
|
||||
#Istio: Values: {
|
||||
// "defaults" is a workaround for Helm limitations. Users should NOT set ".defaults" explicitly, but rather directly set the fields internally.
|
||||
// For instance, instead of `--set defaults.foo=bar`, just set `--set foo=bar`.
|
||||
defaults: {
|
||||
|
||||
//.Values.pilot for discovery and mesh wide config
|
||||
//# Discovery Settings
|
||||
pilot: {
|
||||
autoscaleEnabled: true
|
||||
autoscaleMin: 1
|
||||
autoscaleMax: 5
|
||||
autoscaleBehavior: {}
|
||||
replicaCount: 1
|
||||
rollingMaxSurge: "100%"
|
||||
rollingMaxUnavailable: "25%"
|
||||
hub: ""
|
||||
tag: ""
|
||||
variant: ""
|
||||
|
||||
// Can be a full hub/image:tag
|
||||
image: "pilot"
|
||||
traceSampling: 1.0
|
||||
|
||||
// Resources for a small pilot install
|
||||
resources: {
|
||||
requests: {
|
||||
cpu: "500m"
|
||||
memory: "2048Mi"
|
||||
}
|
||||
}
|
||||
|
||||
// Set to `type: RuntimeDefault` to use the default profile if available.
|
||||
seccompProfile: {}
|
||||
|
||||
// Whether to use an existing CNI installation
|
||||
cni: {
|
||||
enabled: false
|
||||
provider: "default"
|
||||
}
|
||||
|
||||
// Additional container arguments
|
||||
extraContainerArgs: []
|
||||
env: {}
|
||||
|
||||
// Settings related to the untaint controller
|
||||
// This controller will remove `cni.istio.io/not-ready` from nodes when the istio-cni pod becomes ready
|
||||
// It should be noted that cluster operator/owner is responsible for having the taint set by their infrastructure provider when new nodes are added to the cluster; the untaint controller does not taint nodes
|
||||
taint: {
|
||||
// Controls whether or not the untaint controller is active
|
||||
enabled: false
|
||||
// What namespace the untaint controller should watch for istio-cni pods. This is only required when istio-cni is running in a different namespace than istiod
|
||||
namespace: ""
|
||||
}
|
||||
affinity: {}
|
||||
tolerations: []
|
||||
cpu: targetAverageUtilization: 80
|
||||
// targetAverageUtilization: 80
|
||||
memory: {}
|
||||
|
||||
// Additional volumeMounts to the istiod container
|
||||
volumeMounts: []
|
||||
|
||||
// Additional volumes to the istiod pod
|
||||
volumes: []
|
||||
nodeSelector: {}
|
||||
podAnnotations: {}
|
||||
serviceAnnotations: {}
|
||||
serviceAccountAnnotations: {}
|
||||
topologySpreadConstraints: []
|
||||
|
||||
// You can use jwksResolverExtraRootCA to provide a root certificate
|
||||
// in PEM format. This will then be trusted by pilot when resolving
|
||||
// JWKS URIs.
|
||||
jwksResolverExtraRootCA: ""
|
||||
|
||||
// The following is used to limit how long a sidecar can be connected
|
||||
// to a pilot. It balances out load across pilot instances at the cost of
|
||||
// increasing system churn.
|
||||
keepaliveMaxServerConnectionAge: "30m"
|
||||
|
||||
// Additional labels to apply to the deployment.
|
||||
deploymentLabels: {}
|
||||
|
||||
//# Mesh config settings
|
||||
// Install the mesh config map, generated from values.yaml.
|
||||
// If false, pilot wil use default values (by default) or user-supplied values.
|
||||
configMap: true
|
||||
|
||||
// Additional labels to apply on the pod level for monitoring and logging configuration.
|
||||
podLabels: {}
|
||||
|
||||
// Setup how istiod Service is configured. See https://kubernetes.io/docs/concepts/services-networking/dual-stack/#services
|
||||
ipFamilyPolicy: ""
|
||||
ipFamilies: []
|
||||
|
||||
// Ambient mode only.
|
||||
// Set this if you install ztunnel to a different namespace from `istiod`.
|
||||
// If set, `istiod` will allow connections from trusted node proxy ztunnels
|
||||
// in the provided namespace.
|
||||
// If unset, `istiod` will assume the trusted node proxy ztunnel resides
|
||||
// in the same namespace as itself.
|
||||
trustedZtunnelNamespace: ""
|
||||
}
|
||||
sidecarInjectorWebhook: {
|
||||
// You can use the field called alwaysInjectSelector and neverInjectSelector which will always inject the sidecar or
|
||||
// always skip the injection on pods that match that label selector, regardless of the global policy.
|
||||
// See https://istio.io/docs/setup/kubernetes/additional-setup/sidecar-injection/#more-control-adding-exceptions
|
||||
neverInjectSelector: []
|
||||
alwaysInjectSelector: []
|
||||
|
||||
// injectedAnnotations are additional annotations that will be added to the pod spec after injection
|
||||
// This is primarily to support PSP annotations. For example, if you defined a PSP with the annotations:
|
||||
//
|
||||
// annotations:
|
||||
// apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default
|
||||
// apparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default
|
||||
//
|
||||
// The PSP controller would add corresponding annotations to the pod spec for each container. However, this happens before
|
||||
// the inject adds additional containers, so we must specify them explicitly here. With the above example, we could specify:
|
||||
// injectedAnnotations:
|
||||
// container.apparmor.security.beta.kubernetes.io/istio-init: runtime/default
|
||||
// container.apparmor.security.beta.kubernetes.io/istio-proxy: runtime/default
|
||||
injectedAnnotations: {}
|
||||
|
||||
// This enables injection of sidecar in all namespaces,
|
||||
// with the exception of namespaces with "istio-injection:disabled" annotation
|
||||
// Only one environment should have this enabled.
|
||||
enableNamespacesByDefault: false
|
||||
|
||||
// Mutations that occur after the sidecar injector are not handled by default, as the Istio sidecar injector is only run
|
||||
// once. For example, an OPA sidecar injected after the Istio sidecar will not have it's liveness/readiness probes rewritten.
|
||||
// Setting this to `IfNeeded` will result in the sidecar injector being run again if additional mutations occur.
|
||||
reinvocationPolicy: "Never"
|
||||
rewriteAppHTTPProbe: true
|
||||
|
||||
// Templates defines a set of custom injection templates that can be used. For example, defining:
|
||||
//
|
||||
// templates:
|
||||
// hello: |
|
||||
// metadata:
|
||||
// labels:
|
||||
// hello: world
|
||||
//
|
||||
// Then starting a pod with the `inject.istio.io/templates: hello` annotation, will result in the pod
|
||||
// being injected with the hello=world labels.
|
||||
// This is intended for advanced configuration only; most users should use the built in template
|
||||
templates: {}
|
||||
|
||||
// Default templates specifies a set of default templates that are used in sidecar injection.
|
||||
// By default, a template `sidecar` is always provided, which contains the template of default sidecar.
|
||||
// To inject other additional templates, define it using the `templates` option, and add it to
|
||||
// the default templates list.
|
||||
// For example:
|
||||
//
|
||||
// templates:
|
||||
// hello: |
|
||||
// metadata:
|
||||
// labels:
|
||||
// hello: world
|
||||
//
|
||||
// defaultTemplates: ["sidecar", "hello"]
|
||||
defaultTemplates: []
|
||||
}
|
||||
istiodRemote: {
|
||||
// Sidecar injector mutating webhook configuration clientConfig.url value.
|
||||
// For example: https://$remotePilotAddress:15017/inject
|
||||
// The host should not refer to a service running in the cluster; use a service reference by specifying
|
||||
// the clientConfig.service field instead.
|
||||
injectionURL: ""
|
||||
|
||||
// Sidecar injector mutating webhook configuration path value for the clientConfig.service field.
|
||||
// Override to pass env variables, for example: /inject/cluster/remote/net/network2
|
||||
injectionPath: "/inject"
|
||||
injectionCABundle: ""
|
||||
}
|
||||
telemetry: {
|
||||
enabled: true
|
||||
v2: {
|
||||
// For Null VM case now.
|
||||
// This also enables metadata exchange.
|
||||
enabled: true
|
||||
// Indicate if prometheus stats filter is enabled or not
|
||||
prometheus: {
|
||||
enabled: true
|
||||
}
|
||||
// stackdriver filter settings.
|
||||
stackdriver: {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
}
|
||||
// Revision is set as 'version' label and part of the resource names when installing multiple control planes.
|
||||
revision: ""
|
||||
|
||||
// Revision tags are aliases to Istio control plane revisions
|
||||
revisionTags: []
|
||||
|
||||
// For Helm compatibility.
|
||||
ownerName: ""
|
||||
|
||||
// meshConfig defines runtime configuration of components, including Istiod and istio-agent behavior
|
||||
// See https://istio.io/docs/reference/config/istio.mesh.v1alpha1/ for all available options
|
||||
meshConfig: {
|
||||
enablePrometheusMerge: true
|
||||
}
|
||||
experimental: stableValidationPolicy: false
|
||||
global: {
|
||||
// Used to locate istiod.
|
||||
istioNamespace: "istio-system"
|
||||
// List of cert-signers to allow "approve" action in the istio cluster role
|
||||
//
|
||||
// certSigners:
|
||||
// - clusterissuers.cert-manager.io/istio-ca
|
||||
certSigners: []
|
||||
// enable pod disruption budget for the control plane, which is used to
|
||||
// ensure Istio control plane components are gradually upgraded or recovered.
|
||||
defaultPodDisruptionBudget: {
|
||||
// The values aren't mutable due to a current PodDisruptionBudget limitation
|
||||
// minAvailable: 1
|
||||
enabled: true
|
||||
}
|
||||
|
||||
// A minimal set of requested resources to applied to all deployments so that
|
||||
// Horizontal Pod Autoscaler will be able to function (if set).
|
||||
// Each component can overwrite these default values by adding its own resources
|
||||
// block in the relevant section below and setting the desired resources values.
|
||||
defaultResources: {
|
||||
// memory: 128Mi
|
||||
// limits:
|
||||
// cpu: 100m
|
||||
// memory: 128Mi
|
||||
requests: {
|
||||
cpu: "10m"
|
||||
}
|
||||
}
|
||||
|
||||
// Default hub for Istio images.
|
||||
// Releases are published to docker hub under 'istio' project.
|
||||
// Dev builds from prow are on gcr.io
|
||||
hub: "docker.io/istio"
|
||||
// Default tag for Istio images.
|
||||
tag: "1.23.1"
|
||||
// Variant of the image to use.
|
||||
// Currently supported are: [debug, distroless]
|
||||
variant: ""
|
||||
|
||||
// Specify image pull policy if default behavior isn't desired.
|
||||
// Default behavior: latest images will be Always else IfNotPresent.
|
||||
imagePullPolicy: ""
|
||||
|
||||
// ImagePullSecrets for all ServiceAccount, list of secrets in the same namespace
|
||||
// to use for pulling any images in pods that reference this ServiceAccount.
|
||||
// For components that don't use ServiceAccounts (i.e. grafana, servicegraph, tracing)
|
||||
// ImagePullSecrets will be added to the corresponding Deployment(StatefulSet) objects.
|
||||
// Must be set for any cluster configured with private docker registry.
|
||||
// - private-registry-key
|
||||
imagePullSecrets: []
|
||||
|
||||
// Enabled by default in master for maximising testing.
|
||||
istiod: {
|
||||
enableAnalysis: false
|
||||
}
|
||||
|
||||
// To output all istio components logs in json format by adding --log_as_json argument to each container argument
|
||||
logAsJson: false
|
||||
|
||||
// Comma-separated minimum per-scope logging level of messages to output, in the form of <scope>:<level>,<scope>:<level>
|
||||
// The control plane has different scopes depending on component, but can configure default log level across all components
|
||||
// If empty, default scope and level will be used as configured in code
|
||||
logging: {
|
||||
level: "default:info"
|
||||
}
|
||||
omitSidecarInjectorConfigMap: false
|
||||
|
||||
// Configure whether Operator manages webhook configurations. The current behavior
|
||||
// of Istiod is to manage its own webhook configurations.
|
||||
// When this option is set as true, Istio Operator, instead of webhooks, manages the
|
||||
// webhook configurations. When this option is set as false, webhooks manage their
|
||||
// own webhook configurations.
|
||||
operatorManageWebhooks: false
|
||||
|
||||
// Custom DNS config for the pod to resolve names of services in other
|
||||
// clusters. Use this to add additional search domains, and other settings.
|
||||
// see
|
||||
// https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#dns-config
|
||||
// This does not apply to gateway pods as they typically need a different
|
||||
// set of DNS settings than the normal application pods (e.g., in
|
||||
// multicluster scenarios).
|
||||
// NOTE: If using templates, follow the pattern in the commented example below.
|
||||
//podDNSSearchNamespaces:
|
||||
//- global
|
||||
// Kubernetes >=v1.11.0 will create two PriorityClass, including system-cluster-critical and
|
||||
// system-node-critical, it is better to configure this in order to make sure your Istio pods
|
||||
// will not be killed because of low priority class.
|
||||
// Refer to https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass
|
||||
// for more detail.
|
||||
priorityClassName: ""
|
||||
proxy: {
|
||||
image: "proxyv2"
|
||||
|
||||
// This controls the 'policy' in the sidecar injector.
|
||||
autoInject: "enabled"
|
||||
|
||||
// CAUTION: It is important to ensure that all Istio helm charts specify the same clusterDomain value
|
||||
// cluster domain. Default value is "cluster.local".
|
||||
clusterDomain: "cluster.local"
|
||||
|
||||
// Per Component log level for proxy, applies to gateways and sidecars. If a component level is
|
||||
// not set, then the global "logLevel" will be used.
|
||||
componentLogLevel: "misc:error"
|
||||
|
||||
// If set, newly injected sidecars will have core dumps enabled.
|
||||
enableCoreDump: false
|
||||
|
||||
// istio ingress capture allowlist
|
||||
// examples:
|
||||
// Redirect only selected ports: --includeInboundPorts="80,8080"
|
||||
excludeInboundPorts: ""
|
||||
includeInboundPorts: "*"
|
||||
|
||||
// istio egress capture allowlist
|
||||
// https://istio.io/docs/tasks/traffic-management/egress.html#calling-external-services-directly
|
||||
// example: includeIPRanges: "172.30.0.0/16,172.20.0.0/16"
|
||||
// would only capture egress traffic on those two IP Ranges, all other outbound traffic would
|
||||
// be allowed by the sidecar
|
||||
includeIPRanges: "*"
|
||||
excludeIPRanges: ""
|
||||
includeOutboundPorts: ""
|
||||
excludeOutboundPorts: ""
|
||||
|
||||
// Log level for proxy, applies to gateways and sidecars.
|
||||
// Expected values are: trace|debug|info|warning|error|critical|off
|
||||
logLevel: "warning"
|
||||
|
||||
// Specify the path to the outlier event log.
|
||||
// Example: /dev/stdout
|
||||
outlierLogPath: ""
|
||||
|
||||
//If set to true, istio-proxy container will have privileged securityContext
|
||||
privileged: false
|
||||
|
||||
// The number of successive failed probes before indicating readiness failure.
|
||||
readinessFailureThreshold: 4
|
||||
|
||||
// The initial delay for readiness probes in seconds.
|
||||
readinessInitialDelaySeconds: 0
|
||||
|
||||
// The period between readiness probes.
|
||||
readinessPeriodSeconds: 15
|
||||
|
||||
// Enables or disables a startup probe.
|
||||
// For optimal startup times, changing this should be tied to the readiness probe values.
|
||||
//
|
||||
// If the probe is enabled, it is recommended to have delay=0s,period=15s,failureThreshold=4.
|
||||
// This ensures the pod is marked ready immediately after the startup probe passes (which has a 1s poll interval),
|
||||
// and doesn't spam the readiness endpoint too much
|
||||
//
|
||||
// If the probe is disabled, it is recommended to have delay=1s,period=2s,failureThreshold=30.
|
||||
// This ensures the startup is reasonable fast (polling every 2s). 1s delay is used since the startup is not often ready instantly.
|
||||
startupProbe: {
|
||||
enabled: true
|
||||
failureThreshold: 600 // 10 minutes
|
||||
}
|
||||
|
||||
// Resources for the sidecar.
|
||||
resources: {
|
||||
requests: {
|
||||
cpu: "100m"
|
||||
memory: "128Mi"
|
||||
}
|
||||
limits: {
|
||||
cpu: "2000m"
|
||||
memory: "1024Mi"
|
||||
}
|
||||
}
|
||||
|
||||
// Default port for Pilot agent health checks. A value of 0 will disable health checking.
|
||||
statusPort: 15020
|
||||
|
||||
// Specify which tracer to use. One of: zipkin, lightstep, datadog, stackdriver, none.
|
||||
// If using stackdriver tracer outside GCP, set env GOOGLE_APPLICATION_CREDENTIALS to the GCP credential file.
|
||||
tracer: "none"
|
||||
}
|
||||
proxy_init: {
|
||||
// Base name for the proxy_init container, used to configure iptables.
|
||||
image: "proxyv2"
|
||||
}
|
||||
|
||||
// configure remote pilot and istiod service and endpoint
|
||||
remotePilotAddress: ""
|
||||
|
||||
//#############################################################################################
|
||||
// The following values are found in other charts. To effectively modify these values, make #
|
||||
// make sure they are consistent across your Istio helm charts #
|
||||
//#############################################################################################
|
||||
// The customized CA address to retrieve certificates for the pods in the cluster.
|
||||
// CSR clients such as the Istio Agent and ingress gateways can use this to specify the CA endpoint.
|
||||
// If not set explicitly, default to the Istio discovery address.
|
||||
caAddress: ""
|
||||
|
||||
// Configure a remote cluster data plane controlled by an external istiod.
|
||||
// When set to true, istiod is not deployed locally and only a subset of the other
|
||||
// discovery charts are enabled.
|
||||
externalIstiod: false
|
||||
|
||||
// Configure a remote cluster as the config cluster for an external istiod.
|
||||
configCluster: false
|
||||
|
||||
// configValidation enables the validation webhook for Istio configuration.
|
||||
configValidation: true
|
||||
|
||||
// Mesh ID means Mesh Identifier. It should be unique within the scope where
|
||||
// meshes will interact with each other, but it is not required to be
|
||||
// globally/universally unique. For example, if any of the following are true,
|
||||
// then two meshes must have different Mesh IDs:
|
||||
// - Meshes will have their telemetry aggregated in one place
|
||||
// - Meshes will be federated together
|
||||
// - Policy will be written referencing one mesh from the other
|
||||
//
|
||||
// If an administrator expects that any of these conditions may become true in
|
||||
// the future, they should ensure their meshes have different Mesh IDs
|
||||
// assigned.
|
||||
//
|
||||
// Within a multicluster mesh, each cluster must be (manually or auto)
|
||||
// configured to have the same Mesh ID value. If an existing cluster 'joins' a
|
||||
// multicluster mesh, it will need to be migrated to the new mesh ID. Details
|
||||
// of migration TBD, and it may be a disruptive operation to change the Mesh
|
||||
// ID post-install.
|
||||
//
|
||||
// If the mesh admin does not specify a value, Istio will use the value of the
|
||||
// mesh's Trust Domain. The best practice is to select a proper Trust Domain
|
||||
// value.
|
||||
meshID: ""
|
||||
|
||||
// Configure the mesh networks to be used by the Split Horizon EDS.
|
||||
//
|
||||
// The following example defines two networks with different endpoints association methods.
|
||||
// For `network1` all endpoints that their IP belongs to the provided CIDR range will be
|
||||
// mapped to network1. The gateway for this network example is specified by its public IP
|
||||
// address and port.
|
||||
// The second network, `network2`, in this example is defined differently with all endpoints
|
||||
// retrieved through the specified Multi-Cluster registry being mapped to network2. The
|
||||
// gateway is also defined differently with the name of the gateway service on the remote
|
||||
// cluster. The public IP for the gateway will be determined from that remote service (only
|
||||
// LoadBalancer gateway service type is currently supported, for a NodePort type gateway service,
|
||||
// it still need to be configured manually).
|
||||
//
|
||||
// meshNetworks:
|
||||
// network1:
|
||||
// endpoints:
|
||||
// - fromCidr: "192.168.0.1/24"
|
||||
// gateways:
|
||||
// - address: 1.1.1.1
|
||||
// port: 80
|
||||
// network2:
|
||||
// endpoints:
|
||||
// - fromRegistry: reg1
|
||||
// gateways:
|
||||
// - registryServiceName: istio-ingressgateway.istio-system.svc.cluster.local
|
||||
// port: 443
|
||||
//
|
||||
meshNetworks: {}
|
||||
|
||||
// Use the user-specified, secret volume mounted key and certs for Pilot and workloads.
|
||||
mountMtlsCerts: false
|
||||
multiCluster: {
|
||||
// Set to true to connect two kubernetes clusters via their respective
|
||||
// ingressgateway services when pods in each cluster cannot directly
|
||||
// talk to one another. All clusters should be using Istio mTLS and must
|
||||
// have a shared root CA for this model to work.
|
||||
enabled: false
|
||||
// Should be set to the name of the cluster this installation will run in. This is required for sidecar injection
|
||||
// to properly label proxies
|
||||
clusterName: ""
|
||||
}
|
||||
|
||||
// Network defines the network this cluster belong to. This name
|
||||
// corresponds to the networks in the map of mesh networks.
|
||||
network: ""
|
||||
|
||||
// Configure the certificate provider for control plane communication.
|
||||
// Currently, two providers are supported: "kubernetes" and "istiod".
|
||||
// As some platforms may not have kubernetes signing APIs,
|
||||
// Istiod is the default
|
||||
pilotCertProvider: "istiod"
|
||||
sds: {
|
||||
// The JWT token for SDS and the aud field of such JWT. See RFC 7519, section 4.1.3.
|
||||
// When a CSR is sent from Istio Agent to the CA (e.g. Istiod), this aud is to make sure the
|
||||
// JWT is intended for the CA.
|
||||
token: {
|
||||
aud: "istio-ca"
|
||||
}
|
||||
}
|
||||
sts: {
|
||||
// The service port used by Security Token Service (STS) server to handle token exchange requests.
|
||||
// Setting this port to a non-zero value enables STS server.
|
||||
servicePort: 0
|
||||
}
|
||||
|
||||
// The name of the CA for workload certificates.
|
||||
// For example, when caName=GkeWorkloadCertificate, GKE workload certificates
|
||||
// will be used as the certificates for workloads.
|
||||
// The default value is "" and when caName="", the CA will be configured by other
|
||||
// mechanisms (e.g., environmental variable CA_PROVIDER).
|
||||
caName: ""
|
||||
|
||||
// whether to use autoscaling/v2 template for HPA settings
|
||||
// for internal usage only, not to be configured by users.
|
||||
autoscalingv2API: true
|
||||
}
|
||||
base: {
|
||||
// For istioctl usage to disable istio config crds in base
|
||||
enableIstioConfigCRDs: true
|
||||
}
|
||||
|
||||
// `istio_cni` has been deprecated and will be removed in a future release. use `pilot.cni` instead
|
||||
istio_cni: {
|
||||
// `chained` has been deprecated and will be removed in a future release. use `provider` instead
|
||||
chained: true
|
||||
provider: "default"
|
||||
}
|
||||
|
||||
// Gateway Settings
|
||||
gateways: {
|
||||
// Define the security context for the pod.
|
||||
// If unset, this will be automatically set to the minimum privileges required to bind to port 80 and 443.
|
||||
// On Kubernetes 1.22+, this only requires the `net.ipv4.ip_unprivileged_port_start` sysctl.
|
||||
securityContext: {}
|
||||
|
||||
// Set to `type: RuntimeDefault` to use the default profile for templated gateways, if your container runtime supports it
|
||||
seccompProfile: {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
package holos
|
||||
|
||||
// imported from the 1.23.1 ztunnel chart
|
||||
// cue import components/istio/ztunnel/vendor/ztunnel/values.yaml
|
||||
|
||||
#Istio: Values: {
|
||||
// "defaults" is a workaround for Helm limitations. Users should NOT set ".defaults" explicitly, but rather directly set the fields internally.
|
||||
// For instance, instead of `--set defaults.foo=bar`, just set `--set foo=bar`.
|
||||
defaults: {
|
||||
// Hub to pull from. Image will be `Hub/Image:Tag-Variant`
|
||||
hub: "docker.io/istio"
|
||||
// Tag to pull from. Image will be `Hub/Image:Tag-Variant`
|
||||
tag: "1.23.1"
|
||||
// Variant to pull. Options are "debug" or "distroless". Unset will use the default for the given version.
|
||||
variant: ""
|
||||
|
||||
// Image name to pull from. Image will be `Hub/Image:Tag-Variant`
|
||||
// If Image contains a "/", it will replace the entire `image` in the pod.
|
||||
image: "ztunnel"
|
||||
|
||||
// Labels to apply to all top level resources
|
||||
labels: {}
|
||||
// Annotations to apply to all top level resources
|
||||
annotations: {}
|
||||
|
||||
// Additional volumeMounts to the ztunnel container
|
||||
volumeMounts: []
|
||||
|
||||
// Additional volumes to the ztunnel pod
|
||||
volumes: []
|
||||
|
||||
// Annotations added to each pod. The default annotations are required for scraping prometheus (in most environments).
|
||||
podAnnotations: {
|
||||
"prometheus.io/port": "15020"
|
||||
"prometheus.io/scrape": "true"
|
||||
}
|
||||
|
||||
// Additional labels to apply on the pod level
|
||||
podLabels: {}
|
||||
|
||||
// Pod resource configuration
|
||||
resources: {
|
||||
requests: {
|
||||
cpu: "200m"
|
||||
// Ztunnel memory scales with the size of the cluster and traffic load
|
||||
// While there are many factors, this is enough for ~200k pod cluster or 100k concurrently open connections.
|
||||
memory: "512Mi"
|
||||
}
|
||||
}
|
||||
|
||||
// List of secret names to add to the service account as image pull secrets
|
||||
imagePullSecrets: []
|
||||
|
||||
// A `key: value` mapping of environment variables to add to the pod
|
||||
env: {}
|
||||
|
||||
// Override for the pod imagePullPolicy
|
||||
imagePullPolicy: ""
|
||||
|
||||
// Settings for multicluster
|
||||
multiCluster: {
|
||||
// The name of the cluster we are installing in. Note this is a user-defined name, which must be consistent
|
||||
// with Istiod configuration.
|
||||
clusterName: ""
|
||||
}
|
||||
|
||||
// meshConfig defines runtime configuration of components.
|
||||
// For ztunnel, only defaultConfig is used, but this is nested under `meshConfig` for consistency with other
|
||||
// components.
|
||||
// TODO: https://github.com/istio/istio/issues/43248
|
||||
meshConfig: {
|
||||
defaultConfig: proxyMetadata: {}
|
||||
}
|
||||
|
||||
// This value defines:
|
||||
// 1. how many seconds kube waits for ztunnel pod to gracefully exit before forcibly terminating it (this value)
|
||||
// 2. how many seconds ztunnel waits to drain its own connections (this value - 1 sec)
|
||||
// Default K8S value is 30 seconds
|
||||
terminationGracePeriodSeconds: 30
|
||||
|
||||
// Revision is set as 'version' label and part of the resource names when installing multiple control planes.
|
||||
// Used to locate the XDS and CA, if caAddress or xdsAddress are not set explicitly.
|
||||
revision: ""
|
||||
|
||||
// The customized CA address to retrieve certificates for the pods in the cluster.
|
||||
// CSR clients such as the Istio Agent and ingress gateways can use this to specify the CA endpoint.
|
||||
caAddress: ""
|
||||
|
||||
// The customized XDS address to retrieve configuration.
|
||||
// This should include the port - 15012 for Istiod. TLS will be used with the certificates in "istiod-ca-cert" secret.
|
||||
// By default, it is istiod.istio-system.svc:15012 if revision is not set, or istiod-<revision>.<istioNamespace>.svc:15012
|
||||
xdsAddress: ""
|
||||
|
||||
// Used to locate the XDS and CA, if caAddress or xdsAddress are not set.
|
||||
istioNamespace: "istio-system"
|
||||
|
||||
// Configuration log level of ztunnel binary, default is info.
|
||||
// Valid values are: trace, debug, info, warn, error
|
||||
logLevel: "info"
|
||||
|
||||
// Set to `type: RuntimeDefault` to use the default profile if available.
|
||||
// TODO Ambient inpod - for OpenShift, set to the following to get writable sockets in hostmounts to work, eventually consider CSI driver instead
|
||||
//seLinuxOptions:
|
||||
// type: spc_t
|
||||
seLinuxOptions: {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
(#Helm & Chart).Output
|
||||
|
||||
let Chart = {
|
||||
Name: "istio-ztunnel"
|
||||
Version: #Istio.Version
|
||||
Namespace: #Istio.System.Namespace
|
||||
|
||||
Chart: chart: name: "ztunnel"
|
||||
|
||||
Repo: name: "istio"
|
||||
Repo: url: "https://istio-release.storage.googleapis.com/charts"
|
||||
|
||||
Values: #Istio.Values
|
||||
}
|
||||
45
internal/generate/components/v1alpha3/istio/istio.gen.cue
Normal file
@@ -0,0 +1,45 @@
|
||||
package holos
|
||||
|
||||
// #Istio represents platform wide configuration
|
||||
#Istio: {
|
||||
Version: "1.23.1"
|
||||
System: Namespace: "istio-system"
|
||||
Gateway: Namespace: "istio-ingress"
|
||||
|
||||
// Constrain Helm values for safer, easier upgrades and consistency across
|
||||
// platform components.
|
||||
Values: global: istioNamespace: System.Namespace
|
||||
|
||||
// Configure ambient mode
|
||||
Values: profile: "ambient"
|
||||
}
|
||||
|
||||
// Register the Namespaces
|
||||
#Namespaces: (#Istio.System.Namespace): _
|
||||
#Namespaces: (#Istio.Gateway.Namespace): _
|
||||
|
||||
// Manage istio on workload clusters
|
||||
for Cluster in #Fleets.workload.clusters {
|
||||
#Platform: Components: {
|
||||
"\(Cluster.name)/istio-base": {
|
||||
path: "components/istio/base"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
"\(Cluster.name)/istiod": {
|
||||
path: "components/istio/istiod"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
"\(Cluster.name)/istio-cni": {
|
||||
path: "components/istio/cni"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
"\(Cluster.name)/istio-ztunnel": {
|
||||
path: "components/istio/ztunnel"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
"\(Cluster.name)/istio-gateway": {
|
||||
path: "components/istio/gateway"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "istio",
|
||||
"short": "istio service mesh",
|
||||
"long": "Easily build cloud native workloads securely and reliably with Istio."
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package holos
|
||||
|
||||
let Objects = {
|
||||
Name: "namespaces"
|
||||
Resources: Namespace: #Namespaces
|
||||
}
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).Output
|
||||
@@ -0,0 +1,21 @@
|
||||
package holos
|
||||
|
||||
import corev1 "k8s.io/api/core/v1"
|
||||
|
||||
// #Namespaces defines all managed namespaces in the Platform.
|
||||
// Holos adopts the sig-multicluster position of namespace sameness.
|
||||
#Namespaces: {
|
||||
[Name=string]: corev1.#Namespace & {
|
||||
metadata: name: Name
|
||||
}
|
||||
}
|
||||
|
||||
// Manage the Component on every Cluster in the Platform
|
||||
for Fleet in #Fleets {
|
||||
for Cluster in Fleet.clusters {
|
||||
#Platform: Components: "\(Cluster.name)/namespaces": {
|
||||
path: "components/namespaces"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "namespaces",
|
||||
"short": "manage namespaces consistently",
|
||||
"long": "Provides the #Namespaces root struct for components to register with."
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
(#Helm & Chart).Output
|
||||
|
||||
let Chart = {
|
||||
Name: "{{ .Name }}"
|
||||
Version: "{{ .Version }}"
|
||||
@@ -10,6 +13,3 @@ let Chart = {
|
||||
|
||||
Values: {}
|
||||
}
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
(#Helm & Chart).Output
|
||||
@@ -0,0 +1,9 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "workload-cluter",
|
||||
"short": "define a workload cluster for the guides",
|
||||
"long": "Define a workload cluster named workload for use with the documentation."
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package holos
|
||||
|
||||
// Manage a workload cluster named workload for use with the guides.
|
||||
#Fleets: workload: clusters: workload: _
|
||||
@@ -37,27 +37,9 @@ func Platforms() []string {
|
||||
return dirs
|
||||
}
|
||||
|
||||
func writePlatformMetadata(ctx context.Context, rpc *client.Client, orgID string, name string) error {
|
||||
func initPlatformMetadata(ctx context.Context, name string) error {
|
||||
log := logger.FromContext(ctx)
|
||||
|
||||
// Link the local platform the SaaS platform ID.
|
||||
rpcPlatforms, err := rpc.Platforms(ctx, orgID)
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
var rpcPlatform *platform.Platform
|
||||
for _, p := range rpcPlatforms {
|
||||
if p.GetName() == name {
|
||||
rpcPlatform = p
|
||||
break
|
||||
}
|
||||
log.DebugContext(ctx, "checking platform", "want", name, "have", p.GetName())
|
||||
}
|
||||
if rpcPlatform == nil {
|
||||
return errors.Wrap(errors.New("cannot generate: platform not found in the holos server"))
|
||||
}
|
||||
|
||||
rpcPlatform := &platform.Platform{Name: name}
|
||||
// Write the platform data.
|
||||
encoder := protojson.MarshalOptions{Indent: " "}
|
||||
data, err := encoder.Marshal(rpcPlatform)
|
||||
@@ -67,7 +49,7 @@ func writePlatformMetadata(ctx context.Context, rpc *client.Client, orgID string
|
||||
if len(data) > 0 {
|
||||
data = append(data, '\n')
|
||||
}
|
||||
log = log.With("platform_id", rpcPlatform.GetId())
|
||||
|
||||
if err := os.WriteFile(client.PlatformMetadataFile, data, 0644); err != nil {
|
||||
return errors.Wrap(fmt.Errorf("could not write platform metadata: %w", err))
|
||||
}
|
||||
@@ -78,7 +60,7 @@ func writePlatformMetadata(ctx context.Context, rpc *client.Client, orgID string
|
||||
|
||||
// GeneratePlatform writes the cue code for a platform to the local working
|
||||
// directory.
|
||||
func GeneratePlatform(ctx context.Context, rpc *client.Client, orgID string, name string) error {
|
||||
func GeneratePlatform(ctx context.Context, name string) error {
|
||||
log := logger.FromContext(ctx)
|
||||
// Check for a valid platform
|
||||
platformPath := filepath.Join(platformsRoot, name)
|
||||
@@ -90,7 +72,7 @@ func GeneratePlatform(ctx context.Context, rpc *client.Client, orgID string, nam
|
||||
log.DebugContext(ctx, fmt.Sprintf("skipped write %s: already exists", client.PlatformConfigFile))
|
||||
} else {
|
||||
if os.IsNotExist(err) {
|
||||
if err := writePlatformMetadata(ctx, rpc, orgID, name); err != nil {
|
||||
if err := initPlatformMetadata(ctx, name); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -6,11 +6,6 @@ package v1alpha3
|
||||
|
||||
import "google.golang.org/protobuf/types/known/structpb"
|
||||
|
||||
#PlatformMetadata: {
|
||||
// Name represents the Platform name.
|
||||
name: string @go(Name)
|
||||
}
|
||||
|
||||
// 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
|
||||
@@ -30,13 +25,18 @@ import "google.golang.org/protobuf/types/known/structpb"
|
||||
spec: #PlatformSpec @go(Spec)
|
||||
}
|
||||
|
||||
#PlatformMetadata: {
|
||||
// Name represents the Platform name.
|
||||
name: string @go(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.
|
||||
#PlatformSpec: {
|
||||
// Model represents the platform model holos gets from from the
|
||||
// PlatformService.GetPlatform rpc method and provides to CUE using a tag.
|
||||
model: structpb.#Struct @go(Model)
|
||||
model: structpb.#Struct & {...} @go(Model)
|
||||
|
||||
// Components represents a list of holos components to manage.
|
||||
components: [...#PlatformSpecComponent] @go(Components,[]PlatformSpecComponent)
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
// Code generated by cue get go. DO NOT EDIT.
|
||||
|
||||
//cue:generate cue get go 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.
|
||||
package v1alpha3
|
||||
|
||||
import (
|
||||
core "github.com/holos-run/holos/api/core/v1alpha3"
|
||||
"google.golang.org/protobuf/types/known/structpb"
|
||||
)
|
||||
|
||||
// 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.
|
||||
#Helm: {
|
||||
// Name represents the Component name.
|
||||
Name: string
|
||||
|
||||
// Version represents the chart version.
|
||||
Version: string
|
||||
|
||||
// Namespace represents the helm namespace option when rendering the chart.
|
||||
Namespace: string
|
||||
|
||||
// Resources are kubernetes api objects to mix into the output.
|
||||
Resources: {...} @go(,map[string]any)
|
||||
|
||||
// Repo represents the chart repository
|
||||
Repo: {
|
||||
name: string @go(Name)
|
||||
url: string @go(URL)
|
||||
} @go(,"struct{Name string \"json:\\\"name\\\"\"; URL string \"json:\\\"url\\\"\"}")
|
||||
|
||||
// Values represents data to marshal into a values.yaml for helm.
|
||||
Values: _ & {...} @go(,interface{})
|
||||
|
||||
// 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 & (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: {...} & {[string]: {...}} @go(,map[string]any)
|
||||
|
||||
// KustomizePatches represents patches to apply to the helm output. Requires
|
||||
// EnableKustomizePostProcessor: true.
|
||||
KustomizePatches: {...} & {[string]: {...}} @go(,map[core.InternalLabel]any)
|
||||
|
||||
// KustomizeResources represents additional resources files to include in the
|
||||
// kustomize resources list.
|
||||
KustomizeResources: {...} & {[string]: {...}} @go(,map[string]any)
|
||||
|
||||
// ArgoConfig represents the ArgoCD GitOps configuration for this Component.
|
||||
ArgoConfig: #ArgoConfig
|
||||
|
||||
// Output represents the derived BuildPlan for the Holos cli to render.
|
||||
Output: core.#BuildPlan
|
||||
}
|
||||
|
||||
// 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.
|
||||
#ArgoConfig: {
|
||||
// Enabled causes holos to render an ArgoCD Application resource for GitOps if true.
|
||||
Enabled: bool & (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 & (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 & (string | *"main")
|
||||
}
|
||||
|
||||
// Cluster represents a cluster managed by the Platform.
|
||||
#Cluster: {
|
||||
// Name represents the cluster name, for example "east1", "west1", or
|
||||
// "management".
|
||||
name: string @go(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 & (true | *false) @go(Primary)
|
||||
}
|
||||
|
||||
// Fleet represents a named collection of similarly configured Clusters. Useful
|
||||
// to segregate workload clusters from their management cluster.
|
||||
#Fleet: {
|
||||
name: string @go(Name)
|
||||
|
||||
// Clusters represents a mapping of Clusters by their name.
|
||||
clusters: {[string]: #Cluster} & {[Name=_]: name: Name} @go(Clusters,map[string]Cluster)
|
||||
}
|
||||
|
||||
// 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.
|
||||
#StandardFleets: {
|
||||
// Workload represents a Fleet of zero or more workload Clusters.
|
||||
workload: #Fleet & {name: "workload"} @go(Workload)
|
||||
|
||||
// Management represents a Fleet with one Cluster named management.
|
||||
management: #Fleet & {name: "management"} @go(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.
|
||||
#Platform: {
|
||||
// Name represents the Platform name.
|
||||
Name: string & (string | *"holos")
|
||||
|
||||
// Components is a structured map of components to manage by their name.
|
||||
Components: {[string]: core.#PlatformSpecComponent} @go(,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 & {...}
|
||||
|
||||
// Output represents the core Platform spec for the holos cli to iterate over
|
||||
// and render each listed Component, injecting the Model.
|
||||
Output: core.#Platform
|
||||
}
|
||||
|
||||
// Kustomize provides a BuildPlan via the Output field which contains one
|
||||
// KustomizeBuild from package core.
|
||||
#Kustomize: {
|
||||
// Name represents the Component name.
|
||||
Name: string
|
||||
|
||||
// Kustomization represents the kustomize build plan for holos to render.
|
||||
Kustomization: core.#KustomizeBuild
|
||||
|
||||
// Output represents the derived BuildPlan for the Holos cli to render.
|
||||
Output: core.#BuildPlan
|
||||
}
|
||||
|
||||
// Kubernetes provides a BuildPlan via the Output field which contains inline
|
||||
// API Objects provided directly from CUE.
|
||||
#Kubernetes: {
|
||||
// Name represents the Component name.
|
||||
Name: string
|
||||
|
||||
// Resources represents the kubernetes api objects for the Component.
|
||||
Resources: {...} @go(,map[string]any)
|
||||
|
||||
// Output represents the derived BuildPlan for the Holos cli to render.
|
||||
Output: core.#BuildPlan
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
package v1alpha3
|
||||
|
||||
import (
|
||||
"encoding/yaml"
|
||||
core "github.com/holos-run/holos/api/core/v1alpha3"
|
||||
kc "sigs.k8s.io/kustomize/api/types"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
|
||||
app "argoproj.io/application/v1alpha1"
|
||||
)
|
||||
|
||||
#Resources: {
|
||||
[Kind=string]: [InternalLabel=string]: {
|
||||
kind: Kind
|
||||
metadata: name: string | *InternalLabel
|
||||
}
|
||||
|
||||
ClusterRole: [_]: rbacv1.#ClusterRole
|
||||
ClusterRoleBinding: [_]: rbacv1.#ClusterRoleBinding
|
||||
ConfigMap: [_]: corev1.#ConfigMap
|
||||
CronJob: [_]: batchv1.#CronJob
|
||||
Deployment: [_]: appsv1.#Deployment
|
||||
Job: [_]: batchv1.#Job
|
||||
Namespace: [_]: corev1.#Namespace
|
||||
Role: [_]: rbacv1.#Role
|
||||
RoleBinding: [_]: rbacv1.#RoleBinding
|
||||
Service: [_]: corev1.#Service
|
||||
ServiceAccount: [_]: corev1.#ServiceAccount
|
||||
StatefulSet: [_]: appsv1.#StatefulSet
|
||||
...
|
||||
}
|
||||
|
||||
#Helm: {
|
||||
Name: string
|
||||
Version: string
|
||||
Namespace: string
|
||||
Resources: #Resources
|
||||
|
||||
Repo: {
|
||||
name: string | *""
|
||||
url: string | *""
|
||||
}
|
||||
|
||||
Values: {...}
|
||||
|
||||
Chart: core.#HelmChart & {
|
||||
metadata: name: string | *Name
|
||||
metadata: namespace: string | *Namespace
|
||||
chart: name: string | *Name
|
||||
chart: release: chart.name
|
||||
chart: version: string | *Version
|
||||
chart: repository: Repo
|
||||
|
||||
// Render the values to yaml for holos to provide to helm.
|
||||
valuesContent: yaml.Marshal(Values)
|
||||
|
||||
// Kustomize post-processor
|
||||
if EnableKustomizePostProcessor == true {
|
||||
// resourcesFile represents the file helm output is written two and
|
||||
// kustomize reads from. Typically "resources.yaml" but referenced as a
|
||||
// constant to ensure the holos cli uses the same file.
|
||||
kustomize: resourcesFile: core.#ResourcesFile
|
||||
// kustomizeFiles represents the files in a kustomize directory tree.
|
||||
kustomize: kustomizeFiles: core.#FileContentMap
|
||||
for FileName, Object in KustomizeFiles {
|
||||
kustomize: kustomizeFiles: "\(FileName)": yaml.Marshal(Object)
|
||||
}
|
||||
}
|
||||
|
||||
apiObjectMap: (#APIObjects & {apiObjects: Resources}).apiObjectMap
|
||||
}
|
||||
|
||||
// EnableKustomizePostProcessor processes helm output with kustomize if true.
|
||||
EnableKustomizePostProcessor: 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: {
|
||||
// Embed KustomizeResources
|
||||
KustomizeResources
|
||||
|
||||
// The kustomization.yaml file must be included for kustomize to work.
|
||||
"kustomization.yaml": kc.#Kustomization & {
|
||||
apiVersion: "kustomize.config.k8s.io/v1beta1"
|
||||
kind: "Kustomization"
|
||||
resources: [core.#ResourcesFile, for FileName, _ in KustomizeResources {FileName}]
|
||||
patches: [for x in KustomizePatches {x}]
|
||||
}
|
||||
}
|
||||
// KustomizePatches represents patches to apply to the helm output. Requires
|
||||
// EnableKustomizePostProcessor: true.
|
||||
KustomizePatches: [ArbitraryLabel=string]: kc.#Patch
|
||||
// KustomizeResources represents additional resources files to include in the
|
||||
// kustomize resources list.
|
||||
KustomizeResources: [FileName=string]: {...}
|
||||
|
||||
// ArgoConfig represents the ArgoCD GitOps integration for this Component.
|
||||
ArgoConfig: _
|
||||
|
||||
// output represents the build plan provided to the holos cli.
|
||||
Output: #BuildPlan & {
|
||||
_Name: Name
|
||||
_Namespace: Namespace
|
||||
_ArgoConfig: ArgoConfig
|
||||
spec: components: helmChartList: [Chart]
|
||||
}
|
||||
}
|
||||
|
||||
#BuildPlan: core.#BuildPlan & {
|
||||
_Name: string
|
||||
_Namespace?: string
|
||||
_ArgoConfig: #ArgoConfig
|
||||
|
||||
if _ArgoConfig.Enabled {
|
||||
let NAME = "gitops/\(_Name)"
|
||||
|
||||
// Render the ArgoCD Application for GitOps as an additional Component of
|
||||
// the BuildPlan.
|
||||
spec: components: resources: (NAME): {
|
||||
metadata: name: NAME
|
||||
if _Namespace != _|_ {
|
||||
metadata: namespace: _Namespace
|
||||
}
|
||||
|
||||
deployFiles: (#Argo & {ComponentName: _Name, ArgoConfig: _ArgoConfig}).deployFiles
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// #Argo represents an argocd Application resource for each component, written
|
||||
// using the #HolosComponent.deployFiles field.
|
||||
#Argo: {
|
||||
ComponentName: string
|
||||
ArgoConfig: #ArgoConfig
|
||||
|
||||
Application: app.#Application & {
|
||||
metadata: name: ComponentName
|
||||
metadata: namespace: "argocd"
|
||||
spec: {
|
||||
destination: server: "https://kubernetes.default.svc"
|
||||
project: "default"
|
||||
source: {
|
||||
path: "\(ArgoConfig.DeployRoot)/deploy/clusters/\(ArgoConfig.ClusterName)/components/\(ComponentName)"
|
||||
repoURL: ArgoConfig.RepoURL
|
||||
targetRevision: ArgoConfig.TargetRevision
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// deployFiles represents the output files to write along side the component.
|
||||
deployFiles: "clusters/\(ArgoConfig.ClusterName)/gitops/\(ComponentName).application.gen.yaml": yaml.Marshal(Application)
|
||||
}
|
||||
|
||||
// #ArgoDefaultSyncPolicy represents the default argo sync policy.
|
||||
#ArgoDefaultSyncPolicy: {
|
||||
automated: {
|
||||
prune: bool | *true
|
||||
selfHeal: bool | *true
|
||||
}
|
||||
syncOptions: [
|
||||
"RespectIgnoreDifferences=true",
|
||||
"ServerSideApply=true",
|
||||
]
|
||||
retry: limit: number | *2
|
||||
retry: backoff: {
|
||||
duration: string | *"5s"
|
||||
factor: number | *2
|
||||
maxDuration: string | *"3m0s"
|
||||
}
|
||||
}
|
||||
|
||||
// #APIObjects defines the output format for kubernetes api objects. The holos
|
||||
// cli expects the yaml representation of each api object in the apiObjectMap
|
||||
// field.
|
||||
#APIObjects: core.#APIObjects & {
|
||||
// apiObjects represents the un-marshalled form of each kubernetes api object
|
||||
// managed by a holos component.
|
||||
apiObjects: {
|
||||
[Kind=string]: {
|
||||
[string]: {
|
||||
kind: Kind
|
||||
...
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// apiObjectMap holds the marshalled representation of apiObjects
|
||||
for kind, v in apiObjects {
|
||||
for name, obj in v {
|
||||
apiObjectMap: (kind): (name): yaml.Marshal(obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#Platform: {
|
||||
Name: _
|
||||
Model: _
|
||||
Components: [string]: _
|
||||
Output: metadata: name: Name
|
||||
Output: spec: model: Model
|
||||
Output: spec: components: [for c in Components {c}]
|
||||
}
|
||||
|
||||
#Kustomize: {
|
||||
Name: _
|
||||
Kustomization: metadata: name: string | *Name
|
||||
Output: #BuildPlan & {
|
||||
_Name: Name
|
||||
spec: components: kustomizeBuildList: [Kustomization]
|
||||
}
|
||||
}
|
||||
|
||||
#Kubernetes: {
|
||||
Name: _
|
||||
Resources: #Resources
|
||||
|
||||
Output: #BuildPlan & {
|
||||
_Name: Name
|
||||
// resources is a map unlike other build plans which use a list.
|
||||
spec: components: resources: (Name): {
|
||||
metadata: name: Name
|
||||
apiObjectMap: (#APIObjects & {apiObjects: Resources}).apiObjectMap
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,9 @@ package platforms
|
||||
//go generate rm -rf cue.mod/gen/github.com/holos-run/holos/api/meta
|
||||
//go:generate cue get go github.com/holos-run/holos/api/meta/...
|
||||
|
||||
//go generate rm -rf cue.mod/gen/github.com/holos-run/holos/api/schema
|
||||
//go:generate cue get go github.com/holos-run/holos/api/schema/...
|
||||
|
||||
//go generate rm -rf cue.mod/gen/github.com/holos-run/holos/service/gen/holos/object
|
||||
//go:generate cue import ../../../service/holos/object/v1alpha1/object.proto -o cue.mod/gen/github.com/holos-run/holos/service/gen/holos/object/v1alpha1/object.proto_gen.cue -I ../../../proto -f
|
||||
//go:generate rm -f cue.mod/gen/github.com/holos-run/holos/service/gen/holos/object/v1alpha1/object.pb_go_gen.cue
|
||||
|
||||
8
internal/generate/platforms/guide/.gitignore
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
vendor/
|
||||
1
internal/generate/platforms/guide/platform.config.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
3
internal/generate/platforms/guide/platform.gen.cue
Normal file
@@ -0,0 +1,3 @@
|
||||
package holos
|
||||
|
||||
#Platform: Name: "guide"
|
||||
@@ -0,0 +1,3 @@
|
||||
package holos
|
||||
|
||||
#Platform.Output
|
||||
5
internal/generate/platforms/guide/readme.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Holos
|
||||
|
||||
Generated for use with [Holos Guides][guides].
|
||||
|
||||
[guides]: https://holos.run/docs/guides/
|
||||
19
internal/generate/platforms/guide/schema.gen.cue
Normal file
@@ -0,0 +1,19 @@
|
||||
package holos
|
||||
|
||||
import schema "github.com/holos-run/holos/api/schema/v1alpha3"
|
||||
|
||||
#Helm: schema.#Helm & {
|
||||
ArgoConfig: #ArgoConfig
|
||||
}
|
||||
|
||||
#Kustomize: schema.#Kustomize
|
||||
|
||||
#Kubernetes: schema.#Kubernetes
|
||||
|
||||
#ArgoConfig: schema.#ArgoConfig & {
|
||||
ClusterName: _ClusterName
|
||||
}
|
||||
|
||||
#Fleets: schema.#StandardFleets
|
||||
|
||||
#Platform: schema.#Platform
|
||||
14
internal/generate/platforms/guide/tags.gen.cue
Normal file
@@ -0,0 +1,14 @@
|
||||
package holos
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
dto "github.com/holos-run/holos/service/gen/holos/object/v1alpha1:object"
|
||||
)
|
||||
|
||||
// _ClusterName is the --cluster-name flag value provided by the holos cli.
|
||||
_ClusterName: string @tag(cluster, type=string)
|
||||
|
||||
// _PlatformConfig represents all of the data passed from holos to cue, used to
|
||||
// carry the platform and project models.
|
||||
_PlatformConfig: dto.#PlatformConfig & json.Unmarshal(_PlatformConfigJSON)
|
||||
_PlatformConfigJSON: string | *"{}" @tag(platform_config, type=string)
|
||||
8
internal/generate/platforms/quickstart/.gitignore
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
vendor/
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -0,0 +1,3 @@
|
||||
package holos
|
||||
|
||||
#Platform.Output
|
||||
@@ -0,0 +1,3 @@
|
||||
package holos
|
||||
|
||||
#Platform: Name: "quickstart"
|
||||
5
internal/generate/platforms/quickstart/readme.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Holos Quickstart
|
||||
|
||||
Generated from the [Holos Quickstart][quickstart] guide.
|
||||
|
||||
[quickstart]: https://holos.run/docs/quickstart/
|
||||
15
internal/generate/platforms/quickstart/schema.gen.cue
Normal file
@@ -0,0 +1,15 @@
|
||||
package holos
|
||||
|
||||
import schema "github.com/holos-run/holos/api/schema/v1alpha3"
|
||||
|
||||
#Helm: schema.#Helm & {
|
||||
ArgoConfig: #ArgoConfig
|
||||
}
|
||||
|
||||
#ArgoConfig: schema.#ArgoConfig & {
|
||||
ClusterName: _ClusterName
|
||||
}
|
||||
|
||||
#Fleets: schema.#StandardFleets
|
||||
|
||||
#Platform: schema.#Platform
|
||||
14
internal/generate/platforms/quickstart/tags.gen.cue
Normal file
@@ -0,0 +1,14 @@
|
||||
package holos
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
dto "github.com/holos-run/holos/service/gen/holos/object/v1alpha1:object"
|
||||
)
|
||||
|
||||
// _ClusterName is the --cluster-name flag value provided by the holos cli.
|
||||
_ClusterName: string @tag(cluster, type=string)
|
||||
|
||||
// _PlatformConfig represents all of the data passed from holos to cue, used to
|
||||
// carry the platform and project models.
|
||||
_PlatformConfig: dto.#PlatformConfig & json.Unmarshal(_PlatformConfigJSON)
|
||||
_PlatformConfigJSON: string | *"{}" @tag(platform_config, type=string)
|
||||
@@ -1 +1 @@
|
||||
0
|
||||
4
|
||||
|
||||