diff --git a/apps/dot-ai-stack.yaml b/apps/dot-ai-stack.yaml index e105754..5fba970 100644 --- a/apps/dot-ai-stack.yaml +++ b/apps/dot-ai-stack.yaml @@ -34,6 +34,10 @@ metadata: namespace: argocd annotations: argocd.argoproj.io/sync-wave: "1" + notifications.argoproj.io/subscribe.on-sync-running.slack: "" + notifications.argoproj.io/subscribe.on-sync-succeeded.slack: "" + notifications.argoproj.io/subscribe.on-sync-failed.slack: "" + notifications.argoproj.io/subscribe.on-degraded.slack: "" labels: app.kubernetes.io/name: dot-ai-stack app.kubernetes.io/part-of: apps diff --git a/apps/feedback-hub.yaml b/apps/feedback-hub.yaml index 9817fc7..a86c255 100644 --- a/apps/feedback-hub.yaml +++ b/apps/feedback-hub.yaml @@ -7,6 +7,12 @@ metadata: app.kubernetes.io/name: feedback-hub app.kubernetes.io/part-of: apps app.kubernetes.io/managed-by: argocd + annotations: + argocd.argoproj.io/sync-wave: "1" + notifications.argoproj.io/subscribe.on-sync-running.slack: "" + notifications.argoproj.io/subscribe.on-sync-succeeded.slack: "" + notifications.argoproj.io/subscribe.on-sync-failed.slack: "" + notifications.argoproj.io/subscribe.on-degraded.slack: "" spec: project: default source: diff --git a/apps/musicman.yaml b/apps/musicman.yaml index 6abb9ea..e16771f 100644 --- a/apps/musicman.yaml +++ b/apps/musicman.yaml @@ -3,6 +3,12 @@ kind: Application metadata: name: music-man namespace: argocd + annotations: + argocd.argoproj.io/sync-wave: "1" + notifications.argoproj.io/subscribe.on-sync-running.slack: "" + notifications.argoproj.io/subscribe.on-sync-succeeded.slack: "" + notifications.argoproj.io/subscribe.on-sync-failed.slack: "" + notifications.argoproj.io/subscribe.on-degraded.slack: "" labels: app.kubernetes.io/name: music-man app.kubernetes.io/part-of: apps diff --git a/cluster-resources/argocd-notifications-secret-sealed.yaml b/cluster-resources/argocd-notifications-secret-sealed.yaml new file mode 100644 index 0000000..eb573cf --- /dev/null +++ b/cluster-resources/argocd-notifications-secret-sealed.yaml @@ -0,0 +1,16 @@ +--- +apiVersion: bitnami.com/v1alpha1 +kind: SealedSecret +metadata: + creationTimestamp: null + name: argocd-notifications-secret + namespace: argocd +spec: + encryptedData: + slack-webhook-url: AgBIIEfU1TzNNJoQMsiKqF+x0y5vGu5iMwvTADGuUcjlz7DtfExTQu86OdUO1+Gxri/NKKj+KN1Tv7WNJs5Yo/hjjLs/JTxKYuEF6S0xaqLX3sRCkMCdVpRkH079CW4ayDP2moIGrG9+nq0iGNA7qyPssjjSCeMaj6SiHAIXdV+f/5XLrwHUybL2drBp7OVsZcLQJhQRGYIM/R4PvQJGLv95L/XPn5aOK8jxhHIsaxwRlAuGpCP/Ct7mG6H2qL0zKZn/H7Vl+x/Xgx0a/VGcEMosgQY1PeSqihyTcCsSu1g2rd8A03nw8v3kIjkiMzSpIKHoEpWuoNWxDmwMYrpvy1QUnpW2nT9WkLoaoi4lczNr63Z/LT2mCTMhgC83OxF5IA/9cekWh+VMHVsS2c4qQvlDZoT2N4SwkWy++rreFwrXdaMBJHIQI2wT9rtWwRLG4sLigaxBPX7lzVlplkSxHgrVi6c329u6+2Dcw9eMOPfw7GmbnF5H+t1AmFEBbrf2LOPGRy3yd+5g5U4Eyhf7YmA9SaT7TB1w3UhacSCslVH41NLtqNV65lvAjPCyYbEEjmnV02i9rPDyHMitrZ9Z8Spzo3oiK0ZndWh98u8iA7NJY2i+L01n7OLGjRBGL364URHRqcDxCPRrc0ApRBj5aa4HEScowmWCPcoqgzwFfclAz2iNAgQ7h+7/rUN2k96V7Eo0xco+bF/XgwWX5ehIB6FQYKborWa7XHvAGEc85eD3bNOnOUF1RJB/4GzN5yu/7fyeRVnKNEAzZ2cuXD+5RA5gPyqBVgTFspl2MasbMW9KOZT4YKts0ILXqpo= + template: + metadata: + creationTimestamp: null + name: argocd-notifications-secret + namespace: argocd + type: Opaque diff --git a/infra/values/argocd-values.yaml b/infra/values/argocd-values.yaml index 83d2870..0f8d89c 100644 --- a/infra/values/argocd-values.yaml +++ b/infra/values/argocd-values.yaml @@ -20,3 +20,77 @@ server: extraArgs: - --insecure - --disable-auth + +notifications: + # Don't create secret via Helm - using SealedSecret instead + secret: + create: false + + # Configure notification service and templates + cm: + # Define Slack service using webhook URL from sealed secret + service.webhook.slack: | + url: $slack-webhook-url + headers: + - name: Content-Type + value: application/json + + # Template: Application syncing + template.app-syncing: | + webhook: + slack: + method: POST + body: | + { + "text": "🔄 *{{ .app.metadata.name }}* is syncing...\n📦 Revision: {{ .app.status.sync.revision | substr 0 7 }}" + } + + # Template: Sync succeeded + template.app-sync-succeeded: | + webhook: + slack: + method: POST + body: | + { + "text": "✅ *{{ .app.metadata.name }}* sync succeeded\n📦 Revision: {{ .app.status.sync.revision | substr 0 7 }}{{ range .app.status.summary.images }}\n🏷️ Image: {{ . }}{{ end }}" + } + + # Template: Sync failed + template.app-sync-failed: | + webhook: + slack: + method: POST + body: | + { + "text": "❌ *{{ .app.metadata.name }}* sync failed\n📦 Revision: {{ .app.status.sync.revision | substr 0 7 }}\n⚠️ Message: {{ .app.status.operationState.message }}" + } + + # Template: Application degraded + template.app-degraded: | + webhook: + slack: + method: POST + body: | + { + "text": "⚠️ *{{ .app.metadata.name }}* is degraded\n🏥 Health: {{ .app.status.health.status }}\n💬 Message: {{ .app.status.health.message }}" + } + + # Trigger: Sync running + trigger.on-sync-running: | + - when: app.status.operationState.phase in ['Running'] + send: [app-syncing] + + # Trigger: Sync succeeded + trigger.on-sync-succeeded: | + - when: app.status.operationState.phase in ['Succeeded'] + send: [app-sync-succeeded] + + # Trigger: Sync failed + trigger.on-sync-failed: | + - when: app.status.operationState.phase in ['Failed'] + send: [app-sync-failed] + + # Trigger: Application degraded + trigger.on-degraded: | + - when: app.status.health.status == 'Degraded' + send: [app-degraded]