From 7a9da1b971e0db2393146d0898bd49f267252625 Mon Sep 17 00:00:00 2001 From: Patrick Knight Date: Thu, 5 Mar 2026 21:02:12 -0500 Subject: [PATCH] Add argocd plugins Signed-off-by: Patrick Knight --- .env.sample | 5 + config-plugins.sh | 9 + deploy/secret-template.yaml | 6 + docs/argocd.md | 424 +++++++++ guides/README.md | 23 + guides/argocd-advanced-config.md | 875 +++++++++++++++++++ guides/argocd-troubleshooting.md | 812 +++++++++++++++++ resources/argocd/argocd-instance.yaml | 81 ++ resources/argocd/demo-applications.yaml | 71 ++ resources/argocd/demo-catalog-entities.yaml | 101 +++ resources/catalog-entities/operators.yaml | 38 + resources/operators/argocd-subscription.yaml | 11 + resources/rhdh/rhdh-secrets.yaml | 5 + scripts/config-argocd-plugin.sh | 285 ++++++ 14 files changed, 2746 insertions(+) create mode 100644 docs/argocd.md create mode 100644 guides/argocd-advanced-config.md create mode 100644 guides/argocd-troubleshooting.md create mode 100644 resources/argocd/argocd-instance.yaml create mode 100644 resources/argocd/demo-applications.yaml create mode 100644 resources/argocd/demo-catalog-entities.yaml create mode 100644 resources/operators/argocd-subscription.yaml create mode 100755 scripts/config-argocd-plugin.sh diff --git a/.env.sample b/.env.sample index 7535c52..9ee8ec1 100644 --- a/.env.sample +++ b/.env.sample @@ -8,3 +8,8 @@ OCM_HUB_NAME="" # Demo Data Configuration POPULATE_DEMO_DATA=true # Set to false to skip demo data population + +# ArgoCD Configuration (Optional - auto-discovered if not set) +# ARGOCD_URL="" +# ARGOCD_USERNAME="admin" +# ARGOCD_PASSWORD="" diff --git a/config-plugins.sh b/config-plugins.sh index e027e89..550d42b 100755 --- a/config-plugins.sh +++ b/config-plugins.sh @@ -31,6 +31,13 @@ declare -A PACKAGE_TO_CATEGORY=( # Nexus Repository Manager - requires Nexus operator deployment ["plugin-nexus-repository-manager"]="NEXUS" + # ArgoCD - requires ArgoCD operator deployment + # Supports 4 plugins (use both from same repository): + # RoadieHQ: @roadiehq/backstage-plugin-argo-cd + @roadiehq/backstage-plugin-argo-cd-backend + # Backstage Community: @backstage-community/plugin-argocd + @backstage-community/plugin-argocd-backend + ["plugin-argo-cd"]="ARGOCD" + ["plugin-argocd"]="ARGOCD" + #Kubernetes - needs ServiceAccount token setup ["plugin-kubernetes-backend"]="KUBERNETES" ["plugin-kubernetes"]="KUBERNETES" @@ -47,6 +54,7 @@ declare -A CATEGORY_SETUP_FUNCTIONS=( [OCM]="deploy_acm config_secrets_for_ocm_plugins deploy_multicluster_hub apply_ocm_labels" [3SCALE]="copy_3scale_files deploy_3scale deploy_minio deploy_3scale_resources" [NEXUS]="deploy_nexus wait_for_nexus_operator_and_deploy_instance wait_for_nexus_instance config_secrets_for_nexus_plugins apply_nexus_labels populate_nexus_demo_data register_nexus_demo_catalog_entities" + [ARGOCD]="deploy_argocd wait_for_argocd_operator_and_deploy_instance wait_for_argocd_instance_and_deploy_demo_applications config_secrets_for_argocd_plugins apply_argocd_labels register_argocd_demo_catalog_entities" [KUBERNETES]="config_secrets_for_kubernetes_plugins" ) @@ -56,6 +64,7 @@ declare -A CATEGORY_TEARDOWN_FUNCTIONS=( [OCM]="uninstall_acm" [3SCALE]="uninstall_3scale" [NEXUS]="uninstall_nexus" + [ARGOCD]="uninstall_argocd" [KUBERNETES]=":" ) diff --git a/deploy/secret-template.yaml b/deploy/secret-template.yaml index d61d737..1b07c39 100644 --- a/deploy/secret-template.yaml +++ b/deploy/secret-template.yaml @@ -40,3 +40,9 @@ stringData: # Optional: Nexus Repository Manager (Frontend Proxy) NEXUS_URL: "" NEXUS_AUTH_HEADER: "" + + # Optional: ArgoCD Configuration (supports both RoadieHQ and Backstage Community plugins) + ARGOCD_URL: "" + ARGOCD_USERNAME: "" + ARGOCD_PASSWORD: "" + ARGOCD_AUTH_TOKEN: "" diff --git a/docs/argocd.md b/docs/argocd.md new file mode 100644 index 0000000..b14ed60 --- /dev/null +++ b/docs/argocd.md @@ -0,0 +1,424 @@ +# Plugin: ArgoCD Plugins + +## Description + +The ArgoCD plugins integrate Argo CD with Red Hat Developer Hub (RHDH), enabling developers to view +GitOps deployment information, application health status, and sync history directly within the +Backstage catalog. + +**Four ArgoCD Plugins Available:** + +1. **@roadiehq/backstage-plugin-argo-cd** (frontend) - RoadieHQ frontend plugin +2. **@roadiehq/backstage-plugin-argo-cd-backend** (backend) - RoadieHQ backend plugin +3. **@backstage-community/plugin-argocd** (frontend) - Backstage Community frontend plugin +4. **@backstage-community/plugin-argocd-backend** (backend) - Backstage Community backend plugin + +**IMPORTANT: Plugin Selection Strategy** + +Enable **both plugins from the same source** and ensure the other two are disabled. Each pair is a +complete, self-contained integration: + +- **Option A:** Enable both Backstage Community ArgoCD plugins: + - `@backstage-community/plugin-argocd` + - `@backstage-community/plugin-argocd-backend` + +- **Option B:** Enable both RoadieHQ ArgoCD plugins: + - `@roadiehq/backstage-plugin-argo-cd` + - `@roadiehq/backstage-plugin-argo-cd-backend` + +**DO NOT mix plugins from different sources** (e.g., RoadieHQ frontend with Backstage Community +backend), as they might have different annotation requirements and configuration patterns. + +### Key Features + +- Real-time application sync and health status +- Deployment history and rollback information +- Multi-instance ArgoCD support +- GitOps workflow visibility +- Pod and resource status tracking +- Deep-linking to ArgoCD UI + +--- + +## How to Configure + +You can configure these plugins either manually or automatically using the provided scripts. + +### Manual Setup + +1. Deploy required infrastructure: + - Install the ArgoCD Operator (community operator). + - Deploy an `ArgoCD` custom resource to create an ArgoCD instance. + - Wait for the ArgoCD instance to be ready and obtain the URL and credentials. + +2. Configure RHDH integration: + - Choose **one** plugin pair (both from the same source). + - Enable the selected plugins in your dynamic plugins configuration. + - Add the appropriate configuration to your `app-config.yaml`: + +#### For Backstage Community Plugins + +```yaml +argocd: + # Single instance + appLocatorMethods: + - type: "config" + instances: + - name: argoInstance + url: ${ARGOCD_URL} + token: ${ARGOCD_AUTH_TOKEN} +``` + +#### For RoadieHQ Plugins + +```yaml +argocd: + # Single instance + appLocatorMethods: + - type: "config" + instances: + - name: argoInstance + url: ${ARGOCD_URL} + username: ${ARGOCD_USERNAME} + password: ${ARGOCD_PASSWORD} +``` + +3. Configure authentication: + - Add to your secrets: + + ```yaml + ARGOCD_URL: "https://argocd-server-route.example.com" + ARGOCD_AUTH_TOKEN: "" # For Backstage Community plugins + ARGOCD_USERNAME: "admin" # For RoadieHQ plugins + ARGOCD_PASSWORD: "" # For RoadieHQ plugins + ``` + +4. Add annotations to catalog entities: + +#### For Backstage Community Plugins + +Add the following annotations to your component's `catalog-info.yaml`: + +```yaml +metadata: + annotations: + # Label selector for applications + argocd/app-selector: "rht-gitops.com/my-app=my-value" + + # Optional: specify ArgoCD instance (if using multiple instances) + argocd/instance-name: "argoInstance" +``` + +#### For RoadieHQ Plugins + +Add the following annotations to your component's `catalog-info.yaml`: + +```yaml +metadata: + annotations: + # For a single ArgoCD application + argocd/app-name: my-app-name + + # OR for multiple applications using label selector + argocd/app-selector: app.kubernetes.io/name=my-app +``` + +--- + +### Automatic Setup + +Automated setup is available in two levels depending on how much you want configured for you. + +#### Everything + +Runs the root-level script to deploy the complete infrastructure including ArgoCD. Requires the +ArgoCD plugins to be enabled by setting `disabled: false` in your dynamic plugins configuration. + +**Run:** + +```bash +./start.sh +``` + +#### Just the Integration + +Only configures the integration resources for this plugin. Use this if you already have a Backstage +instance running and just need this plugin. + +**Run:** + +```bash +./scripts/config-argocd-plugin.sh +``` + +This script will: + +- Install the ArgoCD Operator +- Deploy an ArgoCD instance with OpenShift OAuth integration +- Configure secrets for RHDH authentication (`ARGOCD_URL`, `ARGOCD_USERNAME`, `ARGOCD_PASSWORD`, + `ARGOCD_AUTH_TOKEN`) +- Apply Kubernetes labels for topology view +- Deploy demo ArgoCD applications (guestbook, helm, kustomize) +- Register demo catalog entities + +**Important - Manual Configuration Required:** + +After running the script, you must add the ArgoCD configuration to your `app-config.yaml` based on +which plugins you choose to use. See the configuration examples in the Manual Setup section above. + +--- + +## Demo + +1. Go to your RHDH instance. +2. Navigate to the Catalog. +3. Open a component that has ArgoCD annotations: + - `demo-guestbook-app` (`argocd/app-name` annotation style) + - `demo-helm-app` (`argocd/app-selector` annotation style) + - `demo-kustomize-app` (both annotation styles) +4. Look for the "ArgoCD" tab or card. +5. View the application sync status, health, deployment history, and pod information. + +Alternatively: + +1. Access the ArgoCD web UI directly at the route created in your namespace. +2. Login with admin credentials (password stored in secrets). +3. Browse the applications and verify demo apps are deployed. + +--- + +## Demo Data + +This plugin includes test resources to demonstrate functionality: + +### Demo Applications + +- **demo-guestbook-app**: Classic Argo CD guestbook demo application using plain Kubernetes + manifests +- **demo-helm-app**: Helm-based guestbook application showcasing Helm chart deployments +- **demo-kustomize-app**: Kustomize-based application demonstrating Kustomize overlays + +All demo applications use public GitHub repositories from the official ArgoCD examples: + +- Repository: https://github.com/argoproj/argocd-example-apps +- Applications are deployed to the `rhdh` namespace +- Labeled with `rht-gitops.com/demo-argocd` for discovery + +### Demo Catalog Entities + +The setup automatically registers demo components in the RHDH catalog: + +- **demo-guestbook-app** (Component) - Demonstrates `argocd/app-name` annotation style + - Annotation: `argocd/app-name: demo-guestbook-app` + - Owner: `group:default/guardians-of-the-galaxy` + - Purpose: Shows single-application annotation style + +- **demo-helm-app** (Component) - Demonstrates `argocd/app-selector` annotation style + - Annotation: `argocd/app-selector: rht-gitops.com/demo-argocd=helm-app` + - Owner: `group:default/x-men` + - Purpose: Shows label selector annotation style + +- **demo-kustomize-app** (Component) - Demonstrates both annotation styles + - Annotations: Both `argocd/app-name` and `argocd/app-selector` + - Owner: `group:default/avengers` + - Purpose: Demonstrates compatibility with both annotation styles for comparison + +These catalog entities use existing Keycloak teams for ownership, enabling RBAC testing. Different +users will see different components based on their team membership. + +### Configuration + +Demo data is automatically populated during setup. To disable: + +```bash +export POPULATE_DEMO_DATA=false +./scripts/config-argocd-plugin.sh +``` + +To manually register catalog entities: + +```bash +oc create configmap argocd-demo-entities-config-map \ + --from-file=demo-argocd-applications.yaml=resources/argocd/demo-catalog-entities.yaml \ + -n rhdh + +oc label configmap argocd-demo-entities-config-map \ + backstage.io/kubernetes-id=developer-hub -n rhdh +``` + +--- + +## Accessing ArgoCD + +### Web UI + +Get the ArgoCD URL and login: + +```bash +# Get the URL +echo "https://$(oc get route argocd-server -n rhdh -o jsonpath='{.spec.host}')" + +# Get admin password +oc get secret argocd-cluster -n rhdh -o jsonpath='{.data.admin\.password}' | base64 -d +echo "" +``` + +Default username: `admin` + +### CLI + +Install the ArgoCD CLI and login: + +```bash +# Install ArgoCD CLI +curl -sSL -o argocd https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64 +chmod +x argocd +sudo mv argocd /usr/local/bin/ + +# Login +ARGOCD_URL=$(oc get route argocd-server -n rhdh -o jsonpath='{.spec.host}') +ARGOCD_PASS=$(oc get secret argocd-cluster -n rhdh -o jsonpath='{.data.admin\.password}' | base64 -d) + +argocd login $ARGOCD_URL --username admin --password $ARGOCD_PASS --insecure + +# List applications +argocd app list +``` + +--- + +## Quick Verification + +After deployment, verify everything is working: + +```bash +# 1. Check operator is installed +oc get csv -n rhdh | grep argocd-operator + +# 2. Check ArgoCD instance is running +oc get argocd argocd -n rhdh + +# 3. Check ArgoCD server is available +oc get route argocd-server -n rhdh + +# 4. Check demo applications are deployed +oc get application -n rhdh + +# 5. Check catalog entities are registered +oc get configmap argocd-demo-entities-config-map -n rhdh + +# 6. Verify applications in ArgoCD +ARGOCD_URL=$(oc get route argocd-server -n rhdh -o jsonpath='{.spec.host}') +curl -k https://${ARGOCD_URL}/api/v1/applications +``` + +--- + +## Troubleshooting + +For detailed troubleshooting procedures, see the comprehensive guides: + +- **[ArgoCD Troubleshooting Guide](../guides/argocd-troubleshooting.md)** - Diagnose and fix common + issues: + - Operator installation problems + - ArgoCD instance startup issues + - Application sync failures + - Plugin integration problems (annotation styles, multiple plugin sets) + - Authentication and RBAC issues + - Network connectivity + - Performance issues + - Complete error message reference + +### Quick Troubleshooting Tips + +**Applications Not Syncing:** + +```bash +# Check application status +oc get application -n rhdh + +# Check ArgoCD server logs +oc logs -n rhdh deployment/argocd-server + +# Check application controller logs +oc logs -n rhdh deployment/argocd-application-controller +``` + +**Plugin Not Showing Applications:** + +1. Verify you're using the correct annotation style for your plugin choice +2. Verify ArgoCD configuration in `app-config.yaml` +3. Check RHDH backend logs: + `oc logs -n rhdh deployment/backstage -c backstage-backend | grep -i argocd` + +**Authentication Issues:** + +```bash +# Verify credentials +oc get secret argocd-cluster -n rhdh -o jsonpath='{.data.admin\.password}' | base64 -d + +# Test ArgoCD API manually +ARGOCD_URL=$(oc get route argocd-server -n rhdh -o jsonpath='{.spec.host}') +ARGOCD_PASS=$(oc get secret argocd-cluster -n rhdh -o jsonpath='{.data.admin\.password}' | base64 -d) +curl -k https://${ARGOCD_URL}/api/v1/session -d '{"username":"admin","password":"'$ARGOCD_PASS'"}' +``` + +For complete troubleshooting procedures, diagnostics, and solutions, see the +[Troubleshooting Guide](../guides/argocd-troubleshooting.md). + +--- + +## Production Configuration + +For production deployments, see the comprehensive guides: + +- **[ArgoCD Advanced Configuration Guide](../guides/argocd-advanced-config.md)** - Production-ready + setups: + - High availability configuration + - Resource tuning and sizing guidelines + - Multiple ArgoCD instance support + - Security configuration (RBAC, SSO, TLS/SSL) + - Git repository configuration (private repos, SSH keys) + - ApplicationSets for application templating + - Custom health checks + - Notifications and webhooks + - Backup and restore procedures + - Monitoring and metrics (Prometheus, Grafana) + - Performance optimization + +--- + +## Related Files + +- `/scripts/config-argocd-plugin.sh` - Automates plugin setup +- `/resources/argocd/` - ArgoCD CRs and supporting manifests +- `/resources/argocd/argocd-instance.yaml` - ArgoCD instance definition +- `/resources/argocd/demo-applications.yaml` - Demo ArgoCD applications +- `/resources/argocd/demo-catalog-entities.yaml` - Demo catalog entities with ArgoCD annotations +- `/resources/operators/argocd-subscription.yaml` - ArgoCD operator subscription + +--- + +## Additional Resources + +For more detailed information: + +- **[ArgoCD Troubleshooting Guide](../guides/argocd-troubleshooting.md)** - Complete troubleshooting + procedures +- **[ArgoCD Advanced Configuration](../guides/argocd-advanced-config.md)** - Production-ready + configurations +- [ArgoCD Documentation](https://argo-cd.readthedocs.io/) +- [Backstage Community ArgoCD Plugin](https://github.com/backstage/community-plugins/tree/main/workspaces/argocd) +- [RoadieHQ ArgoCD Plugin](https://github.com/RoadieHQ/roadie-backstage-plugins/tree/main/plugins/backstage-plugin-argo-cd) +- [ArgoCD Operator Documentation](https://argocd-operator.readthedocs.io/) + +--- + +## Notes + +- The ArgoCD Operator is a community operator and is available in the OperatorHub. +- The default installation uses OpenShift OAuth for SSO integration. +- Initial admin password can be retrieved from the `argocd-cluster` secret. +- The ArgoCD instance is configured with resource limits suitable for demo/testing. +- For production use, adjust resource limits and enable HA mode in the ArgoCD CR. +- Demo applications use public GitHub repositories and do not require Git credentials. diff --git a/guides/README.md b/guides/README.md index 3b29bae..d02fd76 100644 --- a/guides/README.md +++ b/guides/README.md @@ -16,6 +16,8 @@ guides/ ├── README.md # This file ├── nexus-troubleshooting.md # Nexus plugin troubleshooting ├── nexus-advanced-config.md # Nexus production setup +├── argocd-troubleshooting.md # ArgoCD plugin troubleshooting +├── argocd-advanced-config.md # ArgoCD production setup └── [future guides] ``` @@ -40,6 +42,27 @@ guides/ - Monitoring and metrics - Performance optimization +### ArgoCD + +- **[Troubleshooting Guide](argocd-troubleshooting.md)** - Diagnose and fix common issues + - Operator installation problems + - ArgoCD instance startup issues + - Application sync failures + - Plugin integration problems (RoadieHQ vs Backstage Community) + - Authentication and RBAC issues + - Network connectivity + - Performance issues +- **[Advanced Configuration](argocd-advanced-config.md)** - Production-ready setups + - High availability configuration + - Resource tuning and sharding + - Multiple ArgoCD instance support + - Security configuration (RBAC, SSO, TLS) + - Git repository configuration + - ApplicationSets for templating + - Notifications and webhooks + - Backup and restore procedures + - Monitoring and metrics + ## When to Use Docs vs Guides ### Use `docs/.md` for: diff --git a/guides/argocd-advanced-config.md b/guides/argocd-advanced-config.md new file mode 100644 index 0000000..f1ee835 --- /dev/null +++ b/guides/argocd-advanced-config.md @@ -0,0 +1,875 @@ +# ArgoCD - Advanced Configuration + +This guide covers production-ready configurations, performance tuning, and advanced features for the +ArgoCD plugins in RHDH. + +--- + +## Table of Contents + +- [High Availability](#high-availability) +- [Resource Tuning](#resource-tuning) +- [Multiple ArgoCD Instances](#multiple-argocd-instances) +- [Security Configuration](#security-configuration) +- [Git Repository Configuration](#git-repository-configuration) +- [Application Sets](#application-sets) +- [Custom Health Checks](#custom-health-checks) +- [Notifications and Webhooks](#notifications-and-webhooks) +- [Backup and Restore](#backup-and-restore) +- [Monitoring and Metrics](#monitoring-and-metrics) + +--- + +## High Availability + +The default demo configuration runs a single instance of each ArgoCD component. For production, +enable High Availability mode. + +### Enable HA Mode + +Edit `resources/argocd/argocd-instance.yaml`: + +```yaml +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd + namespace: rhdh +spec: + ha: + enabled: true + # Redis HA configuration + redisProxyImage: haproxy + redisProxyVersion: "2.0.4" + + # Scale server replicas + server: + replicas: 3 + autoscale: + enabled: true + hpa: + minReplicas: 3 + maxReplicas: 5 + targetCPUUtilizationPercentage: 50 + + # Scale repo server + repo: + replicas: 3 + autoscale: + enabled: true + hpa: + minReplicas: 3 + maxReplicas: 5 + targetCPUUtilizationPercentage: 50 + + # Application controller (runs as single instance with leader election) + controller: + sharding: + enabled: true + replicas: 3 +``` + +Apply the configuration: + +```bash +oc apply -f resources/argocd/argocd-instance.yaml -n rhdh +``` + +### Redis HA + +For production workloads, configure Redis in HA mode: + +```yaml +spec: + redis: + resources: + limits: + cpu: "1" + memory: 512Mi + requests: + cpu: 250m + memory: 256Mi + + ha: + enabled: true + # Use Redis Sentinel for automatic failover + redisProxyImage: haproxy + redisProxyVersion: "2.0.4" +``` + +--- + +## Resource Tuning + +Optimize resource allocation based on your workload. + +### Recommended Production Resources + +```yaml +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd + namespace: rhdh +spec: + # Application Controller - handles sync operations + controller: + resources: + limits: + cpu: "4" + memory: 4Gi + requests: + cpu: "1" + memory: 2Gi + # Adjust based on number of applications + sharding: + enabled: true + replicas: 3 + # Tuning parameters + env: + - name: ARGOCD_RECONCILIATION_TIMEOUT + value: "180s" + - name: ARGOCD_REPO_SERVER_TIMEOUT_SECONDS + value: "120" + + # Repo Server - handles Git operations + repo: + resources: + limits: + cpu: "2" + memory: 2Gi + requests: + cpu: 500m + memory: 1Gi + # Cache configuration for better performance + env: + - name: ARGOCD_GIT_MODULES_ENABLED + value: "false" + - name: ARGOCD_EXEC_TIMEOUT + value: "180s" + mountsatoken: true + serviceaccount: argocd-repo-server + replicas: 3 + + # API Server - handles UI and API requests + server: + resources: + limits: + cpu: "2" + memory: 1Gi + requests: + cpu: 500m + memory: 512Mi + replicas: 3 + insecure: false + + # Redis - caching layer + redis: + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 250m + memory: 256Mi + + # Dex - SSO/OAuth + dex: + resources: + limits: + cpu: 500m + memory: 256Mi + requests: + cpu: 250m + memory: 128Mi + + # ApplicationSet Controller + applicationSet: + resources: + limits: + cpu: "2" + memory: 1Gi + requests: + cpu: 250m + memory: 512Mi +``` + +### Sizing Guidelines + +| Cluster Size | Applications | Controller CPU | Controller Memory | Repo Server Replicas | +| --------------- | ------------ | -------------- | ----------------- | -------------------- | +| Small (< 50) | < 50 | 1 core | 2Gi | 1-2 | +| Medium (50-200) | 50-200 | 2 cores | 4Gi | 2-3 | +| Large (200-500) | 200-500 | 4 cores | 8Gi | 3-5 | +| XLarge (> 500) | > 500 | 8 cores | 16Gi | 5-10 | + +--- + +## Multiple ArgoCD Instances + +Support multiple ArgoCD instances (dev, staging, prod) in RHDH. + +### Deploy Additional ArgoCD Instance + +Create a new ArgoCD instance CR: + +```yaml +# resources/argocd/argocd-production.yaml +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd-production + namespace: argocd-prod +spec: + server: + route: + enabled: true + # ... rest of configuration +``` + +### Configure Multiple Instances in RHDH + +For **Backstage Community plugins**, add to `app-config.yaml`: + +```yaml +argocd: + appLocatorMethods: + - type: "config" + instances: + - name: devInstance + url: https://argocd-dev.example.com + token: ${ARGOCD_DEV_TOKEN} + - name: prodInstance + url: https://argocd-prod.example.com + token: ${ARGOCD_PROD_TOKEN} +``` + +For **RoadieHQ plugins**, add to `app-config.yaml`: + +```yaml +argocd: + appLocatorMethods: + - type: "config" + instances: + - name: devInstance + url: https://argocd-dev.example.com + username: ${ARGOCD_DEV_USERNAME} + password: ${ARGOCD_DEV_PASSWORD} + - name: prodInstance + url: https://argocd-prod.example.com + username: ${ARGOCD_PROD_USERNAME} + password: ${ARGOCD_PROD_PASSWORD} +``` + +### Specify Instance in Catalog Entities + +For Backstage Community plugins: + +```yaml +metadata: + annotations: + argocd/app-selector: "app=my-app" + argocd/instance-name: "prodInstance" +``` + +For RoadieHQ plugins: + +```yaml +metadata: + annotations: + argocd/app-name: my-app + argocd/proxy-url: "/argocd/api-prod" # Point to specific instance +``` + +--- + +## Security Configuration + +### TLS/SSL Configuration + +#### Custom TLS Certificates + +```yaml +spec: + server: + route: + enabled: true + tls: + termination: reencrypt + insecureEdgeTerminationPolicy: Redirect + # Optional: custom certificates + certificate: | + # + key: | + # + caCertificate: | + # +``` + +#### Insecure Mode (Development Only) + +```yaml +spec: + server: + insecure: true # Disables TLS +``` + +### RBAC Configuration + +#### Advanced RBAC Policies + +```yaml +spec: + rbac: + defaultPolicy: "role:readonly" + policy: | + # Admin access for cluster admins + g, system:cluster-admins, role:admin + g, cluster-admins, role:admin + + # Project-based access + p, role:project-dev, applications, get, project-dev/*, allow + p, role:project-dev, applications, sync, project-dev/*, allow + g, developers, role:project-dev + + # Read-only for viewers + p, role:viewer, applications, get, */*, allow + g, viewers, role:viewer + + # Prevent deletion for non-admins + p, role:project-dev, applications, delete, */*, deny + + scopes: "[groups, email]" +``` + +#### Anonymous Access + +```yaml +spec: + rbac: + policy: | + p, role:anonymous, applications, get, */*, allow + scopes: "[groups]" + + server: + # Enable anonymous access + anonymous: + enabled: true +``` + +### SSO Configuration + +#### OIDC (Non-OpenShift) + +```yaml +spec: + sso: + provider: oidc + oidc: + name: "My SSO" + issuer: https://auth.example.com + clientID: argocd + clientSecret: ${OIDC_CLIENT_SECRET} + requestedScopes: + - openid + - profile + - email + - groups +``` + +#### SAML + +```yaml +spec: + sso: + provider: saml + saml: + metadataURL: https://auth.example.com/saml/metadata +``` + +### Repository Credentials + +#### SSH Private Key + +```bash +# Create secret with SSH key +oc create secret generic git-ssh-credentials \ + --from-file=sshPrivateKey=/path/to/id_rsa \ + -n rhdh + +# Reference in ArgoCD +oc label secret git-ssh-credentials argocd.argoproj.io/secret-type=repository -n rhdh +``` + +#### HTTPS Credentials + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: git-https-credentials + namespace: rhdh + labels: + argocd.argoproj.io/secret-type: repository +stringData: + type: git + url: https://github.com/myorg + username: myuser + password: mytoken +``` + +--- + +## Git Repository Configuration + +### Private Repositories + +```bash +# Add repository via CLI +argocd repo add https://github.com/myorg/private-repo \ + --username myuser \ + --password mytoken + +# Or via secret +oc create -f - << EOF +apiVersion: v1 +kind: Secret +metadata: + name: private-repo + namespace: rhdh + labels: + argocd.argoproj.io/secret-type: repository +stringData: + type: git + url: https://github.com/myorg/private-repo + username: myuser + password: mytoken +EOF +``` + +### Helm Repositories + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: helm-repo + namespace: rhdh + labels: + argocd.argoproj.io/secret-type: repository +stringData: + type: helm + name: stable + url: https://charts.helm.sh/stable + # Optional: for authenticated Helm repos + username: myuser + password: mypass +``` + +### Git Submodules + +Enable Git submodules in repo server: + +```yaml +spec: + repo: + env: + - name: ARGOCD_GIT_MODULES_ENABLED + value: "true" +``` + +--- + +## Application Sets + +ApplicationSets enable managing multiple Applications as templates. + +### List Generator Example + +```yaml +apiVersion: argoproj.io/v1alpha1 +kind: ApplicationSet +metadata: + name: microservices + namespace: rhdh +spec: + generators: + - list: + elements: + - cluster: dev + url: https://kubernetes.default.svc + namespace: dev + - cluster: staging + url: https://kubernetes.default.svc + namespace: staging + + template: + metadata: + name: "{{cluster}}-guestbook" + spec: + project: default + source: + repoURL: https://github.com/argoproj/argocd-example-apps + targetRevision: HEAD + path: guestbook + destination: + server: "{{url}}" + namespace: "{{namespace}}" + syncPolicy: + automated: + prune: true + selfHeal: true +``` + +### Git Generator Example + +Generate applications from Git repository structure: + +```yaml +apiVersion: argoproj.io/v1alpha1 +kind: ApplicationSet +metadata: + name: cluster-apps + namespace: rhdh +spec: + generators: + - git: + repoURL: https://github.com/myorg/cluster-config + revision: HEAD + directories: + - path: apps/* + + template: + metadata: + name: "{{path.basename}}" + spec: + project: default + source: + repoURL: https://github.com/myorg/cluster-config + targetRevision: HEAD + path: "{{path}}" + destination: + server: https://kubernetes.default.svc + namespace: "{{path.basename}}" + syncPolicy: + automated: + prune: true + selfHeal: true +``` + +--- + +## Custom Health Checks + +Define custom health assessments for CRDs. + +### Resource Customization + +```yaml +spec: + resourceCustomizations: | + # Custom health check for a CRD + my.crd.group/MyResource: + health.lua: | + hs = {} + if obj.status ~= nil then + if obj.status.phase == "Running" then + hs.status = "Healthy" + hs.message = "Resource is running" + return hs + end + end + hs.status = "Progressing" + hs.message = "Waiting for resource to be ready" + return hs + + # Ignore differences for certain fields + my.crd.group/MyResource: + ignoreDifferences: | + jsonPointers: + - /status +``` + +### Known Types Configuration + +```yaml +spec: + resourceTrackingMethod: annotation + + resourceCustomizations: | + # Ignore specific resource types + ignoreDifferences: | + - group: apps + kind: Deployment + jsonPointers: + - /spec/replicas +``` + +--- + +## Notifications and Webhooks + +### Configure Notifications + +Create notification configuration: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: argocd-notifications-cm + namespace: rhdh +data: + # Slack notification + service.slack: | + token: $slack-token + + # Email notification + service.email.gmail: | + username: $email-username + password: $email-password + host: smtp.gmail.com + port: 465 + from: $email-username + + # Triggers + trigger.on-deployed: | + - when: app.status.operationState.phase in ['Succeeded'] + send: [app-deployed] + + trigger.on-health-degraded: | + - when: app.status.health.status == 'Degraded' + send: [app-health-degraded] + + # Templates + template.app-deployed: | + message: Application {{.app.metadata.name}} is now running new version. + slack: + attachments: | + [{ + "title": "{{.app.metadata.name}}", + "title_link": "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}", + "color": "good", + "fields": [{ + "title": "Sync Status", + "value": "{{.app.status.sync.status}}", + "short": true + }] + }] +``` + +Create secret for tokens: + +```bash +oc create secret generic argocd-notifications-secret \ + --from-literal=slack-token='xoxb-...' \ + -n rhdh +``` + +### Webhook Configuration + +Configure webhooks in your Git provider to trigger syncs: + +```bash +# Get webhook URL +ARGOCD_URL=$(oc get route argocd-server -n rhdh -o jsonpath='{.spec.host}') +echo "https://${ARGOCD_URL}/api/webhook" + +# Configure in GitHub/GitLab: +# Payload URL: https://argocd-server-route/api/webhook +# Content type: application/json +# Secret: +``` + +--- + +## Backup and Restore + +### Backup ArgoCD Configuration + +```bash +#!/bin/bash +# backup-argocd.sh + +NAMESPACE="rhdh" +BACKUP_DIR="argocd-backup-$(date +%Y%m%d-%H%M%S)" + +mkdir -p "$BACKUP_DIR" + +# Backup ArgoCD CR +oc get argocd argocd -n $NAMESPACE -o yaml > "$BACKUP_DIR/argocd-instance.yaml" + +# Backup Applications +oc get applications -n $NAMESPACE -o yaml > "$BACKUP_DIR/applications.yaml" + +# Backup ApplicationSets +oc get applicationsets -n $NAMESPACE -o yaml > "$BACKUP_DIR/applicationsets.yaml" + +# Backup Projects +oc get appprojects -n $NAMESPACE -o yaml > "$BACKUP_DIR/projects.yaml" + +# Backup Secrets (sanitize sensitive data) +oc get secrets -n $NAMESPACE -l argocd.argoproj.io/secret-type=repository -o yaml > "$BACKUP_DIR/repo-secrets.yaml" + +# Backup ConfigMaps +oc get configmaps -n $NAMESPACE -l app.kubernetes.io/part-of=argocd -o yaml > "$BACKUP_DIR/configmaps.yaml" + +echo "Backup saved to $BACKUP_DIR" +``` + +### Restore from Backup + +```bash +#!/bin/bash +# restore-argocd.sh + +BACKUP_DIR=$1 +NAMESPACE="rhdh" + +if [ -z "$BACKUP_DIR" ]; then + echo "Usage: $0 " + exit 1 +fi + +# Restore in order +oc apply -f "$BACKUP_DIR/argocd-instance.yaml" -n $NAMESPACE +oc apply -f "$BACKUP_DIR/repo-secrets.yaml" -n $NAMESPACE +oc apply -f "$BACKUP_DIR/projects.yaml" -n $NAMESPACE +oc apply -f "$BACKUP_DIR/applications.yaml" -n $NAMESPACE +oc apply -f "$BACKUP_DIR/applicationsets.yaml" -n $NAMESPACE + +echo "Restore complete" +``` + +### Disaster Recovery + +For full disaster recovery, use a GitOps approach: + +1. Store all ArgoCD Application manifests in Git +2. Use ApplicationSets for dynamic generation +3. Store ArgoCD instance configuration in Git (Infrastructure as Code) +4. Backup only repository credentials separately + +--- + +## Monitoring and Metrics + +### Prometheus Integration + +Enable metrics exposure: + +```yaml +spec: + prometheus: + enabled: true + host: prometheus-operated.monitoring.svc + port: 9090 + + server: + metrics: + enabled: true + + repo: + metrics: + enabled: true + + controller: + metrics: + enabled: true +``` + +### ServiceMonitor for OpenShift Monitoring + +```yaml +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: argocd-metrics + namespace: rhdh +spec: + selector: + matchLabels: + app.kubernetes.io/name: argocd-metrics + endpoints: + - port: metrics +``` + +### Key Metrics to Monitor + +| Metric | Description | +| ------------------------------------- | ----------------------------- | +| `argocd_app_info` | Application metadata | +| `argocd_app_sync_total` | Number of syncs | +| `argocd_app_reconcile_count` | Reconciliation count | +| `argocd_app_k8s_request_total` | K8s API requests | +| `argocd_git_request_total` | Git requests | +| `argocd_cluster_api_resource_objects` | Resources managed per cluster | +| `argocd_kubectl_exec_pending` | Pending kubectl operations | +| `argocd_redis_request_total` | Redis requests | + +### Grafana Dashboard + +Import the official ArgoCD Grafana dashboard: + +Dashboard ID: `14584` (from grafana.com) + +--- + +## Performance Optimization + +### Cache Configuration + +```yaml +spec: + repo: + env: + # Enable cache + - name: ARGOCD_REPO_CACHE_EXPIRATION + value: "24h" + # Increase cache size + resources: + limits: + memory: 4Gi +``` + +### Increase Timeouts + +```yaml +spec: + controller: + env: + - name: ARGOCD_RECONCILIATION_TIMEOUT + value: "300s" + - name: ARGOCD_REPO_SERVER_TIMEOUT_SECONDS + value: "180" + + repo: + env: + - name: ARGOCD_EXEC_TIMEOUT + value: "300s" + - name: ARGOCD_GIT_REQUEST_TIMEOUT + value: "30s" +``` + +### Sharding + +Distribute load across multiple controller instances: + +```yaml +spec: + controller: + sharding: + enabled: true + replicas: 3 + # Optionally specify shard allocation + dynamicShardingAlgorithm: "round-robin" +``` + +--- + +## Related Resources + +- [ArgoCD Operator Manual](https://argo-cd.readthedocs.io/en/stable/operator-manual/) +- [ArgoCD Best Practices](https://argo-cd.readthedocs.io/en/stable/user-guide/best_practices/) +- [ArgoCD Troubleshooting Guide](./argocd-troubleshooting.md) +- [ArgoCD Plugin Documentation](../docs/argocd.md) diff --git a/guides/argocd-troubleshooting.md b/guides/argocd-troubleshooting.md new file mode 100644 index 0000000..1106549 --- /dev/null +++ b/guides/argocd-troubleshooting.md @@ -0,0 +1,812 @@ +# ArgoCD - Troubleshooting Guide + +This guide helps you diagnose and fix common issues with the ArgoCD plugins for RHDH. + +--- + +## Table of Contents + +- [Operator Issues](#operator-issues) +- [ArgoCD Instance Issues](#argocd-instance-issues) +- [Application Sync Issues](#application-sync-issues) +- [Plugin Integration Issues](#plugin-integration-issues) +- [Authentication and Authorization](#authentication-and-authorization) +- [Network and Connectivity](#network-and-connectivity) +- [Performance Issues](#performance-issues) +- [Common Error Messages](#common-error-messages) + +--- + +## Operator Issues + +### Operator Not Installing + +**Symptoms:** + +- Subscription exists but CSV never appears +- Install plan is stuck in "Installing" state + +**Diagnosis:** + +```bash +# Check subscription status +oc get subscription argocd-operator-subscription -n rhdh -o yaml + +# Check install plan +oc get installplan -n rhdh + +# Check for operator pod issues +oc get pods -n openshift-marketplace | grep community-operators +``` + +**Solutions:** + +1. **Verify operator catalog is healthy:** + + ```bash + oc get catalogsource -n openshift-marketplace + oc get pods -n openshift-marketplace + ``` + +2. **Delete and recreate the subscription:** + + ```bash + oc delete subscription argocd-operator-subscription -n rhdh + oc apply -f resources/operators/argocd-subscription.yaml -n rhdh + ``` + +3. **Check operator pod logs:** + + ```bash + oc logs -n openshift-marketplace \ + $(oc get pods -n openshift-marketplace -l olm.catalogSource=community-operators -o name | head -n1) + ``` + +### Operator CSV in Failed State + +**Symptoms:** + +- CSV shows "Failed" phase +- Operator pod is crash looping + +**Diagnosis:** + +```bash +# Check CSV status +oc get csv -n rhdh | grep argocd-operator + +# Check operator pod logs +oc logs -n rhdh deployment/argocd-operator-controller-manager +``` + +**Solutions:** + +1. **Check for resource conflicts:** + + ```bash + # Look for existing ArgoCD CRDs from other installations + oc get crd | grep argocd + ``` + +2. **Delete and reinstall the operator:** + + ```bash + ./scripts/config-argocd-plugin.sh + # Or manually: + OPERATOR=$(oc get csv -n rhdh | grep argocd-operator | awk '{print $1}') + oc delete csv $OPERATOR -n rhdh + oc delete subscription argocd-operator-subscription -n rhdh + oc apply -f resources/operators/argocd-subscription.yaml -n rhdh + ``` + +--- + +## ArgoCD Instance Issues + +### ArgoCD Instance Stuck in Pending + +**Symptoms:** + +- `oc get argocd argocd -n rhdh` shows status as empty or "Pending" +- ArgoCD server pod not starting + +**Diagnosis:** + +```bash +# Check ArgoCD CR status +oc get argocd argocd -n rhdh -o yaml + +# Check events +oc get events -n rhdh --sort-by='.lastTimestamp' | grep -i argocd + +# Check pod status +oc get pods -n rhdh | grep argocd +``` + +**Solutions:** + +1. **Check for resource constraints:** + + ```bash + # Check if pods are pending due to resources + oc describe pod -n rhdh -l app.kubernetes.io/name=argocd-server + ``` + +2. **Reduce resource requirements (for testing):** + + Edit `resources/argocd/argocd-instance.yaml` and reduce resource requests: + + ```yaml + spec: + controller: + resources: + requests: + cpu: 100m + memory: 512Mi + ``` + + Then reapply: + + ```bash + oc apply -f resources/argocd/argocd-instance.yaml -n rhdh + ``` + +### ArgoCD Server Not Accessible + +**Symptoms:** + +- Route exists but returns 503 or connection refused +- ArgoCD UI not loading + +**Diagnosis:** + +```bash +# Check route +oc get route argocd-server -n rhdh + +# Check server pod +oc get pods -n rhdh -l app.kubernetes.io/name=argocd-server + +# Check server logs +oc logs -n rhdh deployment/argocd-server +``` + +**Solutions:** + +1. **Verify server pod is running:** + + ```bash + oc get pods -n rhdh -l app.kubernetes.io/name=argocd-server + ``` + +2. **Check for TLS configuration issues:** + + ```bash + # Verify route TLS settings + oc get route argocd-server -n rhdh -o yaml | grep -A5 tls + ``` + +3. **Restart ArgoCD server:** + + ```bash + oc delete pod -n rhdh -l app.kubernetes.io/name=argocd-server + ``` + +### Dex/SSO Integration Issues + +**Symptoms:** + +- Cannot login with OpenShift credentials +- Dex pod crash looping + +**Diagnosis:** + +```bash +# Check Dex pod +oc get pods -n rhdh -l app.kubernetes.io/name=argocd-dex-server + +# Check Dex logs +oc logs -n rhdh deployment/argocd-dex-server +``` + +**Solutions:** + +1. **Verify OAuth configuration:** + + ```bash + # Check if OAuthClient was created + oc get oauthclient argocd -o yaml + ``` + +2. **Recreate Dex pod:** + + ```bash + oc delete pod -n rhdh -l app.kubernetes.io/name=argocd-dex-server + ``` + +3. **Check RBAC configuration:** + + The ArgoCD CR includes RBAC policy. Verify it matches your cluster groups: + + ```bash + oc get argocd argocd -n rhdh -o jsonpath='{.spec.rbac}' + ``` + +--- + +## Application Sync Issues + +### Applications Not Syncing + +**Symptoms:** + +- Application status stuck in "OutOfSync" +- Manual sync fails + +**Diagnosis:** + +```bash +# Check application status +oc get application -n rhdh + +# Get detailed application info +oc describe application demo-guestbook-app -n rhdh + +# Check application controller logs +oc logs -n rhdh deployment/argocd-application-controller +``` + +**Solutions:** + +1. **Check Git repository accessibility:** + + ```bash + # Try to access the repo from a pod + oc run test-curl --image=curlimages/curl --rm -it --restart=Never -- \ + curl -I https://github.com/argoproj/argocd-example-apps.git + ``` + +2. **Verify sync policy:** + + ```bash + # Check if auto-sync is enabled + oc get application demo-guestbook-app -n rhdh -o jsonpath='{.spec.syncPolicy}' + ``` + +3. **Manually trigger sync:** + + ```bash + # Using ArgoCD CLI + argocd app sync demo-guestbook-app --server $(oc get route argocd-server -n rhdh -o jsonpath='{.spec.host}') + + # Or patch the application + oc patch application demo-guestbook-app -n rhdh --type merge -p '{"operation":{"initiatedBy":{"username":"admin"},"sync":{}}}' + ``` + +### Application Health Status Unknown/Degraded + +**Symptoms:** + +- Application shows "Unknown" health status +- Resources deployed but health check fails + +**Diagnosis:** + +```bash +# Check application resources +argocd app get demo-guestbook-app --server $(oc get route argocd-server -n rhdh -o jsonpath='{.spec.host}') + +# Check individual resource status +oc get all -n rhdh -l app.kubernetes.io/instance=demo-guestbook-app +``` + +**Solutions:** + +1. **Check resource health:** + + ```bash + # Check pods + oc get pods -n rhdh -l app.kubernetes.io/instance=demo-guestbook-app + + # Check events + oc get events -n rhdh | grep guestbook + ``` + +2. **Review application manifests:** + + ```bash + # Check what ArgoCD is trying to deploy + argocd app manifests demo-guestbook-app + ``` + +### Repository Connection Issues + +**Symptoms:** + +- "Unable to connect to repository" error +- "Repository not found" errors + +**Diagnosis:** + +```bash +# Check repo server logs +oc logs -n rhdh deployment/argocd-repo-server + +# List repositories +argocd repo list --server $(oc get route argocd-server -n rhdh -o jsonpath='{.spec.host}') +``` + +**Solutions:** + +1. **Verify network connectivity:** + + ```bash + # Test from repo server pod + oc exec -n rhdh deployment/argocd-repo-server -- \ + curl -I https://github.com/argoproj/argocd-example-apps.git + ``` + +2. **Check for proxy/firewall issues:** + + ```bash + # Verify no egress restrictions + oc get networkpolicies -n rhdh + ``` + +--- + +## Plugin Integration Issues + +### Plugin Not Showing Applications in RHDH + +**Symptoms:** + +- ArgoCD tab empty in RHDH component page +- "No applications found" message + +**Diagnosis:** + +```bash +# 1. Verify applications exist in ArgoCD +argocd app list --server $(oc get route argocd-server -n rhdh -o jsonpath='{.spec.host}') + +# 2. Check RHDH backend logs for ArgoCD errors +oc logs -n rhdh deployment/backstage -c backstage-backend | grep -i argocd + +# 3. Verify annotations in catalog entity +oc get configmap argocd-demo-entities-config-map -n rhdh -o yaml +``` + +**Solutions:** + +1. **Verify correct plugin annotations:** + + For Backstage Community plugins: + + ```yaml + annotations: + argocd/app-selector: rht-gitops.com/demo-argocd=guestbook-app + ``` + + For RoadieHQ plugins: + + ```yaml + annotations: + argocd/app-name: demo-guestbook-app + ``` + +2. **Check app-config.yaml configuration:** + + ```bash + # Verify ArgoCD configuration exists + oc get configmap app-config-rhdh -n rhdh -o yaml | grep -A10 argocd + ``` + +3. **Verify environment variables:** + + ```bash + # Check secrets are populated + oc get secret rhdh-secrets -n rhdh -o yaml + ``` + +### Wrong Annotation Style + +**Symptoms:** + +- Using RoadieHQ plugin with Backstage Community annotations (or vice versa) +- Applications not appearing despite correct setup + +**Solution:** + +Ensure you're using the correct annotation style for your plugin choice: + +| Plugin Set | Annotation | +| ------------------- | -------------------------------------------- | +| Backstage Community | `argocd/app-selector: label.key=label.value` | +| RoadieHQ | `argocd/app-name: my-app` | + +Update your catalog entities to match the plugin you're using. + +### Multiple Plugin Sets Enabled + +**Symptoms:** + +- Unexpected behavior +- Duplicate ArgoCD tabs/cards + +**Solution:** + +Disable one pair of plugins. Edit your `dynamic-plugins-configmap.yaml`: + +```yaml +# Option A: Enable Backstage Community, disable RoadieHQ +- package: "@backstage-community/plugin-argocd" + disabled: false +- package: "@backstage-community/plugin-argocd-backend" + disabled: false +- package: "@roadiehq/backstage-plugin-argo-cd" + disabled: true +- package: "@roadiehq/backstage-plugin-argo-cd-backend" + disabled: true +``` + +--- + +## Authentication and Authorization + +### Cannot Login to ArgoCD UI + +**Symptoms:** + +- "Invalid username or password" error +- Admin password not working + +**Diagnosis:** + +```bash +# Get current admin password +oc get secret argocd-cluster -n rhdh -o jsonpath='{.data.admin\.password}' | base64 -d + +# If not found, check initial admin secret +oc get secret argocd-initial-admin-secret -n rhdh -o jsonpath='{.data.password}' | base64 -d +``` + +**Solutions:** + +1. **Reset admin password:** + + ```bash + # Using ArgoCD CLI + argocd account update-password --account admin --server $(oc get route argocd-server -n rhdh -o jsonpath='{.spec.host}') + ``` + +2. **Use OpenShift OAuth (if configured):** + + Login via "Log in via OpenShift" button using your OpenShift credentials. + +### RHDH Plugin Authentication Failing + +**Symptoms:** + +- "Unauthorized" errors in RHDH logs +- ArgoCD API calls failing + +**Diagnosis:** + +```bash +# Check if credentials are set +oc get secret rhdh-secrets -n rhdh -o jsonpath='{.data.ARGOCD_PASSWORD}' | base64 -d + +# Test ArgoCD API manually +ARGOCD_URL=$(oc get route argocd-server -n rhdh -o jsonpath='{.spec.host}') +ARGOCD_PASS=$(oc get secret argocd-cluster -n rhdh -o jsonpath='{.data.admin\.password}' | base64 -d) + +curl -k https://${ARGOCD_URL}/api/v1/session \ + -d '{"username":"admin","password":"'$ARGOCD_PASS'"}' +``` + +**Solutions:** + +1. **Regenerate credentials:** + + ```bash + ./scripts/config-argocd-plugin.sh + ``` + +2. **Verify app-config.yaml has correct env var references:** + + ```yaml + argocd: + appLocatorMethods: + - type: "config" + instances: + - name: argoInstance + url: ${ARGOCD_URL} + password: ${ARGOCD_PASSWORD} # or token: ${ARGOCD_AUTH_TOKEN} + ``` + +### RBAC Issues - Users Cannot View Applications + +**Symptoms:** + +- Users see "permission denied" in ArgoCD UI +- Applications visible in ArgoCD CLI but not in UI + +**Diagnosis:** + +```bash +# Check RBAC configuration +oc get argocd argocd -n rhdh -o jsonpath='{.spec.rbac}' + +# Check user's group memberships +oc get groups +``` + +**Solutions:** + +1. **Update RBAC policy in ArgoCD CR:** + + Edit `resources/argocd/argocd-instance.yaml`: + + ```yaml + spec: + rbac: + policy: | + g, system:cluster-admins, role:admin + g, cluster-admins, role:admin + g, developers, role:readonly + ``` + + Apply changes: + + ```bash + oc apply -f resources/argocd/argocd-instance.yaml -n rhdh + ``` + +--- + +## Network and Connectivity + +### ArgoCD Cannot Reach Git Repositories + +**Symptoms:** + +- "connection refused" errors +- "no route to host" errors + +**Diagnosis:** + +```bash +# Test connectivity from ArgoCD pods +oc exec -n rhdh deployment/argocd-repo-server -- \ + curl -v https://github.com + +# Check network policies +oc get networkpolicies -n rhdh +``` + +**Solutions:** + +1. **Allow egress traffic:** + + If using network policies, ensure egress is allowed: + + ```yaml + apiVersion: networking.k8s.io/v1 + kind: NetworkPolicy + metadata: + name: allow-argocd-egress + namespace: rhdh + spec: + podSelector: + matchLabels: + app.kubernetes.io/part-of: argocd + policyTypes: + - Egress + egress: + - {} + ``` + +2. **Configure HTTP proxy (if needed):** + + Edit ArgoCD CR to add proxy environment variables. + +### Cannot Access ArgoCD Route + +**Symptoms:** + +- Route returns 503 +- "Application is not available" page + +**Diagnosis:** + +```bash +# Check route +oc get route argocd-server -n rhdh -o yaml + +# Check service endpoints +oc get endpoints argocd-server -n rhdh + +# Check if server pod is ready +oc get pods -n rhdh -l app.kubernetes.io/name=argocd-server +``` + +**Solutions:** + +1. **Verify service is targeting correct pods:** + + ```bash + oc get service argocd-server -n rhdh -o yaml + ``` + +2. **Check pod readiness:** + + ```bash + oc describe pod -n rhdh -l app.kubernetes.io/name=argocd-server + ``` + +--- + +## Performance Issues + +### Slow Application Sync + +**Symptoms:** + +- Sync operations take very long +- Timeout errors during sync + +**Diagnosis:** + +```bash +# Check controller resource usage +oc top pods -n rhdh -l app.kubernetes.io/name=argocd-application-controller + +# Check controller logs for slow operations +oc logs -n rhdh deployment/argocd-application-controller --tail=100 +``` + +**Solutions:** + +1. **Increase controller resources:** + + Edit `resources/argocd/argocd-instance.yaml`: + + ```yaml + spec: + controller: + resources: + limits: + cpu: "4" + memory: 4Gi + requests: + cpu: 500m + memory: 2Gi + ``` + +2. **Reduce parallelism for large repos:** + + ```yaml + spec: + controller: + parallelismLimit: 5 # Default is 10 + ``` + +### High Memory Usage + +**Symptoms:** + +- ArgoCD pods being OOMKilled +- Slow UI performance + +**Diagnosis:** + +```bash +# Check memory usage +oc adm top pods -n rhdh | grep argocd + +# Check for OOMKilled events +oc get events -n rhdh | grep OOM +``` + +**Solutions:** + +1. **Increase memory limits** (see Advanced Configuration guide) + +2. **Enable resource caching:** + + ```yaml + spec: + repo: + env: + - name: ARGOCD_EXEC_TIMEOUT + value: "180s" + ``` + +--- + +## Common Error Messages + +### "context deadline exceeded" + +**Cause:** Timeout waiting for operation to complete + +**Solution:** + +```bash +# Increase timeout in ArgoCD CR +oc edit argocd argocd -n rhdh +# Add: spec.controller.appResyncPeriod: "300" +``` + +### "rpc error: code = Unauthenticated" + +**Cause:** Invalid or expired authentication token + +**Solution:** + +```bash +# Regenerate authentication +./scripts/config-argocd-plugin.sh +``` + +### "PermissionDenied desc = permission denied" + +**Cause:** RBAC restrictions + +**Solution:** + +Update RBAC policy (see RBAC Issues section above) + +### "ImagePullBackOff" on ArgoCD pods + +**Cause:** Cannot pull ArgoCD images + +**Solution:** + +```bash +# Check image pull secrets +oc get pods -n rhdh -l app.kubernetes.io/part-of=argocd -o yaml | grep imagePullSecrets + +# If using private registry, add pull secret +oc create secret docker-registry my-registry-secret \ + --docker-server=registry.example.com \ + --docker-username=myuser \ + --docker-password=mypass \ + -n rhdh +``` + +--- + +## Getting Help + +If you're still experiencing issues: + +1. **Collect diagnostics:** + + ```bash + # Save all ArgoCD resources + oc get all -n rhdh -l app.kubernetes.io/part-of=argocd -o yaml > argocd-diagnostics.yaml + + # Save logs + oc logs -n rhdh deployment/argocd-server > argocd-server.log + oc logs -n rhdh deployment/argocd-application-controller > argocd-controller.log + oc logs -n rhdh deployment/argocd-repo-server > argocd-repo.log + ``` + +2. **Check ArgoCD documentation:** + - [ArgoCD Troubleshooting](https://argo-cd.readthedocs.io/en/stable/operator-manual/troubleshooting/) + +3. **Open an issue with:** + - Your cluster version + - ArgoCD operator version + - Error messages and logs + - Steps to reproduce + +--- + +## Related Resources + +- [ArgoCD Documentation](https://argo-cd.readthedocs.io/) +- [ArgoCD Advanced Configuration Guide](./argocd-advanced-config.md) +- [ArgoCD Plugin Documentation](../docs/argocd.md) diff --git a/resources/argocd/argocd-instance.yaml b/resources/argocd/argocd-instance.yaml new file mode 100644 index 0000000..91a7751 --- /dev/null +++ b/resources/argocd/argocd-instance.yaml @@ -0,0 +1,81 @@ +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd + namespace: rhdh +spec: + server: + autoscale: + enabled: false + grpc: + ingress: + enabled: false + ingress: + enabled: false + route: + enabled: true + tls: + termination: reencrypt + insecureEdgeTerminationPolicy: Redirect + service: + type: ClusterIP + grafana: + enabled: false + route: + enabled: false + prometheus: + enabled: false + route: + enabled: false + initialSSHKnownHosts: {} + sso: + provider: dex + dex: + openShiftOAuth: true + resources: + limits: + cpu: 500m + memory: 256Mi + requests: + cpu: 250m + memory: 128Mi + rbac: + defaultPolicy: "role:readonly" + policy: | + g, system:cluster-admins, role:admin + g, cluster-admins, role:admin + scopes: "[groups]" + repo: + resources: + limits: + cpu: "1" + memory: 1Gi + requests: + cpu: 250m + memory: 256Mi + controller: + resources: + limits: + cpu: "2" + memory: 2Gi + requests: + cpu: 250m + memory: 1Gi + redis: + resources: + limits: + cpu: 500m + memory: 256Mi + requests: + cpu: 250m + memory: 128Mi + ha: + enabled: false + applicationSet: + resources: + limits: + cpu: "2" + memory: 1Gi + requests: + cpu: 250m + memory: 512Mi diff --git a/resources/argocd/demo-applications.yaml b/resources/argocd/demo-applications.yaml new file mode 100644 index 0000000..b85d6d3 --- /dev/null +++ b/resources/argocd/demo-applications.yaml @@ -0,0 +1,71 @@ +--- +# Demo ArgoCD Application 1: Guestbook (Classic Demo) +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: demo-guestbook-app + namespace: rhdh + labels: + rht-gitops.com/demo-argocd: guestbook-app + backstage.io/kubernetes-id: argocd-demo +spec: + project: default + source: + repoURL: https://github.com/argoproj/argocd-example-apps.git + targetRevision: HEAD + path: guestbook + destination: + server: https://kubernetes.default.svc + namespace: rhdh + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true +--- +# Demo ArgoCD Application 2: Helm Chart Example +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: demo-helm-app + namespace: rhdh + labels: + rht-gitops.com/demo-argocd: helm-app + backstage.io/kubernetes-id: argocd-demo +spec: + project: default + source: + repoURL: https://github.com/argoproj/argocd-example-apps.git + targetRevision: HEAD + path: helm-guestbook + destination: + server: https://kubernetes.default.svc + namespace: rhdh + syncPolicy: + automated: + prune: false + selfHeal: false +--- +# Demo ArgoCD Application 3: Kustomize Example +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: demo-kustomize-app + namespace: rhdh + labels: + rht-gitops.com/demo-argocd: kustomize-app + backstage.io/kubernetes-id: argocd-demo +spec: + project: default + source: + repoURL: https://github.com/argoproj/argocd-example-apps.git + targetRevision: HEAD + path: kustomize-guestbook + destination: + server: https://kubernetes.default.svc + namespace: rhdh + syncPolicy: + automated: + prune: true + selfHeal: false diff --git a/resources/argocd/demo-catalog-entities.yaml b/resources/argocd/demo-catalog-entities.yaml new file mode 100644 index 0000000..947f465 --- /dev/null +++ b/resources/argocd/demo-catalog-entities.yaml @@ -0,0 +1,101 @@ +--- +# Demo Component 1: Guestbook Application (RoadieHQ annotation style) +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: demo-guestbook-app + title: Guestbook Demo Application + description: Demo application showcasing ArgoCD integration with RHDH using RoadieHQ plugin annotations + annotations: + # RoadieHQ ArgoCD plugin annotation + # See: https://roadie.io/backstage/plugins/argo-cd + argocd/app-name: demo-guestbook-app + + # Backstage Kubernetes integration + backstage.io/kubernetes-id: argocd-demo + + # Source code location + backstage.io/source-location: url:https://github.com/argoproj/argocd-example-apps/tree/master/guestbook + tags: + - demo + - argocd + - gitops + - guestbook + links: + - url: https://argo-cd.readthedocs.io/ + title: ArgoCD Documentation + icon: docs +spec: + type: service + lifecycle: experimental + owner: group:default/guardians-of-the-galaxy + dependencyOf: + - resource:default/argocd-instance +--- +# Demo Component 2: Helm Guestbook (Backstage Community annotation style) +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: demo-helm-app + title: Helm Guestbook Demo Application + description: Demo Helm application showcasing ArgoCD integration with RHDH using Backstage Community plugin annotations + annotations: + # Backstage Community ArgoCD plugin annotation + # See: https://docs.redhat.com/en/documentation/red_hat_plug-ins_for_backstage/2.0/html/argocd_plugin_for_backstage/argocd-plugin-for-backstage + argocd/app-selector: rht-gitops.com/demo-argocd=helm-app + + # Backstage Kubernetes integration + backstage.io/kubernetes-id: argocd-demo + + # Source code location + backstage.io/source-location: url:https://github.com/argoproj/argocd-example-apps/tree/master/helm-guestbook + tags: + - demo + - argocd + - gitops + - helm + links: + - url: https://argo-cd.readthedocs.io/ + title: ArgoCD Documentation + icon: docs +spec: + type: service + lifecycle: experimental + owner: group:default/x-men + dependencyOf: + - resource:default/argocd-instance +--- +# Demo Component 3: Kustomize Application (Mixed annotations for comparison) +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: demo-kustomize-app + title: Kustomize Demo Application + description: Demo Kustomize application showcasing ArgoCD integration with both plugin styles + annotations: + # Both annotation styles for demonstration purposes + # RoadieHQ style + argocd/app-name: demo-kustomize-app + # Backstage Community style + argocd/app-selector: rht-gitops.com/demo-argocd=kustomize-app + + # Backstage Kubernetes integration + backstage.io/kubernetes-id: argocd-demo + + # Source code location + backstage.io/source-location: url:https://github.com/argoproj/argocd-example-apps/tree/master/kustomize-guestbook + tags: + - demo + - argocd + - gitops + - kustomize + links: + - url: https://argo-cd.readthedocs.io/ + title: ArgoCD Documentation + icon: docs +spec: + type: service + lifecycle: experimental + owner: group:default/avengers + dependencyOf: + - resource:default/argocd-instance diff --git a/resources/catalog-entities/operators.yaml b/resources/catalog-entities/operators.yaml index 8b0dfd4..73904f1 100644 --- a/resources/catalog-entities/operators.yaml +++ b/resources/catalog-entities/operators.yaml @@ -146,3 +146,41 @@ data: dependencyOf: component:default/janus-idp-nexus-repository-manager dependsOn: - resource:default/nxrm-operator + --- + # ArgoCD Operator + apiVersion: backstage.io/v1alpha1 + kind: Resource + metadata: + name: argocd-operator + title: ArgoCD Operator + description: Operator that is used to deploy and manage ArgoCD instances for GitOps continuous delivery + annotations: + backstage.io/kubernetes-id: argocd-operator + backstage.io/kubernetes-namespace: rhdh + spec: + type: operator + owner: cluster-admins + dependencyOf: component:default/roadiehq-argocd + dependsOn: + - resource:default/test-cluster + --- + apiVersion: backstage.io/v1alpha1 + kind: Resource + metadata: + name: argocd-instance + title: ArgoCD + description: ArgoCD instance for GitOps continuous delivery workflows + annotations: + backstage.io/kubernetes-id: argocd-instance + backstage.io/kubernetes-namespace: rhdh + links: + - url: https://argo-cd.readthedocs.io/ + title: Documentation + icon: web + spec: + type: gitops-platform + lifecycle: production + owner: cluster-admins + dependencyOf: component:default/roadiehq-argocd + dependsOn: + - resource:default/argocd-operator diff --git a/resources/operators/argocd-subscription.yaml b/resources/operators/argocd-subscription.yaml new file mode 100644 index 0000000..3dd3394 --- /dev/null +++ b/resources/operators/argocd-subscription.yaml @@ -0,0 +1,11 @@ +apiVersion: operators.coreos.com/v1alpha1 +kind: Subscription +metadata: + name: argocd-operator-subscription + namespace: openshift-operators +spec: + channel: alpha + installPlanApproval: Automatic + name: argocd-operator + source: community-operators + sourceNamespace: openshift-marketplace diff --git a/resources/rhdh/rhdh-secrets.yaml b/resources/rhdh/rhdh-secrets.yaml index fe66d1e..2289b9b 100644 --- a/resources/rhdh/rhdh-secrets.yaml +++ b/resources/rhdh/rhdh-secrets.yaml @@ -21,4 +21,9 @@ data: # Nexus Repository Manager (Proxy Configuration) NEXUS_URL: "" NEXUS_AUTH_HEADER: "" + # ArgoCD Configuration (supports both RoadieHQ and Backstage Community plugins) + ARGOCD_URL: "" + ARGOCD_USERNAME: "" + ARGOCD_PASSWORD: "" + ARGOCD_AUTH_TOKEN: "" type: Opaque diff --git a/scripts/config-argocd-plugin.sh b/scripts/config-argocd-plugin.sh new file mode 100755 index 0000000..7baa823 --- /dev/null +++ b/scripts/config-argocd-plugin.sh @@ -0,0 +1,285 @@ +#!/bin/bash + +# ============================================================================= +# ArgoCD Plugin Configuration +# ============================================================================= +# This script deploys and configures resources required for the ArgoCD +# plugin integration with RHDH. +# +# Supported Plugins: +# - @roadiehq/backstage-plugin-argo-cd (frontend) +# - @roadiehq/backstage-plugin-argo-cd-backend (backend) +# - @backstage-community/plugin-argocd (frontend) +# - @backstage-community/plugin-argocd-backend (backend) +# +# NOTE: Users should enable both plugins from the same repository: +# - Enable BOTH RoadieHQ plugins OR +# - Enable BOTH Backstage Community plugins +# - DO NOT mix plugins from different repositories +# ============================================================================= + +deploy_argocd() { + echo "Deploying ArgoCD Operator..." + oc apply -f $PWD/resources/operators/argocd-subscription.yaml +} + +wait_for_argocd_operator_and_deploy_instance() { + # Wait for operator to be ready + echo "Waiting for ArgoCD operator to become ready..." + SECONDS=0 + while true; do + STATUS=$(oc get csv --namespace="openshift-operators" 2>/dev/null | grep argocd-operator | awk '{print $NF}') + + if [[ "$STATUS" == "Succeeded" ]]; then + echo "ArgoCD operator is ready!" + break + fi + + if [[ $SECONDS -ge $TIMEOUT ]]; then + echo "Timeout waiting for ArgoCD operator to become ready." + exit 1 + fi + + echo "ArgoCD operator not ready yet. Retrying in $INTERVAL seconds..." + sleep "$INTERVAL" + done + + # Deploy ArgoCD instance (immediately after operator is ready) + echo "Deploying ArgoCD instance..." + oc apply -f $PWD/resources/argocd/argocd-instance.yaml --namespace=${NAMESPACE} +} + +wait_for_argocd_instance_and_deploy_demo_applications() { + # Wait for ArgoCD instance to be ready + echo "Waiting for ArgoCD instance to be ready..." + SECONDS=0 + while true; do + ARGOCD_STATUS=$(oc get argocd argocd --namespace=${NAMESPACE} -o jsonpath='{.status.phase}' 2>/dev/null) + + if [[ "$ARGOCD_STATUS" == "Available" ]]; then + echo "ArgoCD instance is ready!" + break + fi + + if [[ $SECONDS -ge $TIMEOUT ]]; then + echo "Timeout waiting for ArgoCD instance to become ready." + echo "Current status: ${ARGOCD_STATUS}" + exit 1 + fi + + echo "ArgoCD instance not ready yet (status: ${ARGOCD_STATUS}). Retrying in $INTERVAL seconds..." + sleep "$INTERVAL" + done + + # Deploy demo ArgoCD applications (immediately after instance is ready) + echo "Deploying demo ArgoCD applications..." + oc apply -f $PWD/resources/argocd/demo-applications.yaml --namespace=${NAMESPACE} +} + +config_secrets_for_argocd_plugins() { + echo "Configuring secrets for ArgoCD plugins..." + + # Get ArgoCD URL from the route + ARGOCD_URL=$(oc get route argocd-server --namespace=${NAMESPACE} -o jsonpath='{.spec.host}' 2>/dev/null) + + if [[ -z "$ARGOCD_URL" ]]; then + echo "Warning: Could not retrieve ArgoCD URL from route." + ARGOCD_URL="argocd-server.${NAMESPACE}.svc.cluster.local" + fi + + # Get admin password from secret (generated by operator) + ARGOCD_PASSWORD=$(oc get secret argocd-cluster --namespace=${NAMESPACE} -o jsonpath='{.data.admin\.password}' 2>/dev/null | base64 -d) + + if [ -z "$ARGOCD_PASSWORD" ]; then + echo "Warning: ArgoCD admin password not found in argocd-cluster secret" + echo "Checking argocd-initial-admin-secret..." + ARGOCD_PASSWORD=$(oc get secret argocd-initial-admin-secret --namespace=${NAMESPACE} -o jsonpath='{.data.password}' 2>/dev/null | base64 -d) + fi + + if [ -z "$ARGOCD_PASSWORD" ]; then + echo "Error: ArgoCD admin credentials not found" + echo "The ArgoCD admin password secret must exist before running this job" + echo "This is typically created by the ArgoCD operator during installation" + exit 1 + fi + + ARGOCD_USERNAME="admin" + + # Generate authentication token using ArgoCD API + echo "Generating ArgoCD authentication token..." + + # Use the ArgoCD CLI if available, otherwise use API directly + if command -v argocd &> /dev/null; then + ARGOCD_TOKEN=$(argocd account generate-token --account admin --server "$ARGOCD_URL" --insecure 2>/dev/null || echo "") + fi + + # If token generation failed or argocd CLI not available, use password directly + if [ -z "$ARGOCD_TOKEN" ]; then + echo "Using password-based authentication (token generation not available)" + ARGOCD_TOKEN="$ARGOCD_PASSWORD" + fi + + # Ensure local secrets file exists + if [ ! -f "$PWD/resources/user-resources/rhdh-secrets.local.yaml" ]; then + echo "Creating local secrets file..." + cp $PWD/resources/rhdh/rhdh-secrets.yaml $PWD/resources/user-resources/rhdh-secrets.local.yaml + fi + + # Update secrets file with ArgoCD configuration + echo "Updating RHDH secrets with ArgoCD configuration..." + + # Add or update ARGOCD_URL + if grep -q "ARGOCD_INSTANCE1_URL:" $PWD/resources/user-resources/rhdh-secrets.local.yaml; then + sed -i "s|ARGOCD_INSTANCE1_URL:.*|ARGOCD_INSTANCE1_URL: $(echo -n "https://$ARGOCD_URL" | base64 -w 0)|g" \ + $PWD/resources/user-resources/rhdh-secrets.local.yaml + else + sed -i "/^data:/a\\ ARGOCD_INSTANCE1_URL: $(echo -n "https://$ARGOCD_URL" | base64 -w 0)" \ + $PWD/resources/user-resources/rhdh-secrets.local.yaml + fi + + # Add or update ARGOCD_USERNAME + if grep -q "ARGOCD_USERNAME:" $PWD/resources/user-resources/rhdh-secrets.local.yaml; then + sed -i "s|ARGOCD_USERNAME:.*|ARGOCD_USERNAME: $(echo -n "$ARGOCD_USERNAME" | base64 -w 0)|g" \ + $PWD/resources/user-resources/rhdh-secrets.local.yaml + else + sed -i "/^data:/a\\ ARGOCD_USERNAME: $(echo -n "$ARGOCD_USERNAME" | base64 -w 0)" \ + $PWD/resources/user-resources/rhdh-secrets.local.yaml + fi + + # Add or update ARGOCD_PASSWORD + if grep -q "ARGOCD_PASSWORD:" $PWD/resources/user-resources/rhdh-secrets.local.yaml; then + sed -i "s|ARGOCD_PASSWORD:.*|ARGOCD_PASSWORD: $(echo -n "$ARGOCD_PASSWORD" | base64 -w 0)|g" \ + $PWD/resources/user-resources/rhdh-secrets.local.yaml + else + sed -i "/^data:/a\\ ARGOCD_PASSWORD: $(echo -n "$ARGOCD_PASSWORD" | base64 -w 0)" \ + $PWD/resources/user-resources/rhdh-secrets.local.yaml + fi + + # Add or update ARGOCD_AUTH_TOKEN + if grep -q "ARGOCD_AUTH_TOKEN:" $PWD/resources/user-resources/rhdh-secrets.local.yaml; then + sed -i "s|ARGOCD_AUTH_TOKEN:.*|ARGOCD_AUTH_TOKEN: $(echo -n "$ARGOCD_TOKEN" | base64 -w 0)|g" \ + $PWD/resources/user-resources/rhdh-secrets.local.yaml + else + sed -i "/^data:/a\\ ARGOCD_AUTH_TOKEN: $(echo -n "$ARGOCD_TOKEN" | base64 -w 0)" \ + $PWD/resources/user-resources/rhdh-secrets.local.yaml + fi + + echo "ArgoCD configuration completed:" + echo " URL: https://$ARGOCD_URL" + echo " Username: $ARGOCD_USERNAME" + echo " Password: [configured in secrets]" + echo " Auth Token: [configured in secrets]" + echo "" + echo "NOTE: This supports both RoadieHQ and Backstage Community ArgoCD plugins." + echo "Choose ONE set of plugins (both frontend and backend from same source):" + echo " Option 1: @roadiehq/backstage-plugin-argo-cd + @roadiehq/backstage-plugin-argo-cd-backend" + echo " Option 2: @backstage-community/plugin-argocd + @backstage-community/plugin-argocd-backend" +} + +apply_argocd_labels() { + echo "Applying Kubernetes labels for ArgoCD resources..." + + # Define label patterns for ArgoCD resources + declare -A patterns=( + ["argocd-server"]="backstage.io/kubernetes-id=argocd-instance" + ["argocd-repo-server"]="backstage.io/kubernetes-id=argocd-instance" + ["argocd-redis"]="backstage.io/kubernetes-id=argocd-instance" + ["argocd-application-controller"]="backstage.io/kubernetes-id=argocd-instance" + ["argocd-dex-server"]="backstage.io/kubernetes-id=argocd-instance" + ["argocd-operator"]="backstage.io/kubernetes-id=argocd-operator" + # Demo applications + ["guestbook"]="backstage.io/kubernetes-id=argocd-demo" + ) + + resource_types=("pods" "deployments" "replicasets" "services" "routes" "statefulsets") + + for resource in "${resource_types[@]}"; do + for pattern in "${!patterns[@]}"; do + label="${patterns[$pattern]}" + oc get "$resource" -n $NAMESPACE --no-headers -o custom-columns=":metadata.name" 2>/dev/null \ + | grep "$pattern" \ + | xargs -I {} oc label "$resource" {} "$label" --overwrite -n $NAMESPACE 2>/dev/null || true + done + done + + echo "Labels applied successfully!" +} + +register_argocd_demo_catalog_entities() { + # Check if demo data population is enabled + if [[ "${POPULATE_DEMO_DATA:-true}" == "false" ]]; then + echo "Demo data disabled, skipping catalog entity registration..." + return 0 + fi + + echo "Registering ArgoCD demo catalog entities..." + + # Create ConfigMap for demo catalog entities + oc create configmap argocd-demo-entities-config-map \ + --from-file=demo-argocd-applications.yaml=$PWD/resources/argocd/demo-catalog-entities.yaml \ + --namespace=${NAMESPACE} \ + --dry-run=client -o yaml | oc apply -f - --namespace=${NAMESPACE} + + # Add label for Backstage to discover + oc label configmap argocd-demo-entities-config-map \ + backstage.io/kubernetes-id=developer-hub \ + --overwrite -n ${NAMESPACE} + + echo "Demo catalog entities registered!" + echo "Entities will be available in RHDH catalog:" + echo " - Component: demo-guestbook-app (RoadieHQ annotations)" + echo " - Component: demo-helm-app (Backstage Community annotations)" + echo " - Component: demo-kustomize-app (Both annotation styles)" +} + +uninstall_argocd() { + echo "Uninstalling ArgoCD..." + + # Delete demo catalog entities ConfigMap + oc delete configmap argocd-demo-entities-config-map --namespace=${NAMESPACE} 2>/dev/null || true + + # Delete demo applications + oc delete -f $PWD/resources/argocd/demo-applications.yaml --namespace=${NAMESPACE} 2>/dev/null || true + + # Delete ArgoCD instance + oc delete argocd argocd --namespace=${NAMESPACE} 2>/dev/null || true + + # Wait for resources to be cleaned up + sleep 10 + + # Uninstall the operator + OPERATOR=$(oc get csv --namespace=${NAMESPACE} 2>/dev/null | grep argocd-operator | awk '{print $1}') + if [[ -n "$OPERATOR" ]]; then + oc delete clusterserviceversion $OPERATOR --namespace=${NAMESPACE} + fi + oc delete subscription argocd-operator-subscription --namespace=${NAMESPACE} 2>/dev/null || true + + echo "ArgoCD uninstalled!" +} + +main() { + source "${PWD}/env_variables.sh" + source "${PWD}/.env" + + echo "==============================================" + echo "Configuring ArgoCD Plugin" + echo "==============================================" + + deploy_argocd + wait_for_argocd_operator_and_deploy_instance + wait_for_argocd_instance_and_deploy_demo_applications + config_secrets_for_argocd_plugins + apply_argocd_labels + register_argocd_demo_catalog_entities + + echo "" + echo "==============================================" + echo "ArgoCD configuration complete!" + echo "==============================================" + + exit "${OVERALL_RESULT}" +} + +if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then + main +fi