# Argo CD

{% hint style="info" %}
This plugin is part of Pro and Enterprise plan only
{% endhint %}

### **Introduction**

This document provides step-by-step instructions for integrating your IDP software with ArgoCD. The integration can be achieved through two methods:

1. **Synchronous Method**: Fetching data using a service account token.
2. **Asynchronous Method**: Receiving data via webhooks.

**Ideally for best performance and up to the date information you should have both methods enabled.**

Before proceeding, ensure you have the following information:

* Plugin Name: A unique identifier for your application.
* BaseURL: The public URL of your ArgoCD server.
* Account Token: A token with read permissions for ArgoCD.
* Webhook Token: A token for receiving live changes via webhooks.

### **Method 1: Synchronous Data Fetching**

#### **Creating a Service Account in ArgoCD**

To fetch data synchronously, you need to create a service account in ArgoCD with read permissions.

#### Steps:

1. **Create a Service Account**:
   * Refer to [Creating an Argo CD Service Account](https://www.arthurkoziel.com/creating-argo-cd-service-account/) for detailed steps.
   * Additionally, consult the official ArgoCD documentation on [Service Account Token Generation](https://argo-cd.readthedocs.io/en/stable/user-guide/commands/argocd_account_generate-token/).
2. **Set the Token in IDP Software**:
   * After creating the service account and generating the token, enter this token in plugin configuration as the 'Account Token'.

### **Method 2: Asynchronous Data Fetching via Webhooks**

#### **Setting Up Notifications Service in ArgoCD**

For asynchronous data fetching, configure the notifications service in ArgoCD.

#### Requirements:

* ArgoCD version 2.10 or later: Use the built-in notifications controller.
* Earlier versions of ArgoCD: Install the argocd-notifications helm chart.

#### Installation:

* For ArgoCD 2.10 or later, refer to the [Notifications Controller Documentation](https://argo-cd.readthedocs.io/en/stable/operator-manual/notifications/).
* For earlier versions, use the Helm chart available at [ArgoCD Notifications Documentation](https://argocd-notifications.readthedocs.io/en/stable/), with the chart details:

  ```java
  chart      = "argocd-notifications"
  repository = "https://argoproj.github.io/argo-helm"
  version    = "1.8.1"
  ```
* Configure `values.yaml`

  ```java
  secret:
    create: true
    annotations: {}
    name: ""
    items:
      webhooks-token: <WEBHOOK_API_TOKEN_ON_https://web-env-dev.rely.io/settings>

  notifiers:
    service.webhook.sync-running:
      url: https://magneto.rely.io/api/v1/webhooks/argocd
      headers:
        - name: Content-Type
          value: application/json
        - name: Authorization
          value: Bearer $webhooks-token

  subscriptions:
    # subscription for on-sync-status-unknown trigger notifications
    - recipients:
      - sync-running
      triggers:
        - on-sync-running
        - on-sync-succeeded
        - on-sync-failed
        - on-sync-status-unknown
        - on-deployed
        - on-health-degraded
        - on-created
        - on-deleted

  templates:
    template.app-deleted: |
      webhook:
        sync-running:
          method: POST
          body: |
            {
              "type": "deleted",
              "metadata": {
                "name": "{{.app.metadata.name}}",
                "namespace": "{{.app.spec.destination.namespace}}",
                "annotations": {{ toJson .app.metadata.annotations }},
                "labels": {{ toJson .app.metadata.labels }},
                "creationTimestamp": "{{.app.metadata.creationTimestamp}}"
              }
            }
    template.app-sync-running: |
      webhook:
        sync-running:
          method: POST
          body: |
  					 {
              "type": "generic",
              "metadata": {
                "name": "{{.app.metadata.name}}",
                "namespace": "{{.app.spec.destination.namespace}}",
                "annotations": {{ toJson .app.metadata.annotations }},
                "labels": {{ toJson .app.metadata.labels }},
                "creationTimestamp": "{{.app.metadata.creationTimestamp}}",
                "ownerReferences": {{ toJson .app.metadata.ownerReferences }}
              },
              "spec": {
                "project": "{{.app.spec.project}}",
                "source": {
                  "repoURL": "{{.app.spec.source.repoURL}}",
                  "path": "{{.app.spec.source.path}}",
                  "targetRevision": "{{.app.spec.source.targetRevision}}"
                },
                "destination": {
                  "server": "{{.app.spec.destination.server}}",
                  "namespace": "{{.app.spec.destination.namespace}}"
                },
                "syncPolicy": {{ toJson .app.spec.syncPolicy }}
              },
              "status": {
                "conditions": {{ toJson .app.status.conditions | default "[]" }},
                "health": {
                  "status": "{{.app.status.health.status}}",
                  "message": "{{.app.status.health.message}}"
                },
                "operationState": {
                  "finishedAt": "{{.app.status.operationState.finishedAt}}",
                  "startedAt": "{{.app.status.operationState.startedAt}}",
                  "message": "{{.app.status.operationState.message}}",
                  "phase": "{{.app.status.operationState.phase}}",
                  "syncResult": {
                    "revision": "{{.app.status.operationState.operation.sync.revision}}"
                  }
                },
                "sync": {
                  "status": "{{.app.status.sync.status}}"
                }
              }
            }

  triggers:
    trigger.on-created: |
      - description: Application is created.
        send:
        - app-sync-running
        when: true
    trigger.on-deleted: |
      - description: Application is deleted.
        send:
        - app-deleted
        when: app.metadata.deletionTimestamp != nil
    trigger.on-deployed: |
      - description: Application is synced and healthy. Triggered once per commit.
        send:
        - app-sync-running
        when: app.status.operationState.phase in ['Succeeded'] and app.status.health.status == 'Healthy'
    trigger.on-health-degraded: |
      - description: Application has degraded
        send:
        - app-sync-running
        when: app.status.health.status == 'Degraded'
    trigger.on-sync-failed: |
      - description: Application syncing has failed
        send:
        - app-sync-running
        when: app.status.operationState.phase in ['Error', 'Failed']
    trigger.on-sync-running: |
      - description: Application syncing has succeeded
        send:
        - app-sync-running
        when: app.status.operationState.phase in ['Running']
    trigger.on-sync-status-unknown: |
      - description: Application status is 'Unknown'
        send:
        - app-sync-running
        when: app.status.sync.status == 'Unknown'
    trigger.on-sync-succeeded: |
      - description: Application syncing has succeeded
        send:
        - app-sync-running
        when: app.status.operationState.phase in ['Succeeded']
    defaultTriggers: |
      - on-sync-status-unknown
  ```
