{"id":23316885,"url":"https://github.com/dntosas/capi2argo-cluster-operator","last_synced_at":"2025-04-06T14:11:00.861Z","repository":{"id":37040416,"uuid":"460118398","full_name":"dntosas/capi2argo-cluster-operator","owner":"dntosas","description":"Capi2Argo Cluster Operator (CACO) can be deployed on a CAPI Management cluster and dynamically convert Workload cluster credentials into Argo Cluster definitions.","archived":false,"fork":false,"pushed_at":"2024-11-19T13:30:02.000Z","size":25039,"stargazers_count":83,"open_issues_count":15,"forks_count":17,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-03-30T13:08:00.195Z","etag":null,"topics":["argo","argocd","capi","cluster-api","clusterapi","kubernetes","operator"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dntosas.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-02-16T17:59:52.000Z","updated_at":"2025-03-11T21:09:17.000Z","dependencies_parsed_at":"2023-10-11T22:35:37.687Z","dependency_job_id":"36ce606a-326c-4b1c-9802-15b6950b8d6f","html_url":"https://github.com/dntosas/capi2argo-cluster-operator","commit_stats":null,"previous_names":[],"tags_count":48,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dntosas%2Fcapi2argo-cluster-operator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dntosas%2Fcapi2argo-cluster-operator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dntosas%2Fcapi2argo-cluster-operator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dntosas%2Fcapi2argo-cluster-operator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dntosas","download_url":"https://codeload.github.com/dntosas/capi2argo-cluster-operator/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247492513,"owners_count":20947544,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["argo","argocd","capi","cluster-api","clusterapi","kubernetes","operator"],"created_at":"2024-12-20T16:16:55.991Z","updated_at":"2025-04-06T14:11:00.843Z","avatar_url":"https://github.com/dntosas.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Capi2Argo Cluster Operator\n\n[![CI](https://github.com/dntosas/capi2argo-cluster-operator/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/dntosas/capi2argo-cluster-operator/actions/workflows/ci.yml) | [![Go Report](https://goreportcard.com/badge/github.com/dntosas/capi2argo-cluster-operator)](https://goreportcard.com/badge/github.com/dntosas/capi2argo-cluster-operator) | [![Go Release](https://github.com/dntosas/capi2argo-cluster-operator/actions/workflows/go-release.yml/badge.svg)](https://github.com/dntosas/capi2argo-cluster-operator/actions/workflows/go-release.yml) | [![Helm Chart Release](https://github.com/dntosas/capi2argo-cluster-operator/actions/workflows/helm-release.yml/badge.svg)](https://github.com/dntosas/capi2argo-cluster-operator/actions/workflows/helm-release.yml) | [![codecov](https://codecov.io/gh/dntosas/capi2argo-cluster-operator/branch/main/graph/badge.svg?token=5GDS0GGTY3)](https://codecov.io/gh/dntosas/capi2argo-cluster-operator)\n\nCapi-2-Argo Cluster Operator (CACO) converts ClusterAPI Cluster credentials into ArgoCD Cluster definitions and keep them synchronized. It aims to act as an integration bridge and solve an automation gap for users that combine these tools to provision Kubernetes Clusters.\n\n## What It Does\n\nProbably to be here, you are already aware of **ClusterAPI** and **ArgoCD**. If not, lets say few words about these projects and what they want to offer:\n\n- [ClusterAPI](https://cluster-api.sigs.k8s.io/) provides declarative APIs and tooling to simplify provisioning, upgrading, and operating multiple Kubernetes clusters. In simple words, users can define all aspects of their Kubernetes setup as CRDs and CAPI controller -which follows [operator pattern](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/)- is responsible to reconcile on them and keep their desired state.\n\n- [ArgoCD](https://argo-cd.readthedocs.io/en/stable/) is a declarative, GitOps continuous delivery tool for Kubernetes. It automates the deployment of the desired application states in the specified target environments. In simple words, give a Git and a target Kubernetes Cluster and Argo will keep you package up, running and always in-sync with your source.\n\nSo, we have CAPI that enables us to define Clusters as native k8s objects and ArgoCD that can take these objects and deploy them. Let's demonstrate how a pipeline like this could look like:\n\n![flow-without-capi2argo](docs/flow-without-operator.png)\n\n0. Git holds multiple Kubernetes Clusters definitions as CRDs\n1. Argo watches these resources from Git\n2. Argo deploys definitions on a Management Cluster\n3. CAPI reconciles on these definitions\n4. CAPI provisions these Clusters on Cloud Provider\n5. CAPI returns provisioned Cluster information as k8s Secrets\n6. :x: Argo is not aware of remote Clusters plus cannot authenticate to provision additional resources\n\nOk, all good until here. But having bare naked k8s clusters is not something useful. Probably dozens of utils and addons are needed for a cluster to look handy (eg. CSI Drivers, Ingress Controllers, Monitoring, etc).\n\nArgo can also take care of deploying these utils but eventually credentials will be essential to authenticate against target clusters. Of course, we can proceed with the following three manual steps to solve that:\n\n- Read CAPI credentials\n- Translate them to Argo types\n- Create new Argo credentials\n\nBut how can we automate this? Capi2Argo Cluster Operator was created so it can take care of above actions.\n\nCACO implements them in an automated loop that watches for changing events in secret resources and if conditions are met to be a CAPI compliant, it converts and deploy them as Argo compatible ones. What is actually does under the hood, is a god simple [KRM](https://github.com/kubernetes/design-proposals-archive/blob/8da1442ea29adccea40693357d04727127e045ed/architecture/resource-management.md) transformation like this:\n\nBefore we got only [CAPI Cluster Spec]():\n\n```yaml\nkind: Secret\napiVersion: v1\ntype: cluster.x-k8s.io/secret\nmetadata:\n  labels:\n    cluster.x-k8s.io/cluster-name: CAPICluster\n  name: CAPICluster-kubeconfig\ndata:\n  value: \u003c\u003c CAPICluster KUBECONFIG based64-encoded \u003e\u003e\n```\n\nAfter we have also [Argo Cluster Spec](https://argo-cd.readthedocs.io/en/stable/operator-manual/declarative-setup/#clusters):\n\n```yaml\nkind: Secret\napiVersion: v1\ntype: Opaque\nmetadata:\n  labels:\n    argocd.argoproj.io/secret-type: cluster\n    capi-to-argocd/owned: \"true\" # Capi2Argo Controller Ownership Label\n  name: ArgoCluster\n  namespace: argocd\nstringData:\n  name: CAPICluster\n  server: CAPIClusterHost\n  config: |\n    {\n      \"tlsClientConfig\": {\n        \"caData\": \"b64-ca-cert\",\n        \"keyData\": \"b64-token\",\n        \"certData\": \"b64-cert\",\n      }\n    }\n```\n\nAbove functionality use-case can be demonstrated by extending the Workflow mentioned above by automating following steps:\n\n6. CACO watches for CAPI cluster secrets\n7. CACO converts them to Argo Clusters\n8. CACO creates them as Argo Clusters\n9. Argo reads these new Clusters\n10. :heavy_check_mark: Argo provisions resources to CAPI Workload Clusters\n\n![flow-with-capi2argo](docs/flow-with-operator.png)\n\n## Take along labels from cluster resources\n\nCapi-2-Argo Cluster Operator is able to take along labels from a `Cluster` resource and place them on the `Secret` resource that is created for the cluster. This is especially useful when using labels to instruct ArgoCD which clusters to sync with certain applications.\n\nTo enable this feature, add a label with this format to the `Cluster` resource: `take-along-label.capi-to-argocd.\u003clabel-key\u003e: \"\"`.\n\nThe following example \n\n```yaml\napiVersion: cluster.x-k8s.io/v1beta1\nkind: Cluster\nmetadata: \n  name: ArgoCluster\n  namespace: default\n  labels: \n    foo: bar\n    my.domain.com/env: stage\n    take-along-label.capi-to-argocd.foo: \"\"\n    take-along-label.capi-to-argocd.my.domain.com/env: \"\"\nspec: \n// ..\n```\nResults in the following `Secret` resource:\n\n```yaml\nkind: Secret\napiVersion: v1\ntype: Opaque\nmetadata:\n  name: ArgoCluster\n  namespace: argocd\n  labels:\n    argocd.argoproj.io/secret-type: cluster\n    capi-to-argocd/owned: \"true\" \n    foo: bar\n    my.domain.com/env: stage\n    taken-from-cluster-label.capi-to-argocd.foo: \"\"\n    taken-from-cluster-label.capi-to-argocd.my.domain.com/env: \"\"\nstringData:\n// ...\n```\n\n## Use Cases\n\n1. Keeping your Production Pipelines DRY, everything as testable Code\n2. Avoid manual steps for credentials management through UI, cron scripts and orphaned YAML files\n3. Write end-2-end Infrastructure tests by bundling all the logic\n4. Enabler for creating trully dynamic environments when using ClusterAPI and ArgoCD\n\n## Installation\n\n**Helm**\n\n```console\n$ helm repo add capi2argo https://dntosas.github.io/capi2argo-cluster-operator/\n$ helm repo update\n$ helm upgrade -i capi2argo capi2argo/capi2argo-cluster-operator\n```\n\nCheck additional values configuration in [chart readme file](./charts/capi2argo-cluster-operator/README.md).\n\n## Development\n\nCapi2Argo is builded upon the powerful [Operator SDK](link).\n\nGradually -and depends on how free time allow us- will try adopting all best practices that are suggested on the community, find more in [here](https://sdk.operatorframework.io/docs/best-practices/best-practices/).\n- `make all`\n- `make ci`\n- `make run`\n- `make docker-build`\n\n## Contributing\n\nTODO\nIn the meantime, feel free to grab any of unimplemented bullets on the Roadmap section :).\n\n## Roadmap\n\n### v0.1.0\n\n- [x] Core Functionality: Convert CAPI to Argo Clusters\n- [x] Unit Tests\n- [x] Integration Tests\n- [x] Helm Chart Deployment\n- [x] FAQ and Docs\n\n### v0.2.0\n\n- [ ] Adopt [Operator Best Practices](https://sdk.operatorframework.io/docs/best-practices/best-practices/)\n- [x] Garbage Collection\n- [ ] Quickstart Deployment (Kind Cluster)\n- [ ] Support for filtering Namespaces\n- [x] Support for multi-arch Docker images (amd64/arm64)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdntosas%2Fcapi2argo-cluster-operator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdntosas%2Fcapi2argo-cluster-operator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdntosas%2Fcapi2argo-cluster-operator/lists"}