Compare commits

...

48 Commits

Author SHA1 Message Date
Jeff McCune
b737543c13 version: 0.95.0 2024-09-17 08:06:38 -07:00
Jeff McCune
8e150ee0d7 generate: fix external-secrets always out of sync in argocd
Without this patch ArgoCD treats the Application as constantly out of
sync.  This is also a good example of how to patch an arbitrary
component, though it patches the core BuildPlan itself now.  If this is
widely used, it would be nice to add this behavior to the schema api
(aka author api).
2024-09-16 21:22:23 -07:00
Jeff McCune
117a2a886d generate: fix istio-base always out of sync in argocd
Without this patch ArgoCD treats the Application as constantly out of
sync.  This is also a good example of how to patch an arbitrary
component, though it patches the core BuildPlan itself now.  If this is
widely used, it would be nice to add this behavior to the schema api
(aka author api).
2024-09-16 20:46:29 -07:00
Jeff McCune
79b41dfbf5 generate: fix istiod always out of sync in argocd
Without this patch ArgoCD treats the Application as constantly out of
sync.  This is also a good example of how to patch an arbitrary
component, though it patches the core BuildPlan itself now.  If this is
widely used, it would be nice to add this behavior to the schema api
(aka author api).
2024-09-16 20:38:35 -07:00
Jeff McCune
55562f9d83 generate: move istio-k3d schematic to projects structure
To match the current layout of the guide platform we're using for the
guides.
2024-09-16 20:02:23 -07:00
Jeff McCune
e0a636f183 generate: move gateway-api schematic to projects structure
To match the current layout of the guide platform we're using for the
guides.
2024-09-16 19:53:28 -07:00
Jeff McCune
1fa74214cf generate: move istio schematic to projects structure
To match the current layout of the guide platform we're using for the
guides.
2024-09-16 19:51:02 -07:00
Jeff McCune
e5851cac57 generate: fix bank of holos connection reset
Without this patch browsing https://bank.holos.localhost frequently gets
connection reset errors.  These errors are caused by the frontend
deployment redirecting the browser to http, which is not enabled on the
Gateway we use in the guides.

This patch sets the scheme to https which corrects the problems.

See https://github.com/GoogleCloudPlatform/bank-of-anthos/issues/478
2024-09-16 19:29:21 -07:00
Jeff McCune
4a26662b92 generate: add bank-contacts
Needed to load the home page of the Bank of Holos demo.
2024-09-16 19:29:02 -07:00
Jeff McCune
6bc6888ffc generate: add bank-transaction-history
Needed to load the home page of the Bank of Holos demo.
2024-09-16 17:00:15 -07:00
Jeff McCune
dab1f305e1 generate: add bank-balance-reader
Needed to load the home page of the Bank of Holos demo.
2024-09-16 16:52:52 -07:00
Jeff McCune
fbe79dd0af generate: add bank-ledger-db and bank-ledger-writer
Needed to load the home page of the Bank of Holos demo.
2024-09-16 16:46:35 -07:00
Jeff McCune
6d6829b149 generate: refactor bank backend config to a component
To fix ArgoCD SharedResourceWarning.
2024-09-16 16:18:31 -07:00
Jeff McCune
971a3fa280 generate: fix accounts-db using wrong service account
Needs to match the bank-of-holos service account name.
2024-09-16 15:58:50 -07:00
Jeff McCune
7632344cd1 generate: add bank-accounts-db needed by userservice
With this patch the frontend, accounts-db, and userservice all start and
become ready.

The user can log in, but on redirecting to home the site can't be
reached.
2024-09-16 15:51:29 -07:00
Jeff McCune
42067748ad generate: add bank userservice to backend 2024-09-16 15:49:25 -07:00
Jeff McCune
340c3484e5 generate: refactor how the bank jwt-key is created
This makes the example more re-usable, reader need only change the
SecretName, the bash script, and replace the #BankOfHolos references.
2024-09-16 15:02:12 -07:00
Jeff McCune
250238c286 generate: add secret store and external secret to bank-of-holos
Rather than commit the jwt private key to version control like upstream
does, we use a SecretStore and ExternalSecret to sync the secret
generated by the security team in the bank-security namespace.

With this patch the SecretStore validates and the ExternalSecret
automatically syncs the secret from the bank-security namespace to the
bank-frontend namespace.

```
❯ k get ss
NAME            AGE   STATUS   CAPABILITIES   READY
bank-security   1s    Valid    ReadWrite      True

❯ k get es
NAME      STORE           REFRESH INTERVAL   STATUS         READY
jwt-key   bank-security   5s                 SecretSynced   True
```

The pod start successfully.

```
❯ k get pods
NAME                        READY   STATUS    RESTARTS   AGE
frontend-646d797d6b-7jhrx   1/1     Running   0          2m39s

❯ k logs frontend-646d797d6b-7jhrx
{"timestamp": "2024-09-16 21:44:47", "message": "info | Starting gunicorn 22.0.0", "severity": "INFO"}
{"timestamp": "2024-09-16 21:44:47", "message": "info | Listening at: http://0.0.0.0:8080 (7)", "severity": "INFO"}
{"timestamp": "2024-09-16 21:44:47", "message": "info | Using worker: gthread", "severity": "INFO"}
{"timestamp": "2024-09-16 21:44:47", "message": "info | Booting worker with pid: 8", "severity": "INFO"}
{"timestamp": "2024-09-16 21:44:57", "message": "create_app | Unable to retrieve cluster name from metadata server metadata.google.internal.", "severity": "WARNING"}
{"timestamp": "2024-09-16 21:44:57", "message": "create_app | Unable to retrieve zone from metadata server metadata.google.internal.", "severity": "WARNING"}
{"timestamp": "2024-09-16 21:44:57", "message": "create_app | Starting frontend service.", "severity": "INFO"}
{"timestamp": "2024-09-16 21:44:57", "message": "create_app | 🚫 Tracing disabled.", "severity": "INFO"}
{"timestamp": "2024-09-16 21:44:57", "message": "create_app | Platform is set to 'local'", "severity": "INFO"}
```
2024-09-16 14:47:33 -07:00
Jeff McCune
a223e2b426 generate: fix duplicate external secrets crds
They're handled outside the helm chart to make upgrades easier.
2024-09-16 13:39:04 -07:00
Jeff McCune
63a7da02e7 generate: add external secrets operator
Need this to sync secrets into the bank-frontend and bank-backend
namespace from the bank-security namespace.
2024-09-16 13:29:03 -07:00
Jeff McCune
569f827e30 speed up argocd crds with raw urls 2024-09-16 13:29:02 -07:00
Jeff McCune
4a656db2ec render: log total render platform time 2024-09-16 13:29:02 -07:00
Jeff McCune
77b0933961 generate: add httproute for bank.holos.localhost
Expose Service frontend in the bank-frontend namespace via httproute
https://bank.holos.localhost

Organize into frontend, backend, security projects to align with three
teams who would each own this work.

remove secret from version control

Google added the secret to version control but we can generate the
secret in-cluster.  Holos makes it easier to manage the ExternalSecret
or RoleBinding necessary to get it in the right place.
2024-09-16 12:46:00 -07:00
Jeff McCune
3b796cfbbd generate: add bank-of-holos frontend
We need a way to demonstrate the value Holos offers in a platform team
managing projects for other teams.  This patch addresses the need by
establishing the bank-of-holos schematic, which is a port of the Bank of
Anthos project to Holos.

This patch adds only the frontend to get the process started.  As of
this patch the frontend pod starts and becomes ready but is not exposed
via HTTPRoute.

Refer to https://github.com/GoogleCloudPlatform/bank-of-anthos/
2024-09-15 22:08:28 -07:00
Jeff McCune
8a7a010b94 version 0.94.0 2024-09-15 15:41:17 -07:00
Jeff McCune
2454f6e9ee generate: app-projects to organize ArgoCD Applications into Projects
Previously all generated ArgoCD Application resources go into the
default project following the Quickstart guide.  The configuration code
is being organized into the concept of projects in the filesystem, so we
want to the GitOps configuration to also reflect this concept of
projects.

This patch extends the ArgoConfig user facing schema to accept a project
string.  The app-projects component automatically manages AppProject
resources in the argocd namespace for each of the defined projects.

This allows CUE configuration in the a project directory to specify the
project name so that all Applications are automatically assigned to the
correct project.
2024-09-15 14:57:13 -07:00
Jeff McCune
63d00bfddf schema: handle ArgoConfig for all component kinds
Providing ArgoConfig only works with the Helm kind without this patch.
This is a problem because we want to produce an Application for every
supported component kind when rendering the platform.

This patch threads the ArgoConfig struct described in the Quickstart
guide through every supported component kind.
2024-09-15 13:09:07 -07:00
Jeff McCune
f34da6c24e generate: add schematic for manage a project guide gitops
This patch configures the platform to generate Application resources for
all of the components in the manage a project guide.
2024-09-15 12:57:51 -07:00
Jeff McCune
1d98069b73 generate: add httproutes schematic
Define a place for components to register HTTPRoute resources the
platform team needs to manage in the Gateway namespace.

The files are organized to delegate to the platform team.

This patch also fixes the naming of the argocd component so that the
Service is argocd-server instead of argo-cd-argocd-server.
2024-09-15 12:32:45 -07:00
Jeff McCune
e956b64d04 schematic: comment how kustomization of argocd crds works
This is the only example we have right now of producing a kustomization
entirely from CUE.
2024-09-15 09:37:42 -07:00
Jeff McCune
054d33b498 builder: add kustomization post-processing to kubernetes build plans (#246)
Holos does not post-process a KubernetesObjects core package build plan
with kustomize.  This is necessary to pass the ArgoCD version through to
Kustomize to fetch the correct crds.

This patch enables the kustomization and provides an example in the
argocd schematic.

Result: The KubernetesObjects component doesn't actually have any
resources defined, so holos creates an empty `build-plan-resources.yaml`
file.  This is fine, the kustomize post-processing adds the actual
resources via https URL passing in the correct ArgoCD version.

```
❯ holos render component --cluster-name=workload ./projects/platform/components/argocd/crds --log-level=debug --log-format=text
9:20AM DBG config.go:166 finalized config from flags version=0.93.4 state=finalized
9:20AM DBG builder.go:234 cue: building instances version=0.93.4
9:20AM DBG builder.go:251 cue: validating instance version=0.93.4 dir=/Users/jeff/Holos/holos-manage-a-project-guide/projects/platform/components/argocd/crds
9:20AM DBG builder.go:256 cue: decoding holos build plan version=0.93.4 dir=/Users/jeff/Holos/holos-manage-a-project-guide/projects/platform/components/argocd/crds
9:20AM DBG builder.go:270 cue: discriminated build kind: BuildPlan version=0.93.4 dir=/Users/jeff/Holos/holos-manage-a-project-guide/projects/platform/components/argocd/crds kind=BuildPlan apiVersion=v1alpha3
9:20AM DBG builder.go:314 allocated results slice version=0.93.4 cap=1
9:20AM DBG result.go:156 wrote: /var/folders/22/zt67pphj6h1fgknqfy23ppl80000gn/T/holos.kustomize3526125146/build-plan-resources.yaml version=0.93.4 op=write path=/var/folders/22/zt67pphj6h1fgknqfy23ppl80000gn/T/holos.kustomize3526125146/build-plan-resources.yaml bytes=0
9:20AM DBG result.go:169 wrote: /var/folders/22/zt67pphj6h1fgknqfy23ppl80000gn/T/holos.kustomize3526125146/kustomization.yaml version=0.93.4 op=write path=/var/folders/22/zt67pphj6h1fgknqfy23ppl80000gn/T/holos.kustomize3526125146/kustomization.yaml bytes=174
9:20AM DBG run.go:40 running: kubectl version=0.93.4 name=kubectl args="[kustomize /var/folders/22/zt67pphj6h1fgknqfy23ppl80000gn/T/holos.kustomize3526125146]"
9:20AM DBG remove.go:16 tmp: removed version=0.93.4 path=/var/folders/22/zt67pphj6h1fgknqfy23ppl80000gn/T/holos.kustomize3526125146
9:20AM DBG builder.go:350 returning results version=0.93.4 len=1
9:20AM DBG result.go:214 out: wrote deploy/clusters/workload/components/argocd-crds/argocd-crds.gen.yaml version=0.93.4 action=write path=deploy/clusters/workload/components/argocd-crds/argocd-crds.gen.yaml status=ok
9:20AM INF render.go:79 rendered argocd-crds version=0.93.4 cluster=workload name=argocd-crds status=ok action=rendered
```

Closes: #246
2024-09-15 09:25:25 -07:00
Jeff McCune
f2f75a4e00 generate: fix argo-cd component 2024-09-15 09:06:53 -07:00
Jeff McCune
a0cf73faf9 generate: remove argocd kustomization.yaml 2024-09-15 09:00:41 -07:00
Jeff McCune
d74655c632 generate: add argocd schematic
Using the projects layout.

This patch also includes a method to pass a version to a Kustomization.
2024-09-15 08:57:57 -07:00
Jeff McCune
b8019429b8 docs: add manage a project guide draft (#242)
Initial draft of the Manage a Project guide focused on how a development
team can self serve resources provided by a platform team.
2024-09-14 15:35:12 -07:00
Jeff McCune
9c08214118 docs: add the outline of the projects guide (#242) 2024-09-14 13:43:31 -07:00
Jeff McCune
f58d791e03 api: move #Resources to package holos
Previously, the #Resources struct listing valid resources to use with
APIObjects in each of the components types was closed.  This made it
very difficult for users to mix in new resources and use the Kubernetes
component kind.

This patch moves the definition of the valid resources to package holos
from the schema API.  The schema still enforces some light constraints,
but doesn't keep the struct closed.

A new convention is introduced in the form of configuring all components
using _ComponentConfig defined at the root, then unifying this struct
with all of the component kinds.  See schema.gen.cue for how this works.

This approach enables mixing in ArgoCD applications to all component
kinds, not just Helm as was done previously.  Similarly, the
user-constrained #Resources definition unifies with all component kinds.

It's OK to leave the yaml.Marshall in the schema API.  The user
shouldn't ever have to deal with #APIObjects, instead they should pass
Resources through the schema API which will use APIObjects to create
apiObjectMap for each component type and the BuildPlan.

This is still more awkward than I want, but it's a good step in the
right direction.
2024-09-13 16:43:12 -07:00
Jeff McCune
836033e16a docs: move istio-gateway to a separate schematic
Without this patch the istio-gateway component isn't functional, the
HTTPRoute created for httpbin isn't programmed correctly.  There is no
Gateway resource, just a deployment created by the istio helm chart.

This patch replaces the helm chart with a Gateway resource as was done
previously in the k3d platform schematic.

This patch also simplifies the certificate management to issue a single
cert valid for the platform domain and a wildcard.  We intentionally
avoid building a dynamic Gateway.spec.listeners structure to keep the
expose a service guide relatively simple and focused on getting started
with Holos.
2024-09-13 11:13:18 -07:00
Jeff McCune
77279d9baf docs: add httpbin routes section to expose a service guide
This patch adds the httpbin routes component.  It's missing the
Certificate component, the next step is to wire up automatic certificate
management in the gateway configuration, which is a prime use case for
holos.  Similar to how we register components and namespaces, we'll
register certificates.

This patch also adds the #Platform.Domain field to the user facing
schema API.  We previously stored the domain in the Model but it makes
sense to lift it up to the Platform and have a sensible default value
for it.

Another example of #237 needing to be addressed soon.
2024-09-12 17:35:06 -07:00
Jeff McCune
bf19aee1a7 docs: add httpbin workload section to expose a service
This patch manages the httpbin Deployment, Service, and ReferenceGrant.
The remaining final step is to expose the service with an HTTPRoute and
Certificate.

We again needed to add a field to the schema APIObjects to get this to
work.  We need to fix #237 soon.  We'll need to do it again for the
HTTPRoute and Certificate resources.
2024-09-12 16:55:09 -07:00
Jeff McCune
4de88b3155 docs: insert cert-manager after namespaces in expose a service
The progression of namespaces, cert-manager, then gateway api and istio
makes much more sense than the previous progression of gateway api,
namespaces, istio.

cert-manager builds nicely on top of namespaces.  gateway api are only
crds necessary for istio.

This patch also adds the local-ca component which surfaces issue #237
The Kubernetes APIObjects are unnecessarily constrained to resources we
define in the schema.  We need to move the marshal code into package
holos so the user can add their own resource kinds.
2024-09-12 15:20:08 -07:00
Jeff McCune
6f39cc6fdc docs: add istio section to expose-a-service
This patch adds Istio to the Expose a Service documentation and
introduces new concepts.  The Kubernetes build plan schema, the
namespaces component, and an example of how to safely re-use Helm values
from the root to multiple leaf components.

fix: istio cni not ready on k3d
---

The istio-k3d component embedded into holos fixes the cni pod not
becoming ready with our k3d local cluster guide.  The pod log error this
fixes is:

    configuration requires updates, (re)writing CNI config file at "": no networks found in /host/etc/cni/net.d
    Istio CNI is configured as chained plugin, but cannot find existing CNI network config: no networks found in /host/etc/cni/net.d
    Waiting for CNI network config file to be written in /host/etc/cni/net.d...

[Platform k3d]: https://istio.io/latest/docs/ambient/install/platform-prerequisites/#k3d

docs: clarify how to reset the local cluster
---

This is something we do all the time while developing and documenting,
so make it easy and fast to reset the cluster to a known good state.
2024-09-12 10:36:56 -07:00
Jeff McCune
e410563f82 docs: add namespaces to expose a service guide
This patch adds the schema api for the Kubernetes build plan, which
produces plain API resources directly from CUE.  It's needed for the
namespaces component which is foundational to many of our guides.

The first guide that needs this is the expose a service guide, we need
to register the namespaces from the istio component.
2024-09-11 17:22:01 -07:00
Jeff McCune
0a53bef72a docs: apply the gateway-api in the expose a service doc
This patch completes the first draft of the Gateway API section.
2024-09-11 14:31:02 -07:00
Jeff McCune
02a450e597 api: clarify Name field of Helm and Kustomize schema 2024-09-11 14:09:13 -07:00
Jeff McCune
e1222cf367 docs: add the gateway-api to the expose-a-service doc
The Expose a Service doc is meant to be the second step after the
Quickstart doc.  This commit adds the section describing how to install
the Gateway API.

The Kustomize build plan is introduced at this point in a similar way
the Helm build plan was introduced in the quickstart.
2024-09-11 14:03:40 -07:00
Jeff McCune
740a3d21a1 generate: add schematic for a workload-cluster
We need an easy way to help people add a workload cluster to their
workload fleet when working through the guides.  Generated platforms
should not define any clusters so they can be reused with multiple
guides.

This patch adds a simple component schematic that drops a root cue file
to define a workload cluster named workload.

The result is the following sequence renders the Gateway API when run
from an empty directory.

    holos generate platform guide
    holos generate component workload-cluster
    holos generate component gateway-api
    holos render platform ./platform

Without this patch nothing is rendered because there are no workload
clusters in the base guide platform.
2024-09-11 13:23:36 -07:00
Jeff McCune
1114b65a47 schema: remove management cluster from standard fleet
Having the management cluster hard coded into the definition of the
standard fleets is problematic for guides that don't need a management
cluster.

Define the fleets, but leave the set of clusters empty until they're
needed.
2024-09-11 13:12:44 -07:00
180 changed files with 23130 additions and 353 deletions

View File

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

View File

@@ -11,18 +11,29 @@ import (
//go:generate ../../../hack/gendoc
// Component represents the fields common the different kinds of component. All
// components have a name, support mixing in resources, and produce a BuildPlan.
type ComponentFields struct {
// Name represents the Component name.
Name string
// Resources are kubernetes api objects to mix into the output.
Resources map[string]any
// ArgoConfig represents the ArgoCD GitOps configuration for this Component.
ArgoConfig ArgoConfig
// BuildPlan represents the derived BuildPlan for the Holos cli to render.
BuildPlan core.BuildPlan
}
// Helm provides a BuildPlan via the Output field which contains one HelmChart
// from package core. Useful as a convenience wrapper to render a HelmChart
// with optional mix-in resources and Kustomization post-processing.
type Helm struct {
// Name represents the chart name.
Name string
ComponentFields `json:",inline"`
// 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 `cue:"{...}"`
// Repo represents the chart repository
Repo struct {
@@ -57,27 +68,23 @@ type Helm struct {
// 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
// Kustomize provides a BuildPlan via the Output field which contains one
// KustomizeBuild from package core.
type Kustomize struct {
ComponentFields `json:",inline"`
// Kustomization represents the kustomize build plan for holos to render.
Kustomization core.KustomizeBuild
}
// Kubernetes provides a BuildPlan via the Output field which contains inline
// API Objects provided directly from CUE.
type Kubernetes struct {
ComponentFields `json:",inline"`
// Objects represents the kubernetes api objects for the Component.
Objects core.KubernetesObjects
}
// ArgoConfig represents the ArgoCD GitOps configuration for a Component.
// Useful to define once at the root of the Platform configuration and reuse
@@ -99,6 +106,8 @@ type ArgoConfig struct {
// Application.spec.source.targetRevision field. Defaults to the branch named
// main.
TargetRevision string `cue:"string | *\"main\""`
// AppProject represents the ArgoCD Project to associate the Application with.
AppProject string `cue:"string | *\"default\""`
}
// Cluster represents a cluster managed by the Platform.
@@ -129,7 +138,7 @@ 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\", clusters: management: _}"`
Management Fleet `json:"management" cue:"{name: \"management\"}"`
}
// Platform is a convenience structure to produce a core Platform specification
@@ -147,4 +156,8 @@ type Platform 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
// Domain represents the primary domain the Platform operates in. This field
// is intended as a sensible default for component authors to reference and
// platform operators to define.
Domain string `cue:"string | *\"holos.localhost\""`
}

View File

@@ -12,8 +12,11 @@ Package v1alpha3 contains CUE definitions intended as convenience wrappers aroun
- [type ArgoConfig](<#ArgoConfig>)
- [type Cluster](<#Cluster>)
- [type ComponentFields](<#ComponentFields>)
- [type Fleet](<#Fleet>)
- [type Helm](<#Helm>)
- [type Kubernetes](<#Kubernetes>)
- [type Kustomize](<#Kustomize>)
- [type Platform](<#Platform>)
- [type StandardFleets](<#StandardFleets>)
@@ -41,6 +44,8 @@ type ArgoConfig struct {
// Application.spec.source.targetRevision field. Defaults to the branch named
// main.
TargetRevision string `cue:"string | *\"main\""`
// AppProject represents the ArgoCD Project to associate the Application with.
AppProject string `cue:"string | *\"default\""`
}
```
@@ -60,6 +65,24 @@ type Cluster struct {
}
```
<a name="ComponentFields"></a>
## type ComponentFields {#ComponentFields}
Component represents the fields common the different kinds of component. All components have a name, support mixing in resources, and produce a BuildPlan.
```go
type ComponentFields struct {
// Name represents the Component name.
Name string
// Resources are kubernetes api objects to mix into the output.
Resources map[string]any
// ArgoConfig represents the ArgoCD GitOps configuration for this Component.
ArgoConfig ArgoConfig
// BuildPlan represents the derived BuildPlan for the Holos cli to render.
BuildPlan core.BuildPlan
}
```
<a name="Fleet"></a>
## type Fleet {#Fleet}
@@ -80,14 +103,12 @@ Helm provides a BuildPlan via the Output field which contains one HelmChart from
```go
type Helm struct {
// Name represents the chart name.
Name string
ComponentFields `json:",inline"`
// 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 `cue:"{...}"`
// Repo represents the chart repository
Repo struct {
@@ -122,12 +143,32 @@ type Helm struct {
// 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
<a name="Kubernetes"></a>
## type Kubernetes {#Kubernetes}
// 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.
```go
type Kubernetes struct {
ComponentFields `json:",inline"`
// Objects represents the kubernetes api objects for the Component.
Objects core.KubernetesObjects
}
```
<a name="Kustomize"></a>
## type Kustomize {#Kustomize}
Kustomize provides a BuildPlan via the Output field which contains one KustomizeBuild from package core.
```go
type Kustomize struct {
ComponentFields `json:",inline"`
// Kustomization represents the kustomize build plan for holos to render.
Kustomization core.KustomizeBuild
}
```
@@ -148,6 +189,10 @@ type Platform 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
// Domain represents the primary domain the Platform operates in. This field
// is intended as a sensible default for component authors to reference and
// platform operators to define.
Domain string `cue:"string | *\"holos.localhost\""`
}
```
@@ -161,7 +206,7 @@ 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\", clusters: management: _}"`
Management Fleet `json:"management" cue:"{name: \"management\"}"`
}
```

File diff suppressed because it is too large Load Diff

View File

@@ -1,95 +0,0 @@
---
description: Use Holos to expose a Service with the Gateway API.
slug: /guides/expose-a-service
sidebar_position: 300
---
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.
:::warning TODO
Complete this section once the steps are complete.
:::
The [Concepts](/docs/concepts) page defines capitalized terms such as Platform
and Component.
## What you'll need {#requirements}
:::warning TODO
Complete this section once the steps are complete.
:::
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 [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
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 used as the basis for our guides.
```bash
holos generate platform guide
```
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
[main (root-commit) 0b17b7f] holos generate platform guide - 0.93.3
213 files changed, 72349 insertions(+)
...
```
</TabItem>
</Tabs>
## Manage httpbin {#manage-httpbin}
The platform you generated is currently empty. Run the following command to
generate a Holos Component for the
[httpbin](https://github.com/mccutchen/go-httpbin) service.
httpbin is a simple backend service useful for end-to-end testing. In this
guide, we use httpbin as a example of a service your organization develops and
deploy onto your Platform.

View File

@@ -1,7 +1,7 @@
---
description: Build a local Cluster to use with these guides.
slug: /guides/local-cluster
sidebar_position: 200
sidebar_position: 300
---
import Tabs from '@theme/Tabs';
@@ -10,15 +10,97 @@ import Admonition from '@theme/Admonition';
# Local Cluster
In this guide you'll set up a Cluster on your local host 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.
In this guide we'll set up a local k3d cluster to apply and explore the
configuration described in our other guides. After completing this guide you'll
have a standard Kubernetes API server with proper DNS and TLS certificates.
You'll be able to easily reset the cluster to a known good state to iterate on
your own Platform.
The [Concepts](/docs/concepts) page defines capitalized terms such as Platform
and Component.
## Reset the Cluster
If you've already followed this guide, reset the cluster by running the
following commands. Skip this section if you're creating a cluster for the
first time.
First, delete the cluster.
<Tabs groupId="k3d-cluster-delete">
<TabItem value="command" label="Command">
```bash
k3d cluster delete workload
```
</TabItem>
<TabItem value="output" label="Output">
```txt showLineNumbers
INFO[0000] Deleting cluster 'workload'
INFO[0000] Deleting cluster network 'k3d-workload'
INFO[0000] Deleting 1 attached volumes...
INFO[0000] Removing cluster details from default kubeconfig...
INFO[0000] Removing standalone kubeconfig file (if there is one)...
INFO[0000] Successfully deleted cluster workload!
```
</TabItem>
</Tabs>
Then create the cluster again.
<Tabs groupId="k3d-cluster-create">
<TabItem value="command" label="Command">
```bash
k3d cluster create workload \
--registry-use k3d-registry.holos.localhost:5100 \
--port "443:443@loadbalancer" \
--k3s-arg "--disable=traefik@server:0"
```
</TabItem>
<TabItem value="output" label="Output">
```txt showLineNumbers
INFO[0000] portmapping '443:443' targets the loadbalancer: defaulting to [servers:*:proxy agents:*:proxy]
INFO[0000] Prep: Network
INFO[0000] Created network 'k3d-workload'
INFO[0000] Created image volume k3d-workload-images
INFO[0000] Starting new tools node...
INFO[0000] Starting node 'k3d-workload-tools'
INFO[0001] Creating node 'k3d-workload-server-0'
INFO[0001] Creating LoadBalancer 'k3d-workload-serverlb'
INFO[0001] Using the k3d-tools node to gather environment information
INFO[0001] HostIP: using network gateway 172.17.0.1 address
INFO[0001] Starting cluster 'workload'
INFO[0001] Starting servers...
INFO[0001] Starting node 'k3d-workload-server-0'
INFO[0003] All agents already running.
INFO[0003] Starting helpers...
INFO[0003] Starting node 'k3d-workload-serverlb'
INFO[0009] Injecting records for hostAliases (incl. host.k3d.internal) and for 3 network members into CoreDNS configmap...
INFO[0012] Cluster 'workload' created successfully!
INFO[0012] You can now use it like this:
kubectl cluster-info
```
</TabItem>
</Tabs>
Finally, add your trusted certificate authority.
<Tabs groupId="apply-local-ca">
<TabItem value="command" label="Command">
```bash
kubectl apply --server-side=true -f "$(mkcert -CAROOT)/namespace.yaml"
kubectl apply --server-side=true -n cert-manager -f "$(mkcert -CAROOT)/local-ca.yaml"
```
</TabItem>
<TabItem value="output" label="Output">
```txt showLineNumbers
namespace/cert-manager serverside-applied
secret/local-ca serverside-applied
```
</TabItem>
</Tabs>
You're back to the same state as the first time you completed this guide.
## What you'll need {#requirements}
You'll need the following tools installed to complete this guide.
@@ -150,10 +232,11 @@ 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 ..
echo 'type: kubernetes.io/tls' >> local-ca.yaml
kubectl apply --server-side=true -f- <<EOF
cat <<EOF > namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
@@ -164,8 +247,12 @@ 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
@@ -184,12 +271,6 @@ with:
k3d cluster delete workload
```
## Reset {#reset}
If you'd like to reset to a known good state, execute the [Clean Up](#clean-up)
section, then [Create the Cluster](#create-the-cluster) and the [Setup Root
CA](#setup-root-ca) tasks.
## Next Steps
Now that you have a real cluster, apply and explore the manifests Holos renders

View File

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

View File

@@ -263,7 +263,7 @@ following contents:
#ArgoConfig: {
Enabled: true
RepoURL: "https://example.com/holos-quickstart.git"
RepoURL: "https://github.com/holos-run/holos-quickstart-guide"
}
```
</TabItem>

View File

@@ -5,10 +5,10 @@
*/
/* Enable wrapping by default for mobile */
pre code {
/* pre code {
white-space: pre-wrap;
overflow-wrap: anywhere;
}
} */
/* You can override the default Infima variables here. */
:root {

View File

@@ -1,4 +1,4 @@
package holos
// Produce a kubectl kustomize build plan.
(#Kustomize & {Name: "{{ .Name }}"}).Output
(#Kustomize & {Name: "{{ .Name }}"}).BuildPlan

View File

@@ -18,4 +18,4 @@ let Objects = {
}
// Produce a kubernetes objects build plan.
(#Kubernetes & Objects).Output
(#Kubernetes & Objects).BuildPlan

View File

@@ -8,4 +8,4 @@ let Objects = {
}
// Produce a kubernetes objects build plan.
(#Kubernetes & Objects).Output
(#Kubernetes & Objects).BuildPlan

View File

@@ -17,4 +17,4 @@ let Chart = {
}
// Produce a helm chart build plan.
(#Helm & Chart).Output
(#Helm & Chart).BuildPlan

View File

@@ -12,4 +12,4 @@ let Chart = {
}
// Produce a helm chart build plan.
(#Helm & Chart).Output
(#Helm & Chart).BuildPlan

View File

@@ -0,0 +1,11 @@
package holos
// Manage the Component on every Cluster in the Platform
for Fleet in #Fleets {
for Cluster in Fleet.clusters {
#Platform: Components: "\(Cluster.name)/app-projects": {
path: "projects/platform/components/app-projects"
cluster: Cluster.name
}
}
}

View File

@@ -0,0 +1,17 @@
package holos
import ap "argoproj.io/appproject/v1alpha1"
// Registration point for AppProjects
#AppProjects: [Name=string]: ap.#AppProject & {
metadata: name: Name
metadata: namespace: #ArgoCD.Namespace
spec: description: string | *"Holos managed AppProject"
spec: clusterResourceWhitelist: [{group: "*", kind: "*"}]
spec: destinations: [{namespace: "*", server: "*"}]
spec: sourceRepos: ["*"]
}
// Define at least the platform project. Other components can register projects
// the same way from the root of the configuration.
#AppProjects: platform: _

View File

@@ -0,0 +1,9 @@
package holos
let Objects = {
Name: "app-projects"
Resources: AppProject: #AppProjects
}
// Produce a kubernetes objects build plan.
(#Kubernetes & Objects).BuildPlan

View File

@@ -0,0 +1,5 @@
{
"name": "app-projects",
"short": "#AppProjects registration point",
"long": "Manage ArgoCD AppProject resources centrally."
}

View File

@@ -0,0 +1,6 @@
package holos
#ArgoConfig: {
Enabled: true
RepoURL: "https://github.com/holos-run/holos-manage-a-project-guide"
}

View File

@@ -0,0 +1,3 @@
package holos
#ArgoConfig: AppProject: #AppProjects.platform.metadata.name

View File

@@ -0,0 +1,5 @@
{
"name": "argocd-config-manage-a-project-guide",
"short": "generate applications for the manage-a-project guide",
"long": "https://github.com/holos-run/holos-manage-a-project-guide"
}

View File

@@ -0,0 +1,15 @@
package holos
// Manage the Component on every Cluster in the Platform
for Fleet in #Fleets {
for Cluster in Fleet.clusters {
#Platform: Components: "\(Cluster.name)/argocd-crds": {
path: "projects/platform/components/argocd/crds"
cluster: Cluster.name
}
#Platform: Components: "\(Cluster.name)/argocd": {
path: "projects/platform/components/argocd/argocd"
cluster: Cluster.name
}
}
}

View File

@@ -0,0 +1,13 @@
package holos
// #ArgoCD represents platform wide configuration
#ArgoCD: {
Version: "2.12.3"
Namespace: "argocd"
}
// Register namespaces
#Namespaces: (#ArgoCD.Namespace): _
// Register the HTTPRoute to the backend Service
#HTTPRoutes: argocd: _backendRefs: "argocd-server": namespace: #ArgoCD.Namespace

View File

@@ -0,0 +1,60 @@
package holos
import "strings"
// Produce a helm chart build plan.
(#Helm & Chart).BuildPlan
let Chart = {
Name: "argocd"
Namespace: #ArgoCD.Namespace
Version: "7.5.2"
Repo: name: "argocd"
Repo: url: "https://argoproj.github.io/argo-helm"
Chart: chart: name: "argo-cd"
Chart: chart: release: Name
// Upstream uses a Kubernetes Job to create the argocd-redis Secret. Enable
// hooks to enable the Job.
Chart: enableHooks: true
Resources: [_]: [_]: metadata: namespace: Namespace
// Grant the Gateway namespace the ability to refer to the backend service
// from HTTPRoute resources.
Resources: ReferenceGrant: (#Istio.Gateway.Namespace): #ReferenceGrant
EnableKustomizePostProcessor: true
// Force all resources into the component namespace, some resources in the
// helm chart may not specify the namespace so they may get mis-applied
// depending on the kubectl (client-go) context.
KustomizeFiles: "kustomization.yaml": namespace: Namespace
Values: #Values & {
kubeVersionOverride: "1.29.0"
// handled in the argo-crds component
crds: install: false
// Configure the same fqdn the HTTPRoute is configured with.
global: domain: #HTTPRoutes.argocd.spec.hostnames[0]
dex: enabled: false
// the platform handles mutual tls to the backend
configs: params: "server.insecure": true
configs: cm: {
"admin.enabled": false
"oidc.config": "{}"
"users.anonymous.enabled": "true"
}
// Refer to https://argo-cd.readthedocs.io/en/stable/operator-manual/rbac/
let Policy = [
"g, argocd-view, role:readonly",
"g, prod-cluster-view, role:readonly",
"g, prod-cluster-edit, role:readonly",
"g, prod-cluster-admin, role:admin",
]
configs: rbac: "policy.csv": strings.Join(Policy, "\n")
configs: rbac: "policy.default": "role:admin"
}
}

View File

@@ -0,0 +1,37 @@
package holos
import (
"encoding/yaml"
ks "sigs.k8s.io/kustomize/api/types"
)
(#Kubernetes & {Name: "argocd-crds"}).BuildPlan
// Holos stages BuildPlan resources as an intermediate step of the rendering
// pipeline. The purpose is to provide the resources to kustomize for
// post-processing.
let BuildPlanResources = "build-plan-resources.yaml"
let Kustomization = ks.#Kustomization & {
apiVersion: "kustomize.config.k8s.io/v1beta1"
kind: "Kustomization"
resources: [
// Kustomize the intermediate build plan resources.
BuildPlanResources,
// Mix-in external resources.
"https://raw.githubusercontent.com/argoproj/argo-cd/v\(#ArgoCD.Version)/manifests/crds/application-crd.yaml",
"https://raw.githubusercontent.com/argoproj/argo-cd/v\(#ArgoCD.Version)/manifests/crds/applicationset-crd.yaml",
"https://raw.githubusercontent.com/argoproj/argo-cd/v\(#ArgoCD.Version)/manifests/crds/appproject-crd.yaml",
// This method also works, but takes about 5 seconds longer each build.
// "https://github.com/argoproj/argo-cd//manifests/crds/?ref=v\(#ArgoCD.Version)",
]
}
// Generate a kustomization.yaml directly from CUE so we can provide the correct
// version.
spec: components: kubernetesObjectsList: [{
// intermediate build plan resources to kustomize. Necessary to activate the
// kustomization post-rendering step in holos.
kustomize: resourcesFile: BuildPlanResources
kustomize: kustomizeFiles: "kustomization.yaml": yaml.Marshal(Kustomization)
}]

View File

@@ -0,0 +1,5 @@
{
"name": "argocd",
"short": "declaritive gitops for kubernetes",
"long": "Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes."
}

View File

@@ -0,0 +1,51 @@
package holos
// Manage on workload clusters only
for Cluster in #Fleets.workload.clusters {
// Owned by the security team
#Platform: Components: "\(Cluster.name)/bank-secrets": {
path: "projects/bank-of-holos/security/components/bank-secrets"
cluster: Cluster.name
}
// Owned by the frontend team
#Platform: Components: "\(Cluster.name)/bank-frontend": {
path: "projects/bank-of-holos/frontend/components/bank-frontend"
cluster: Cluster.name
}
// Owned by the backend team
#Platform: Components: "\(Cluster.name)/bank-backend-config": {
path: "projects/bank-of-holos/backend/components/bank-backend-config"
cluster: Cluster.name
}
#Platform: Components: "\(Cluster.name)/bank-accounts-db": {
path: "projects/bank-of-holos/backend/components/bank-accounts-db"
cluster: Cluster.name
}
#Platform: Components: "\(Cluster.name)/bank-userservice": {
path: "projects/bank-of-holos/backend/components/bank-userservice"
cluster: Cluster.name
}
#Platform: Components: "\(Cluster.name)/bank-ledger-db": {
path: "projects/bank-of-holos/backend/components/bank-ledger-db"
cluster: Cluster.name
}
#Platform: Components: "\(Cluster.name)/bank-ledger-writer": {
path: "projects/bank-of-holos/backend/components/bank-ledger-writer"
cluster: Cluster.name
}
#Platform: Components: "\(Cluster.name)/bank-balance-reader": {
path: "projects/bank-of-holos/backend/components/bank-balance-reader"
cluster: Cluster.name
}
#Platform: Components: "\(Cluster.name)/bank-transaction-history": {
path: "projects/bank-of-holos/backend/components/bank-transaction-history"
cluster: Cluster.name
}
#Platform: Components: "\(Cluster.name)/bank-contacts": {
path: "projects/bank-of-holos/backend/components/bank-contacts"
cluster: Cluster.name
}
}

View File

@@ -0,0 +1,26 @@
package holos
// Platform wide definitions
#BankOfHolos: {
Name: "bank-of-holos"
Frontend: Namespace: "bank-frontend"
Backend: Namespace: "bank-backend"
Security: Namespace: "bank-security"
// Resources to manage in each of the namespaces.
Resources: #Resources
}
// Register namespaces
#Namespaces: (#BankOfHolos.Frontend.Namespace): _
#Namespaces: (#BankOfHolos.Backend.Namespace): _
#Namespaces: (#BankOfHolos.Security.Namespace): _
// Register projects
#AppProjects: "bank-frontend": _
#AppProjects: "bank-backend": _
#AppProjects: "bank-security": _
// Register HTTPRoutes.
// bank.example.com routes to Service frontend in the bank-frontend namespace.
#HTTPRoutes: bank: _backendRefs: frontend: namespace: #BankOfHolos.Frontend.Namespace

View File

@@ -0,0 +1,3 @@
package holos
#ArgoConfig: AppProject: #AppProjects["bank-backend"].metadata.name

View File

@@ -0,0 +1,122 @@
package holos
// Produce a kubernetes objects build plan.
(#Kubernetes & Objects).BuildPlan
let BankName = #BankOfHolos.Name
let CommonLabels = {
application: BankName
environment: "development"
team: "accounts"
tier: "db"
}
let Objects = {
Name: "bank-accounts-db"
Namespace: #BankOfHolos.Backend.Namespace
// Ensure resources go in the correct namespace
Resources: [_]: [_]: metadata: namespace: Namespace
// https://github.com/GoogleCloudPlatform/bank-of-anthos/blob/release/v0.6.5/kubernetes-manifests/accounts-db.yaml
Resources: {
ConfigMap: "accounts-db-config": {
apiVersion: "v1"
data: {
ACCOUNTS_DB_URI: "postgresql://accounts-admin:accounts-pwd@accounts-db:5432/accounts-db"
POSTGRES_DB: "accounts-db"
POSTGRES_PASSWORD: "accounts-pwd"
POSTGRES_USER: "accounts-admin"
}
kind: "ConfigMap"
metadata: {
labels: {
app: "accounts-db"
CommonLabels
}
name: "accounts-db-config"
}
}
Service: "accounts-db": {
apiVersion: "v1"
kind: "Service"
metadata: {
name: "accounts-db"
labels: CommonLabels
}
spec: {
ports: [{
name: "tcp"
port: 5432
protocol: "TCP"
targetPort: 5432
}]
selector: {
app: "accounts-db"
CommonLabels
}
type: "ClusterIP"
}
}
StatefulSet: "accounts-db": {
apiVersion: "apps/v1"
kind: "StatefulSet"
metadata: {
name: "accounts-db"
labels: CommonLabels
}
spec: {
replicas: 1
selector: matchLabels: {
app: "accounts-db"
CommonLabels
}
serviceName: "accounts-db"
template: {
metadata: labels: {
app: "accounts-db"
CommonLabels
}
spec: {
containers: [{
envFrom: [{
configMapRef: name: "environment-config"
}, {
configMapRef: name: "accounts-db-config"
}, {
configMapRef: name: "demo-data-config"
}]
image: "us-central1-docker.pkg.dev/bank-of-anthos-ci/bank-of-anthos/accounts-db:v0.6.5@sha256:abb955756a82b115e0fd9c5fa1527ae1a744b398b357fd6d7a26348feccad181"
name: "accounts-db"
ports: [{containerPort: 5432}]
resources: {
limits: {
cpu: "250m"
memory: "512Mi"
}
requests: {
cpu: "100m"
memory: "128Mi"
}
}
volumeMounts: [{
mountPath: "/var/lib/postgresql/data"
name: "postgresdb"
subPath: "postgres"
}]
}]
serviceAccount: BankName
serviceAccountName: BankName
volumes: [{
emptyDir: {}
name: "postgresdb"
}]
}
}
}
}
}
}

View File

@@ -0,0 +1,33 @@
package holos
// Produce a kubernetes objects build plan.
(#Kubernetes & Objects).BuildPlan
let BankName = #BankOfHolos.Name
let CommonLabels = {
application: BankName
environment: "development"
tier: "backend"
}
let Objects = {
Name: "bank-backend-config"
Namespace: #BankOfHolos.Backend.Namespace
// Ensure resources go in the correct namespace
Resources: [_]: [_]: metadata: namespace: Namespace
Resources: [_]: [_]: metadata: labels: CommonLabels
// https://github.com/GoogleCloudPlatform/bank-of-anthos/blob/release/v0.6.5/kubernetes-manifests/userservice.yaml
Resources: {
// Allow HTTPRoutes in the ingress gateway namespace to reference Services
// in this namespace.
ReferenceGrant: grant: #ReferenceGrant & {
metadata: namespace: Namespace
}
// Include shared resources
#BankOfHolos.Resources
}
}

View File

@@ -0,0 +1,179 @@
package holos
// Produce a kubernetes objects build plan.
(#Kubernetes & Objects).BuildPlan
let BankName = #BankOfHolos.Name
let CommonLabels = {
application: BankName
environment: "development"
team: "ledger"
tier: "backend"
}
let Objects = {
Name: "bank-balance-reader"
Namespace: #BankOfHolos.Backend.Namespace
// Ensure resources go in the correct namespace
Resources: [_]: [_]: metadata: namespace: Namespace
Resources: [_]: [_]: metadata: labels: CommonLabels
// https://github.com/GoogleCloudPlatform/bank-of-anthos/blob/release/v0.6.5/kubernetes-manifests
Resources: {
Service: balancereader: {
apiVersion: "v1"
kind: "Service"
metadata: {
name: "balancereader"
labels: CommonLabels
}
spec: {
ports: [{
name: "http"
port: 8080
targetPort: 8080
}]
selector: {
app: "balancereader"
CommonLabels
}
type: "ClusterIP"
}
}
Deployment: balancereader: {
apiVersion: "apps/v1"
kind: "Deployment"
metadata: {
name: "balancereader"
labels: CommonLabels
}
spec: {
selector: matchLabels: {
app: "balancereader"
CommonLabels
}
template: {
metadata: labels: {
app: "balancereader"
CommonLabels
}
spec: {
containers: [{
env: [{
name: "VERSION"
value: "v0.6.5"
}, {
name: "PORT"
value: "8080"
}, {
name: "ENABLE_TRACING"
value: "false"
}, {
name: "ENABLE_METRICS"
value: "false"
}, {
name: "POLL_MS"
value: "100"
}, {
name: "CACHE_SIZE"
value: "1000000"
}, {
name: "JVM_OPTS"
value: "-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -Xms256m -Xmx512m"
}, {
name: "LOG_LEVEL"
value: "info"
}, {
name: "NAMESPACE"
valueFrom: fieldRef: fieldPath: "metadata.namespace"
}]
envFrom: [{
configMapRef: name: "environment-config"
}, {
configMapRef: name: "ledger-db-config"
}]
image: "us-central1-docker.pkg.dev/bank-of-anthos-ci/bank-of-anthos/balancereader:v0.6.5@sha256:de01f16554ae2d0b49ac85116e6307da8c0f8a35f50a0cf25e1e4a4fe18dca83"
livenessProbe: {
httpGet: {
path: "/healthy"
port: 8080
}
initialDelaySeconds: 120
periodSeconds: 5
timeoutSeconds: 10
}
name: "balancereader"
readinessProbe: {
httpGet: {
path: "/ready"
port: 8080
}
initialDelaySeconds: 60
periodSeconds: 5
timeoutSeconds: 10
}
resources: {
limits: {
cpu: "500m"
"ephemeral-storage": "0.5Gi"
memory: "512Mi"
}
requests: {
cpu: "100m"
"ephemeral-storage": "0.5Gi"
memory: "256Mi"
}
}
securityContext: {
allowPrivilegeEscalation: false
capabilities: drop: ["all"]
privileged: false
readOnlyRootFilesystem: true
}
startupProbe: {
failureThreshold: 30
httpGet: {
path: "/healthy"
port: 8080
}
periodSeconds: 10
}
volumeMounts: [{
mountPath: "/tmp"
name: "tmp"
}, {
mountPath: "/tmp/.ssh"
name: "publickey"
readOnly: true
}]
}]
securityContext: {
fsGroup: 1000
runAsGroup: 1000
runAsNonRoot: true
runAsUser: 1000
}
serviceAccountName: BankName
terminationGracePeriodSeconds: 5
volumes: [{
emptyDir: {}
name: "tmp"
}, {
name: "publickey"
secret: {
items: [{
key: "jwtRS256.key.pub"
path: "publickey"
}]
secretName: "jwt-key"
}
}]
}
}
}
}
}
}

View File

@@ -0,0 +1,143 @@
package holos
// Produce a kubernetes objects build plan.
(#Kubernetes & Objects).BuildPlan
let BankName = #BankOfHolos.Name
let CommonLabels = {
application: BankName
environment: "development"
team: "accounts"
tier: "backend"
}
let Objects = {
Name: "bank-contacts"
Namespace: #BankOfHolos.Backend.Namespace
// Ensure resources go in the correct namespace
Resources: [_]: [_]: metadata: namespace: Namespace
Resources: [_]: [_]: metadata: labels: CommonLabels
// https://github.com/GoogleCloudPlatform/bank-of-anthos/blob/release/v0.6.5/kubernetes-manifests
Resources: {
Service: contacts: {
apiVersion: "v1"
kind: "Service"
metadata: name: "contacts"
spec: {
ports: [{
name: "http"
port: 8080
targetPort: 8080
}]
selector: {
app: "contacts"
CommonLabels
}
type: "ClusterIP"
}
}
Deployment: contacts: {
apiVersion: "apps/v1"
kind: "Deployment"
metadata: name: "contacts"
spec: {
selector: matchLabels: {
app: "contacts"
CommonLabels
}
template: {
metadata: {
labels: {
app: "contacts"
CommonLabels
}
}
spec: {
containers: [{
env: [{
name: "VERSION"
value: "v0.6.5"
}, {
name: "PORT"
value: "8080"
}, {
name: "ENABLE_TRACING"
value: "false"
}, {
name: "LOG_LEVEL"
value: "info"
}]
envFrom: [{
configMapRef: name: "environment-config"
}, {
configMapRef: name: "accounts-db-config"
}]
image: "us-central1-docker.pkg.dev/bank-of-anthos-ci/bank-of-anthos/contacts:v0.6.5@sha256:e451dcac7d34a7bde979c7f02d4c7ebd83a77aff373e1131ce3a2bba2f7fdc1a"
name: "contacts"
readinessProbe: {
httpGet: {
path: "/ready"
port: 8080
}
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 10
}
resources: {
limits: {
cpu: "250m"
"ephemeral-storage": "0.25Gi"
memory: "128Mi"
}
requests: {
cpu: "100m"
"ephemeral-storage": "0.25Gi"
memory: "64Mi"
}
}
securityContext: {
allowPrivilegeEscalation: false
capabilities: drop: ["all"]
privileged: false
readOnlyRootFilesystem: true
}
volumeMounts: [{
mountPath: "/tmp"
name: "tmp"
}, {
mountPath: "/tmp/.ssh"
name: "publickey"
readOnly: true
}]
}]
securityContext: {
fsGroup: 1000
runAsGroup: 1000
runAsNonRoot: true
runAsUser: 1000
}
serviceAccountName: BankName
terminationGracePeriodSeconds: 5
volumes: [{
emptyDir: {}
name: "tmp"
}, {
name: "publickey"
secret: {
items: [{
key: "jwtRS256.key.pub"
path: "publickey"
}]
secretName: "jwt-key"
}
}]
}
}
}
}
}
}

View File

@@ -0,0 +1,121 @@
package holos
// Produce a kubernetes objects build plan.
(#Kubernetes & Objects).BuildPlan
let BankName = #BankOfHolos.Name
let CommonLabels = {
application: BankName
environment: "development"
team: "ledger"
tier: "db"
}
let Objects = {
Name: "bank-ledger-db"
Namespace: #BankOfHolos.Backend.Namespace
// Ensure resources go in the correct namespace
Resources: [_]: [_]: metadata: namespace: Namespace
// https://github.com/GoogleCloudPlatform/bank-of-anthos/blob/release/v0.6.5/kubernetes-manifests
Resources: {
ConfigMap: "ledger-db-config": {
apiVersion: "v1"
metadata: {
name: "ledger-db-config"
labels: {
app: "ledger-db"
CommonLabels
}
}
data: {
POSTGRES_DB: "postgresdb"
POSTGRES_PASSWORD: "password"
POSTGRES_USER: "admin"
SPRING_DATASOURCE_PASSWORD: "password"
SPRING_DATASOURCE_URL: "jdbc:postgresql://ledger-db:5432/postgresdb"
SPRING_DATASOURCE_USERNAME: "admin"
}
}
Service: "ledger-db": {
apiVersion: "v1"
kind: "Service"
metadata: {
name: "ledger-db"
labels: CommonLabels
}
spec: {
ports: [{
name: "tcp"
port: 5432
targetPort: 5432
}]
selector: {
app: "ledger-db"
CommonLabels
}
type: "ClusterIP"
}
}
StatefulSet: "ledger-db": {
apiVersion: "apps/v1"
kind: "StatefulSet"
metadata: {
name: "ledger-db"
labels: CommonLabels
}
spec: {
replicas: 1
selector: matchLabels: {
app: "ledger-db"
CommonLabels
}
serviceName: "ledger-db"
template: {
metadata: labels: {
app: "ledger-db"
CommonLabels
}
spec: {
containers: [{
envFrom: [{
configMapRef: name: "environment-config"
}, {
configMapRef: name: "ledger-db-config"
}, {
configMapRef: name: "demo-data-config"
}]
image: "us-central1-docker.pkg.dev/bank-of-anthos-ci/bank-of-anthos/ledger-db:v0.6.5@sha256:cc4fd25f301ab6d46b1312244d6931babc4c6cb66c5cb6d31d4a1adfa318a321"
name: "postgres"
ports: [{containerPort: 5432}]
resources: {
limits: {
cpu: "250m"
memory: "1Gi"
}
requests: {
cpu: "100m"
memory: "512Mi"
}
}
volumeMounts: [{
mountPath: "/var/lib/postgresql/data"
name: "postgresdb"
subPath: "postgres"
}]
}]
serviceAccountName: BankName
volumes: [{
emptyDir: {}
name: "postgresdb"
}]
}
}
}
}
}
}

View File

@@ -0,0 +1,169 @@
package holos
// Produce a kubernetes objects build plan.
(#Kubernetes & Objects).BuildPlan
let BankName = #BankOfHolos.Name
let CommonLabels = {
application: BankName
environment: "development"
team: "ledger"
tier: "backend"
}
let Objects = {
Name: "bank-ledger-writer"
Namespace: #BankOfHolos.Backend.Namespace
// Ensure resources go in the correct namespace
Resources: [_]: [_]: metadata: namespace: Namespace
Resources: [_]: [_]: metadata: labels: CommonLabels
// https://github.com/GoogleCloudPlatform/bank-of-anthos/blob/release/v0.6.5/kubernetes-manifests
Resources: {
Service: ledgerwriter: {
apiVersion: "v1"
kind: "Service"
metadata: {
name: "ledgerwriter"
labels: CommonLabels
}
spec: {
ports: [{
name: "http"
port: 8080
targetPort: 8080
}]
selector: {
app: "ledgerwriter"
CommonLabels
}
type: "ClusterIP"
}
}
Deployment: ledgerwriter: {
apiVersion: "apps/v1"
kind: "Deployment"
metadata: {
name: "ledgerwriter"
labels: CommonLabels
}
spec: {
selector: matchLabels: {
app: "ledgerwriter"
CommonLabels
}
template: {
metadata: {
labels: {
app: "ledgerwriter"
CommonLabels
}
}
spec: {
containers: [{
env: [{
name: "VERSION"
value: "v0.6.5"
}, {
name: "PORT"
value: "8080"
}, {
name: "ENABLE_TRACING"
value: "false"
}, {
name: "ENABLE_METRICS"
value: "false"
}, {
name: "JVM_OPTS"
value: "-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -Xms256m -Xmx512m"
}, {
name: "LOG_LEVEL"
value: "info"
}, {
name: "NAMESPACE"
valueFrom: fieldRef: fieldPath: "metadata.namespace"
}]
envFrom: [{
configMapRef: name: "environment-config"
}, {
configMapRef: name: "service-api-config"
}, {
configMapRef: name: "ledger-db-config"
}]
image: "us-central1-docker.pkg.dev/bank-of-anthos-ci/bank-of-anthos/ledgerwriter:v0.6.5@sha256:5b66d6888b87993c8ebe260fe33005c4e4bc2bdae4b5682874e1a078d37ff3b2"
name: "ledgerwriter"
readinessProbe: {
httpGet: {
path: "/ready"
port: 8080
}
initialDelaySeconds: 60
periodSeconds: 5
timeoutSeconds: 10
}
resources: {
limits: {
cpu: "500m"
"ephemeral-storage": "0.5Gi"
memory: "512Mi"
}
requests: {
cpu: "100m"
"ephemeral-storage": "0.5Gi"
memory: "256Mi"
}
}
securityContext: {
allowPrivilegeEscalation: false
capabilities: drop: ["all"]
privileged: false
readOnlyRootFilesystem: true
}
startupProbe: {
failureThreshold: 30
httpGet: {
path: "/ready"
port: 8080
}
periodSeconds: 10
}
volumeMounts: [{
mountPath: "/tmp"
name: "tmp"
}, {
mountPath: "/tmp/.ssh"
name: "publickey"
readOnly: true
}]
}]
securityContext: {
fsGroup: 1000
runAsGroup: 1000
runAsNonRoot: true
runAsUser: 1000
}
serviceAccountName: BankName
terminationGracePeriodSeconds: 5
volumes: [{
emptyDir: {}
name: "tmp"
}, {
name: "publickey"
secret: {
items: [{
key: "jwtRS256.key.pub"
path: "publickey"
}]
secretName: "jwt-key"
}
}]
}
}
}
}
}
}

View File

@@ -0,0 +1,187 @@
package holos
// Produce a kubernetes objects build plan.
(#Kubernetes & Objects).BuildPlan
let BankName = #BankOfHolos.Name
let CommonLabels = {
application: BankName
environment: "development"
team: "ledger"
tier: "backend"
}
let Objects = {
Name: "bank-transaction-history"
Namespace: #BankOfHolos.Backend.Namespace
// Ensure resources go in the correct namespace
Resources: [_]: [_]: metadata: namespace: Namespace
Resources: [_]: [_]: metadata: labels: CommonLabels
// https://github.com/GoogleCloudPlatform/bank-of-anthos/blob/release/v0.6.5/kubernetes-manifests
Resources: {
Service: transactionhistory: {
apiVersion: "v1"
kind: "Service"
metadata: {
labels: CommonLabels
name: "transactionhistory"
}
spec: {
ports: [{
name: "http"
port: 8080
targetPort: 8080
}]
selector: {
app: "transactionhistory"
CommonLabels
}
type: "ClusterIP"
}
}
Deployment: transactionhistory: {
apiVersion: "apps/v1"
kind: "Deployment"
metadata: {
name: "transactionhistory"
labels: CommonLabels
}
spec: {
selector: matchLabels: {
app: "transactionhistory"
CommonLabels
}
template: {
metadata: {
labels: {
app: "transactionhistory"
CommonLabels
}
}
spec: {
containers: [{
env: [{
name: "VERSION"
value: "v0.6.5"
}, {
name: "PORT"
value: "8080"
}, {
name: "ENABLE_TRACING"
value: "false"
}, {
name: "ENABLE_METRICS"
value: "false"
}, {
name: "POLL_MS"
value: "100"
}, {
name: "CACHE_SIZE"
value: "1000"
}, {
name: "CACHE_MINUTES"
value: "60"
}, {
name: "HISTORY_LIMIT"
value: "100"
}, {
name: "JVM_OPTS"
value: "-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -Xms256m -Xmx512m"
}, {
name: "LOG_LEVEL"
value: "info"
}, {
name: "NAMESPACE"
valueFrom: fieldRef: fieldPath: "metadata.namespace"
}]
envFrom: [{
configMapRef: name: "environment-config"
}, {
configMapRef: name: "ledger-db-config"
}]
image: "us-central1-docker.pkg.dev/bank-of-anthos-ci/bank-of-anthos/transactionhistory:v0.6.5@sha256:54a2b0866df44a50832e71b130f3e069fe8bbce71309fb6cf390b19f64d92c09"
livenessProbe: {
httpGet: {
path: "/healthy"
port: 8080
}
initialDelaySeconds: 120
periodSeconds: 5
timeoutSeconds: 10
}
name: "transactionhistory"
readinessProbe: {
httpGet: {
path: "/ready"
port: 8080
}
initialDelaySeconds: 60
periodSeconds: 5
timeoutSeconds: 10
}
resources: {
limits: {
cpu: "500m"
"ephemeral-storage": "0.5Gi"
memory: "512Mi"
}
requests: {
cpu: "100m"
"ephemeral-storage": "0.5Gi"
memory: "256Mi"
}
}
securityContext: {
allowPrivilegeEscalation: false
capabilities: drop: ["all"]
privileged: false
readOnlyRootFilesystem: true
}
startupProbe: {
failureThreshold: 30
httpGet: {
path: "/healthy"
port: 8080
}
periodSeconds: 10
}
volumeMounts: [{
mountPath: "/tmp"
name: "tmp"
}, {
mountPath: "/tmp/.ssh"
name: "publickey"
readOnly: true
}]
}]
securityContext: {
fsGroup: 1000
runAsGroup: 1000
runAsNonRoot: true
runAsUser: 1000
}
serviceAccountName: BankName
terminationGracePeriodSeconds: 5
volumes: [{
emptyDir: {}
name: "tmp"
}, {
name: "publickey"
secret: {
items: [{
key: "jwtRS256.key.pub"
path: "publickey"
}]
secretName: "jwt-key"
}
}]
}
}
}
}
}
}

View File

@@ -0,0 +1,156 @@
package holos
// Produce a kubernetes objects build plan.
(#Kubernetes & Objects).BuildPlan
let BankName = #BankOfHolos.Name
let CommonLabels = {
application: BankName
environment: "development"
team: "accounts"
tier: "backend"
}
let Objects = {
Name: "bank-userservice"
Namespace: #BankOfHolos.Backend.Namespace
// Ensure resources go in the correct namespace
Resources: [_]: [_]: metadata: namespace: Namespace
// https://github.com/GoogleCloudPlatform/bank-of-anthos/blob/release/v0.6.5/kubernetes-manifests/userservice.yaml
Resources: {
Service: userservice: {
metadata: name: "userservice"
metadata: labels: CommonLabels
spec: {
selector: {
app: "userservice"
CommonLabels
}
_ports: http: {
name: "http"
port: 8080
targetPort: 8080
protocol: "TCP"
}
ports: [for x in _ports {x}]
}
}
Deployment: userservice: {
metadata: name: "userservice"
metadata: labels: CommonLabels
spec: {
selector: matchLabels: {
app: "userservice"
CommonLabels
}
template: {
metadata: labels: {
app: "userservice"
CommonLabels
}
spec: {
serviceAccountName: BankName
terminationGracePeriodSeconds: 5
containers: [{
env: [{
name: "VERSION"
value: "v0.6.5"
}, {
name: "PORT"
value: "8080"
}, {
name: "ENABLE_TRACING"
value: "false"
}, {
name: "LOG_LEVEL"
value: "info"
}, {
name: "TOKEN_EXPIRY_SECONDS"
value: "3600"
}, {
name: "PRIV_KEY_PATH"
value: "/tmp/.ssh/privatekey"
}]
envFrom: [{
configMapRef: name: "environment-config"
}, {
configMapRef: name: "accounts-db-config"
}]
image: "us-central1-docker.pkg.dev/bank-of-anthos-ci/bank-of-anthos/userservice:v0.6.5@sha256:f91e0e5bd6cdb16f6b867b2e3e874b23dd01f11592de006776f1dfb136702941"
name: "userservice"
ports: [{
containerPort: 8080
name: "http-server"
}]
readinessProbe: {
httpGet: {
path: "/ready"
port: 8080
}
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 10
}
resources: {
limits: {
cpu: "500m"
"ephemeral-storage": "0.25Gi"
memory: "256Mi"
}
requests: {
cpu: "260m"
"ephemeral-storage": "0.25Gi"
memory: "128Mi"
}
}
securityContext: {
allowPrivilegeEscalation: false
capabilities: drop: ["all"]
privileged: false
readOnlyRootFilesystem: true
}
volumeMounts: [{
mountPath: "/tmp"
name: "tmp"
}, {
mountPath: "/tmp/.ssh"
name: "keys"
readOnly: true
}]
}]
volumes: [{
emptyDir: {}
name: "tmp"
}, {
name: "keys"
secret: {
secretName: "jwt-key"
items: [
{
key: "jwtRS256.key"
path: "privatekey"
},
{
key: "jwtRS256.key.pub"
path: "publickey"
},
]
}
}]
securityContext: {
seccompProfile: type: "RuntimeDefault"
fsGroup: 1000
runAsGroup: 1000
runAsNonRoot: true
runAsUser: 1000
}
}
}
}
}
}
}

View File

@@ -0,0 +1,88 @@
package holos
import (
core "k8s.io/api/core/v1"
es "external-secrets.io/externalsecret/v1beta1"
ss "external-secrets.io/secretstore/v1beta1"
)
let BankName = #BankOfHolos.Name
#BankOfHolos: {
// Resources to make available in each of the project namespaces.
Resources: {
ServiceAccount: (BankName): core.#ServiceAccount & {
apiVersion: "v1"
kind: "ServiceAccount"
metadata: name: BankName
}
// SecretStore to fetch secrets owned by the security team
SecretStore: (BankName): ss.#SecretStore & {
metadata: name: #BankOfHolos.Security.Namespace
spec: provider: {
kubernetes: {
remoteNamespace: #BankOfHolos.Security.Namespace
auth: serviceAccount: name: ServiceAccount[BankName].metadata.name
server: {
url: "https://kubernetes.default.svc"
caProvider: {
type: "ConfigMap"
name: "kube-root-ca.crt"
key: "ca.crt"
}
}
}
}
}
// We do not check the private key into version control.
// https://github.com/GoogleCloudPlatform/bank-of-anthos/tree/v0.6.5/extras/jwt
ExternalSecret: "jwt-key": es.#ExternalSecret & {
metadata: name: "jwt-key"
spec: {
target: name: metadata.name
dataFrom: [{extract: {key: metadata.name}}]
refreshInterval: "5s"
secretStoreRef: kind: "SecretStore"
secretStoreRef: name: SecretStore[BankName].metadata.name
}
}
// https://github.com/GoogleCloudPlatform/bank-of-anthos/blob/release/v0.6.5/kubernetes-manifests/config.yaml
ConfigMap: "environment-config": core.#ConfigMap & {
apiVersion: "v1"
kind: "ConfigMap"
metadata: name: "environment-config"
data: {
LOCAL_ROUTING_NUM: "883745000"
PUB_KEY_PATH: "/tmp/.ssh/publickey"
}
}
ConfigMap: "service-api-config": core.#ConfigMap & {
apiVersion: "v1"
kind: "ConfigMap"
metadata: name: "service-api-config"
data: {
TRANSACTIONS_API_ADDR: "ledgerwriter.\(#BankOfHolos.Backend.Namespace).svc:8080"
BALANCES_API_ADDR: "balancereader.\(#BankOfHolos.Backend.Namespace).svc:8080"
HISTORY_API_ADDR: "transactionhistory.\(#BankOfHolos.Backend.Namespace).svc:8080"
CONTACTS_API_ADDR: "contacts.\(#BankOfHolos.Backend.Namespace).svc:8080"
USERSERVICE_API_ADDR: "userservice.\(#BankOfHolos.Backend.Namespace).svc:8080"
}
}
ConfigMap: "demo-data-config": core.#ConfigMap & {
apiVersion: "v1"
kind: "ConfigMap"
metadata: name: "demo-data-config"
data: {
USE_DEMO_DATA: "True"
DEMO_LOGIN_USERNAME: "testuser"
// All demo user accounts are hardcoded to use the login password 'bankofanthos'
DEMO_LOGIN_PASSWORD: "bankofanthos"
}
}
}
}

View File

@@ -0,0 +1,201 @@
package holos
// Produce a kubernetes objects build plan.
(#Kubernetes & Objects).BuildPlan
let Objects = {
Name: "bank-frontend"
Namespace: #BankOfHolos.Frontend.Namespace
// Ensure resources go in the correct namespace
Resources: [_]: [_]: metadata: namespace: Namespace
// https://github.com/GoogleCloudPlatform/bank-of-anthos/blob/release/v0.6.5/kubernetes-manifests/frontend.yaml
Resources: {
Service: frontend: {
metadata: name: "frontend"
metadata: labels: {
application: "bank-of-holos"
environment: "development"
team: "frontend"
tier: "web"
}
spec: {
selector: {
app: "frontend"
application: "bank-of-holos"
environment: "development"
team: "frontend"
tier: "web"
}
_ports: http: {
name: "http"
port: 80
targetPort: 8080
protocol: "TCP"
}
ports: [for x in _ports {x}]
}
}
Deployment: frontend: {
metadata: name: "frontend"
metadata: labels: {
application: "bank-of-holos"
environment: "development"
team: "frontend"
tier: "web"
}
spec: {
selector: matchLabels: {
app: "frontend"
application: "bank-of-holos"
environment: "development"
team: "frontend"
tier: "web"
}
template: {
metadata: labels: {
app: "frontend"
application: "bank-of-holos"
environment: "development"
team: "frontend"
tier: "web"
}
spec: {
securityContext: {
seccompProfile: type: "RuntimeDefault"
fsGroup: 1000
runAsGroup: 1000
runAsNonRoot: true
runAsUser: 1000
}
serviceAccountName: "bank-of-holos"
terminationGracePeriodSeconds: 5
containers: [{
env: [{
name: "BANK_NAME"
value: "Bank of Holos"
}, {
name: "ENV_PLATFORM"
value: "local"
}, {
name: "VERSION"
value: "v0.6.5"
}, {
name: "PORT"
value: "8080"
}, {
name: "ENABLE_TRACING"
value: "false"
}, {
name: "SCHEME"
value: "https"
}, {
name: "LOG_LEVEL"
value: "info"
}, {
name: "DEFAULT_USERNAME"
valueFrom: configMapKeyRef: {
key: "DEMO_LOGIN_USERNAME"
name: "demo-data-config"
}
}, {
name: "DEFAULT_PASSWORD"
valueFrom: configMapKeyRef: {
key: "DEMO_LOGIN_PASSWORD"
name: "demo-data-config"
}
}, {
name: "REGISTERED_OAUTH_CLIENT_ID"
valueFrom: configMapKeyRef: {
key: "DEMO_OAUTH_CLIENT_ID"
name: "oauth-config"
optional: true
}
}, {
name: "ALLOWED_OAUTH_REDIRECT_URI"
valueFrom: configMapKeyRef: {
key: "DEMO_OAUTH_REDIRECT_URI"
name: "oauth-config"
optional: true
}
}]
envFrom: [{
configMapRef: name: "environment-config"
}, {
configMapRef: name: "service-api-config"
}]
image: "us-central1-docker.pkg.dev/bank-of-anthos-ci/bank-of-anthos/frontend:v0.6.5@sha256:d72050f70d12383e4434ad04d189b681dc625f696087ddf0b5df641645c9dafa"
livenessProbe: {
httpGet: {
path: "/ready"
port: 8080
}
initialDelaySeconds: 60
periodSeconds: 15
timeoutSeconds: 30
}
name: "front"
readinessProbe: {
httpGet: {
path: "/ready"
port: 8080
}
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 10
}
resources: {
limits: {
cpu: "250m"
memory: "128Mi"
}
requests: {
cpu: "100m"
memory: "64Mi"
}
}
securityContext: {
allowPrivilegeEscalation: false
capabilities: drop: ["all"]
privileged: false
readOnlyRootFilesystem: true
}
volumeMounts: [{
mountPath: "/tmp"
name: "tmp"
}, {
mountPath: "/tmp/.ssh"
name: "publickey"
readOnly: true
}]
}]
volumes: [
{
emptyDir: {}
name: "tmp"
},
{
name: "publickey"
secret: {
items: [{key: "jwtRS256.key.pub", path: "publickey"}]
secretName: "jwt-key"
}
},
]
}
}
}
}
// Allow HTTPRoutes in the ingress gateway namespace to reference Services
// in this namespace.
ReferenceGrant: grant: #ReferenceGrant & {
metadata: namespace: Namespace
}
// Include shared resources
#BankOfHolos.Resources
}
}

View File

@@ -0,0 +1,3 @@
package holos
#ArgoConfig: AppProject: #AppProjects["bank-frontend"].metadata.name

View File

@@ -0,0 +1,165 @@
package holos
import (
corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
batchv1 "k8s.io/api/batch/v1"
)
// Produce a kubernetes objects build plan.
(#Kubernetes & Objects).BuildPlan
// This may be useful to copy and generate other secrets.
let SecretName = "jwt-key"
// Roles for reading and writing secrets
let Reader = "\(SecretName)-reader"
let Writer = "\(SecretName)-writer"
// AllowedName represents the service account allowed to read the generated
// secret.
let AllowedName = #BankOfHolos.Name
let Objects = {
Name: "bank-secrets"
Namespace: #BankOfHolos.Security.Namespace
Resources: [_]: [_]: metadata: namespace: Namespace
Resources: [_]: [ID=string]: metadata: name: string | *ID
Resources: {
// Kubernetes ServiceAccount used by the secret generator job.
ServiceAccount: (Writer): corev1.#ServiceAccount
// Role to allow the ServiceAccount to update secrets.
Role: (Writer): rbacv1.#Role & {
rules: [{
apiGroups: [""]
resources: ["secrets"]
verbs: ["create", "update", "patch"]
}]
}
// Bind the role to the service account.
RoleBinding: (Writer): rbacv1.#RoleBinding & {
roleRef: {
apiGroup: "rbac.authorization.k8s.io"
kind: "Role"
name: Role[Writer].metadata.name
}
subjects: [{
kind: "ServiceAccount"
name: ServiceAccount[Writer].metadata.name
namespace: Namespace
}]
}
let JobSpec = {
serviceAccountName: Writer
restartPolicy: "OnFailure"
securityContext: {
seccompProfile: type: "RuntimeDefault"
runAsNonRoot: true
runAsUser: 8192 // app
}
containers: [
{
name: "toolkit"
image: "quay.io/holos-run/toolkit:2024-09-16"
securityContext: {
capabilities: drop: ["ALL"]
allowPrivilegeEscalation: false
}
command: ["/bin/bash"]
args: ["/config/entrypoint"]
env: [{
name: "HOME"
value: "/tmp"
}]
volumeMounts: [{
name: "config"
mountPath: "/config"
readOnly: true
}]
},
]
volumes: [{
name: "config"
configMap: name: Writer
}]
}
Job: (Writer): batchv1.#Job & {
spec: template: spec: JobSpec
}
ConfigMap: (Writer): corev1.#ConfigMap & {
data: entrypoint: ENTRYPOINT
}
// Allow the SecretStore in the frontend and backend namespaces to read the
// secret.
Role: (Reader): rbacv1.#Role & {
rules: [{
apiGroups: [""]
resources: ["secrets"]
resourceNames: [SecretName]
verbs: ["get"]
}]
}
// Grant access to the bank-of-holos service account in the frontend and
// backend namespaces.
RoleBinding: (Reader): rbacv1.#RoleBinding & {
roleRef: {
apiGroup: "rbac.authorization.k8s.io"
kind: "Role"
name: Role[Reader].metadata.name
}
subjects: [{
kind: "ServiceAccount"
name: AllowedName
namespace: #BankOfHolos.Frontend.Namespace
}, {
kind: "ServiceAccount"
name: AllowedName
namespace: #BankOfHolos.Backend.Namespace
},
]
}
}
}
let ENTRYPOINT = """
#! /bin/bash
#
tmpdir="$(mktemp -d)"
finish() {
status=$?
rm -rf "${tmpdir}"
return $status
}
trap finish EXIT
set -euo pipefail
cd "$tmpdir"
mkdir secret
cd secret
echo "generating private key" >&2
ssh-keygen -t rsa -b 4096 -m PEM -f jwtRS256.key -q -N "" -C \(AllowedName)
echo "generating public key" >&2
ssh-keygen -e -m PKCS8 -f jwtRS256.key > jwtRS256.key.pub
cd ..
echo "copying secret into kubernetes manifest secret.yaml" >&2
kubectl create secret generic \(SecretName) --from-file=secret --dry-run=client -o yaml > secret.yaml
echo "applying secret.yaml" >&2
kubectl apply --server-side=true -f secret.yaml
echo "cleaning up" >&2
rm -rf secret secret.yaml
echo "ok done" >&2
"""

View File

@@ -0,0 +1,3 @@
package holos
#ArgoConfig: AppProject: #AppProjects["bank-security"].metadata.name

View File

@@ -0,0 +1,5 @@
{
"name": "bank-of-holos",
"short": "demo bank composed of two projects",
"long": "Bank of Holos is a sample HTTP-based web app that simulates a bank's payment processing network, allowing users to create artificial bank accounts and complete transactions."
}

View File

@@ -0,0 +1,20 @@
package holos
// Platform wide configuration
#CertManager: {
Version: "{{ .Version }}"
Namespace: "{{ .Namespace }}"
}
// Register the namespace
#Namespaces: (#CertManager.Namespace): _
// Manage the component on every cluster in the platform
for Fleet in #Fleets {
for Cluster in Fleet.clusters {
#Platform: Components: "\(Cluster.name)/{{ .Name }}": {
path: "components/cert-manager"
cluster: Cluster.name
}
}
}

View File

@@ -0,0 +1,16 @@
package holos
// Produce a helm chart build plan.
(#Helm & Chart).BuildPlan
let Chart = {
Name: "{{ .Name }}"
Version: #CertManager.Version
Namespace: #CertManager.Namespace
Repo: name: "{{ .RepoName }}"
Repo: url: "{{ .RepoURL }}"
Values: installCRDs: true
Values: startupapicheck: enabled: false
}

View File

@@ -0,0 +1,10 @@
{
"name": "cert-manager",
"short": "cloud native X.509 certificate management for kubernetes",
"long": "cert-manager creates tls certificates for workloads in your kubernetes cluster and renews the certificates before they expire.",
"chart": "",
"reponame": "jetstack",
"repourl": "https://charts.jetstack.io",
"version": "1.15.3",
"namespace": "cert-manager"
}

View File

@@ -0,0 +1,15 @@
package holos
// Manage the component on every cluster in the platform
for Fleet in #Fleets {
for Cluster in Fleet.clusters {
#Platform: Components: "\(Cluster.name)/external-secrets-crds": {
path: "projects/platform/components/external-secrets-crds"
cluster: Cluster.name
}
#Platform: Components: "\(Cluster.name)/external-secrets": {
path: "projects/platform/components/external-secrets"
cluster: Cluster.name
}
}
}

View File

@@ -0,0 +1,10 @@
package holos
// Platform wide configuration
#ExternalSecrets: {
Version: "{{ .Version }}"
Namespace: "external-secrets"
}
// Register the namespace
#Namespaces: (#ExternalSecrets.Namespace): _

View File

@@ -0,0 +1,33 @@
package holos
import (
"encoding/yaml"
ks "sigs.k8s.io/kustomize/api/types"
)
(#Kubernetes & {Name: "external-secrets-crds"}).BuildPlan
// Holos stages BuildPlan resources as an intermediate step of the rendering
// pipeline. The purpose is to provide the resources to kustomize for
// post-processing.
let BuildPlanResources = "build-plan-resources.yaml"
_Kustomization: ks.#Kustomization & {
apiVersion: "kustomize.config.k8s.io/v1beta1"
kind: "Kustomization"
resources: [
// Kustomize the intermediate build plan resources.
BuildPlanResources,
// Mix-in external resources.
"https://raw.githubusercontent.com/external-secrets/external-secrets/v\(#ExternalSecrets.Version)/deploy/crds/bundle.yaml",
]
}
// Generate a kustomization.yaml directly from CUE so we can provide the correct
// version.
spec: components: kubernetesObjectsList: [{
// intermediate build plan resources to kustomize. Necessary to activate the
// kustomization post-rendering step in holos.
kustomize: resourcesFile: BuildPlanResources
kustomize: kustomizeFiles: "kustomization.yaml": yaml.Marshal(_Kustomization)
}]

View File

@@ -0,0 +1,50 @@
package holos
import (
"encoding/yaml"
ks "sigs.k8s.io/kustomize/api/types"
)
// Patch the the build plan output.
_Kustomization: patches: [for x in KustomizePatches {x}]
#KustomizePatches: [ArbitraryLabel=string]: ks.#Patch
let KustomizePatches = #KustomizePatches & {
let Patch = [{
op: "replace"
path: "/spec/conversion/webhook/clientConfig/service/name"
value: "external-secrets-webhook"
}, {
op: "replace"
path: "/spec/conversion/webhook/clientConfig/service/namespace"
value: "external-secrets"
}]
clustersecretstores: {
target: {
group: "apiextensions.k8s.io"
version: "v1"
kind: "CustomResourceDefinition"
name: "clustersecretstores.external-secrets.io"
}
patch: yaml.Marshal(Patch)
}
externalsecrets: {
target: {
group: "apiextensions.k8s.io"
version: "v1"
kind: "CustomResourceDefinition"
name: "externalsecrets.external-secrets.io"
}
patch: yaml.Marshal(Patch)
}
secretstores: {
target: {
group: "apiextensions.k8s.io"
version: "v1"
kind: "CustomResourceDefinition"
name: "secretstores.external-secrets.io"
}
patch: yaml.Marshal(Patch)
}
}

View File

@@ -0,0 +1,15 @@
package holos
_Chart: {
Name: "external-secrets"
Version: "0.10.3"
Namespace: "external-secrets"
Repo: name: "external-secrets"
Repo: url: "https://charts.external-secrets.io"
Values: installCRDs: false
}
// Produce a helm chart build plan.
(#Helm & _Chart).BuildPlan

View File

@@ -0,0 +1,6 @@
{
"name": "external-secrets",
"short": "safer secret management",
"long": "https://external-secrets.io",
"version": "0.10.3"
}

View File

@@ -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: "projects/platform/components/gateway-api"
cluster: Cluster.name
}
}
}

View File

@@ -0,0 +1,4 @@
package holos
// Produce a kubectl kustomize build plan.
(#Kustomize & {Name: "gateway-api"}).BuildPlan

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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."
}

View File

@@ -0,0 +1,37 @@
package holos
// Produce a kubernetes objects build plan.
(#Kubernetes & Objects).BuildPlan
let Objects = {
Name: "{{ .Name }}"
Namespace: #Istio.Gateway.Namespace
Resources: [_]: [_]: metadata: namespace: Namespace
Resources: HTTPRoute: (#HTTPRouteClone & {Name: "httpbin"}).BuildPlan
}
#HTTPRouteClone: {
Name: string
let Host = "\(Name).\(#Platform.Domain)"
Output: "\(Name)": {
metadata: namespace: _
metadata: name: Name
metadata: labels: app: Name
spec: hostnames: [Host]
spec: parentRefs: [{
name: "default"
namespace: metadata.namespace
}]
spec: rules: [
{
matches: [{path: {type: "PathPrefix", value: "/"}}]
backendRefs: [{
name: Name
namespace: #HTTPBin.Namespace
port: #HTTPBin.Port
}]
},
]
}
}

View File

@@ -0,0 +1,9 @@
package holos
// Manage the component on workload clusters
for Cluster in #Fleets.workload.clusters {
#Platform: Components: "\(Cluster.name)/{{ .Name }}": {
path: "components/httpbin/routes"
cluster: Cluster.name
}
}

View File

@@ -0,0 +1,6 @@
{
"name": "httpbin-routes",
"short": "expose httpbin with httproute resources",
"long": "expose httpbin with httproute resources",
"namespace": "istio-ingress"
}

View File

@@ -0,0 +1,61 @@
package holos
// Produce a kubernetes objects build plan.
(#Kubernetes & Objects).BuildPlan
let Objects = {
Name: "{{ .Name }}"
Namespace: #HTTPBin.Namespace
// Constrain resources to the httpbin namespace
Resources: [_]: [_]: metadata: namespace: #HTTPBin.Namespace
Resources: {
Deployment: httpbin: {
metadata: name: "httpbin"
metadata: labels: app: metadata.name
spec: {
selector: matchLabels: {
app: metadata.labels.app
"app.kubernetes.io/instance": app
}
template: {
metadata: labels: selector.matchLabels
spec: securityContext: seccompProfile: type: "RuntimeDefault"
spec: containers: [{
name: "httpbin"
image: "quay.io/holos/mccutchen/go-httpbin"
ports: [{containerPort: 8080}]
securityContext: {
seccompProfile: type: "RuntimeDefault"
allowPrivilegeEscalation: false
runAsNonRoot: true
runAsUser: 8192
runAsGroup: 8192
capabilities: drop: ["ALL"]
}}]
}
}
}
Service: httpbin: {
metadata: labels: Deployment.httpbin.metadata.labels
spec: {
selector: Deployment.httpbin.spec.selector.matchLabels
_ports: http: {
port: #HTTPBin.Port
targetPort: Deployment.httpbin.spec.template.spec.containers[0].ports[0].containerPort
protocol: "TCP"
name: "http"
}
ports: [for x in _ports {x}]
}
}
// Allow istio-ingress to refer to Services from HTTPRoutes
ReferenceGrant: httpbin: #ReferenceGrant & {
metadata: labels: Deployment.httpbin.metadata.labels
}
}
}

View File

@@ -0,0 +1,18 @@
package holos
// Platform wide configuration
#HTTPBin: {
Namespace: "{{ .Namespace }}"
Port: 80
}
// Register the namespace
#Namespaces: (#HTTPBin.Namespace): _
// Manage the component on workload clusters
for Cluster in #Fleets.workload.clusters {
#Platform: Components: "\(Cluster.name)/{{ .Name }}": {
path: "components/httpbin/workload"
cluster: Cluster.name
}
}

View File

@@ -0,0 +1,6 @@
{
"name": "httpbin-workload",
"short": "manages the httpbin deployment and service",
"long": "httpbin is useful to inspect requests and responses",
"namespace": "httpbin"
}

View File

@@ -0,0 +1,9 @@
package holos
// Manage on workload clusters
for Cluster in #Fleets.workload.clusters {
#Platform: Components: "\(Cluster.name)/httproutes": {
path: "projects/platform/components/httproutes"
cluster: Cluster.name
}
}

View File

@@ -0,0 +1,34 @@
package holos
import v1 "gateway.networking.k8s.io/httproute/v1"
// #HTTPRoutes defines managed HTTPRoute resources for the platform. These
// resources are managed in the istio-ingress namespace. Other components
// define the routes they need close to the root of configuration.
#HTTPRoutes: {
// For the guides, we simplify this down to a flat namespace.
[Name=string]: v1.#HTTPRoute & {
let HOST = Name + "." + #Platform.Domain
_backendRefs: [NAME=string]: {
name: NAME
namespace: string
port: number | *80
}
metadata: name: Name
metadata: namespace: #Istio.Gateway.Namespace
metadata: labels: app: Name
spec: hostnames: [HOST]
spec: parentRefs: [{
name: "default"
namespace: metadata.namespace
}]
spec: rules: [
{
matches: [{path: {type: "PathPrefix", value: "/"}}]
backendRefs: [for x in _backendRefs {x}]
},
]
}
}

View File

@@ -0,0 +1,9 @@
package holos
let Objects = {
Name: "httproutes"
Resources: HTTPRoute: #HTTPRoutes
}
// Produce a kubernetes objects build plan.
(#Kubernetes & Objects).BuildPlan

View File

@@ -0,0 +1,5 @@
{
"name": "httproutes",
"short": "#HTTPRoutes registration point",
"long": "Provides the #HTTPRoutes registration point to manage httproutes in the istio-ingress namespace."
}

View File

@@ -0,0 +1,61 @@
package holos
// Produce a kubernetes objects build plan.
(#Kubernetes & Objects).BuildPlan
let Objects = {
Name: "{{ .Name }}"
Namespace: #Istio.Gateway.Namespace
Resources: {
// The default gateway with all listeners attached to tls certs.
Gateway: default: {
metadata: namespace: Namespace
let Listeners = {
http: {
name: "http"
protocol: "HTTP"
port: 80
allowedRoutes: namespaces: from: "Same"
}
https: {
name: "https"
protocol: "HTTPS"
port: 443
allowedRoutes: namespaces: from: "Same"
tls: mode: "Terminate"
tls: certificateRefs: [{
kind: "Secret"
name: "gateway-cert"
}]
}
}
spec: listeners: [for x in Listeners {x}]
}
// Manage a simple cert for example.com and *.example.com
Certificate: "gateway-cert": {
metadata: name: "gateway-cert"
metadata: namespace: Namespace
spec: commonName: #Platform.Domain
spec: dnsNames: [spec.commonName, "*.\(spec.commonName)"]
spec: secretName: metadata.name
spec: issuerRef: {
kind: "ClusterIssuer"
name: "local-ca"
}
}
// Manage a service account to prevent ArgoCD from pruning it.
ServiceAccount: "default-istio": {
metadata: namespace: Namespace
metadata: labels: {
"gateway.istio.io/managed": "istio.io-gateway-controller"
"gateway.networking.k8s.io/gateway-name": "default"
"istio.io/gateway-name": "default"
}
}
}
}

View File

@@ -0,0 +1,7 @@
# Gateway API
This component uses the [Gateway API][1] to manage an istio Gateway. This will
become the default method in upstream istio so it is the preferred method in
Holos.
[1]: https://gateway-api.sigs.k8s.io/

View File

@@ -0,0 +1,17 @@
package holos
// #Istio represents platform wide configuration
#Istio: Gateway: Namespace: "istio-ingress"
// Register the Namespaces
#Namespaces: (#Istio.Gateway.Namespace): _
// Manage istio on workload clusters
for Cluster in #Fleets.workload.clusters {
#Platform: Components: {
"\(Cluster.name)/{{ .Name }}": {
path: "components/istio/gateway"
cluster: Cluster.name
}
}
}

View File

@@ -0,0 +1,5 @@
{
"name": "istio-gateway",
"short": "kubernetes ingress gateway api",
"long": "Gateway API ingress gateway with certificate management"
}

View File

@@ -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"
}

View File

@@ -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"
}

View File

@@ -0,0 +1,24 @@
package holos
// #Istio represents platform wide configuration
// Manage istio on workload clusters
for Cluster in #Fleets.workload.clusters {
#Platform: Components: {
"\(Cluster.name)/istio-base": {
path: "projects/platform/components/istio/base"
cluster: Cluster.name
}
"\(Cluster.name)/istiod": {
path: "projects/platform/components/istio/istiod"
cluster: Cluster.name
}
"\(Cluster.name)/istio-cni": {
path: "projects/platform/components/istio/cni"
cluster: Cluster.name
}
"\(Cluster.name)/istio-ztunnel": {
path: "projects/platform/components/istio/ztunnel"
cluster: Cluster.name
}
}
}

View File

@@ -0,0 +1,17 @@
package holos
// #Istio represents platform wide configuration
#Istio: {
Version: "1.23.1"
System: Namespace: "istio-system"
// 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): _

View File

@@ -0,0 +1,17 @@
package holos
// Produce a helm chart build plan.
(#Helm & Chart).BuildPlan
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
}

View File

@@ -0,0 +1,48 @@
package holos
import (
"encoding/yaml"
ks "sigs.k8s.io/kustomize/api/types"
)
// Holos stages BuildPlan resources as an intermediate step of the rendering
// pipeline. The purpose is to provide the resources to kustomize for
// post-processing.
let BuildPlanOutputManifest = "build-plan-output-manifest.yaml"
// Patch istio so it's not constantly out of sync in ArgoCD
let Kustomization = ks.#Kustomization & {
apiVersion: "kustomize.config.k8s.io/v1beta1"
kind: "Kustomization"
// Kustomize the build plan output.
resources: [BuildPlanOutputManifest]
// Patch the the build plan output.
patches: [for x in KustomizePatches {x}]
}
#KustomizePatches: [ArbitraryLabel=string]: ks.#Patch
let KustomizePatches = #KustomizePatches & {
validator: {
target: {
group: "admissionregistration.k8s.io"
version: "v1"
kind: "ValidatingWebhookConfiguration"
name: "istiod-default-validator"
}
let Patch = [{
op: "replace"
path: "/webhooks/0/failurePolicy"
value: "Fail"
}]
patch: yaml.Marshal(Patch)
}
}
// Generate a kustomization.yaml directly from CUE so we can provide the correct
// version.
spec: components: helmChartList: [{
// intermediate build plan resources to kustomize. Necessary to activate the
// kustomization post-rendering step in holos.
kustomize: resourcesFile: BuildPlanOutputManifest
kustomize: kustomizeFiles: "kustomization.yaml": yaml.Marshal(Kustomization)
}]

View File

@@ -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
}
}

View File

@@ -0,0 +1,17 @@
package holos
// Produce a helm chart build plan.
(#Helm & Chart).BuildPlan
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
}

View File

@@ -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"
}
}
}
}
}

View File

@@ -0,0 +1,61 @@
package holos
// Produce a kubernetes objects build plan.
(#Kubernetes & Objects).BuildPlan
let Objects = {
Name: "istio-gateway"
Namespace: #Istio.Gateway.Namespace
Resources: {
// The default gateway with all listeners attached to tls certs.
Gateway: default: {
metadata: namespace: Namespace
let Listeners = {
http: {
name: "http"
protocol: "HTTP"
port: 80
allowedRoutes: namespaces: from: "Same"
}
https: {
name: "https"
protocol: "HTTPS"
port: 443
allowedRoutes: namespaces: from: "Same"
tls: mode: "Terminate"
tls: certificateRefs: [{
kind: "Secret"
name: "gateway-cert"
}]
}
}
spec: listeners: [for x in Listeners {x}]
}
// Manage a simple cert for example.com and *.example.com
Certificate: "gateway-cert": {
metadata: name: "gateway-cert"
metadata: namespace: Namespace
spec: commonName: #Platform.Domain
spec: dnsNames: [spec.commonName, "*.\(spec.commonName)"]
spec: secretName: metadata.name
spec: issuerRef: {
kind: "ClusterIssuer"
name: "local-ca"
}
}
// Manage a service account to prevent ArgoCD from pruning it.
ServiceAccount: "default-istio": {
metadata: namespace: Namespace
metadata: labels: {
"gateway.istio.io/managed": "istio.io-gateway-controller"
"gateway.networking.k8s.io/gateway-name": "default"
"istio.io/gateway-name": "default"
}
}
}
}

View File

@@ -0,0 +1,7 @@
# Gateway API
This component uses the [Gateway API][1] to manage an istio Gateway. This will
become the default method in upstream istio so it is the preferred method in
Holos.
[1]: https://gateway-api.sigs.k8s.io/

View File

@@ -0,0 +1,48 @@
package holos
import (
"encoding/yaml"
ks "sigs.k8s.io/kustomize/api/types"
)
// Holos stages BuildPlan resources as an intermediate step of the rendering
// pipeline. The purpose is to provide the resources to kustomize for
// post-processing.
let BuildPlanOutputManifest = "build-plan-output-manifest.yaml"
// Patch istio so it's not constantly out of sync in ArgoCD
let Kustomization = ks.#Kustomization & {
apiVersion: "kustomize.config.k8s.io/v1beta1"
kind: "Kustomization"
// Kustomize the build plan output.
resources: [BuildPlanOutputManifest]
// Patch the the build plan output.
patches: [for x in KustomizePatches {x}]
}
#KustomizePatches: [ArbitraryLabel=string]: ks.#Patch
let KustomizePatches = #KustomizePatches & {
validator: {
target: {
group: "admissionregistration.k8s.io"
version: "v1"
kind: "ValidatingWebhookConfiguration"
name: "istio-validator-istio-system"
}
let Patch = [{
op: "replace"
path: "/webhooks/0/failurePolicy"
value: "Fail"
}]
patch: yaml.Marshal(Patch)
}
}
// Generate a kustomization.yaml directly from CUE so we can provide the correct
// version.
spec: components: helmChartList: [{
// intermediate build plan resources to kustomize. Necessary to activate the
// kustomization post-rendering step in holos.
kustomize: resourcesFile: BuildPlanOutputManifest
kustomize: kustomizeFiles: "kustomization.yaml": yaml.Marshal(Kustomization)
}]

View File

@@ -0,0 +1,17 @@
package holos
// Produce a helm chart build plan.
(#Helm & Chart).BuildPlan
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
}

View File

@@ -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: {}
}
}
}

View File

@@ -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: {}
}
}

View File

@@ -0,0 +1,17 @@
package holos
// Produce a helm chart build plan.
(#Helm & Chart).BuildPlan
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
}

View File

@@ -0,0 +1,5 @@
{
"name": "istio",
"short": "istio service mesh",
"long": "Easily build cloud native workloads securely and reliably with Istio."
}

View File

@@ -0,0 +1,20 @@
package holos
import ci "cert-manager.io/clusterissuer/v1"
// Produce a kubernetes objects build plan.
(#Kubernetes & Objects).BuildPlan
let Objects = {
Name: "local-ca"
Namespace: #CertManager.Namespace
Resources: ClusterIssuer: LocalCA: ci.#ClusterIssuer & {
metadata: name: "local-ca"
metadata: namespace: #CertManager.Namespace
// The secret name must align with the local cluster guide at
// https://holos.run/docs/guides/local-cluster/
spec: ca: secretName: "local-ca"
}
}

View File

@@ -0,0 +1,11 @@
package holos
// Manage the component on every cluster in the platform
for Fleet in #Fleets {
for Cluster in Fleet.clusters {
#Platform: Components: "\(Cluster.name)/{{ .Name }}": {
path: "components/local-ca"
cluster: Cluster.name
}
}
}

View File

@@ -0,0 +1,6 @@
{
"name": "local-ca",
"short": "manages a cluster issuer for use with our guides",
"long": "manages a cluster issuer that uses the mkcert ca private key to issue certs",
"namespace": "cert-manager"
}

View File

@@ -0,0 +1,9 @@
package holos
let Objects = {
Name: "namespaces"
Resources: Namespace: #Namespaces
}
// Produce a kubernetes objects build plan.
(#Kubernetes & Objects).BuildPlan

View File

@@ -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
}
}
}

View File

@@ -0,0 +1,5 @@
{
"name": "namespaces",
"short": "manage namespaces consistently",
"long": "Provides the #Namespaces root struct for components to register with."
}

View File

@@ -1,7 +1,7 @@
package holos
// Produce a helm chart build plan.
(#Helm & Chart).Output
(#Helm & Chart).BuildPlan
let Chart = {
Name: "{{ .Name }}"

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