Compare commits

..

1 Commits

Author SHA1 Message Date
unkin-agent 797e1bc7bc kea-operator: bump to v0.1.6
Stop the operator's reconcile hot-loop, which was hot-reloading Kea about 9 times a second and flooding the dhcp-system logs.
2026-10-06 00:05:34 +11:00
58 changed files with 102 additions and 1459 deletions
+1 -1
View File
@@ -36,7 +36,7 @@ spec:
mountPath: /combined-certs mountPath: /combined-certs
containers: containers:
- name: api - name: api
image: artifactapi.k8s.syd1.au.unkin.net/docker-internal/artifactapi:v3.13.1 image: git.unkin.net/unkin/artifactapi:v3.12.0
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
ports: ports:
- containerPort: 8000 - containerPort: 8000
-105
View File
@@ -1,105 +0,0 @@
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: image-keeper
namespace: artifactapi
spec:
selector:
matchLabels:
app: image-keeper
updateStrategy:
rollingUpdate:
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: image-keeper
spec:
automountServiceAccountToken: false
priorityClassName: low
tolerations:
- operator: Exists
securityContext:
runAsNonRoot: true
runAsUser: 65532
runAsGroup: 65532
seccompProfile:
type: RuntimeDefault
initContainers:
# artifactapi is distroless with no exit-0 flag, so run a static busybox as `true`
- name: copy-true
image: busybox:1.37.0-musl
imagePullPolicy: IfNotPresent
command: ["cp", "/bin/busybox", "/keeper/true"]
volumeMounts:
- name: keeper
mountPath: /keeper
resources:
limits:
cpu: 10m
memory: 16Mi
requests:
cpu: 1m
memory: 4Mi
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
- name: api
image: artifactapi.k8s.syd1.au.unkin.net/docker-internal/artifactapi:v3.13.1
imagePullPolicy: IfNotPresent
command: ["/keeper/true"]
volumeMounts:
- name: keeper
mountPath: /keeper
readOnly: true
resources:
limits:
cpu: 10m
memory: 16Mi
requests:
cpu: 1m
memory: 4Mi
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
- name: ui
image: artifactapi.k8s.syd1.au.unkin.net/docker-internal/artifactapi-ui:v3.13.1
imagePullPolicy: IfNotPresent
command: ["true"]
resources:
limits:
cpu: 10m
memory: 16Mi
requests:
cpu: 1m
memory: 4Mi
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
containers:
- name: pause
image: rancher/mirrored-pause:3.6
imagePullPolicy: IfNotPresent
resources:
limits:
cpu: 10m
memory: 16Mi
requests:
cpu: 1m
memory: 4Mi
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
volumes:
- name: keeper
emptyDir: {}
-1
View File
@@ -11,7 +11,6 @@ resources:
- cnpg_pooler.yaml - cnpg_pooler.yaml
- gateway.yaml - gateway.yaml
- httproute.yaml - httproute.yaml
- image-keeper.yaml
- namespace.yaml - namespace.yaml
- oauth2-proxy-configmap.yaml - oauth2-proxy-configmap.yaml
- oauth2-proxy-deployment.yaml - oauth2-proxy-deployment.yaml
+1 -1
View File
@@ -22,7 +22,7 @@ spec:
automountServiceAccountToken: true automountServiceAccountToken: true
containers: containers:
- name: ui - name: ui
image: artifactapi.k8s.syd1.au.unkin.net/docker-internal/artifactapi-ui:v3.13.1 image: git.unkin.net/unkin/artifactapi-ui:v3.12.0
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
ports: ports:
- containerPort: 80 - containerPort: 80
@@ -16,6 +16,5 @@ resources:
- identity.yaml - identity.yaml
- lb1.yaml - lb1.yaml
- logviewer.yaml - logviewer.yaml
- mail.yaml
- vlogs.yaml - vlogs.yaml
- watchstate.yaml - watchstate.yaml
@@ -1,14 +0,0 @@
---
apiVersion: bind.unkin.net/v1alpha1
kind: DNSRecord
metadata:
name: mail-dns-internal
namespace: bind-internal
spec:
zoneRef: unkin-net
name: mail
type: A
ttl: 600
values:
# stalwart-lb PureLB VIP (IMAPS, submission, HTTPS).
- 198.18.200.18
@@ -1,6 +1,6 @@
--- ---
# Let's Encrypt *.main.unkin.net wildcard for the haproxy edge (pve, arr stack, # Let's Encrypt *.main.unkin.net wildcard for the haproxy edge (pve, arr stack,
# jellyfin, stalwart webadmin/autoconfig) and the mail smarthost. DNS-01 needs the delegated # jellyfin, stalwart webadmin/autoconfig). DNS-01 needs the delegated
# _acme-challenge.main.unkin.net CNAME in the public unkin.net zone. # _acme-challenge.main.unkin.net CNAME in the public unkin.net zone.
# _acme-challenge.main.unkin.net. CNAME _acme-challenge.main.acme.unkin.net. # _acme-challenge.main.unkin.net. CNAME _acme-challenge.main.acme.unkin.net.
apiVersion: cert-manager.io/v1 apiVersion: cert-manager.io/v1
@@ -13,9 +13,9 @@ spec:
secretTemplate: secretTemplate:
annotations: annotations:
reflector.v1.k8s.emberstack.com/reflection-allowed: "true" reflector.v1.k8s.emberstack.com/reflection-allowed: "true"
reflector.v1.k8s.emberstack.com/reflection-allowed-namespaces: "haproxy,mail" reflector.v1.k8s.emberstack.com/reflection-allowed-namespaces: "haproxy"
reflector.v1.k8s.emberstack.com/reflection-auto-enabled: "true" reflector.v1.k8s.emberstack.com/reflection-auto-enabled: "true"
reflector.v1.k8s.emberstack.com/reflection-auto-namespaces: "haproxy,mail" reflector.v1.k8s.emberstack.com/reflection-auto-namespaces: "haproxy"
privateKey: privateKey:
size: 4096 size: 4096
dnsNames: dnsNames:
+1 -1
View File
@@ -11,7 +11,7 @@ metadata:
argocd.argoproj.io/sync-wave: "1" argocd.argoproj.io/sync-wave: "1"
spec: spec:
replicas: 1 replicas: 1
image: artifactapi.k8s.syd1.au.unkin.net/docker-internal/kea-api:v0.1.7 image: git.unkin.net/unkin/kea-api:v0.1.3
tokenSecretName: kea-api-token tokenSecretName: kea-api-token
service: service:
type: ClusterIP type: ClusterIP
+1 -1
View File
@@ -11,7 +11,7 @@ metadata:
argocd.argoproj.io/sync-wave: "1" argocd.argoproj.io/sync-wave: "1"
spec: spec:
replicas: 2 replicas: 2
image: artifactapi.k8s.syd1.au.unkin.net/docker-internal/kea:v0.1.7 image: git.unkin.net/unkin/kea:v0.1.3
domainName: main.unkin.net domainName: main.unkin.net
defaultLeaseTime: 1200 defaultLeaseTime: 1200
maxLeaseTime: 86400 maxLeaseTime: 86400
+1 -1
View File
@@ -21,7 +21,7 @@ spec:
runAsNonRoot: true runAsNonRoot: true
containers: containers:
- name: operator - name: operator
image: artifactapi.k8s.syd1.au.unkin.net/docker-internal/kea-operator:v0.1.7 image: git.unkin.net/unkin/kea-operator:v0.1.6
args: args:
- --metrics-bind-address=:8080 - --metrics-bind-address=:8080
- --health-probe-bind-address=:8081 - --health-probe-bind-address=:8081
-87
View File
@@ -1,87 +0,0 @@
---
# clamd + freshclam (the image's init runs both); signatures come from database.clamav.net.
apiVersion: apps/v1
kind: Deployment
metadata:
name: clamav
namespace: mail
spec:
replicas: 2
selector:
matchLabels:
app.kubernetes.io/name: clamav
template:
metadata:
labels:
app.kubernetes.io/name: clamav
spec:
automountServiceAccountToken: false
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app.kubernetes.io/name: clamav
securityContext:
seccompProfile:
type: RuntimeDefault
containers:
- name: clamav
image: docker.io/clamav/clamav:1.5.4
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3310
name: clamd
protocol: TCP
startupProbe:
tcpSocket:
port: clamd
periodSeconds: 10
failureThreshold: 60
readinessProbe:
tcpSocket:
port: clamd
periodSeconds: 10
livenessProbe:
tcpSocket:
port: clamd
periodSeconds: 30
resources:
requests:
cpu: 100m
memory: 1536Mi
limits:
cpu: "2"
memory: 3Gi
volumeMounts:
- name: db
mountPath: /var/lib/clamav
volumes:
- name: db
emptyDir: {}
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: clamav
namespace: mail
spec:
maxUnavailable: 1
selector:
matchLabels:
app.kubernetes.io/name: clamav
---
apiVersion: v1
kind: Service
metadata:
name: clamav
namespace: mail
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: clamav
ports:
- name: clamd
port: 3310
targetPort: clamd
-40
View File
@@ -1,40 +0,0 @@
---
apiVersion: ceph.unkin.net/v1alpha1
kind: ObjectStoreUser
metadata:
name: cnpg-mail-backup
namespace: mail
spec:
displayName: "CNPG backup owner (mail)"
uid: cnpg-mail-backup
maxBuckets: 5
secretName: cnpg-mail-backup-s3
retainOnDelete: true
---
apiVersion: ceph.unkin.net/v1alpha1
kind: Bucket
metadata:
name: cnpg-mail
namespace: mail
spec:
placementTarget: ec
bucketName: cnpg-mail
ownerRef: cnpg-mail-backup
versioning: false
tags:
app: mail
purpose: cnpg-backup
retainOnDelete: true
---
apiVersion: postgresql.cnpg.io/v1
kind: ScheduledBackup
metadata:
name: cnpg-mail-nightly
namespace: mail
spec:
schedule: "0 20 4 * * *"
immediate: false
backupOwnerReference: self
method: barmanObjectStore
cluster:
name: stalwart-db
-118
View File
@@ -1,118 +0,0 @@
---
# Stalwart metadata store. No bootstrap secret: CNPG mints stalwart-db-app
# (username/password/dbname/uri) for Stalwart to consume.
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: stalwart-db
namespace: mail
spec:
affinity:
podAntiAffinityType: preferred
backup:
retentionPolicy: 30d
barmanObjectStore:
destinationPath: s3://cnpg-mail
endpointURL: https://s3.ceph.unkin.net
endpointCA:
name: vault-ca-cert
key: ca.crt
s3Credentials:
accessKeyId:
name: cnpg-mail-backup-s3
key: AWS_ACCESS_KEY_ID
secretAccessKey:
name: cnpg-mail-backup-s3
key: AWS_SECRET_ACCESS_KEY
serverName: stalwart-db
data:
compression: bzip2
jobs: 2
wal:
compression: zstd
maxParallel: 2
bootstrap:
initdb:
database: stalwart
encoding: UTF8
localeCType: C
localeCollate: C
owner: stalwart
enablePDB: true
enableSuperuserAccess: false
failoverDelay: 0
imageName: ghcr.io/cloudnative-pg/postgresql:18.1-system-trixie
instances: 3
logLevel: info
maxSyncReplicas: 0
minSyncReplicas: 0
monitoring:
customQueriesConfigMap:
- key: queries
name: cnpg-default-monitoring
disableDefaultQueries: false
enablePodMonitor: false
postgresql:
parameters:
archive_mode: "on"
archive_timeout: 5min
dynamic_shared_memory_type: posix
effective_cache_size: 256MB
full_page_writes: "on"
hot_standby_feedback: "on"
log_destination: csvlog
log_directory: /controller/log
log_filename: postgres
log_rotation_age: "0"
log_rotation_size: "0"
log_truncate_on_rotation: "false"
logging_collector: "on"
max_connections: "200"
max_parallel_workers: "16"
max_replication_slots: "16"
max_worker_processes: "16"
pg_stat_statements.max: "10000"
pg_stat_statements.track: top
shared_buffers: 128MB
shared_memory_type: mmap
ssl_max_protocol_version: TLSv1.3
ssl_min_protocol_version: TLSv1.3
wal_keep_size: 256MB
wal_level: logical
wal_log_hints: "on"
wal_receiver_timeout: 5s
wal_sender_timeout: 5s
shared_preload_libraries:
- pg_stat_statements
syncReplicaElectionConstraint:
enabled: false
primaryUpdateMethod: restart
primaryUpdateStrategy: unsupervised
probes:
liveness:
isolationCheck:
connectionTimeout: 1000
enabled: true
requestTimeout: 1000
replicationSlots:
highAvailability:
enabled: true
slotPrefix: _cnpg_
synchronizeReplicas:
enabled: true
updateInterval: 30
resources:
limits:
cpu: "1"
memory: 1Gi
requests:
cpu: 50m
memory: 512Mi
smartShutdownTimeout: 180
startDelay: 3600
stopDelay: 1800
storage:
resizeInUseVolumes: true
size: 10Gi
storageClass: cephrbd-fast-delete
switchoverDelay: 3600
-61
View File
@@ -1,61 +0,0 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- clamav.yaml
- cnpg_backup.yaml
- cnpg_cluster.yaml
- namespace.yaml
- rspamd-deployment.yaml
- rspamd-sa-rules.yaml
- rspamd-valkey.yaml
- rspamd-vault.yaml
- smarthost-networkpolicy.yaml
- smarthost-pdb.yaml
- smarthost-service.yaml
- smarthost-statefulset.yaml
- stalwart-blobs-bucket.yaml
- vaultauth.yaml
configMapGenerator:
- name: rspamd-config
namespace: mail
options:
disableNameSuffixHash: true
files:
- rspamd/actions.conf
- rspamd/antivirus.conf
- rspamd/dkim_signing.conf
- rspamd/external_relay.conf
- rspamd/force_actions.conf
- rspamd/gpt.conf
- rspamd/greylist.conf
- rspamd/history_redis.conf
- rspamd/local_networks.map
- rspamd/milter_headers.conf
- rspamd/options.inc
- rspamd/redis.conf
- rspamd/settings.conf
- rspamd/spamassassin.conf
- rspamd/worker-controller.inc
- rspamd/worker-normal.inc
- rspamd/worker-proxy.inc
- name: rspamd-valkey-scripts
namespace: mail
options:
disableNameSuffixHash: true
files:
- rspamd-valkey/start.sh
- name: smarthost-config
namespace: mail
options:
disableNameSuffixHash: true
files:
- smarthost/main.cf
- smarthost/master.cf
- smarthost/relay_domains
- smarthost/transport
- smarthost/gateways.cidr
- smarthost/mynetworks.cidr
- smarthost/tls_policy
-5
View File
@@ -1,5 +0,0 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: mail
-140
View File
@@ -1,140 +0,0 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: rspamd
namespace: mail
annotations:
reloader.stakater.com/auto: "true"
spec:
replicas: 2
selector:
matchLabels:
app.kubernetes.io/name: rspamd
template:
metadata:
labels:
app.kubernetes.io/name: rspamd
spec:
serviceAccountName: rspamd
automountServiceAccountToken: false
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app.kubernetes.io/name: rspamd
securityContext:
runAsNonRoot: true
runAsUser: 11333
runAsGroup: 11333
fsGroup: 11333
seccompProfile:
type: RuntimeDefault
containers:
- name: rspamd
image: docker.io/rspamd/rspamd:4.2.2
imagePullPolicy: IfNotPresent
env:
- name: RSPAMD_LOCAL_ADDR
value: "*"
- name: RSPAMD_LOG_TYPE
value: console
- name: RSPAMD_LITELLM_API_KEY
valueFrom:
secretKeyRef:
name: rspamd-litellm
key: key
- name: RSPAMD_CONTROLLER_PASSWORD_HASH
valueFrom:
secretKeyRef:
name: rspamd-controller
key: password_hash
ports:
- containerPort: 11332
name: milter
protocol: TCP
- containerPort: 11334
name: controller
protocol: TCP
readinessProbe:
tcpSocket:
port: milter
initialDelaySeconds: 10
periodSeconds: 10
livenessProbe:
httpGet:
path: /ping
port: controller
initialDelaySeconds: 60
periodSeconds: 30
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: "2"
memory: 1536Mi
volumeMounts:
- name: config
mountPath: /etc/rspamd/local.d
readOnly: true
- name: sa-rules
mountPath: /etc/rspamd/sa-rules
readOnly: true
- name: dkim
mountPath: /etc/rspamd/dkim
readOnly: true
- name: data
mountPath: /var/lib/rspamd
volumes:
- name: config
configMap:
name: rspamd-config
- name: sa-rules
configMap:
name: rspamd-sa-rules
- name: dkim
secret:
secretName: dkim-unkin-net
defaultMode: 0440
items:
- key: private_key
path: unkin.net.mail.key
- name: data
emptyDir: {}
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: rspamd
namespace: mail
spec:
maxUnavailable: 1
selector:
matchLabels:
app.kubernetes.io/name: rspamd
---
# Milter for the smarthost only (rspamd.mail.svc:11332); controller/web UI is in-cluster only.
apiVersion: v1
kind: Service
metadata:
name: rspamd
namespace: mail
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: rspamd
ports:
- name: milter
port: 11332
targetPort: milter
- name: controller
port: 11334
targetPort: controller
-8
View File
@@ -1,8 +0,0 @@
---
# SpamAssassin rules loaded by the rspamd spamassassin module (*.cf).
apiVersion: v1
kind: ConfigMap
metadata:
name: rspamd-sa-rules
namespace: mail
data: {}
-178
View File
@@ -1,178 +0,0 @@
---
# Sentinel-managed Valkey for rspamd (bayes, history, ratelimit, gpt cache).
# rspamd has no Redis Cluster support, so the valkey-operator (cluster mode)
# cannot be used. start.sh follows the master the sentinels report; on a full
# restart the highest replication offset wins. Hostnames carry a trailing dot so
# lookups of a deleted pod fail fast instead of walking the search list (sentinel TILT).
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: rspamd-valkey
namespace: mail
annotations:
configmap.reloader.stakater.com/reload: "rspamd-valkey-scripts"
spec:
serviceName: rspamd-valkey
podManagementPolicy: Parallel
replicas: 3
selector:
matchLabels:
app.kubernetes.io/name: rspamd-valkey
template:
metadata:
labels:
app.kubernetes.io/name: rspamd-valkey
spec:
automountServiceAccountToken: false
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app.kubernetes.io/name: rspamd-valkey
securityContext:
runAsNonRoot: true
runAsUser: 999
runAsGroup: 999
fsGroup: 999
seccompProfile:
type: RuntimeDefault
containers:
- name: valkey
image: docker.io/valkey/valkey:9.0.0
imagePullPolicy: IfNotPresent
command: ["sh", "/scripts/start.sh", "valkey"]
env:
- name: DOMAIN_SUFFIX
value: .rspamd-valkey.mail.svc.cluster.local.
ports:
- containerPort: 6379
name: valkey
protocol: TCP
readinessProbe:
exec:
command: ["sh", "-c", "valkey-cli info replication | grep -q '^master_host:127.0.0.1' && exit 1; valkey-cli ping | grep -q PONG"]
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
exec:
command: ["valkey-cli", "ping"]
initialDelaySeconds: 30
periodSeconds: 30
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
volumeMounts:
- name: data
mountPath: /data
- name: scripts
mountPath: /scripts
readOnly: true
- name: sentinel
image: docker.io/valkey/valkey:9.0.0
imagePullPolicy: IfNotPresent
command: ["sh", "/scripts/start.sh", "sentinel"]
env:
- name: DOMAIN_SUFFIX
value: .rspamd-valkey.mail.svc.cluster.local.
ports:
- containerPort: 26379
name: sentinel
protocol: TCP
readinessProbe:
exec:
command: ["valkey-cli", "-p", "26379", "ping"]
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
exec:
command: ["valkey-cli", "-p", "26379", "ping"]
initialDelaySeconds: 30
periodSeconds: 30
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
resources:
requests:
cpu: 10m
memory: 32Mi
limits:
cpu: 100m
memory: 64Mi
volumeMounts:
- name: sentinel
mountPath: /sentinel
- name: scripts
mountPath: /scripts
readOnly: true
volumes:
- name: scripts
configMap:
name: rspamd-valkey-scripts
- name: sentinel
emptyDir: {}
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ReadWriteOnce]
storageClassName: cephrbd-fast-delete
resources:
requests:
storage: 5Gi
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: rspamd-valkey
namespace: mail
spec:
maxUnavailable: 1
selector:
matchLabels:
app.kubernetes.io/name: rspamd-valkey
---
# Stable per-pod DNS, published before readiness so replicas can find the seed.
apiVersion: v1
kind: Service
metadata:
name: rspamd-valkey
namespace: mail
spec:
clusterIP: None
publishNotReadyAddresses: true
selector:
app.kubernetes.io/name: rspamd-valkey
ports:
- name: valkey
port: 6379
targetPort: valkey
- name: sentinel
port: 26379
targetPort: sentinel
---
apiVersion: v1
kind: Service
metadata:
name: rspamd-valkey-sentinel
namespace: mail
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: rspamd-valkey
ports:
- name: sentinel
port: 26379
targetPort: sentinel
-82
View File
@@ -1,82 +0,0 @@
#!/bin/sh
# Usage: start.sh valkey|sentinel. valkey boots read-only as a replica of
# 127.0.0.1:1 ("undecided") so peers can compare offsets; decide() then follows
# the sentinels' master, a live peer master, or the highest-offset node.
set -eu
name="$(hostname)"
sts="${name%-*}"
self="${name}${DOMAIN_SUFFIX}"
info() {
timeout 3 valkey-cli -h "$1" info replication 2>/dev/null | tr -d '\r' || true
}
field() {
printf '%s\n' "$1" | sed -n "s/^$2://p"
}
undecided() {
[ "$(field "$1" master_host)" = 127.0.0.1 ]
}
choose_master() {
deadline=$(($(date +%s) + 60))
while :; do
best=""
best_off=-1
answered=0
for i in 0 1 2; do
peer="${sts}-${i}${DOMAIN_SUFFIX}"
if [ "$peer" = "$self" ]; then
r="$(info 127.0.0.1)"
else
m="$(timeout 3 valkey-cli -h "$peer" -p 26379 --raw sentinel get-master-addr-by-name rspamd 2>/dev/null | head -n1 || true)"
[ -n "$m" ] && { echo "$m"; return; }
r="$(info "$peer")"
[ -n "$r" ] || continue
answered=$((answered + 1))
[ "$(field "$r" role)" = master ] && { echo "$peer"; return; }
fi
undecided "$r" || continue
off="$(field "$r" master_repl_offset)"
[ "${off:-0}" -gt "$best_off" ] && best="$peer" best_off="${off:-0}"
done
if [ "$best" = "$self" ] && { [ "$answered" -eq 2 ] || [ "$(date +%s)" -ge "$deadline" ]; }; then
echo "$self"
return
fi
sleep 3
done
}
decide() {
until valkey-cli ping >/dev/null 2>&1; do sleep 1; done
master="$(choose_master)"
target="$master 6379"
[ "$master" = "$self" ] && target="no one"
until valkey-cli replicaof $target; do sleep 1; done
}
if [ "$1" = sentinel ]; then
until r="$(info 127.0.0.1)" && [ -n "$(field "$r" role)" ] && ! undecided "$r"; do sleep 2; done
master="$self"
[ "$(field "$r" role)" = master ] || master="$(field "$r" master_host)"
cat > /sentinel/sentinel.conf <<CONF
port 26379
protected-mode no
sentinel resolve-hostnames yes
sentinel announce-hostnames yes
sentinel announce-ip $self
sentinel monitor rspamd $master 6379 2
sentinel down-after-milliseconds rspamd 5000
sentinel failover-timeout rspamd 60000
sentinel parallel-syncs rspamd 1
CONF
exec valkey-sentinel /sentinel/sentinel.conf
fi
decide &
# RDB only: an AOF reload resets the replication offset that choose_master compares.
exec valkey-server --dir /data --appendonly no --save "60 1" \
--maxmemory 384mb --maxmemory-policy volatile-ttl \
--protected-mode no --replica-announce-ip "$self" --replicaof 127.0.0.1 1
-79
View File
@@ -1,79 +0,0 @@
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: rspamd
namespace: mail
---
# Separate auth for the litellm engine: the `rspamd` k8s role is the only one
# whose policy grants litellm/creds/rspamd.
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultAuth
metadata:
name: rspamd
namespace: mail
spec:
allowedNamespaces:
- mail
kubernetes:
audiences:
- vault
role: rspamd
serviceAccount: rspamd
tokenExpirationSeconds: 600
method: kubernetes
mount: k8s/au/syd1
vaultConnectionRef: vso-system/default
---
# Haiku-scoped LiteLLM virtual key for the gpt module (field `key`).
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultDynamicSecret
metadata:
name: rspamd-litellm
namespace: mail
spec:
allowStaticCreds: false
destination:
create: true
name: rspamd-litellm
overwrite: true
mount: litellm
path: creds/rspamd
revoke: true
vaultAuthRef: rspamd
---
# DKIM private key for unkin.net, selector `mail` (field `private_key`).
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
name: dkim-unkin-net
namespace: mail
spec:
destination:
create: true
name: dkim-unkin-net
overwrite: true
hmacSecretData: true
mount: kv
path: kubernetes/namespace/mail/default/dkim-unkin-net
refreshAfter: 5m
type: kv-v2
vaultAuthRef: default
---
# Controller (web UI) password; config reads the `rspamadm pw` hash (field `password_hash`).
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
name: rspamd-controller
namespace: mail
spec:
destination:
create: true
name: rspamd-controller
overwrite: true
hmacSecretData: true
mount: kv
path: kubernetes/namespace/mail/default/rspamd-controller
refreshAfter: 5m
type: kv-v2
vaultAuthRef: default
-3
View File
@@ -1,3 +0,0 @@
reject = 15;
add_header = 6;
greylist = null;
-8
View File
@@ -1,8 +0,0 @@
clamav {
type = "clamav";
servers = "clamav.mail.svc.cluster.local:3310";
symbol = "CLAM_VIRUS";
action = "reject";
scan_mime_parts = true;
log_clean = false;
}
-7
View File
@@ -1,7 +0,0 @@
sign_authenticated = false;
sign_local = true;
sign_inbound = false;
use_domain = "header";
allow_hdrfrom_mismatch = false;
selector = "mail";
path = "/etc/rspamd/dkim/$domain.$selector.key";
@@ -1,8 +0,0 @@
# Edge gateway public IPs (smarthost gateways.cidr): score the first hop before them.
enabled = true;
rules {
EDGE_RELAY {
strategy = "ip_map";
ip_map = ["192.0.2.1/32", "192.0.2.2/32"];
}
}
-7
View File
@@ -1,7 +0,0 @@
rules {
CLAMAV_UNAVAILABLE {
action = "soft reject";
expression = "CLAM_VIRUS_FAIL";
message = "Virus scanner unavailable, try again later";
}
}
-22
View File
@@ -1,22 +0,0 @@
enabled = true;
type = "openai";
url = "http://litellm.litellm.svc.cluster.local:4000/v1/chat/completions";
api_key = "{= env.LITELLM_API_KEY =}";
model = "claude-haiku-4-5";
model_parameters = {
"claude-haiku-4-5" = {
max_tokens = 400,
temperature = 0.0,
}
};
timeout = 10s;
# Inbound only (settings.conf disables it outbound); only uncertain scores (2 <= score < 12).
condition = <<EOD
return function(task)
local res = task:get_metric_result()
if not res then return false, 'no result' end
if res.passthrough then return false, 'passthrough' end
if res.score < 2 or res.score >= 12 then return false, 'score not uncertain' end
return true
end
EOD
-1
View File
@@ -1 +0,0 @@
enabled = false;
-1
View File
@@ -1 +0,0 @@
nrows = 5000;
-30
View File
@@ -1,30 +0,0 @@
# Outbound sources (smarthost mynetworks): DKIM-signed, scored with reject, no GPT.
127.0.0.0/8
::1
10.42.0.0/16
10.10.12.200/32
198.18.1.10/32
198.18.2.160/27
198.18.2.192/27
198.18.13.0/24
198.18.14.0/24
198.18.15.0/24
198.18.16.0/24
198.18.17.0/24
198.18.18.0/24
198.18.19.0/24
198.18.20.0/24
198.18.21.0/24
198.18.22.0/24
198.18.23.0/24
198.18.25.0/24
198.18.26.0/24
198.18.27.0/24
198.18.28.0/24
198.18.29.0/24
198.18.64.0/24
198.18.65.0/24
198.18.66.0/24
198.18.67.0/24
198.18.68.0/24
198.18.69.0/24
@@ -1,2 +0,0 @@
use = ["x-spamd-result", "x-spam-status", "x-spam-level", "authentication-results"];
skip_local = true;
-2
View File
@@ -1,2 +0,0 @@
local_addrs = "/etc/rspamd/local.d/local_networks.map";
task_timeout = 20s;
-4
View File
@@ -1,4 +0,0 @@
sentinels = "rspamd-valkey-sentinel.mail.svc.cluster.local:26379";
sentinel_masters_pattern = "^rspamd$";
sentinel_watch_time = 10s;
servers = "rspamd-valkey-0.rspamd-valkey.mail.svc.cluster.local.:6379";
-19
View File
@@ -1,19 +0,0 @@
outbound {
priority = high;
ip_map = "/etc/rspamd/local.d/local_networks.map";
apply {
symbols_disabled = ["GPT_CHECK"];
}
}
inbound {
priority = high;
ip_map = "/etc/rspamd/local.d/local_networks.map";
inverse = true;
apply {
symbols_disabled = ["DKIM_SIGNED"];
# Tag only; reject stays defined (unreachable by score) so ClamAV's virus reject still applies.
actions {
reject = 1000;
}
}
}
-1
View File
@@ -1 +0,0 @@
ruleset = "/etc/rspamd/sa-rules/*.cf";
@@ -1,3 +0,0 @@
password = "{= env.CONTROLLER_PASSWORD_HASH =}";
enable_password = "{= env.CONTROLLER_PASSWORD_HASH =}";
allow_file_and_shm_inputs = false;
-2
View File
@@ -1,2 +0,0 @@
count = 2;
allow_file_and_shm_inputs = false;
-1
View File
@@ -1 +0,0 @@
allow_file_and_shm_inputs = false;
@@ -1,78 +0,0 @@
---
# Gateways (public IPs, see smarthost/gateways.cidr), lab networks (incl. node IPs for kubelet probes) and opted-in pods in any namespace.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: smarthost
namespace: mail
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: smarthost
policyTypes:
- Ingress
ingress:
- from:
- ipBlock:
cidr: 192.0.2.1/32
- ipBlock:
cidr: 192.0.2.2/32
- ipBlock:
cidr: 10.10.12.200/32
- ipBlock:
cidr: 198.18.1.10/32
- ipBlock:
cidr: 198.18.2.160/27
- ipBlock:
cidr: 198.18.2.192/27
- ipBlock:
cidr: 198.18.13.0/24
- ipBlock:
cidr: 198.18.14.0/24
- ipBlock:
cidr: 198.18.15.0/24
- ipBlock:
cidr: 198.18.16.0/24
- ipBlock:
cidr: 198.18.17.0/24
- ipBlock:
cidr: 198.18.18.0/24
- ipBlock:
cidr: 198.18.19.0/24
- ipBlock:
cidr: 198.18.20.0/24
- ipBlock:
cidr: 198.18.21.0/24
- ipBlock:
cidr: 198.18.22.0/24
- ipBlock:
cidr: 198.18.23.0/24
- ipBlock:
cidr: 198.18.25.0/24
- ipBlock:
cidr: 198.18.26.0/24
- ipBlock:
cidr: 198.18.27.0/24
- ipBlock:
cidr: 198.18.28.0/24
- ipBlock:
cidr: 198.18.29.0/24
- ipBlock:
cidr: 198.18.64.0/24
- ipBlock:
cidr: 198.18.65.0/24
- ipBlock:
cidr: 198.18.66.0/24
- ipBlock:
cidr: 198.18.67.0/24
- ipBlock:
cidr: 198.18.68.0/24
- ipBlock:
cidr: 198.18.69.0/24
- namespaceSelector: {}
podSelector:
matchLabels:
mail.unkin.net/smarthost-client: "true"
ports:
- port: smtp
protocol: TCP
-11
View File
@@ -1,11 +0,0 @@
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: smarthost
namespace: mail
spec:
maxUnavailable: 1
selector:
matchLabels:
app.kubernetes.io/name: smarthost
-33
View File
@@ -1,33 +0,0 @@
---
apiVersion: v1
kind: Service
metadata:
name: smarthost
namespace: mail
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: smarthost
ports:
- name: smtp
port: 25
targetPort: smtp
---
# Gateways and lab networks; Local keeps client IPs for the postfix CIDR checks.
apiVersion: v1
kind: Service
metadata:
name: smarthost-lb
namespace: mail
annotations:
purelb.io/addresses: 198.18.200.16
purelb.io/service-group: common
spec:
type: LoadBalancer
externalTrafficPolicy: Local
selector:
app.kubernetes.io/name: smarthost
ports:
- name: smtp
port: 25
targetPort: smtp
-117
View File
@@ -1,117 +0,0 @@
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: smarthost
namespace: mail
annotations:
configmap.reloader.stakater.com/reload: "smarthost-config"
spec:
serviceName: smarthost
replicas: 2
selector:
matchLabels:
app.kubernetes.io/name: smarthost
template:
metadata:
labels:
app.kubernetes.io/name: smarthost
spec:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app.kubernetes.io/name: smarthost
securityContext:
seccompProfile:
type: RuntimeDefault
containers:
- name: postfix
image: artifactapi.k8s.syd1.au.unkin.net/docker-internal/postfix:0.1.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 25
name: smtp
protocol: TCP
readinessProbe:
tcpSocket:
port: smtp
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
exec:
command: ["postfix", "status"]
initialDelaySeconds: 30
periodSeconds: 30
# postfix master runs as root and drops to the postfix user per service.
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
add:
- CHOWN
- DAC_OVERRIDE
- FOWNER
- SETUID
- SETGID
- NET_BIND_SERVICE
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
volumeMounts:
- name: spool
mountPath: /var/spool/postfix
- name: tls
mountPath: /etc/postfix/tls
readOnly: true
- name: config
mountPath: /etc/postfix/main.cf
subPath: main.cf
readOnly: true
- name: config
mountPath: /etc/postfix/master.cf
subPath: master.cf
readOnly: true
- name: config
mountPath: /etc/postfix/relay_domains
subPath: relay_domains
readOnly: true
- name: config
mountPath: /etc/postfix/transport
subPath: transport
readOnly: true
- name: config
mountPath: /etc/postfix/gateways.cidr
subPath: gateways.cidr
readOnly: true
- name: config
mountPath: /etc/postfix/mynetworks.cidr
subPath: mynetworks.cidr
readOnly: true
- name: config
mountPath: /etc/postfix/tls_policy
subPath: tls_policy
readOnly: true
volumes:
- name: config
configMap:
name: smarthost-config
- name: tls
secret:
secretName: wildcard-main-unkin-net-tls
volumeClaimTemplates:
- metadata:
name: spool
spec:
accessModes: [ReadWriteOnce]
storageClassName: cephrbd-fast-delete
resources:
requests:
storage: 50Gi
-3
View File
@@ -1,3 +0,0 @@
# Gateway (mta1/mta2) public IPs; TEST-NET placeholders until the BinaryLane servers exist.
192.0.2.1/32 reject_plaintext_session, permit
192.0.2.2/32 reject_plaintext_session, permit
-42
View File
@@ -1,42 +0,0 @@
compatibility_level = 3.5
myhostname = mail-in.main.unkin.net
myorigin = unkin.net
mydestination =
alias_maps =
local_recipient_maps =
inet_interfaces = all
inet_protocols = ipv4
maillog_file = /dev/stdout
message_size_limit = 52428800
# Relay-anywhere clients; gateways must stay out.
mynetworks = cidr:/etc/postfix/mynetworks.cidr
relay_domains = texthash:/etc/postfix/relay_domains
# Default minus relay_domains: subdomains are not delivered and would loop back out via the gateways.
parent_domain_matches_subdomains = debug_peer_list,fast_flush_domains,mynetworks,permit_mx_backup_networks,qmqpd_authorized_clients,smtpd_access_maps
transport_maps = texthash:/etc/postfix/transport
relayhost = [mta1.edge.unkin.net]:25
smtp_fallback_relay = [mta2.edge.unkin.net]:25
smtp_tls_policy_maps = texthash:/etc/postfix/tls_policy
smtp_tls_CAfile = /etc/pki/tls/certs/ca-bundle.crt
smtpd_client_restrictions = permit_mynetworks, check_client_access cidr:/etc/postfix/gateways.cidr, reject
smtpd_relay_restrictions = permit_mynetworks, reject_unauth_destination
smtpd_recipient_restrictions = permit_mynetworks, reject_unverified_recipient
unverified_recipient_reject_code = 550
unverified_recipient_tempfail_action = defer_if_permit
address_verify_negative_refresh_time = 5m
address_verify_negative_expire_time = 1h
address_verify_positive_refresh_time = 1h
address_verify_positive_expire_time = 1d
milter_default_action = tempfail
smtpd_milters = inet:rspamd.mail.svc:11332
smtpd_authorized_xforward_hosts = cidr:/etc/postfix/gateways.cidr
smtpd_tls_security_level = may
smtpd_tls_cert_file = /etc/postfix/tls/tls.crt
smtpd_tls_key_file = /etc/postfix/tls/tls.key
smtpd_tls_received_header = yes
smtp_tls_security_level = may
lmtp_tls_security_level = none
-27
View File
@@ -1,27 +0,0 @@
# Gateways (inbound to relay_domains) and mynetworks (relay anywhere); all via the rspamd milter.
25 inet n - n - - smtpd
pickup unix n - n 60 1 pickup
cleanup unix n - n - 0 cleanup
qmgr unix n - n 300 1 qmgr
tlsmgr unix - - n 1000? 1 tlsmgr
rewrite unix - - n - - trivial-rewrite
bounce unix - - n - 0 bounce
defer unix - - n - 0 bounce
trace unix - - n - 0 bounce
verify unix - - n - 1 verify
flush unix n - n 1000? 0 flush
proxymap unix - - n - - proxymap
proxywrite unix - - n - 1 proxymap
smtp unix - - n - - smtp
relay unix - - n - - smtp
-o syslog_name=postfix/$service_name
showq unix n - n - - showq
error unix - - n - - error
retry unix - - n - - error
discard unix - - n - - discard
local unix - n n - - local
virtual unix - n n - - virtual
lmtp unix - - n - - lmtp
anvil unix - - n - 1 anvil
scache unix - - n - 1 scache
postlog unix-dgram n - n - 1 postlogd
-31
View File
@@ -1,31 +0,0 @@
# Pod CIDR (narrowed by smarthost-networkpolicy.yaml) plus the lab networks from bind-internal acl-main/acl-common/acl-nomad-jobs.
# Keep in sync with the NetworkPolicy.
10.42.0.0/16 OK
10.10.12.200/32 OK
198.18.1.10/32 OK
198.18.2.160/27 OK
198.18.2.192/27 OK
198.18.21.160/27 OK
198.18.21.192/27 OK
198.18.13.0/24 OK
198.18.14.0/24 OK
198.18.15.0/24 OK
198.18.16.0/24 OK
198.18.17.0/24 OK
198.18.18.0/24 OK
198.18.19.0/24 OK
198.18.20.0/24 OK
198.18.21.0/24 OK
198.18.22.0/24 OK
198.18.23.0/24 OK
198.18.25.0/24 OK
198.18.26.0/24 OK
198.18.27.0/24 OK
198.18.28.0/24 OK
198.18.29.0/24 OK
198.18.64.0/24 OK
198.18.65.0/24 OK
198.18.66.0/24 OK
198.18.67.0/24 OK
198.18.68.0/24 OK
198.18.69.0/24 OK
-1
View File
@@ -1 +0,0 @@
unkin.net OK
-2
View File
@@ -1,2 +0,0 @@
[mta1.edge.unkin.net]:25 secure match=hostname
[mta2.edge.unkin.net]:25 secure match=hostname
-1
View File
@@ -1 +0,0 @@
unkin.net lmtp:[stalwart.mail.svc.cluster.local]:24
-30
View File
@@ -1,30 +0,0 @@
---
# Stalwart S3 blob store. The owner user has read-write on its own bucket; the
# operator mints AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / S3_ENDPOINT into
# stalwart-blobs-s3.
apiVersion: ceph.unkin.net/v1alpha1
kind: ObjectStoreUser
metadata:
name: stalwart-blobs
namespace: mail
spec:
displayName: "Stalwart blob store owner"
uid: mail-stalwart-blobs
maxBuckets: 5
secretName: stalwart-blobs-s3
retainOnDelete: true
---
apiVersion: ceph.unkin.net/v1alpha1
kind: Bucket
metadata:
name: stalwart-blobs
namespace: mail
spec:
placementTarget: ec
bucketName: stalwart-blobs
ownerRef: stalwart-blobs
versioning: false
tags:
app: stalwart
purpose: blob-store
retainOnDelete: true
-18
View File
@@ -1,18 +0,0 @@
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultAuth
metadata:
name: default
namespace: mail
spec:
allowedNamespaces:
- mail
kubernetes:
audiences:
- vault
role: default
serviceAccount: default
tokenExpirationSeconds: 600
method: kubernetes
mount: k8s/au/syd1
vaultConnectionRef: vso-system/default
+1 -1
View File
@@ -25,7 +25,7 @@ spec:
- name: pdbmux - name: pdbmux
# Image is published by the pdbmux repo's .woodpecker/docker.yaml on # Image is published by the pdbmux repo's .woodpecker/docker.yaml on
# a v* tag. It only exists after that tag is cut (see PR merge gates). # a v* tag. It only exists after that tag is cut (see PR merge gates).
image: artifactapi.k8s.syd1.au.unkin.net/docker-internal/pdbmux:v0.5.0 image: artifactapi.k8s.syd1.au.unkin.net/docker-internal/pdbmux:v0.4.0
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
ports: ports:
- containerPort: 8080 - containerPort: 8080
-1
View File
@@ -20,7 +20,6 @@ resources:
- serviceaccount_repospawner_ci.yaml - serviceaccount_repospawner_ci.yaml
- serviceaccount_terraform_artifactapi.yaml - serviceaccount_terraform_artifactapi.yaml
- serviceaccount_terraform_authentik.yaml - serviceaccount_terraform_authentik.yaml
- serviceaccount_terraform_binarylane.yaml
- serviceaccount_terraform_enc.yaml - serviceaccount_terraform_enc.yaml
- serviceaccount_terraform_git.yaml - serviceaccount_terraform_git.yaml
- serviceaccount_terraform_netbox.yaml - serviceaccount_terraform_netbox.yaml
@@ -1,6 +0,0 @@
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: terraform-binarylane
namespace: woodpecker
@@ -0,0 +1,16 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../../base/consul
helmCharts:
- name: consul
repo: https://helm.releases.hashicorp.com
version: "1.9.7"
releaseName: consul
namespace: consul
valuesFile: values.yaml
apiVersions:
- policy/v1/PodDisruptionBudget
+77
View File
@@ -0,0 +1,77 @@
global:
name: consul
datacenter: au-syd1
domain: consul
acls:
# Enable chart-managed ACL tokens/policies for Consul system components.
manageSystemACLs: true
# Source the bootstrap/management token from a pre-existing Kubernetes secret
# instead of letting the chart generate one. The secret is synced from Vault
# via VSO (see ../../../base/consul/vaultauth.yaml and vaultstaticsecret.yaml).
# When this secret is populated the server-acl-init job SKIPS bootstrapping and
# uses the supplied token as the management token, so the k8s cluster bootstraps
# with the SAME initial_management token as the authoritative VM cluster.
bootstrapToken:
secretName: consul-bootstrap-acl-token
secretKey: token
server:
image: hashicorp/consul:1.22.7
replicas: 5
bootstrapExpect: 5
storage: 10Gi
storageClass: cephrbd-fast-delete
connect: true
disruptionBudget:
maxUnavailable: 1
extraConfig: |
{
"acl": {
"enabled": true,
"default_policy": "deny",
"down_policy": "extend-cache",
"enable_token_persistence": true
},
"disable_remote_exec": true,
"disable_update_check": true,
"performance": {
"raft_multiplier": 10
},
"ports": {
"dns": 8600,
"grpc": 8502,
"http": 8500,
"https": -1
},
"primary_datacenter": "au-syd1"
}
resources:
requests:
memory: 256Mi
cpu: 100m
limits:
memory: 2Gi
cpu: "1"
client:
enabled: false
ui:
enabled: true
service:
type: ClusterIP
connectInject:
enabled: false
dns:
enabled: true
type: LoadBalancer
annotations: |
purelb.io/service-group: "common"
purelb.io/addresses: 198.18.200.5
@@ -1,6 +0,0 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../../base/mail
-1
View File
@@ -34,7 +34,6 @@ spec:
- path: apps/overlays/*/jfrog - path: apps/overlays/*/jfrog
- path: apps/overlays/*/k8up-system - path: apps/overlays/*/k8up-system
- path: apps/overlays/*/kanidm - path: apps/overlays/*/kanidm
- path: apps/overlays/*/mail
- path: apps/overlays/*/netbox - path: apps/overlays/*/netbox
- path: apps/overlays/*/node-feature-discovery - path: apps/overlays/*/node-feature-discovery
- path: apps/overlays/*/pdbmux - path: apps/overlays/*/pdbmux
-2
View File
@@ -49,8 +49,6 @@ spec:
server: https://kubernetes.default.svc server: https://kubernetes.default.svc
- namespace: 'kanidm' - namespace: 'kanidm'
server: https://kubernetes.default.svc server: https://kubernetes.default.svc
- namespace: 'mail'
server: https://kubernetes.default.svc
- namespace: 'netbox' - namespace: 'netbox'
server: https://kubernetes.default.svc server: https://kubernetes.default.svc
- namespace: 'node-feature-discovery' - namespace: 'node-feature-discovery'