Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 252470@bnt-lap001 Assistant-Session: ad628c8f-4be2-4979-94c9-76c7ed6f8241
159 lines
5.2 KiB
YAML
159 lines
5.2 KiB
YAML
# MAS live provider test (mail-address-semantics MAS-WP-0003).
|
|
# Founder go for A-D: 2026-10-08. Temporary: delete the namespace after the test.
|
|
# A namespace + MX pod B LoadBalancer :25 C statute-only ingress D no outbound mail
|
|
# D superseded 2026-10-18: operator chose replies via Scaleway TEM (Secret mas-relay,
|
|
# synced by ExternalSecret from OpenBao platform/suppliers/scaleway/mas-tem-relay).
|
|
# IMAGE is replaced with the pushed digest at apply time.
|
|
apiVersion: v1
|
|
kind: Namespace
|
|
metadata:
|
|
name: mas
|
|
labels: {app.kubernetes.io/part-of: mail-address-semantics}
|
|
---
|
|
apiVersion: v1
|
|
kind: PersistentVolumeClaim
|
|
metadata: {name: mas-evidence, namespace: mas}
|
|
spec:
|
|
accessModes: [ReadWriteOnce]
|
|
storageClassName: local-path
|
|
resources: {requests: {storage: 1Gi}}
|
|
---
|
|
# TEM SMTP login from OpenBao (ops-mason MASON-WP-0014, CCR-2026-0051).
|
|
# OpenBao role external-secrets-mas-tem-relay and its read policy are
|
|
# cluster-scoped. Retire them at MAS-WP-0003 close; deleting the namespace
|
|
# does not remove them.
|
|
apiVersion: v1
|
|
kind: ServiceAccount
|
|
metadata: {name: mas-tem-relay-eso, namespace: mas}
|
|
automountServiceAccountToken: false
|
|
---
|
|
apiVersion: external-secrets.io/v1
|
|
kind: SecretStore
|
|
metadata: {name: openbao-mas-tem-relay, namespace: mas}
|
|
spec:
|
|
provider:
|
|
vault:
|
|
server: http://openbao.openbao.svc:8200
|
|
path: platform
|
|
version: v2
|
|
auth:
|
|
kubernetes:
|
|
mountPath: kubernetes
|
|
role: external-secrets-mas-tem-relay
|
|
serviceAccountRef: {name: mas-tem-relay-eso, audiences: [openbao]}
|
|
---
|
|
apiVersion: external-secrets.io/v1
|
|
kind: ExternalSecret
|
|
metadata: {name: mas-relay, namespace: mas}
|
|
spec:
|
|
refreshInterval: 1h
|
|
secretStoreRef: {name: openbao-mas-tem-relay, kind: SecretStore}
|
|
target:
|
|
name: mas-relay
|
|
creationPolicy: Owner
|
|
# Explicit target metadata stops ESO copying the last-applied annotation,
|
|
# which policy reject-secret-last-applied forbids on Secrets.
|
|
template:
|
|
metadata:
|
|
labels: {app.kubernetes.io/name: mas-mx}
|
|
data:
|
|
- {secretKey: username, remoteRef: {key: suppliers/scaleway/mas-tem-relay, property: username}}
|
|
- {secretKey: password, remoteRef: {key: suppliers/scaleway/mas-tem-relay, property: password}}
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: mas-mx
|
|
namespace: mas
|
|
labels: {app.kubernetes.io/name: mas-mx}
|
|
spec:
|
|
replicas: 1
|
|
strategy: {type: Recreate}
|
|
selector: {matchLabels: {app.kubernetes.io/name: mas-mx}}
|
|
template:
|
|
metadata: {labels: {app.kubernetes.io/name: mas-mx}}
|
|
spec:
|
|
automountServiceAccountToken: false
|
|
containers:
|
|
- name: mx
|
|
image: IMAGE
|
|
args: [mx]
|
|
# Outbound replies via Scaleway TEM, enabled only when Secret mas-relay
|
|
# (keys username, password) exists. Port 25 out is blocked on the node.
|
|
# MAS_MAX_SENT: lifetime cap on replies sent (counted in the ticket db).
|
|
env:
|
|
- {name: MAS_RELAY, value: "[smtp.tem.scaleway.com]:587"}
|
|
- {name: MAS_MAX_SENT, value: "300"}
|
|
ports: [{name: smtp, containerPort: 25}]
|
|
volumeMounts:
|
|
- {name: evidence, mountPath: /var/lib/mas}
|
|
- {name: relay, mountPath: /etc/mas-relay, readOnly: true}
|
|
readinessProbe: {tcpSocket: {port: 25}, periodSeconds: 10}
|
|
resources:
|
|
requests: {cpu: 20m, memory: 64Mi}
|
|
limits: {memory: 256Mi}
|
|
volumes:
|
|
- name: evidence
|
|
persistentVolumeClaim: {claimName: mas-evidence}
|
|
- name: relay
|
|
secret: {secretName: mas-relay, optional: true}
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata: {name: mas-smtp, namespace: mas}
|
|
spec:
|
|
type: LoadBalancer
|
|
externalTrafficPolicy: Local # keep real client IPs in the Postfix log
|
|
selector: {app.kubernetes.io/name: mas-mx}
|
|
ports: [{name: smtp, port: 25, targetPort: 25, protocol: TCP}]
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: mas-statute
|
|
namespace: mas
|
|
labels: {app.kubernetes.io/name: mas-statute}
|
|
spec:
|
|
replicas: 1
|
|
selector: {matchLabels: {app.kubernetes.io/name: mas-statute}}
|
|
template:
|
|
metadata: {labels: {app.kubernetes.io/name: mas-statute}}
|
|
spec:
|
|
automountServiceAccountToken: false
|
|
securityContext: {runAsNonRoot: true, runAsUser: 65534}
|
|
containers:
|
|
- name: statute
|
|
image: IMAGE
|
|
args: [statute]
|
|
ports: [{name: http, containerPort: 8080}]
|
|
readinessProbe: {httpGet: {path: /.well-known/mas, port: 8080}}
|
|
resources:
|
|
requests: {cpu: 5m, memory: 32Mi}
|
|
limits: {memory: 64Mi}
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata: {name: mas-statute, namespace: mas}
|
|
spec:
|
|
selector: {app.kubernetes.io/name: mas-statute}
|
|
ports: [{name: http, port: 80, targetPort: 8080}]
|
|
---
|
|
apiVersion: networking.k8s.io/v1
|
|
kind: Ingress
|
|
metadata:
|
|
name: mas-statute
|
|
namespace: mas
|
|
annotations:
|
|
cert-manager.io/cluster-issuer: letsencrypt-prod
|
|
spec:
|
|
ingressClassName: traefik
|
|
rules:
|
|
- host: mas.coulomb.social
|
|
http:
|
|
paths:
|
|
- path: /.well-known/mas
|
|
pathType: Exact
|
|
backend: {service: {name: mas-statute, port: {number: 80}}}
|
|
tls:
|
|
- hosts: [mas.coulomb.social]
|
|
secretName: mas-coulomb-social-tls
|