Compare commits

...

12 Commits

Author SHA1 Message Date
Jeff McCune
a689c53a9c (#47) v0.62.1 - Projects v1alpha1 milestone complete 2024-04-03 15:32:34 -07:00
Jeff McCune
58cdda1d35 Merge pull request #100 from holos-run/jeff/47-iam-v2
(#47) Remove the prod-iam-zitadel namespace
2024-04-03 15:23:48 -07:00
Jeff McCune
bcb02b5c5c (#47) Remove the prod-iam-zitadel namespace
No longer needed, cluster has moved to prod-iam namespace.
2024-04-03 15:10:30 -07:00
Jeff McCune
0736c7de1a (#47) Bind ALL VirtualServices to the default gateway
Problem:
The VirtualService that catches auth routes for paths, e.g.
`/holos/authproxy/istio-ingress` is bound to the default gateway which
no longer exists because it has no hosts.

Solution:
It's unnecessary and complicated to create a Gateway for every project.
Instead, put all server entries into one `default` gateway and
consolidate the list using CUE.

Result:
It's easier to reason about this system.  There is only one ingress
gateway, `default` and everything gets added to it.  VirtualServices
need only bind to this gateway, which has a hosts entry appropriately
namespaced for the project.
2024-04-03 14:56:40 -07:00
Jeff McCune
28be9f9fbb (#47) Use the project specific Gateway
The login service is unavailable because the wrong gateway is used.
When using projects the VS needs to attach to the correct Gateway.
2024-04-03 12:59:48 -07:00
Jeff McCune
647681de38 (#99) Restore backups from prod-iam namespace
This patch configures the standby cluster to restore backups from the
prod-iam namespace instead of the prod-iam-zitadel namespace.
2024-04-03 12:30:12 -07:00
Jeff McCune
81beb5c539 (#47) Restore ZITADEL from existing backups
Problem:
The ZITADEL database isn't restoring into the prod-iam namespace after
moving from prod-iam-zitadel because no backup exists at the bucket
path.

Solution:
Hard-code the path to the old namespace to restore the database.  We'll
figure out how to move the backups to the new location in a follow up
change.
2024-04-03 11:44:16 -07:00
Jeff McCune
5c1e0a29c8 (#47) Have Ceph depend on secret stores
Another kustomization reconciling too early.
2024-04-03 11:22:15 -07:00
Jeff McCune
01ac5276a9 (#47) Have Gateway depend on secret stores
The `prod-platform-gateway` kustomization is reconciling early:

ExternalSecret/istio-ingress/argocd.ois.run dry-run failed: failed to
get API group resources: unable to retrieve the complete list of server
APIs: external-secrets.io/v1beta1: the server could not find the
requested resource
2024-04-03 11:20:15 -07:00
Jeff McCune
e40594ad8e (#47) Move ZITADEL to prod-iam project namespace
This patch moves ZITADEL from the prod-iam-zitadel namespace to the
projects managed prod-iam namespace, which is the prod environment of
the prod stage of the iam project.
2024-04-03 11:06:55 -07:00
Jeff McCune
bc9c6a622a (#97) Increase ZITADEL pgdata volume to 20Gi
Problem:

```
❯ k exec zitadel-pgha1-4npq-0 -it -- bash
Defaulted container "database" out of: database, replication-cert-copy, pgbackrest, pgbackrest-config, postgres-startup (init), nss-wrapper-init (init)
bash-4.4$ df -h
Filesystem      Size  Used Avail Use% Mounted on
overlay         119G   51G   68G  43% /
tmpfs            64M     0   64M   0% /dev
/dev/rbd3       9.8G  9.8G     0 100% /pgdata
/dev/sda6       119G   51G   68G  43% /tmp
tmpfs            16G   24K   16G   1% /pgconf/tls
tmpfs            16G   24K   16G   1% /etc/database-containerinfo
tmpfs            16G   16K   16G   1% /etc/patroni
tmpfs            16G     0   16G   0% /dev/shm
tmpfs            16G   28K   16G   1% /etc/pgbackrest/conf.d
tmpfs            16G   12K   16G   1% /run/secrets/kubernetes.io/serviceaccount
tmpfs           7.9G     0  7.9G   0% /proc/acpi
tmpfs           7.9G     0  7.9G   0% /proc/scsi
tmpfs           7.9G     0  7.9G   0% /sys/firmware
```
2024-04-03 10:09:49 -07:00
Jeff McCune
17f22199b7 (#86) ArgoCD - Disable Dex
Not needed
2024-04-02 15:47:22 -07:00
15 changed files with 79 additions and 63 deletions

View File

@@ -1,5 +1,21 @@
package holos
#PlatformServers: {
for cluster in #Platform.clusters {
(cluster.name): {
"https-istio-ingress-httpbin": {
let cert = #PlatformCerts[cluster.name+"-httpbin"]
hosts: [for host in cert.spec.dnsNames {"istio-ingress/\(host)"}]
port: name: "https-istio-ingress-httpbin"
port: number: 443
port: protocol: "HTTPS"
tls: credentialName: cert.spec.secretName
tls: mode: "SIMPLE"
}
}
}
}
#PlatformCerts: {
// Globally scoped platform services are defined here.
login: #PlatformCert & {

View File

@@ -4,4 +4,4 @@ package holos
#InputKeys: project: "iam"
// Shared dependencies for all components in this collection.
#DependsOn: namespaces: name: "\(#StageName)-secrets-namespaces"
#DependsOn: namespaces: name: "\(#StageName)-secrets-stores"

View File

@@ -37,7 +37,7 @@ spec: components: KubernetesObjectsList: [
#KubernetesObjects & {
metadata: name: "prod-iam-postgres"
_dependsOn: "prod-secrets-namespaces": _
_dependsOn: "prod-secrets-stores": _
_dependsOn: "prod-iam-postgres-certs": _
apiObjectMap: OBJECTS.apiObjectMap
},
@@ -68,7 +68,7 @@ let OBJECTS = #APIObjects & {
replicas: 2
dataVolumeClaimSpec: {
accessModes: ["ReadWriteOnce"]
resources: requests: storage: "10Gi"
resources: requests: storage: "20Gi"
}
}]
standby: {
@@ -124,7 +124,7 @@ let OBJECTS = #APIObjects & {
"\(BucketRepoName)-cipher-type": "aes-256-cbc"
// "The convention we recommend for setting this variable is /pgbackrest/$NAMESPACE/$CLUSTER_NAME/repoN"
// Ref: https://access.crunchydata.com/documentation/postgres-operator/latest/tutorials/backups-disaster-recovery/backups#understanding-backup-configuration-and-basic-operations
"\(BucketRepoName)-path": "/pgbackrest/\(#TargetNamespace)/\(metadata.name)/\(manual.repoName)"
"\(BucketRepoName)-path": "/pgbackrest/\(metadata.namespace)/\(metadata.name)/\(manual.repoName)"
}
repos: [
{
@@ -165,7 +165,7 @@ let HighlyAvailable = {
replicas: 2
dataVolumeClaimSpec: {
accessModes: ["ReadWriteOnce"]
resources: requests: storage: string | *"10Gi"
resources: requests: storage: string | *"20Gi"
}
affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: [{
weight: 1

View File

@@ -1,7 +1,9 @@
package holos
#InstancePrefix: "prod-iam"
#TargetNamespace: #InstancePrefix + "-zitadel"
#InstancePrefix: "prod-iam"
// The namespace is managed by a project.
#TargetNamespace: _Projects.iam.environments.prod.namespace
// _DBName is the database name used across multiple holos components in this project
_DBName: "zitadel"

View File

@@ -25,9 +25,9 @@ spec: components: HelmChartList: [
_values: #ArgoCDValues & {
kubeVersionOverride: "1.29.0"
global: domain: "argocd.\(#ClusterName).\(#Platform.org.domain)"
dex: enabled: false
// for integration with istio
configs: params: "server.insecure": true
configs: cm: {
"admin.enabled": false
"oidc.config": yaml.Marshal(OIDCConfig)
@@ -49,7 +49,7 @@ let OBJECTS = #APIObjects & {
ArgoCD + ".\(#Platform.org.domain)",
ArgoCD + ".\(#ClusterName).\(#Platform.org.domain)",
]
spec: gateways: ["istio-ingress/\(Namespace)"]
spec: gateways: ["istio-ingress/default"]
spec: http: [{route: [{destination: {
host: "argocd-server.\(Namespace).svc.cluster.local"
port: number: 80

View File

@@ -887,7 +887,7 @@ package holos
//# Dex
dex: {
// -- Enable dex
enabled: true
enabled: *true | false
// -- Dex name
name: "dex-server"

View File

@@ -7,48 +7,53 @@ let Name = "gateway"
#InputKeys: component: Name
#TargetNamespace: "istio-ingress"
let LoginCert = #PlatformCerts.login
spec: components: KubernetesObjectsList: [
#KubernetesObjects & {
_dependsOn: "prod-secrets-namespaces": _
_dependsOn: "prod-mesh-istio-base": _
_dependsOn: "prod-mesh-ingress": _
_dependsOn: "prod-secrets-stores": _
_dependsOn: "prod-mesh-istio-base": _
_dependsOn: "prod-mesh-ingress": _
metadata: name: "\(#InstancePrefix)-\(Name)"
apiObjectMap: OBJECTS.apiObjectMap
},
]
// GatewayServers represents all hosts for all VirtualServices in the cluster attached to Gateway/default
// NOTE: This is a critical structure because the default Gateway should be used in most cases.
let GatewayServers = {
for Project in _Projects {
for server in (#ProjectTemplate & {project: Project}).ClusterGatewayServers {
(server.port.name): server
}
}
for k, svc in #OptionalServices {
if svc.enabled && list.Contains(svc.clusterNames, #ClusterName) {
for server in svc.servers {
(server.port.name): server
}
}
}
if #PlatformServers[#ClusterName] != _|_ {
for server in #PlatformServers[#ClusterName] {
(server.port.name): server
}
}
}
let OBJECTS = #APIObjects & {
apiObjects: {
ExternalSecret: login: #ExternalSecret & {
_name: "login"
}
Gateway: default: #Gateway & {
metadata: name: "default"
metadata: namespace: #TargetNamespace
spec: selector: istio: "ingressgateway"
spec: servers: [
{
hosts: [for dnsName in LoginCert.spec.dnsNames {"prod-iam-zitadel/\(dnsName)"}]
port: name: "https-prod-iam-login"
port: number: 443
port: protocol: "HTTPS"
tls: credentialName: LoginCert.spec.secretName
tls: mode: "SIMPLE"
},
]
spec: servers: [for x in GatewayServers {x}]
}
for k, svc in #OptionalServices {
if svc.enabled && list.Contains(svc.clusterNames, #ClusterName) {
Gateway: "\(svc.name)": #Gateway & {
metadata: name: svc.name
metadata: namespace: #TargetNamespace
spec: selector: istio: "ingressgateway"
spec: servers: [for s in svc.servers {s}]
}
for k, s in svc.servers {
ExternalSecret: "\(s.tls.credentialName)": _
}

View File

@@ -3,7 +3,6 @@ package holos
let Name = "httpbin"
let ComponentName = "\(#InstancePrefix)-\(Name)"
let SecretName = #InputKeys.cluster + "-" + Name
let MatchLabels = {
app: Name
"app.kubernetes.io/instance": ComponentName
@@ -18,7 +17,7 @@ let Metadata = {
#TargetNamespace: "istio-ingress"
let Cert = #PlatformCerts[SecretName]
let Cert = #PlatformCerts["\(#ClusterName)-httpbin"]
spec: components: KubernetesObjectsList: [
#KubernetesObjects & {
@@ -63,24 +62,10 @@ let OBJECTS = #APIObjects & {
{port: 80, targetPort: 8080, protocol: "TCP", name: "http"},
]
}
Gateway: httpbin: #Gateway & {
metadata: Metadata
spec: selector: istio: "ingressgateway"
spec: servers: [
{
hosts: [for host in Cert.spec.dnsNames {"\(#TargetNamespace)/\(host)"}]
port: name: "https-\(ComponentName)"
port: number: 443
port: protocol: "HTTPS"
tls: credentialName: Cert.spec.secretName
tls: mode: "SIMPLE"
},
]
}
VirtualService: httpbin: #VirtualService & {
metadata: Metadata
spec: hosts: [for host in Cert.spec.dnsNames {host}]
spec: gateways: ["\(#TargetNamespace)/\(Name)"]
spec: gateways: ["istio-ingress/default"]
spec: http: [{route: [{destination: host: Name}]}]
}
}

View File

@@ -10,7 +10,7 @@ package holos
spec: components: HelmChartList: [
#HelmChart & {
_dependsOn: "prod-secrets-namespaces": _
_dependsOn: "prod-secrets-stores": _
metadata: name: "prod-metal-ceph"

View File

@@ -67,7 +67,7 @@ let OBJECTS = #APIObjects & {
metadata: name: Name
metadata: namespace: #TargetNamespace
spec: hosts: [for cert in Vault.certs {cert.spec.commonName}]
spec: gateways: ["istio-ingress/\(Name)"]
spec: gateways: ["istio-ingress/default"]
spec: http: [
{
route: [

View File

@@ -34,6 +34,7 @@ _Projects: #Projects & {
iam: {
resourceId: ZitadelProjectID
hosts: login: _
clusters: {
core1: _
core2: _

View File

@@ -8,7 +8,7 @@ package holos
// Refer to [Using Cert Manager to Deploy TLS for Postgres on Kubernetes](https://www.crunchydata.com/blog/using-cert-manager-to-deploy-tls-for-postgres-on-kubernetes)
#TargetNamespace: "prod-iam-zitadel"
#TargetNamespace: _Projects.iam.environments.prod.namespace
#InputKeys: component: "postgres-certs"
let DBName = "zitadel"

View File

@@ -22,7 +22,6 @@ let Privileged = {
{name: "istio-ingress"} & Restricted,
{name: "cert-manager"},
{name: "argocd"},
{name: "prod-iam-zitadel"},
{name: "arc-system"},
{name: "arc-runner"},
// https://github.com/CrunchyData/postgres-operator-examples/blob/main/kustomize/install/namespace/namespace.yaml

View File

@@ -55,6 +55,18 @@ import "encoding/yaml"
}
}
// ClusterGatewayServers provides a struct of Gateway servers for the current cluster.
// This is intended for Gateway/default to add all servers to the default gateway.
ClusterGatewayServers: {
if project.clusters[#ClusterName] != _|_ {
for Stage in project.stages {
for server in GatewayServers[Stage.name] {
(server.port.name): server
}
}
}
}
workload: resources: {
// Provide resources only if the project is managed on --cluster-name
if project.clusters[#ClusterName] != _|_ {
@@ -64,10 +76,6 @@ import "encoding/yaml"
// Istio Gateway
"\(stage.slug)-gateway": #KubernetesObjects & {
apiObjectMap: (#APIObjects & {
apiObjects: Gateway: (stage.slug): #Gateway & {
spec: servers: [for server in GatewayServers[stage.name] {server}]
}
for host in GatewayServers[stage.name] {
apiObjects: ExternalSecret: (host.tls.credentialName): metadata: namespace: "istio-ingress"
}
@@ -186,7 +194,7 @@ let HTTPBIN = {
let Project = project
let Env = env
spec: hosts: [for host in (#EnvHosts & {project: Project, env: Env}).hosts {host.name}]
spec: gateways: ["istio-ingress/\(env.stageSlug)"]
spec: gateways: ["istio-ingress/default"]
spec: http: [{route: [{destination: host: Name}]}]
}
}
@@ -359,7 +367,7 @@ let AUTHPROXY = {
VirtualService: (Name): #VirtualService & {
metadata: Metadata
spec: hosts: ["*"]
spec: gateways: ["istio-ingress/\(stage.slug)"]
spec: gateways: ["istio-ingress/default"]
spec: http: [{
match: [{uri: prefix: AuthProxySpec.proxyPrefix}]
route: [{

View File

@@ -1 +1 @@
0
1