ce7cb702218693d08ea6d83464d2457c9250027c

This commit is contained in:
ms2k 2026-11-12 20:46:28 +09:00
commit 34c5f8963c
17 changed files with 145336 additions and 0 deletions

View file

@ -0,0 +1,54 @@
# Phase A canary: write an artifact via the executor → VersityGW path.
# Submit after install (not auto-run by Flux):
# kubectl -n argo create -f - <<'EOF'
# apiVersion: argoproj.io/v1alpha1
# kind: Workflow
# metadata:
# generateName: artifact-canary-
# namespace: argo
# spec:
# workflowTemplateRef:
# name: artifact-canary
# EOF
---
apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
name: artifact-canary
namespace: argo
labels:
app.kubernetes.io/name: argo-workflow
app.kubernetes.io/instance: argo-workflows
app.kubernetes.io/component: canary
spec:
entrypoint: main
serviceAccountName: argo-workflow
podMetadata:
labels:
app.kubernetes.io/name: argo-workflow
app.kubernetes.io/instance: argo-workflows
app.kubernetes.io/component: canary
templates:
- name: main
container:
image: docker.io/library/busybox:1.37.0@sha256:9532d8c39891ca2ecde4d30d7710e01fb739c87a8b9299685c63704296b16028
command: [sh, -c]
args:
- echo "argo-workflows artifact canary $(date -u +%Y-%m-%dT%H:%M:%SZ)" > /tmp/hello.txt && cat /tmp/hello.txt
resources:
requests:
cpu: 10m
memory: 16Mi
limits:
memory: 32Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
runAsNonRoot: true
runAsUser: 1000
outputs:
artifacts:
- name: hello
path: /tmp/hello.txt

View file

@ -0,0 +1,10 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- canary-workflowtemplate.yaml
- relay-admission-workflowtemplate.yaml
- relay-admission-cronworkflows.yaml
- relay-smtp-deny-workflowtemplate.yaml
- relay-smtp-deny-cronworkflow.yaml
- opnsense-certificate-workflowtemplate.yaml
- opnsense-certificate-cronworkflow.yaml

View file

@ -0,0 +1,20 @@
apiVersion: argoproj.io/v1alpha1
kind: CronWorkflow
metadata:
name: opnsense-certificate-daily
namespace: argo-opnsense-certificate
labels:
app.kubernetes.io/name: opnsense-certificate-rotator
app.kubernetes.io/instance: opnsense-certificate-rotator
spec:
schedules:
- "47 17 * * *"
timezone: UTC
suspend: false
concurrencyPolicy: Forbid
startingDeadlineSeconds: 1800
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 7
workflowSpec:
workflowTemplateRef:
name: opnsense-certificate-rotator

View file

@ -0,0 +1,100 @@
apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
name: opnsense-certificate-rotator
namespace: argo-opnsense-certificate
labels:
app.kubernetes.io/name: opnsense-certificate-rotator
app.kubernetes.io/instance: opnsense-certificate-rotator
spec:
entrypoint: rotate
arguments:
parameters:
- name: bootstrap-mode
value: "false"
serviceAccountName: opnsense-certificate-rotator
nodeSelector:
node-role.kubernetes.io/control-plane: "true"
activeDeadlineSeconds: 300
parallelism: 1
synchronization:
mutexes:
- name: opnsense-certificate-rotator
podMetadata:
labels:
app.kubernetes.io/name: opnsense-certificate-rotator
app.kubernetes.io/instance: opnsense-certificate-rotator
securityContext:
fsGroup: 65532
fsGroupChangePolicy: OnRootMismatch
runAsNonRoot: true
runAsUser: 65532
runAsGroup: 65532
seccompProfile:
type: RuntimeDefault
volumes:
- name: opnsense-credentials
secret:
secretName: opnsense-certificate-credentials
defaultMode: 0440
- name: opnsense-bootstrap-ca
secret:
secretName: opnsense-certificate-bootstrap-ca
defaultMode: 0440
- name: vault-ca
secret:
secretName: opnsense-certificate-vault-ca
defaultMode: 0440
- name: opnsense-managed-ca
secret:
secretName: opnsense-certificate-managed-ca
defaultMode: 0440
ttlStrategy:
secondsAfterCompletion: 604800
secondsAfterSuccess: 86400
secondsAfterFailure: 604800
templates:
- name: rotate
container:
image: registry.quorate.internal/quorate/opnsense-certificate-rotator@sha256:f50651bcfc1cba33f4d631205bebfa748f647a400e9bafa69db1411a140b7936
imagePullPolicy: IfNotPresent
command:
- /opnsense-certificate-rotator
env:
- name: OPNSENSE_URL
value: https://10.212.111.120:8443
- name: OPNSENSE_IP_SANS
value: 10.77.102.91,10.212.111.120,10.31.87.181,10.86.169.153,10.146.95.240
- name: BOOTSTRAP_MODE
value: "{{workflow.parameters.bootstrap-mode}}"
- name: RENEW_BEFORE
value: 720h
- name: CERTIFICATE_TTL
value: 2160h
- name: ACTIVATION_TIMEOUT
value: 180s
volumeMounts:
- name: opnsense-credentials
mountPath: /opnsense-credentials
readOnly: true
- name: opnsense-bootstrap-ca
mountPath: /opnsense-bootstrap-ca
readOnly: true
- name: vault-ca
mountPath: /vault-ca
readOnly: true
- name: opnsense-managed-ca
mountPath: /opnsense-managed-ca
readOnly: true
resources:
requests:
cpu: 10m
memory: 32Mi
limits:
memory: 128Mi
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL

View file

@ -0,0 +1,99 @@
apiVersion: argoproj.io/v1alpha1
kind: CronWorkflow
metadata:
name: relay-admission-daily
namespace: argo-relay-admission
labels:
app.kubernetes.io/name: relay-admission-publisher
app.kubernetes.io/instance: relay-admission-publisher
spec:
schedules:
- "23 16 * * *"
timezone: UTC
suspend: false
concurrencyPolicy: Forbid
startingDeadlineSeconds: 1800
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 7
workflowSpec:
workflowTemplateRef:
name: relay-admission-publisher
arguments:
parameters:
- name: sources
value: iplocate-country,iplocate-asn,spamhaus-drop,oci
---
apiVersion: argoproj.io/v1alpha1
kind: CronWorkflow
metadata:
name: relay-admission-maxmind
namespace: argo-relay-admission
labels:
app.kubernetes.io/name: relay-admission-publisher
app.kubernetes.io/instance: relay-admission-publisher
spec:
schedules:
- "23 17 * * 2,5"
timezone: UTC
suspend: false
concurrencyPolicy: Forbid
startingDeadlineSeconds: 1800
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 7
workflowSpec:
workflowTemplateRef:
name: relay-admission-publisher
arguments:
parameters:
- name: sources
value: maxmind-country
---
apiVersion: argoproj.io/v1alpha1
kind: CronWorkflow
metadata:
name: relay-admission-azure
namespace: argo-relay-admission
labels:
app.kubernetes.io/name: relay-admission-publisher
app.kubernetes.io/instance: relay-admission-publisher
spec:
schedules:
- "23 18 * * 0"
timezone: UTC
suspend: false
concurrencyPolicy: Forbid
startingDeadlineSeconds: 1800
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 7
workflowSpec:
workflowTemplateRef:
name: relay-admission-publisher
arguments:
parameters:
- name: sources
value: azure
---
apiVersion: argoproj.io/v1alpha1
kind: CronWorkflow
metadata:
name: relay-admission-reconcile
namespace: argo-relay-admission
labels:
app.kubernetes.io/name: relay-admission-publisher
app.kubernetes.io/instance: relay-admission-publisher
spec:
schedules:
- "23 19 * * 6"
timezone: UTC
suspend: false
concurrencyPolicy: Forbid
startingDeadlineSeconds: 1800
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 7
workflowSpec:
workflowTemplateRef:
name: relay-admission-publisher
arguments:
parameters:
- name: sources
value: tor-exits,aws,gcp,cloudflare,fastly,github,atlassian,digitalocean,linode,vultr

View file

@ -0,0 +1,368 @@
apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
name: relay-admission-publisher
namespace: argo-relay-admission
labels:
app.kubernetes.io/name: relay-admission-publisher
app.kubernetes.io/instance: relay-admission-publisher
spec:
entrypoint: refresh
serviceAccountName: relay-admission-publisher
activeDeadlineSeconds: 3600
parallelism: 1
synchronization:
mutexes:
- name: relay-admission-publisher
podMetadata:
labels:
app.kubernetes.io/name: relay-admission-publisher
app.kubernetes.io/instance: relay-admission-publisher
securityContext:
fsGroup: 65532
fsGroupChangePolicy: OnRootMismatch
runAsNonRoot: true
runAsUser: 65532
runAsGroup: 65532
seccompProfile:
type: RuntimeDefault
arguments:
parameters:
- name: sources
value: iplocate-country,iplocate-asn,spamhaus-drop,oci
volumes:
- name: cache
persistentVolumeClaim:
claimName: relay-admission-cache
- name: maxmind
secret:
secretName: relay-admission-maxmind
defaultMode: 0440
- name: ip2location
secret:
secretName: relay-admission-ip2location
defaultMode: 0440
- name: oci
secret:
secretName: relay-admission-oci
defaultMode: 0440
ttlStrategy:
secondsAfterCompletion: 604800
secondsAfterSuccess: 86400
secondsAfterFailure: 604800
templates:
- name: refresh
inputs:
parameters:
- name: sources
dag:
tasks:
- name: fetch
template: fetch
arguments:
parameters:
- name: sources
value: '{{inputs.parameters.sources}}'
- name: compile
depends: fetch.Succeeded
template: compile
- name: validate
depends: compile.Succeeded
template: validate
- name: publish
depends: validate.Succeeded
template: publish
arguments:
parameters:
- name: promote-current
value: "true"
- name: bootstrap
dag:
tasks:
- name: fetch-ip2proxy
template: fetch-ip2proxy
- name: fetch
depends: fetch-ip2proxy.Succeeded
template: fetch
arguments:
parameters:
- name: sources
value: maxmind-country,iplocate-country,iplocate-asn,spamhaus-drop,tor-exits,aws,gcp,azure,oci,cloudflare,fastly,github,atlassian,digitalocean,linode,vultr
- name: compile
depends: fetch.Succeeded
template: compile
- name: validate
depends: compile.Succeeded
template: validate
- name: resume-bootstrap
dag:
tasks:
- name: fetch
template: fetch
arguments:
parameters:
- name: sources
value: maxmind-country,iplocate-country,iplocate-asn,spamhaus-drop,tor-exits,aws,gcp,azure,oci,cloudflare,fastly,github,atlassian,digitalocean,linode,vultr
- name: compile
depends: fetch.Succeeded
template: compile
- name: validate
depends: compile.Succeeded
template: validate
- name: probe-candidate
dag:
tasks:
- name: validate
template: validate
- name: publish
depends: validate.Succeeded
template: publish
arguments:
parameters:
- name: promote-current
value: "false"
- name: compile-cached
dag:
tasks:
- name: compile
template: compile
- name: validate
depends: compile.Succeeded
template: validate
- name: restore-current
inputs:
parameters:
- name: bundle-sha256
dag:
tasks:
- name: download
template: download-version
arguments:
parameters:
- name: bundle-sha256
value: '{{inputs.parameters.bundle-sha256}}'
- name: validate
depends: download.Succeeded
template: validate
arguments:
parameters:
- name: bundle-path
value: /work/run/{{workflow.uid}}/restore.json.gz
- name: publish
depends: validate.Succeeded
template: publish
arguments:
parameters:
- name: bundle-path
value: /work/run/{{workflow.uid}}/restore.json.gz
- name: promote-current
value: "true"
- name: publish-candidate
dag:
tasks:
- name: validate
template: validate
- name: publish
depends: validate.Succeeded
template: publish
arguments:
parameters:
- name: promote-current
value: "true"
- name: fetch
inputs:
parameters:
- name: sources
retryStrategy:
limit: "2"
retryPolicy: OnFailure
backoff:
duration: 30s
factor: 2
maxDuration: 5m
container:
image: registry.quorate.internal/quorate/oci-l4-relay-publisher@sha256:3cc58cbdf9709777a016c5546b4747b1f0392b14052ee8bb7db15ef88b43ae45
imagePullPolicy: IfNotPresent
command: [/publisher/fetch-public]
args:
- -sources
- '{{inputs.parameters.sources}}'
- -changed-file
- /work/run/{{workflow.uid}}/fetch-changed
- -summary-file
- /work/run/{{workflow.uid}}/fetch-summary.json
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
memory: 768Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
volumeMounts:
- name: cache
mountPath: /work
- name: maxmind
mountPath: /credentials/maxmind
readOnly: true
- name: fetch-ip2proxy
container:
image: registry.quorate.internal/quorate/oci-l4-relay-publisher@sha256:3cc58cbdf9709777a016c5546b4747b1f0392b14052ee8bb7db15ef88b43ae45
imagePullPolicy: IfNotPresent
command: [/publisher/fetch-ip2proxy]
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
memory: 768Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
volumeMounts:
- name: cache
mountPath: /work
- name: ip2location
mountPath: /credentials/ip2location
readOnly: true
- name: compile
container:
image: registry.quorate.internal/quorate/oci-l4-relay-publisher@sha256:3cc58cbdf9709777a016c5546b4747b1f0392b14052ee8bb7db15ef88b43ae45
imagePullPolicy: IfNotPresent
command: [/publisher/compile]
args:
- -bundle-output
- /work/output/candidate.json.gz
- -vpn-exception-asn
- "147049"
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
memory: 1Gi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
volumeMounts:
- name: cache
mountPath: /work
- name: validate
inputs:
parameters:
- name: bundle-path
default: /work/output/candidate.json.gz
container:
image: registry.quorate.internal/quorate/oci-l4-relay-publisher@sha256:3cc58cbdf9709777a016c5546b4747b1f0392b14052ee8bb7db15ef88b43ae45
imagePullPolicy: IfNotPresent
command: [/publisher/validate]
args:
- validate
- -input
- '{{inputs.parameters.bundle-path}}'
- -minimum-admitted-addresses
- "1000000000"
- -maximum-admitted-addresses
- "3500000000"
- -minimum-admitted-intervals
- "10000"
- -maximum-exception-addresses
- "4096"
- -maximum-exception-intervals
- "512"
- -summary-output
- /work/run/{{workflow.uid}}/validation-summary.json
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
memory: 512Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
volumeMounts:
- name: cache
mountPath: /work
- name: publish
inputs:
parameters:
- name: bundle-path
default: /work/output/candidate.json.gz
- name: promote-current
container:
image: registry.quorate.internal/quorate/oci-l4-relay-publisher@sha256:3cc58cbdf9709777a016c5546b4747b1f0392b14052ee8bb7db15ef88b43ae45
imagePullPolicy: IfNotPresent
command: [/publisher/publish]
args:
- -bundle
- '{{inputs.parameters.bundle-path}}'
- -result-file
- /work/run/{{workflow.uid}}/publication-result.json
- -object-prefix
- admission/v1
- -additional-object-prefix
- web-allow/v1
- -promote-current={{inputs.parameters.promote-current}}
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
memory: 512Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
volumeMounts:
- name: cache
mountPath: /work
- name: oci
mountPath: /credentials/oci
readOnly: true
- name: download-version
inputs:
parameters:
- name: bundle-sha256
container:
image: registry.quorate.internal/quorate/oci-l4-relay-publisher@sha256:3cc58cbdf9709777a016c5546b4747b1f0392b14052ee8bb7db15ef88b43ae45
imagePullPolicy: IfNotPresent
command: [/publisher/publish]
args:
- -restore-version-sha256
- '{{inputs.parameters.bundle-sha256}}'
- -restore-output
- /work/run/{{workflow.uid}}/restore.json.gz
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
memory: 512Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
volumeMounts:
- name: cache
mountPath: /work
- name: oci
mountPath: /credentials/oci
readOnly: true

View file

@ -0,0 +1,20 @@
apiVersion: argoproj.io/v1alpha1
kind: CronWorkflow
metadata:
name: relay-smtp-deny-refresh
namespace: argo-relay-smtp-deny
labels:
app.kubernetes.io/name: relay-smtp-deny-publisher
app.kubernetes.io/instance: relay-smtp-deny-publisher
spec:
schedules:
- "23 */6 * * *"
timezone: UTC
suspend: false
concurrencyPolicy: Forbid
startingDeadlineSeconds: 1800
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 7
workflowSpec:
workflowTemplateRef:
name: relay-smtp-deny-publisher

View file

@ -0,0 +1,130 @@
apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
name: relay-smtp-deny-publisher
namespace: argo-relay-smtp-deny
labels:
app.kubernetes.io/name: relay-smtp-deny-publisher
app.kubernetes.io/instance: relay-smtp-deny-publisher
spec:
entrypoint: publish-empty
serviceAccountName: relay-smtp-deny-publisher
activeDeadlineSeconds: 600
parallelism: 1
synchronization:
mutexes:
- name: relay-smtp-deny-publisher
podMetadata:
labels:
app.kubernetes.io/name: relay-smtp-deny-publisher
app.kubernetes.io/instance: relay-smtp-deny-publisher
securityContext:
fsGroup: 65532
fsGroupChangePolicy: OnRootMismatch
runAsNonRoot: true
runAsUser: 65532
runAsGroup: 65532
seccompProfile:
type: RuntimeDefault
volumes:
- name: work
emptyDir: {}
- name: oci
secret:
secretName: relay-smtp-deny-oci
defaultMode: 0440
ttlStrategy:
secondsAfterCompletion: 604800
secondsAfterSuccess: 86400
secondsAfterFailure: 604800
templates:
- name: publish-empty
containerSet:
volumeMounts:
- name: work
mountPath: /work
- name: oci
mountPath: /credentials/oci
readOnly: true
containers:
- name: create
image: registry.quorate.internal/quorate/oci-l4-relay-publisher@sha256:3cc58cbdf9709777a016c5546b4747b1f0392b14052ee8bb7db15ef88b43ae45
imagePullPolicy: IfNotPresent
command: [/publisher/smtp-deny]
args:
- empty
- -output
- /work/current.json.gz
- -lifetime
- 24h
resources:
requests:
cpu: 10m
memory: 32Mi
limits:
memory: 64Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
- name: validate
dependencies: [create]
image: registry.quorate.internal/quorate/oci-l4-relay-publisher@sha256:3cc58cbdf9709777a016c5546b4747b1f0392b14052ee8bb7db15ef88b43ae45
imagePullPolicy: IfNotPresent
command: [/publisher/smtp-deny]
args:
- validate
- -input
- /work/current.json.gz
- -minimum-observations
- "20"
- -maximum-addresses
- "4096"
- -maximum-intervals
- "1024"
- -maximum-lifetime
- 24h
- -maximum-observation-window
- 10m
- -summary-output
- /work/validation-summary.json
resources:
requests:
cpu: 10m
memory: 32Mi
limits:
memory: 64Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
- name: publish
dependencies: [validate]
image: registry.quorate.internal/quorate/oci-l4-relay-publisher@sha256:3cc58cbdf9709777a016c5546b4747b1f0392b14052ee8bb7db15ef88b43ae45
imagePullPolicy: IfNotPresent
command: [/publisher/publish]
args:
- -bundle
- /work/current.json.gz
- -object-prefix
- smtp-deny/v1
- -smtp-deny-summary
- /work/validation-summary.json
- -result-file
- /work/publication-result.json
resources:
requests:
cpu: 10m
memory: 32Mi
limits:
memory: 64Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true

View file

@ -0,0 +1,222 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: argo-workflows
namespace: argo
spec:
interval: 15m
releaseName: argo-workflows
targetNamespace: argo
chart:
spec:
chart: argo-workflows
version: 2.0.14
sourceRef:
kind: HelmRepository
name: argo
namespace: flux-system
install:
remediation:
retries: 3
upgrade:
remediation:
retries: 3
values:
images:
tag: v4.1.6
pullPolicy: IfNotPresent
crds:
install: true
keep: true
full: true
upgradeJob:
image:
registry: quay.io
repository: argoproj/argo-workflows-crdinstaller
tag: v4.1.6@sha256:b9be70ef3f4a0709d771e9c098a99fd2d97be1b095c1b160c668a2fde61dc237
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
memory: 256Mi
singleNamespace: false
workflow:
serviceAccount:
create: true
name: argo-workflow
rbac:
create: true
rules:
- apiGroups: [""]
resources: [secrets]
resourceNames:
- argo-artifacts
- argo-internal-ca
verbs: [get]
controller:
image:
registry: quay.io
repository: argoproj/workflow-controller
tag: v4.1.6@sha256:a012a639ead374a4a9306093d6b29dfdc7e6c4c1a85c684582cb961a6cc8bcf3
extraEnv:
- name: WORKFLOW_USER_OVERRIDE_ALLOWLIST
value: synchronization
replicas: 2
pdb:
enabled: true
minAvailable: 1
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app.kubernetes.io/name: argo-workflows-workflow-controller
app.kubernetes.io/instance: argo-workflows
topologyKey: kubernetes.io/hostname
workflowNamespaces:
- argo
- argo-opnsense-certificate
workflowRestrictions:
templateReferencing: Secure
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
memory: 1Gi
securityContext:
readOnlyRootFilesystem: true
runAsNonRoot: true
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
persistence:
archive: true
archiveTTL: 30d
nodeStatusOffLoad: true
connectionPool:
maxIdleConns: 100
maxOpenConns: 0
postgresql:
host: main-rw.postgres.svc.cluster.local
port: 5432
database: argo
tableName: argo_workflows
userNameSecret:
name: argo-db
key: username
passwordSecret:
name: argo-db
key: password
ssl: true
sslMode: require
workflowDefaults:
metadata:
labels:
app.kubernetes.io/part-of: argo-workflows
spec:
serviceAccountName: argo-workflow
podMetadata:
labels:
app.kubernetes.io/name: argo-workflow
app.kubernetes.io/instance: argo-workflows
ttlStrategy:
secondsAfterSuccess: 86400
secondsAfterFailure: 259200
secondsAfterCompletion: 604800
securityContext:
runAsNonRoot: true
runAsUser: 1000
seccompProfile:
type: RuntimeDefault
executor:
image:
registry: quay.io
repository: argoproj/argoexec
tag: v4.1.6@sha256:28432d912a716167709429b28e2755f49416eb4754c35ca3013863fb72717a00
resources:
requests:
cpu: 10m
memory: 64Mi
limits:
memory: 256Mi
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 8737
capabilities:
drop:
- ALL
mainContainer:
resources:
requests:
cpu: 50m
memory: 64Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
server:
enabled: true
image:
registry: quay.io
repository: argoproj/argocli
tag: v4.1.6@sha256:acb4c1de9a9c5fa109fb3094eebbc3eac42d2dd328181b0a395488cc97de75e5
replicas: 2
pdb:
enabled: true
minAvailable: 1
authModes:
- server
secure: false
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app.kubernetes.io/name: argo-workflows-server
app.kubernetes.io/instance: argo-workflows
topologyKey: kubernetes.io/hostname
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
memory: 512Mi
securityContext:
readOnlyRootFilesystem: false
runAsNonRoot: true
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
useStaticCredentials: true
artifactRepository:
archiveLogs: false
s3:
bucket: argo-workflows
endpoint: s3.quorate.internal
region: us-east-1
insecure: false
accessKeySecret:
name: argo-artifacts
key: accesskey
secretKeySecret:
name: argo-artifacts
key: secretkey
caSecret:
name: argo-internal-ca
key: internal-ca.crt
keyFormat: "artifacts/{{workflow.namespace}}/{{workflow.name}}/{{pod.name}}"

View file

@ -0,0 +1,11 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- vso.yaml
- vso-relay-admission.yaml
- vso-opnsense-certificate.yaml
- helm-release.yaml
- network-policies.yaml
- network-policy-relay-admission.yaml
- network-policy-opnsense-certificate.yaml

View file

@ -0,0 +1,141 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: argo
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: argo-vso
namespace: argo
---
apiVersion: v1
kind: Namespace
metadata:
name: argo-relay-admission
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: relay-admission-vso
namespace: argo-relay-admission
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: relay-admission-publisher
namespace: argo-relay-admission
imagePullSecrets:
- name: quay-cluster-pull
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: relay-admission-executor
namespace: argo-relay-admission
rules:
- apiGroups: [argoproj.io]
resources: [workflowtaskresults]
verbs: [create, get, patch]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: relay-admission-executor
namespace: argo-relay-admission
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: relay-admission-executor
subjects:
- kind: ServiceAccount
name: relay-admission-publisher
namespace: argo-relay-admission
---
apiVersion: v1
kind: Namespace
metadata:
name: argo-relay-smtp-deny
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: relay-smtp-deny-vso
namespace: argo-relay-smtp-deny
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: relay-smtp-deny-publisher
namespace: argo-relay-smtp-deny
imagePullSecrets:
- name: quay-cluster-pull
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: relay-smtp-deny-executor
namespace: argo-relay-smtp-deny
rules:
- apiGroups: [argoproj.io]
resources: [workflowtaskresults]
verbs: [create, get, patch]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: relay-smtp-deny-executor
namespace: argo-relay-smtp-deny
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: relay-smtp-deny-executor
subjects:
- kind: ServiceAccount
name: relay-smtp-deny-publisher
namespace: argo-relay-smtp-deny
---
apiVersion: v1
kind: Namespace
metadata:
name: argo-opnsense-certificate
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: opnsense-certificate-vso
namespace: argo-opnsense-certificate
automountServiceAccountToken: false
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: opnsense-certificate-rotator
namespace: argo-opnsense-certificate
imagePullSecrets:
- name: quay-cluster-pull
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: opnsense-certificate-executor
namespace: argo-opnsense-certificate
rules:
- apiGroups: [argoproj.io]
resources: [workflowtaskresults]
verbs: [create, get, patch]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: opnsense-certificate-executor
namespace: argo-opnsense-certificate
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: opnsense-certificate-executor
subjects:
- kind: ServiceAccount
name: opnsense-certificate-rotator
namespace: argo-opnsense-certificate

View file

@ -0,0 +1,162 @@
---
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: argo-dns
namespace: argo
spec:
endpointSelector: {}
egress:
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: kube-system
k8s-app: kube-dns
toPorts:
- ports:
- port: "53"
protocol: UDP
- port: "53"
protocol: TCP
- toServices:
- k8sService:
namespace: kube-system
serviceName: kube-dns
toPorts:
- ports:
- port: "53"
protocol: UDP
- port: "53"
protocol: TCP
---
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: argo-crd-install
namespace: argo
spec:
endpointSelector:
matchLabels:
app.kubernetes.io/name: argo-workflows-crd-install
app.kubernetes.io/instance: argo-workflows
egress:
- toEntities:
- world
toPorts:
- ports:
- port: "443"
protocol: TCP
---
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: argo-workflow-controller
namespace: argo
spec:
endpointSelector:
matchLabels:
app.kubernetes.io/name: argo-workflows-workflow-controller
app.kubernetes.io/instance: argo-workflows
ingress:
- fromEntities:
- host
toPorts:
- ports:
- port: "6060"
protocol: TCP
egress:
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: postgres
cnpg.io/cluster: main
toPorts:
- ports:
- port: "5432"
protocol: TCP
---
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: argo-workflows-server
namespace: argo
spec:
endpointSelector:
matchLabels:
app.kubernetes.io/name: argo-workflows-server
app.kubernetes.io/instance: argo-workflows
ingress:
- fromEntities:
- host
toPorts:
- ports:
- port: "2746"
protocol: TCP
egress:
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: postgres
cnpg.io/cluster: main
toPorts:
- ports:
- port: "5432"
protocol: TCP
---
apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata:
name: host-egress-argo-server
spec:
nodeSelector: {}
egress:
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: argo
app.kubernetes.io/name: argo-workflows-server
app.kubernetes.io/instance: argo-workflows
toPorts:
- ports:
- port: "2746"
protocol: TCP
---
apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata:
name: host-egress-argo-workflow-controller
spec:
nodeSelector: {}
egress:
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: argo
app.kubernetes.io/name: argo-workflows-workflow-controller
app.kubernetes.io/instance: argo-workflows
toPorts:
- ports:
- port: "6060"
protocol: TCP
---
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: argo-workflow-pods
namespace: argo
spec:
endpointSelector:
matchLabels:
app.kubernetes.io/name: argo-workflow
app.kubernetes.io/instance: argo-workflows
egress:
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: versitygw
app.kubernetes.io/name: versitygw
app.kubernetes.io/instance: versitygw
toPorts:
- ports:
- port: "7070"
protocol: TCP
- toCIDR:
- 10.66.127.81/32
toPorts:
- ports:
- port: "443"
protocol: TCP

View file

@ -0,0 +1,49 @@
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: opnsense-certificate-rotator
namespace: argo-opnsense-certificate
spec:
endpointSelector: {}
egress:
- toEntities:
- kube-apiserver
toPorts:
- ports:
- port: "6443"
protocol: TCP
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: kube-system
k8s-app: kube-dns
toPorts:
- ports:
- port: "53"
protocol: UDP
- port: "53"
protocol: TCP
- toServices:
- k8sService:
namespace: kube-system
serviceName: kube-dns
toPorts:
- ports:
- port: "53"
protocol: UDP
- port: "53"
protocol: TCP
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: vault
app.kubernetes.io/name: vault
component: server
toPorts:
- ports:
- port: "8200"
protocol: TCP
- toCIDR:
- 10.212.111.120/32
toPorts:
- ports:
- port: "8443"
protocol: TCP

View file

@ -0,0 +1,81 @@
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: relay-admission-publisher
namespace: argo-relay-admission
spec:
endpointSelector: {}
egress:
- toEntities:
- kube-apiserver
toPorts:
- ports:
- port: "6443"
protocol: TCP
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: kube-system
k8s-app: kube-dns
toPorts:
- ports:
- port: "53"
protocol: UDP
- port: "53"
protocol: TCP
- toServices:
- k8sService:
namespace: kube-system
serviceName: kube-dns
toPorts:
- ports:
- port: "53"
protocol: UDP
- port: "53"
protocol: TCP
- toEntities:
- world
toPorts:
- ports:
- port: "443"
protocol: TCP
---
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: relay-smtp-deny-publisher
namespace: argo-relay-smtp-deny
spec:
endpointSelector: {}
egress:
- toEntities:
- kube-apiserver
toPorts:
- ports:
- port: "6443"
protocol: TCP
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: kube-system
k8s-app: kube-dns
toPorts:
- ports:
- port: "53"
protocol: UDP
- port: "53"
protocol: TCP
- toServices:
- k8sService:
namespace: kube-system
serviceName: kube-dns
toPorts:
- ports:
- port: "53"
protocol: UDP
- port: "53"
protocol: TCP
- toEntities:
- world
toPorts:
- ports:
- port: "443"
protocol: TCP

View file

@ -0,0 +1,132 @@
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultAuth
metadata:
name: default
namespace: argo-opnsense-certificate
spec:
method: kubernetes
mount: kubernetes
kubernetes:
role: argo-opnsense-certificate-kv
serviceAccount: opnsense-certificate-vso
vaultConnectionRef: vault/vault
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
name: opnsense-certificate-credentials
namespace: argo-opnsense-certificate
spec:
type: kv-v2
mount: secret
path: opnsense/certificate-rotator
destination:
name: opnsense-certificate-credentials
create: true
overwrite: true
transformation:
excludeRaw: true
excludes:
- .*
templates:
key:
text: '{{ get .Secrets "key" }}'
secret:
text: '{{ get .Secrets "secret" }}'
vaultAuthRef: default
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
name: quay-cluster-pull
namespace: argo-opnsense-certificate
spec:
type: kv-v2
mount: secret
path: quay/robots/cluster_pull
destination:
name: quay-cluster-pull
create: true
overwrite: true
type: kubernetes.io/dockerconfigjson
transformation:
excludeRaw: true
excludes:
- .*
templates:
.dockerconfigjson:
text: >-
{"auths":{"registry.quorate.internal":{"auth":"{{ printf "%s:%s" (get .Secrets "username") (get .Secrets "token") | b64enc }}"}}}
refreshAfter: 1h
vaultAuthRef: default
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
name: opnsense-certificate-bootstrap-ca
namespace: argo-opnsense-certificate
spec:
type: kv-v2
mount: secret
path: opnsense/web-certificate
destination:
name: opnsense-certificate-bootstrap-ca
create: true
overwrite: true
transformation:
excludeRaw: true
excludes:
- .*
templates:
ca.crt:
text: |
{{ get .Secrets "ca.crt" }}
vaultAuthRef: default
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultDynamicSecret
metadata:
name: opnsense-certificate-vault-ca
namespace: argo-opnsense-certificate
spec:
mount: pki
path: cert/ca
requestHTTPMethod: GET
refreshAfter: 1h
destination:
name: opnsense-certificate-vault-ca
create: true
overwrite: true
transformation:
excludeRaw: true
excludes:
- .*
templates:
ca.crt:
text: |
{{ get .Secrets "certificate" }}
vaultAuthRef: default
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultDynamicSecret
metadata:
name: opnsense-certificate-managed-ca
namespace: argo-opnsense-certificate
spec:
mount: pki_opnsense
path: cert/ca
requestHTTPMethod: GET
refreshAfter: 1h
destination:
name: opnsense-certificate-managed-ca
create: true
overwrite: true
transformation:
excludeRaw: true
excludes:
- .*
templates:
ca.crt:
text: |
{{ get .Secrets "certificate" }}
vaultAuthRef: default

View file

@ -0,0 +1,189 @@
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultAuth
metadata:
name: default
namespace: argo-relay-admission
spec:
method: kubernetes
mount: kubernetes
kubernetes:
role: argo-relay-admission
serviceAccount: relay-admission-vso
vaultConnectionRef: vault/vault
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
name: relay-admission-maxmind
namespace: argo-relay-admission
spec:
type: kv-v2
mount: secret
path: mindmax
destination:
name: relay-admission-maxmind
create: true
overwrite: true
transformation:
excludeRaw: true
excludes:
- .*
templates:
license-key:
text: '{{ get .Secrets "license-key" }}'
vaultAuthRef: default
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
name: quay-cluster-pull
namespace: argo-relay-smtp-deny
spec:
type: kv-v2
mount: secret
path: quay/robots/cluster_pull
destination:
name: quay-cluster-pull
create: true
overwrite: true
type: kubernetes.io/dockerconfigjson
transformation:
excludeRaw: true
excludes:
- .*
templates:
.dockerconfigjson:
text: >-
{"auths":{"registry.quorate.internal":{"auth":"{{ printf "%s:%s" (get .Secrets "username") (get .Secrets "token") | b64enc }}"}}}
refreshAfter: 1h
vaultAuthRef: default
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
name: quay-cluster-pull
namespace: argo-relay-admission
spec:
type: kv-v2
mount: secret
path: quay/robots/cluster_pull
destination:
name: quay-cluster-pull
create: true
overwrite: true
type: kubernetes.io/dockerconfigjson
transformation:
excludeRaw: true
excludes:
- .*
templates:
.dockerconfigjson:
text: >-
{"auths":{"registry.quorate.internal":{"auth":"{{ printf "%s:%s" (get .Secrets "username") (get .Secrets "token") | b64enc }}"}}}
refreshAfter: 1h
vaultAuthRef: default
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultAuth
metadata:
name: default
namespace: argo-relay-smtp-deny
spec:
method: kubernetes
mount: kubernetes
kubernetes:
role: argo-relay-smtp-deny
serviceAccount: relay-smtp-deny-vso
vaultConnectionRef: vault/vault
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
name: relay-smtp-deny-oci
namespace: argo-relay-smtp-deny
spec:
type: kv-v2
mount: secret
path: oci/relay/smtp-deny-publisher-api
destination:
name: relay-smtp-deny-oci
create: true
overwrite: true
transformation:
excludeRaw: true
excludes:
- .*
templates:
tenancy_ocid:
text: '{{ get .Secrets "tenancy_ocid" }}'
user_ocid:
text: '{{ get .Secrets "user_ocid" }}'
fingerprint:
text: '{{ get .Secrets "fingerprint" }}'
private_key:
text: |
{{ get .Secrets "private_key" }}
region:
text: '{{ get .Secrets "region" }}'
object_storage_namespace:
text: '{{ get .Secrets "object_storage_namespace" }}'
bucket_name:
text: '{{ get .Secrets "bucket_name" }}'
vaultAuthRef: default
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
name: relay-admission-ip2location
namespace: argo-relay-admission
spec:
type: kv-v2
mount: secret
path: ip2location
destination:
name: relay-admission-ip2location
create: true
overwrite: true
transformation:
excludeRaw: true
excludes:
- .*
templates:
download-token:
text: '{{ get .Secrets "download-token" }}'
vaultAuthRef: default
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
name: relay-admission-oci
namespace: argo-relay-admission
spec:
type: kv-v2
mount: secret
path: oci/relay/publisher-api
destination:
name: relay-admission-oci
create: true
overwrite: true
transformation:
excludeRaw: true
excludes:
- .*
templates:
tenancy_ocid:
text: '{{ get .Secrets "tenancy_ocid" }}'
user_ocid:
text: '{{ get .Secrets "user_ocid" }}'
fingerprint:
text: '{{ get .Secrets "fingerprint" }}'
private_key:
text: |
{{ get .Secrets "private_key" }}
region:
text: '{{ get .Secrets "region" }}'
object_storage_namespace:
text: '{{ get .Secrets "object_storage_namespace" }}'
bucket_name:
text: '{{ get .Secrets "bucket_name" }}'
vaultAuthRef: default

92
vendor/platform/argo-workflows/vso.yaml vendored Normal file
View file

@ -0,0 +1,92 @@
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultAuth
metadata:
name: default
namespace: argo
spec:
method: kubernetes
mount: kubernetes
kubernetes:
role: argo
serviceAccount: argo-vso
vaultConnectionRef: vault/vault
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultDynamicSecret
metadata:
name: argo-db
namespace: argo
spec:
mount: database
path: static-creds/argo
allowStaticCreds: true
refreshAfter: 5m
destination:
name: argo-db
create: true
overwrite: true
transformation:
excludeRaw: true
excludes:
- .*
templates:
username:
text: '{{ get .Secrets "username" }}'
password:
text: '{{ get .Secrets "password" }}'
rolloutRestartTargets:
- kind: Deployment
name: argo-workflows-workflow-controller
- kind: Deployment
name: argo-workflows-server
vaultAuthRef: default
---
# S3 credentials for the workflow executor (artifact upload/download).
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
name: argo-artifacts
namespace: argo
spec:
type: kv-v2
mount: secret
path: argo/artifacts
destination:
name: argo-artifacts
create: true
overwrite: true
transformation:
excludeRaw: true
excludes:
- .*
templates:
accesskey:
text: '{{ get .Secrets "access_key_id" }}'
secretkey:
text: '{{ get .Secrets "secret_access_key" }}'
vaultAuthRef: default
---
# Internal root CA so executors can verify s3.quorate.internal TLS.
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
name: argo-internal-ca
namespace: argo
spec:
type: kv-v2
mount: secret
path: argo/artifacts
destination:
name: argo-internal-ca
create: true
overwrite: true
transformation:
excludeRaw: true
excludes:
- .*
templates:
internal-ca.crt:
text: |
{{ get .Secrets "internal_ca_cert" }}
vaultAuthRef: default