mirror of
https://github.com/holos-run/holos.git
synced 2026-03-19 16:54:58 +00:00
This patch is a partial step toward getting the choria broker up and running in my own namespace. The choria broker is necessary for provisioning machine room agents such as the holos controller.
416 lines
13 KiB
CUE
416 lines
13 KiB
CUE
package holos
|
|
|
|
import "strings"
|
|
|
|
import (
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
appsv1 "k8s.io/api/apps/v1"
|
|
corev1 "k8s.io/api/core/v1"
|
|
rbacv1 "k8s.io/api/rbac/v1"
|
|
batchv1 "k8s.io/api/batch/v1"
|
|
es "external-secrets.io/externalsecret/v1beta1"
|
|
ss "external-secrets.io/secretstore/v1beta1"
|
|
is "cert-manager.io/issuer/v1"
|
|
ci "cert-manager.io/clusterissuer/v1"
|
|
crt "cert-manager.io/certificate/v1"
|
|
gw "networking.istio.io/gateway/v1beta1"
|
|
vs "networking.istio.io/virtualservice/v1beta1"
|
|
dr "networking.istio.io/destinationrule/v1beta1"
|
|
ra "security.istio.io/requestauthentication/v1"
|
|
ap "security.istio.io/authorizationpolicy/v1"
|
|
pg "postgres-operator.crunchydata.com/postgrescluster/v1beta1"
|
|
)
|
|
|
|
// _apiVersion is the version of this schema. Defines the interface between CUE output and the holos cli.
|
|
_apiVersion: "holos.run/v1alpha1"
|
|
|
|
// #ComponentName is the name of the holos component.
|
|
// TODO: Refactor to support multiple components per BuildPlan
|
|
#ComponentName: #InputKeys.component
|
|
|
|
// #StageName is prod, dev, stage, etc... Usually prod for platform components.
|
|
#StageName: #InputKeys.stage
|
|
|
|
// #TargetNamespace is the target namespace for a holos component.
|
|
#TargetNamespace: string
|
|
|
|
#ClusterObject: {
|
|
_description: string | *""
|
|
metadata: metav1.#ObjectMeta & {
|
|
// labels: #CommonLabels
|
|
annotations: #Description & {
|
|
_Description: _description
|
|
...
|
|
}
|
|
}
|
|
...
|
|
}
|
|
|
|
#Description: {
|
|
_Description: string | *""
|
|
"holos.run/description": _Description
|
|
...
|
|
}
|
|
|
|
#NamespaceObject: #ClusterObject & {
|
|
metadata: name: string
|
|
metadata: namespace: string
|
|
...
|
|
}
|
|
|
|
// Kubernetes API Objects
|
|
#Namespace: corev1.#Namespace & {
|
|
metadata: name: string
|
|
metadata: labels: "kubernetes.io/metadata.name": metadata.name
|
|
}
|
|
|
|
#ClusterRole: #ClusterObject & rbacv1.#ClusterRole
|
|
#ClusterRoleBinding: #ClusterObject & rbacv1.#ClusterRoleBinding
|
|
#ClusterIssuer: #ClusterObject & ci.#ClusterIssuer & {...}
|
|
|
|
#Issuer: #NamespaceObject & is.#Issuer
|
|
#Role: #NamespaceObject & rbacv1.#Role
|
|
#RoleBinding: #NamespaceObject & rbacv1.#RoleBinding
|
|
#ConfigMap: #NamespaceObject & corev1.#ConfigMap
|
|
#ServiceAccount: #NamespaceObject & corev1.#ServiceAccount
|
|
#Pod: #NamespaceObject & corev1.#Pod
|
|
#Service: #NamespaceObject & corev1.#Service
|
|
#Job: #NamespaceObject & batchv1.#Job
|
|
#CronJob: #NamespaceObject & batchv1.#CronJob
|
|
#Deployment: #NamespaceObject & appsv1.#Deployment
|
|
#StatefulSet: #NamespaceObject & appsv1.#StatefulSet
|
|
#VirtualService: #NamespaceObject & vs.#VirtualService
|
|
#DestinationRule: #NamespaceObject & dr.#DestinationRule
|
|
#RequestAuthentication: #NamespaceObject & ra.#RequestAuthentication
|
|
#AuthorizationPolicy: #NamespaceObject & ap.#AuthorizationPolicy
|
|
#Certificate: #NamespaceObject & crt.#Certificate
|
|
#PostgresCluster: #NamespaceObject & pg.#PostgresCluster
|
|
|
|
#Gateway: #NamespaceObject & gw.#Gateway & {
|
|
metadata: namespace: string | *"istio-ingress"
|
|
spec: selector: istio: string | *"ingressgateway"
|
|
}
|
|
|
|
// #HTTP01Cert defines a http01 certificate.
|
|
#HTTP01Cert: {
|
|
_name: string
|
|
_secret: string | *_name
|
|
SecretName: _secret
|
|
Host: _name + "." + #ClusterDomain
|
|
object: #Certificate & {
|
|
metadata: {
|
|
name: _secret
|
|
namespace: string | *#TargetNamespace
|
|
}
|
|
spec: {
|
|
commonName: Host
|
|
dnsNames: [Host]
|
|
secretName: _secret
|
|
issuerRef: kind: "ClusterIssuer"
|
|
issuerRef: name: "letsencrypt"
|
|
}
|
|
}
|
|
}
|
|
|
|
// External Secrets CRDs
|
|
#ExternalSecret: #NamespaceObject & es.#ExternalSecret & {
|
|
_name: string
|
|
metadata: {
|
|
name: _name
|
|
namespace: string | *#TargetNamespace
|
|
}
|
|
spec: {
|
|
refreshInterval: string | *"1h"
|
|
secretStoreRef: {
|
|
kind: string | *"SecretStore"
|
|
name: string | *"default"
|
|
}
|
|
target: {
|
|
name: _name
|
|
creationPolicy: string | *"Owner"
|
|
deletionPolicy: string | *"Retain"
|
|
}
|
|
// Copy fields 1:1 from external Secret to target Secret.
|
|
dataFrom: [{extract: key: _name}]
|
|
}
|
|
}
|
|
|
|
#SecretStore: #NamespaceObject & ss.#SecretStore & {
|
|
_namespace: string
|
|
metadata: {
|
|
name: string | *"default"
|
|
namespace: _namespace
|
|
}
|
|
spec: provider: {
|
|
kubernetes: {
|
|
remoteNamespace: _namespace
|
|
auth: token: bearerToken: {
|
|
name: string | *"eso-reader"
|
|
key: string | *"token"
|
|
}
|
|
server: {
|
|
caBundle: #InputKeys.provisionerCABundle
|
|
url: #InputKeys.provisionerURL
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// #InputKeys defines the set of cue tags required to build a cue holos component. The values are used as lookup keys into the #Platform data.
|
|
#InputKeys: {
|
|
// cluster is usually the only key necessary when working with a component on the command line.
|
|
cluster: string @tag(cluster, type=string)
|
|
// stage is usually set by the platform or project.
|
|
stage: *"prod" | string @tag(stage, type=string)
|
|
// service is usually set by the component.
|
|
service: *component | string @tag(service, type=string)
|
|
// component is the name of the component
|
|
component: string @tag(component, type=string)
|
|
|
|
// GCP Project Info used for the Provisioner Cluster
|
|
gcpProjectID: string @tag(gcpProjectID, type=string)
|
|
gcpProjectNumber: int @tag(gcpProjectNumber, type=int)
|
|
|
|
// Same as cluster certificate-authority-data field in ~/.holos/kubeconfig.provisioner
|
|
provisionerCABundle: string @tag(provisionerCABundle, type=string)
|
|
// Same as the cluster server field in ~/.holos/kubeconfig.provisioner
|
|
provisionerURL: string @tag(provisionerURL, type=string)
|
|
}
|
|
|
|
// #ClusterSpec is the specification of a holos platform cluster member.
|
|
#ClusterSpec: {
|
|
// name is the cluster name.
|
|
name: string
|
|
// pool is the optional ceph pool of the cluster.
|
|
pool?: string
|
|
// region is the geographic region of the cluster.
|
|
region?: string
|
|
// primary is true if the cluster is the primary cluster among a group of related clusters.
|
|
primary: bool
|
|
}
|
|
|
|
// #Platform defines the primary lookup table for the platform. Lookup keys should be limited to those defined in #KeyTags.
|
|
#Platform: {
|
|
// org holds user defined values scoped organization wide. A platform has one and only one organization.
|
|
org: {
|
|
// e.g. "example"
|
|
name: string
|
|
// e.g. "example.com"
|
|
domain: string
|
|
// e.g. "example.com"
|
|
emailDomain: string | *domain
|
|
// e.g. "Example"
|
|
displayName: string
|
|
// e.g. "platform@example.com"
|
|
contact: email: string
|
|
// e.g. "platform@example.com"
|
|
cloudflare: email: string
|
|
// e.g. "example"
|
|
github: orgs: primary: name: string
|
|
}
|
|
// Only one cluster may be primary at a time. All others are standby.
|
|
// Refer to [repo based standby](https://access.crunchydata.com/documentation/postgres-operator/latest/tutorials/backups-disaster-recovery/disaster-recovery#repo-based-standby)
|
|
primaryCluster: {
|
|
name: string
|
|
}
|
|
clusters: [Name=_]: #ClusterSpec & {
|
|
name: string & Name
|
|
if Name == primaryCluster.name {
|
|
primary: true
|
|
}
|
|
if Name != primaryCluster.name {
|
|
primary: false
|
|
}
|
|
}
|
|
// TODO: Remove stages, they're in the subdomain of projects.
|
|
stages: [ID=_]: {
|
|
name: string & ID
|
|
environments: [...{name: string}]
|
|
}
|
|
projects: [ID=_]: {
|
|
name: string & ID
|
|
}
|
|
// TODO: Remove services, they're in the subdomain of projects.
|
|
services: [ID=_]: {
|
|
name: string & ID
|
|
}
|
|
|
|
// authproxy configures the auth proxy attached to the default ingress gateway in the istio-ingress namespace.
|
|
authproxy: #AuthProxySpec & {
|
|
namespace: "istio-ingress"
|
|
provider: "ingressauth"
|
|
}
|
|
|
|
oauthClients: [Name=_]: #OAuthClientSpec & {name: Name}
|
|
}
|
|
|
|
#OAuthClientSpec: {
|
|
name: string
|
|
orgDomain: string | *#Platform.org.emailDomain
|
|
spec: {
|
|
issuer: string | *"https://login.\(#Platform.org.domain)"
|
|
clientID: string | *name
|
|
scopes: string | *strings.Join(scopesList, " ")
|
|
scopesList: ["openid", "profile", "email", "groups", "urn:zitadel:iam:org:domain:primary:\(orgDomain)"]
|
|
jwks_uri: string | *"\(issuer)/oauth/v2/keys"
|
|
authorization_endpoint: string | *"\(issuer)/oauth/v2/authorize"
|
|
token_endpoint: string | *"\(issuer)/oauth/v2/token"
|
|
introspection_endpoint: string | *"\(issuer)/oauth/v2/introspect"
|
|
userinfo_endpoint: string | *"\(issuer)/oauth/v1/userinfo"
|
|
revocation_endpoint: string | *"\(issuer)/oauth/v2/revoke"
|
|
end_session_endpoint: string | *"\(issuer)/oauth/v1/end_session"
|
|
}
|
|
}
|
|
|
|
#AuthProxySpec: {
|
|
// projectID is the zitadel project resource id.
|
|
projectID: number
|
|
// clientID is the zitadel application client id.
|
|
clientID: string
|
|
// namespace is the namespace
|
|
namespace: string
|
|
// provider is the istio extension provider name in the mesh config.
|
|
provider: string
|
|
// orgDomain is the zitadel organization domain for logins.
|
|
orgDomain: string | *#Platform.org.domain
|
|
// issuerHost is the Host: header value of the oidc issuer
|
|
issuerHost: string | *"login.\(#Platform.org.domain)"
|
|
// issuer is the oidc identity provider issuer url
|
|
issuer: string | *"https://\(issuerHost)"
|
|
// path is the oauth2-proxy --proxy-prefix value. The default callback url is the Host: value with a path of /holos/oidc/callback
|
|
proxyPrefix: string | *"/holos/authproxy/\(namespace)"
|
|
// idTokenHeader represents the header where the id token is placed
|
|
idTokenHeader: string | *"x-oidc-id-token"
|
|
}
|
|
|
|
// #Backups defines backup configuration.
|
|
// TODO: Consider the best place for this, possibly as part of the site platform config. This represents the primary location for backups.
|
|
#Backups: {
|
|
s3: {
|
|
region: string
|
|
endpoint: string | *"s3.dualstack.\(region).amazonaws.com"
|
|
}
|
|
}
|
|
|
|
// #Chart defines an upstream helm chart
|
|
#Chart: {
|
|
name: string
|
|
version: string
|
|
release: string | *name
|
|
repository: {
|
|
name?: string
|
|
url?: string
|
|
}
|
|
}
|
|
|
|
// #ChartValues represent the values provided to a helm chart. Existing values may be imorted using cue import values.yaml -p holos then wrapping the values.cue content in #Values: {}
|
|
#ChartValues: {...}
|
|
|
|
// #SecretName is the name of a Secret, ususally coupling a Deployment to an ExternalSecret
|
|
#SecretName: string
|
|
|
|
// Cluster Domain is the cluster specific domain
|
|
#ClusterDomain: #InputKeys.cluster + "." + #Platform.org.domain
|
|
|
|
// #SidecarInject represents the istio sidecar inject label
|
|
#IstioSidecar: {
|
|
"sidecar.istio.io/inject": "true"
|
|
...
|
|
}
|
|
|
|
// #DefaultSecurityContext is the holos default security context to comply with the restricted namespace policy.
|
|
// Refer to https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted
|
|
#DefaultSecurityContext: {
|
|
securityContext: {
|
|
allowPrivilegeEscalation: false
|
|
runAsNonRoot: true
|
|
capabilities: drop: ["ALL"]
|
|
seccompProfile: type: "RuntimeDefault"
|
|
}
|
|
...
|
|
}
|
|
|
|
// Certificate name should always match the secret name.
|
|
#Certificate: {
|
|
metadata: name: _
|
|
spec: secretName: metadata.name
|
|
}
|
|
|
|
// #IsPrimaryCluster is true if the cluster being rendered is the primary cluster
|
|
// Used by the iam project to determine where https://login.example.com is active.
|
|
#IsPrimaryCluster: bool & #ClusterName == #Platform.primaryCluster.name
|
|
|
|
// #GatewayServer defines the value of the istio Gateway.spec.servers field.
|
|
#GatewayServer: {
|
|
// The ip or the Unix domain socket to which the listener should
|
|
// be bound to.
|
|
bind?: string
|
|
defaultEndpoint?: string
|
|
|
|
// One or more hosts exposed by this gateway.
|
|
hosts: [...string]
|
|
|
|
// An optional name of the server, when set must be unique across
|
|
// all servers.
|
|
name?: string
|
|
|
|
// The Port on which the proxy should listen for incoming
|
|
// connections.
|
|
port: {
|
|
// Label assigned to the port.
|
|
name: string
|
|
|
|
// A valid non-negative integer port number.
|
|
number: int
|
|
|
|
// The protocol exposed on the port.
|
|
protocol: string
|
|
targetPort?: int
|
|
}
|
|
|
|
// Set of TLS related options that govern the server's behavior.
|
|
tls?: {
|
|
// REQUIRED if mode is `MUTUAL` or `OPTIONAL_MUTUAL`.
|
|
caCertificates?: string
|
|
|
|
// Optional: If specified, only support the specified cipher list.
|
|
cipherSuites?: [...string]
|
|
|
|
// For gateways running on Kubernetes, the name of the secret that
|
|
// holds the TLS certs including the CA certificates.
|
|
credentialName?: string
|
|
|
|
// If set to true, the load balancer will send a 301 redirect for
|
|
// all http connections, asking the clients to use HTTPS.
|
|
httpsRedirect?: bool
|
|
|
|
// Optional: Maximum TLS protocol version.
|
|
maxProtocolVersion?: "TLS_AUTO" | "TLSV1_0" | "TLSV1_1" | "TLSV1_2" | "TLSV1_3"
|
|
|
|
// Optional: Minimum TLS protocol version.
|
|
minProtocolVersion?: "TLS_AUTO" | "TLSV1_0" | "TLSV1_1" | "TLSV1_2" | "TLSV1_3"
|
|
|
|
// Optional: Indicates whether connections to this port should be
|
|
// secured using TLS.
|
|
mode?: "PASSTHROUGH" | "SIMPLE" | "MUTUAL" | "AUTO_PASSTHROUGH" | "ISTIO_MUTUAL" | "OPTIONAL_MUTUAL"
|
|
|
|
// REQUIRED if mode is `SIMPLE` or `MUTUAL`.
|
|
privateKey?: string
|
|
|
|
// REQUIRED if mode is `SIMPLE` or `MUTUAL`.
|
|
serverCertificate?: string
|
|
|
|
// A list of alternate names to verify the subject identity in the
|
|
// certificate presented by the client.
|
|
subjectAltNames?: [...string]
|
|
|
|
// An optional list of hex-encoded SHA-256 hashes of the
|
|
// authorized client certificates.
|
|
verifyCertificateHash?: [...string]
|
|
|
|
// An optional list of base64-encoded SHA-256 hashes of the SPKIs
|
|
// of authorized client certificates.
|
|
verifyCertificateSpki?: [...string]
|
|
}
|
|
}
|