Compare commits

...

9 Commits

Author SHA1 Message Date
Jeff McCune
56375b82d8 (#30) Fix httpbin Deployment selector match labels
Without this patch the deployment fails with:

```
Deployment/istio-ingress/httpbin dry-run failed, reason: Invalid:
Deployment.apps "httpbin" is invalid: spec.template.metadata.labels:
Invalid value:
map[string]string{"app.kubernetes.io/component":"httpbin",
"app.kubernetes.io/instance":"prod-mesh-httpbin",
"app.kubernetes.io/name":"mesh", "app .kubernetes.io/part-of":"prod",
"holos.run/component.name":"httpbin", "holos.run/project.name":"mesh",
"holos.run/stage.name":"prod", "sidecar.istio.io/inject":"true"}:
`selector` does not match template `labels`
```
2024-03-02 20:23:23 -08:00
Jeff McCune
dc27489249 (#30) Add httpbin Deployment in istio-ingress namespace
This patch gets the Deployment running with a restricted seccomp
profile.
2024-03-02 20:17:16 -08:00
Jeff McCune
7d8a618e25 (#30) Add httpbin Certificate to verify the mesh
Also fix certmanager which was not installing role bindings correctly
because the flux kustomization was writing over the metadata namespace
field.
2024-03-02 17:16:42 -08:00
Jeff McCune
646f6fcdb0 (#30) Add https redirect overlay resources
This patch migrates the https redirect and the
istio-ingressgateway-loopback Service from
`holos-infra/components/core/istio/ingress/templates/deployment`
2024-03-02 15:01:58 -08:00
Jeff McCune
4ce39db745 (#30) Enforce restricted pod security profile on istio-ingress namespace
This patch enforces the restricted pod security profile on the istio
ingress namespace. The istio cni to move the traffic redirection from
the init container to a cni daemon set pod.

Refer to:

 - https://istio.io/latest/docs/setup/additional-setup/pod-security-admission/
 - https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted
2024-03-02 11:16:55 -08:00
Jeff McCune
eba58d1639 (#30) Add ingress component and istio-ingressgateway Deployment
Migrated from holos-infra/components/core/istio/ingress
2024-03-02 10:22:21 -08:00
Jeff McCune
765832d90d (#30) Trim istiod 2024-03-01 16:27:49 -08:00
Jeff McCune
d1163d689a (#30) Add istiod istio controller and meshconfig
This patch adds the standard istiod controller, which depends on
istio-base.

The holos reference platform heavily customizes the meshconfig, so the
upstream istio ConfigMap is disabled in the helm chart values.  The mesh
config is generated from cue data defined in the controller holos
component.

Note: This patch adds a static configuration for the istio meshconfig in
the meshconfig.cue file.  The extauthz providers are a core piece of
functionality in the holos reference platform and a key motivation of
moving to CUE from Helm is the need to dynamically generate the
meshconfig from a platform scoped set of projects and services across
multiple clusters.

For expedience this dynamic generation is not part of this patch but is
expected to replace the static meshconfig once the cluster is more fully
configured with the new cue based holos command line interface.
2024-03-01 16:13:19 -08:00
Jeff McCune
63009ba419 (#30) Fix cue formatting 2024-03-01 10:35:32 -08:00
23 changed files with 2610 additions and 68 deletions

View File

@@ -3066,7 +3066,7 @@ import (
// If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext.
// More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
// +optional
securityContext?: null | #SecurityContext @go(SecurityContext,*SecurityContext) @protobuf(15,bytes,opt)
securityContext?: #SecurityContext @go(SecurityContext,*SecurityContext) @protobuf(15,bytes,opt)
// Whether this container should allocate a buffer for stdin in the container runtime. If this
// is not set, reads from stdin in the container will always result in EOF.
@@ -3982,7 +3982,7 @@ import (
// SecurityContext holds pod-level security attributes and common container settings.
// Optional: Defaults to empty. See type description for default values of each field.
// +optional
securityContext?: null | #PodSecurityContext @go(SecurityContext,*PodSecurityContext) @protobuf(14,bytes,opt)
securityContext?: #PodSecurityContext @go(SecurityContext,*PodSecurityContext) @protobuf(14,bytes,opt)
// ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec.
// If specified, these secrets will be passed to individual puller implementations for them to use.

View File

@@ -324,13 +324,7 @@ import "strings"
// withoutHeader has the same syntax with the header, but has
// opposite meaning.
withoutHeaders?: {
[string]: ({} | {
exact: _
} | {
prefix: _
} | {
regex: _
}) & {
[string]: {
exact?: string
prefix?: string
@@ -383,11 +377,7 @@ import "strings"
// A HTTP rule can either return a direct_response, redirect or
// forward (default) traffic.
redirect?: ({} | {
port: _
} | {
derivePort: _
}) & {
redirect?: {
// On a redirect, overwrite the Authority/Host portion of the URL
// with this value.
authority?: string

View File

@@ -0,0 +1,6 @@
package v1
#Deployment: {
apiVersion: "apps/v1"
kind: "Deployment"
}

View File

@@ -19,3 +19,8 @@ package v1
apiVersion: "v1"
kind: "Pod"
}
#Service: {
apiVersion: "v1"
kind: "Service"
}

View File

@@ -4,6 +4,7 @@ package holos
#PlatformNamespace: {
name: string
labels?: {[string]: string}
annotations?: {[string]: string}
}
// #PlatformNamespaces is a list of namespaces to manage across the platform.

View File

@@ -10,7 +10,9 @@ package holos
}
#HelmChart & {
values: installCRDs: true
values: #UpstreamValues & {
installCRDs: true
}
namespace: #TargetNamespace
chart: {
name: "cert-manager"

View File

@@ -0,0 +1,17 @@
package holos
#InputKeys: component: "istio-base"
#TargetNamespace: "istio-system"
#HelmChart & {
namespace: #TargetNamespace
chart: {
name: "base"
version: "1.20.3"
repository: {
name: "istio"
url: "https://istio-release.storage.googleapis.com/charts"
}
}
values: #IstioValues
}

View File

@@ -1,42 +0,0 @@
package holos
#InputKeys: component: "istio-base"
#TargetNamespace: "istio-system"
#HelmChart & {
namespace: #TargetNamespace
chart: {
name: "base"
version: "1.20.3"
repository: {
name: "istio"
url: "https://istio-release.storage.googleapis.com/charts"
}
}
values: {
global: {
// Used to locate istiod.
istioNamespace: #TargetNamespace
// Switch the hub away from the default docker.io to avoid rate limits
hub: "gcr.io/istio-release"
// 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: []
istiod: enableAnalysis: false
configValidation: true
externalIstiod: false
remotePilotAddress: ""
}
base: {
// Include the CRDs in the helm template output
enableCRDTemplates: true
// Validation webhook configuration url
// For example: https://$remotePilotAddress:15017/validate
validationURL: ""
// For istioctl usage to disable istio config crds in base
enableIstioConfigCRDs: true
}
defaultRevision: "default"
}
}

View File

@@ -0,0 +1,10 @@
package holos
#InputKeys: component: "cni"
#TargetNamespace: "kube-system"
#HelmChart & {
namespace: #TargetNamespace
chart: name: "cni"
values: #IstioValues
}

View File

@@ -0,0 +1,45 @@
package holos
let Name = "httpbin"
let SecretName = #InputKeys.cluster + "-" + Name
let MatchLabels = {app: Name} & #SelectorLabels
#InputKeys: component: Name
#TargetNamespace: "istio-ingress"
#DependsOn: _IngressGateway
#KubernetesObjects & {
apiObjects: {
Certificate: httpbin: #HTTP01Cert & {
_name: Name
_secret: SecretName
}
Deployment: httpbin: #Deployment & {
metadata: {
name: Name
namespace: #TargetNamespace
labels: app: Name
}
spec: selector: matchLabels: MatchLabels
spec: template: {
metadata: labels: MatchLabels
metadata: labels: #CommonLabels
metadata: labels: #IstioSidecar
spec: securityContext: seccompProfile: type: "RuntimeDefault"
spec: containers: [{
name: Name
image: "quay.io/holos/mccutchen/go-httpbin"
ports: [{containerPort: 8080}]
securityContext: {
seccompProfile: type: "RuntimeDefault"
allowPrivilegeEscalation: false
runAsNonRoot: true
runAsUser: 1337
runAsGroup: 1337
capabilities: drop: ["ALL"]
}}]
}
}
}
}

View File

@@ -0,0 +1,155 @@
package holos
import "encoding/json"
#InputKeys: component: "ingress"
#TargetNamespace: "istio-ingress"
#DependsOn: _IstioD
#HelmChart & {
chart: name: "gateway"
namespace: #TargetNamespace
values: #GatewayValues & {
// This component expects the load balancer to send the PROXY protocol header.
// Refer to: https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.2/guide/service/annotations/#proxy-protocol-v2
podAnnotations: "proxy.istio.io/config": json.Marshal(_ProxyProtocol)
// TODO This configuration is specific to the OIS Metal NLB, refactor it out to the metal collection.
service: {
type: "NodePort"
annotations: "service.beta.kubernetes.io/aws-load-balancer-proxy-protocol": "*"
externalTrafficPolicy: "Local"
// Add 30000 to the port to get the Nodeport
ports: [
{
name: "status-port"
port: 15021
protocol: "TCP"
targetPort: 15021
nodePort: 30021
},
{
name: "http2"
port: 80
protocol: "TCP"
targetPort: 80
nodePort: 30080
},
{
name: "https"
port: 443
protocol: "TCP"
targetPort: 443
nodePort: 30443
},
]
}
}
apiObjects: _APIObjects
}
_ProxyProtocol: gatewayTopology: proxyProtocol: {}
// Additional holos specific API Objects
let Name = #GatewayValues.name
let GatewayLabels = {
app: Name
istio: "ingressgateway"
}
let RedirectMetaName = {
name: Name + "-https-redirect"
namespace: #TargetNamespace
}
// https-redirect
_APIObjects: {
Gateway: {
httpsRedirect: #Gateway & {
metadata: RedirectMetaName
spec: selector: GatewayLabels
spec: servers: [{
port: {
number: 80
name: "http2"
protocol: "HTTP2"
}
hosts: ["*"]
// handled by the VirtualService
tls: httpsRedirect: false
}]
}
}
VirtualService: {
httpsRedirect: #VirtualService & {
metadata: RedirectMetaName
spec: hosts: ["*"]
spec: gateways: [RedirectMetaName.name]
spec: http: [{
match: [{withoutHeaders: ":path": prefix: "/.well-known/acme-challenge/"}]
redirect: {
scheme: "https"
redirectCode: 302
}
}]
}
}
}
let LoopbackName = Name + "-loopback"
let LoopbackDescription = "Allows in-cluster traffic to stay in cluster via traffic routing"
let LoopbackLabels = {
app: LoopbackName
istio: "ingressgateway"
}
let LoopbackMetaName = {
name: LoopbackName
namespace: #TargetNamespace
}
// istio-ingressgateway-loopback
_APIObjects: {
Deployment: {
loopback: #Deployment & {
_description: LoopbackDescription
metadata: LoopbackMetaName
spec: {
selector: matchLabels: LoopbackLabels
template: {
metadata: {
annotations: "inject.istio.io/templates": "gateway"
annotations: #Description & {
_Description: LoopbackDescription
}
labels: LoopbackLabels & {"sidecar.istio.io/inject": "true"}
}
spec: {
serviceAccountName: "istio-ingressgateway"
// Allow binding to all ports (such as 80 and 443)
securityContext: {
runAsNonRoot: true
seccompProfile: type: "RuntimeDefault"
sysctls: [{name: "net.ipv4.ip_unprivileged_port_start", value: "0"}]
}
containers: [{
name: "istio-proxy"
image: "auto" // Managed by istiod
securityContext: {
allowPrivilegeEscalation: false
capabilities: drop: ["ALL"]
runAsUser: 1337
runAsGroup: 1337
}
}]
}
}
}
}
}
Service: {
loopback: #Service & {
_description: LoopbackDescription
metadata: LoopbackMetaName
spec: selector: LoopbackLabels
spec: ports: [{port: 80, name: "http"}, {port: 443, name: "https"}]
}
}
}

View File

@@ -0,0 +1,13 @@
package holos
#DependsOn: _IstioBase
#HelmChart: {
chart: {
version: "1.20.3"
repository: {
name: "istio"
url: "https://istio-release.storage.googleapis.com/charts"
}
}
}

View File

@@ -0,0 +1,34 @@
package holos
import "encoding/yaml"
#InputKeys: component: "istiod"
#TargetNamespace: "istio-system"
#HelmChart & {
namespace: #TargetNamespace
chart: {
name: "istiod"
}
values: #IstioValues & {
pilot: {
// The istio meshconfig ConfigMap is handled in the holos component instead of
// the upstream chart so extension providers can be collected from holos data.
configMap: false
// Set to `type: RuntimeDefault` to use the default profile if available.
seccompProfile: type: "RuntimeDefault"
}
}
apiObjects: ConfigMap: istio: #IstioConfigMap
}
#IstioConfigMap: #ConfigMap & {
metadata: {
name: "istio"
namespace: #TargetNamespace
}
data: {
mesh: yaml.Marshal(_MeshConfig)
meshNetworks: "networks: {}"
}
}

View File

@@ -0,0 +1,74 @@
package holos
// Istio meshconfig
// TODO: Generate per-project extauthz providers.
_MeshConfig: {
accessLogEncoding: "JSON"
accessLogFile: "/dev/stdout"
defaultConfig: {
discoveryAddress: "istiod.istio-system.svc:15012"
tracing: zipkin: address: "zipkin.istio-system:9411"
}
defaultProviders: metrics: ["prometheus"]
enablePrometheusMerge: true
// For PROXY PROTOCOL at the ingress gateway.
gatewayTopology: {
numTrustedProxies: 2
}
rootNamespace: "istio-system"
trustDomain: "cluster.local"
extensionProviders: [{
name: "cluster-trace"
zipkin: {
maxTagLength: 56
port: 9411
service: "zipkin.istio-system.svc"
}
}, {
name: "cluster-gatekeeper"
envoyExtAuthzHttp: {
headersToDownstreamOnDeny: [
"content-type",
"set-cookie",
]
headersToUpstreamOnAllow: [
"authorization",
"path",
"x-auth-request-user",
"x-auth-request-email",
"x-auth-request-access-token",
]
includeAdditionalHeadersInCheck: "X-Auth-Request-Redirect": "%REQ(x-forwarded-proto)%://%REQ(:authority)%%REQ(:path)%%REQ(:query)%"
includeRequestHeadersInCheck: [
"authorization",
"cookie",
"x-forwarded-for",
]
port: 4180
service: "oauth2-proxy.istio-ingress.svc.cluster.local"
}
}, {
name: "core-authorizer"
envoyExtAuthzHttp: {
headersToDownstreamOnDeny: [
"content-type",
"set-cookie",
]
headersToUpstreamOnAllow: [
"authorization",
"path",
"x-auth-request-user",
"x-auth-request-email",
"x-auth-request-access-token",
]
includeAdditionalHeadersInCheck: "X-Auth-Request-Redirect": "%REQ(x-forwarded-proto)%://%REQ(:authority)%%REQ(:path)%%REQ(:query)%"
includeRequestHeadersInCheck: [
"authorization",
"cookie",
"x-forwarded-for",
]
port: 4180
service: "oauth2-proxy.prod-core-system.svc.cluster.local"
}
}]
}

View File

@@ -0,0 +1,161 @@
package holos
// Default values.yaml imported from the cni chart
#CNIValues: {
cni: {
hub: ""
tag: ""
variant: ""
image: "install-cni"
pullPolicy: ""
// Refer to https://istio.io/latest/docs/setup/additional-setup/cni/#installing-with-helm
enabled: #IstioValues.istio_cni.enabled
// Configuration log level of istio-cni binary
// by default istio-cni send all logs to UDS server
// if want to see them you need change global.logging.level with cni:debug
logLevel: "debug"
// 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: [
"istio-system",
"kube-system",
]
// Allows user to set custom affinity for the DaemonSet
affinity: {}
// Custom annotations on pod level, if you need them
podAnnotations: {}
// If this value is set a RoleBinding will be created
// in the same namespace as the istio-cni DaemonSet is created.
// This can be used to bind a preexisting ClusterRole to the istio/cni ServiceAccount
// e.g. if you use PodSecurityPolicies
psp_cluster_role: ""
// 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: #IstioValues.istio_cni.chained
// Allow the istio-cni container to run in privileged mode, needed for some platforms (e.g. OpenShift) or features (repairPods)
privileged: false
// 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 redirection mode: "iptables" or "ebpf"
redirectMode: "iptables"
// Set ambient config dir path: defaults to /etc/ambient-config
configDir: ""
}
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).
labelPods: false
// deletePods will delete any broken pod. These will then be rescheduled, hopefully onto a node that is fully ready.
deletePods: true
// 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`.
repairPods: false
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.20.3"
// 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: "default:info,cni: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.
imagePullSecrets: []
// - private-registry-key
// Default resources allocated
defaultResources: {
requests: {
cpu: "100m"
memory: "100Mi"
}
}
}
}

View File

@@ -0,0 +1,170 @@
package holos
// Gateway default values.yaml imported from the gateway chart.
#GatewayValues: {
// Name allows overriding the release name. Generally this should not be set
name: "istio-ingressgateway"
// revision declares which revision this gateway is a part of
revision: ""
// Controls the spec.replicas setting for the Gateway deployment if set.
// Otherwise defaults to Kubernetes Deployment default (1).
replicaCount: null
kind: "Deployment"
rbac: {
// If enabled, roles will be created to enable accessing certificates from Gateways. This is not needed
// when using http://gateway-api.org/.
enabled: true
}
serviceAccount: {
// If set, a service account will be created. Otherwise, the default is used
create: true
// Annotations to add to the service account
annotations: {}
// The name of the service account to use.
// If not set, the release name is used
name: ""
}
podAnnotations: {
"prometheus.io/port": "15020"
"prometheus.io/scrape": "true"
"prometheus.io/path": "/stats/prometheus"
"inject.istio.io/templates": "gateway"
"sidecar.istio.io/inject": "true"
...
}
// Define the security context for the pod.
// If unset, this will be automatically set to the minimum privileges required to bind to port 80 and 443.
// On Kubernetes 1.22+, this only requires the `net.ipv4.ip_unprivileged_port_start` sysctl.
securityContext: {
seccompProfile: type: "RuntimeDefault"
sysctls: [{name: "net.ipv4.ip_unprivileged_port_start", value: "0"}]
}
containerSecurityContext: null
service: {
// Type of service. Set to "None" to disable the service entirely
type: string | *"LoadBalancer"
ports: [...] | *[{
name: "status-port"
port: 15021
protocol: "TCP"
targetPort: 15021
}, {
name: "http2"
port: 80
protocol: "TCP"
targetPort: 80
}, {
name: "https"
port: 443
protocol: "TCP"
targetPort: 443
}]
annotations: {...}
loadBalancerIP: ""
loadBalancerSourceRanges: []
externalTrafficPolicy: string | *""
externalIPs: []
ipFamilyPolicy: ""
ipFamilies: []
}
resources: {
requests: {
cpu: "100m"
memory: "128Mi"
}
limits: {
cpu: "2000m"
memory: "1024Mi"
}
}
autoscaling: {
enabled: true
minReplicas: 1
maxReplicas: 5
targetCPUUtilizationPercentage: 80
autoscaleBehavior: {}
}
// Pod environment variables
env: {}
// Labels to apply to all resources
labels: {}
// Annotations to apply to all resources
annotations: {}
nodeSelector: {}
tolerations: []
topologySpreadConstraints: []
affinity: {}
// If specified, the gateway will act as a network gateway for the given network.
networkGateway: ""
// Specify image pull policy if default behavior isn't desired.
// Default behavior: latest images will be Always else IfNotPresent
imagePullPolicy: ""
imagePullSecrets: []
// This value is used to configure a Kubernetes PodDisruptionBudget for the gateway.
//
// By default, the `podDisruptionBudget` is disabled (set to `{}`),
// which means that no PodDisruptionBudget resource will be created.
//
// To enable the PodDisruptionBudget, configure it by specifying the
// `minAvailable` or `maxUnavailable`. For example, to set the
// minimum number of available replicas to 1, you can update this value as follows:
//
// podDisruptionBudget:
// minAvailable: 1
//
// Or, to allow a maximum of 1 unavailable replica, you can set:
//
// podDisruptionBudget:
// maxUnavailable: 1
//
// You can also specify the `unhealthyPodEvictionPolicy` field, and the valid values are `IfHealthyBudget` and `AlwaysAllow`.
// For example, to set the `unhealthyPodEvictionPolicy` to `AlwaysAllow`, you can update this value as follows:
//
// podDisruptionBudget:
// minAvailable: 1
// unhealthyPodEvictionPolicy: AlwaysAllow
//
// To disable the PodDisruptionBudget, you can leave it as an empty object `{}`:
//
// podDisruptionBudget: {}
//
podDisruptionBudget: {}
terminationGracePeriodSeconds: 30
// A list of `Volumes` added into the Gateway Pods. See
// https://kubernetes.io/docs/concepts/storage/volumes/.
volumes: []
// A list of `VolumeMounts` added into the Gateway Pods. See
// https://kubernetes.io/docs/concepts/storage/volumes/.
volumeMounts: []
// Configure this to a higher priority class in order to make sure your Istio gateway pods
// will not be killed because of low priority class.
// Refer to https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass
// for more detail.
priorityClassName: ""
}

View File

@@ -4,9 +4,11 @@ package holos
#InputKeys: project: "mesh"
// Shared dependencies for all components in this collection.
#Kustomization: spec: targetNamespace: #TargetNamespace
#DependsOn: _Namespaces
// Common Dependencies
_CertManager: CertManager: name: "\(#InstancePrefix)-certmanager"
_Namespaces: Namespaces: name: "\(#StageName)-secrets-namespaces"
_CertManager: CertManager: name: "\(#InstancePrefix)-certmanager"
_Namespaces: Namespaces: name: "\(#StageName)-secrets-namespaces"
_IstioBase: IstioBase: name: "\(#InstancePrefix)-istio-base"
_IstioD: IstioD: name: "\(#InstancePrefix)-istiod"
_IngressGateway: IngressGateway: name: "\(#InstancePrefix)-ingress"

View File

@@ -0,0 +1,547 @@
package holos
// Default istio values from the istiod chart using cue import values.yaml
#IstioValues: {
// Discovery Settings
pilot: {
autoscaleEnabled: true
autoscaleMin: 1
autoscaleMax: 5
autoscaleBehavior: {}
replicaCount: 1
rollingMaxSurge: "100%"
rollingMaxUnavailable: "25%"
hub: string | *""
tag: string | *""
variant: string | *""
// 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: {...}
// Additional container arguments
extraContainerArgs: []
env: {}
cpu: targetAverageUtilization: 80
// Additional volumeMounts to the istiod container
volumeMounts: []
// Additional volumes to the istiod pod
volumes: []
nodeSelector: {}
podAnnotations: {}
serviceAnnotations: {}
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: ""
// This is used to set the source of configuration for
// the associated address in configSource, if nothing is specified
// the default MCP is assumed.
configSource: {
subscribedResources: []
}
plugins: []
// 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 | false
// 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: []
}
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"
}
telemetry: {
enabled: true
v2: {
// For Null VM case now.
// This also enables metadata exchange.
enabled: true
metadataExchange: {
// Indicates whether to enable WebAssembly runtime for metadata exchange filter.
wasmEnabled: false
}
// Indicate if prometheus stats filter is enabled or not
prometheus: {
enabled: true
// Indicates whether to enable WebAssembly runtime for stats filter.
wasmEnabled: false
// overrides stats EnvoyFilter configuration.
configOverride: {
gateway: {}
inboundSidecar: {}
outboundSidecar: {}
}
}
// stackdriver filter settings.
stackdriver: {
enabled: false
logging: false
monitoring: false
topology: false // deprecated. setting this to true will have no effect, as this option is no longer supported.
disableOutbound: false
// configOverride parts give you the ability to override the low level configuration params passed to envoy filter.
configOverride: {}
}
// e.g.
// disable_server_access_logging: false
// disable_host_header_fallback: true
// Access Log Policy Filter Settings. This enables filtering of access logs from stackdriver.
accessLogPolicy: {
enabled: false
// To reduce the number of successful logs, default log window duration is
// set to 12 hours.
logWindowDuration: "43200s"
}
}
}
// 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
}
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: {
enabled: true
}
// The values aren't mutable due to a current PodDisruptionBudget limitation
// minAvailable: 1
// 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: {
requests: cpu: "10m"
}
// memory: 128Mi
// limits:
// cpu: 100m
// memory: 128Mi
// Default hub for Istio images.
// Releases are published to docker hub under 'istio' project.
// Dev builds from prow are on gcr.io
hub: string | *"docker.io/istio"
// Default tag for Istio images.
tag: string | *"1.20.3"
// Variant of the image to use.
// Currently supported are: [debug, distroless]
variant: string | *""
// Specify image pull policy if default behavior isn't desired.
// Default behavior: latest images will be Always else IfNotPresent.
imagePullPolicy: string | *""
// 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.
imagePullSecrets: []
// - private-registry-key
// 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
// Whether to restrict the applications namespace the controller manages;
// If not set, controller watches all namespaces
oneNamespace: 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
//- "{{ valueOrDefault .DeploymentMeta.Namespace \"default\" }}.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"
//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.
// If using stackdriver tracer outside GCP, set env GOOGLE_APPLICATION_CREDENTIALS to the GCP credential file.
tracer: "zipkin"
}
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
// Configure the policy for validating JWT.
// Currently, two options are supported: "third-party-jwt" and "first-party-jwt".
jwtPolicy: "third-party-jwt"
// 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
// If enabled, gateway-api types will be validated using the standard upstream validation logic.
// This is an alternative to deploying the standalone validation server the project provides.
// This is disabled by default, as the cluster may already have a validation server; while technically
// it works to have multiple redundant validations, this adds complexity and operational risks.
// Users should consider enabling this if they want full gateway-api validation but don't have other validation servers.
validateGateway: false
}
// keep in sync with settings used when installing the Istio CNI chart
istio_cni: {
// Refer to https://istio.io/latest/docs/setup/additional-setup/cni/#installing-with-helm
// values.istio_cni.enabled should be set to the same value as values.cni.enabled.
// values.istio_cni.chained should be set to the same value as values.cni.chained.
enabled: true
chained: true
}
}

View File

@@ -0,0 +1,28 @@
package holos
#IstioValues: {
global: {
// Used to locate istiod.
istioNamespace: "istio-system"
// Switch the hub away from the default docker.io to avoid rate limits
hub: "gcr.io/istio-release"
// 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: []
istiod: enableAnalysis: false
configValidation: true
externalIstiod: false
remotePilotAddress: ""
}
base: {
// Include the CRDs in the helm template output
enableCRDTemplates: true
// Validation webhook configuration url
// For example: https://$remotePilotAddress:15017/validate
validationURL: ""
// For istioctl usage to disable istio config crds in base
enableIstioConfigCRDs: true
}
defaultRevision: "default"
}

View File

@@ -1,6 +1,14 @@
package holos
let Privileged = {labels: "pod-security.kubernetes.io/enforce": "privileged"}
// Refer to https://kubernetes.io/docs/concepts/security/pod-security-standards/
let Restricted = {
labels: "pod-security.kubernetes.io/enforce": "restricted"
labels: "pod-security.kubernetes.io/enforce-version": "latest"
}
let Privileged = {
labels: "pod-security.kubernetes.io/enforce": "privileged"
labels: "pod-security.kubernetes.io/enforce-version": "latest"
}
// #PlatformNamespaces is the union of all namespaces across all cluster types. Namespaces are created in all clusters regardless of if they're
// used within the cluster or not. The is important for security and consistency with IAM, RBAC, and Secrets sync between clusters.
@@ -10,7 +18,7 @@ let Privileged = {labels: "pod-security.kubernetes.io/enforce": "privileged"}
{name: "flux-system"},
{name: "ceph-system"} & Privileged,
{name: "istio-system"} & Privileged,
{name: "istio-ingress"} & Privileged,
{name: "istio-ingress"} & Restricted,
{name: "cert-manager"},
{name: "argocd"},
]

View File

@@ -3,12 +3,16 @@ package holos
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
ksv1 "kustomize.toolkit.fluxcd.io/kustomization/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"
cm "cert-manager.io/clusterissuer/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"
"encoding/yaml"
)
@@ -36,11 +40,17 @@ _apiVersion: "holos.run/v1alpha1"
// #TargetNamespace is the target namespace for a holos component.
#TargetNamespace: string
// #SelectorLabels are mixed into selectors.
#SelectorLabels: {
"holos.run/stage.name": #StageName
"holos.run/project.name": #CollectionName
"holos.run/component.name": #ComponentName
...
}
// #CommonLabels are mixed into every kubernetes api object.
#CommonLabels: {
"holos.run/stage.name": #StageName
"holos.run/project.name": #CollectionName
"holos.run/component.name": #ComponentName
#SelectorLabels
"app.kubernetes.io/part-of": #StageName
"app.kubernetes.io/name": #CollectionName
"app.kubernetes.io/component": #ComponentName
@@ -49,14 +59,26 @@ _apiVersion: "holos.run/v1alpha1"
}
#ClusterObject: {
_description: string | *""
metadata: metav1.#ObjectMeta & {
labels: #CommonLabels
annotations: #Description & {
_Description: _description
...
}
}
...
}
#Description: {
_Description: string | *""
"holos.run/description": _Description
...
}
#NamespaceObject: #ClusterObject & {
metadata: namespace: string
...
}
// Kubernetes API Objects
@@ -68,14 +90,37 @@ _apiVersion: "holos.run/v1alpha1"
}
#ClusterRole: #ClusterObject & rbacv1.#ClusterRole
#ClusterRoleBinding: #ClusterObject & rbacv1.#ClusterRoleBinding
#ClusterIssuer: #ClusterObject & cm.#ClusterIssuer & {...}
#ClusterIssuer: #ClusterObject & ci.#ClusterIssuer & {...}
#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
#Gateway: #NamespaceObject & gw.#Gateway
#VirtualService: #NamespaceObject & vs.#VirtualService
#Certificate: #NamespaceObject & crt.#Certificate
// #HTTP01Cert defines a http01 certificate.
#HTTP01Cert: #Certificate & {
_name: string
_secret: string | *_name
let Host = _name + "." + #ClusterDomain
metadata: {
name: _secret
namespace: string | *#TargetNamespace
}
spec: {
commonName: Host
dnsNames: [Host]
secretName: _secret
issuerRef: kind: "ClusterIssuer"
issuerRef: name: "letsencrypt"
}
}
// Flux Kustomization CRDs
#Kustomization: #NamespaceObject & ksv1.#Kustomization & {
@@ -300,6 +345,15 @@ _apiVersion: "holos.run/v1alpha1"
// #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"
...
}
// By default, render kind: Skipped so holos knows to skip over intermediate cue files.
// This enables the use of holos render ./foo/bar/baz/... when bar contains intermediary constraints which are not complete components.
// Holos skips over these intermediary cue instances.

View File

@@ -1 +1 @@
0
6