Manage ArgoCD Resources Programmatically with Golang š¹
In this article, we will examine how to manage ArgoCD resources with Go for programmatically creating projects, clusters, and destinations with example codes.
Prerequisites
- Go for developing a resource manager program.
- Docker Desktop for virtualization.
- Minikube for creating a local Kubernetes cluster.
- Kubectl for a Kubernetes command-line tool.
- ArgoCD CLI for generating a account token.
Steps
Open a terminal window and execute the following commands:
Start Docker Desktop
This command initiates the Docker engine for virtualization.
open -a dockerCreate a local Kubernetes cluster
This command launches the local Kubernetes cluster and adds the Minikube context to the ~/.kube/config file.
minikube startSwitch to Minikube context
In an environment with multiple clusters, we will switch to the Minikube context using this command.
This step is typically performed automatically after installing Minikube.
kubectl config use-context minikubeCreate a namespace
Namespaces serve as a logical grouping of objects within a Kubernetes cluster. This command establishes a new namespace in the current Minikube Kubernetes context, where the ArgoCD installation will take place.
kubectl create namespace argocdInstall the latest version of ArgoCD
This command deploys ArgoCD on the current Minikube Kubernetes context, enabling access to ArgoCD in a local environment.
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yamlCheck deployments
Letās see what happens on the cluster after the ArgoCD installation.
kubectl get all -n argocdAdd a new fully authorized account
While our admin account typically possesses comprehensive permissions, it cannot generate tokens for security reasons.
Consequently, we must create a fully authorized account to modify ArgoCD resources. This command introduces an account named foo:
EDITOR=nano kubectl edit configmap argocd-cm -n argocdAppend the following fields to the YAML file in the opened editorĀ andĀ save:
data:
accounts.foo: apiKey, loginThis action successfully generates a new account.
Next, configure the permissions for the account we created by running the following command to open the editor:
EDITOR=nano kubectl edit configmap argocd-rbac-cm -n argocdAppend the following fields to the YAML file in the opened editor and save:
data:
policy.csv: |
g, foo, role:adminWe now have a foo account with full permissions.
Obtain the default admin password
Upon installation, ArgoCD provides an admin user. To log in to ArgoCD using the admin user, we require the password.
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echoForward argocd-server port to local machine network
To access ArgoCD from our browser, we must forward the argocd-server port to our local machine. Port forwarding terminates when the terminal closes.
To execute other commands in the same terminal, add a &to the end of the following command:
kubectl port-forward svc/argocd-server -n argocd 8080:443This command forwards the ArgoCD serverās port to our local machineās port 8080. We can now access the ArgoCD web interface by launching a browser and navigating to localhost:8080.
Generate an account token
A token is required for ArgoCD resource operations within the Go program. Letās log in using the ArgoCD CLI:
argocd login localhost:8080 --insecureWhen prompted for a username and password, enter admin the username and the previously acquired password for the admin user.
After logging in, generate an account token for the foo account with the following command:
argocd account generate-token --account fooDevelop Golang Resource Manager Program
We have completed the necessary installations. Now, letās start building our application to manage ArgoCD resources using Golang.
In this project, we perform resource operations over gRPC using the ArgoCD Go library. Because it is more type-safe and fast. You can do the same using REST API. If you want to see the ArgoCD Swagger: http://localhost:8080/swagger-ui
Create project with folder structure
We may need to manage multiple resources in a project using ArgoCD or another tool. Therefore, we must establish a project structure that supports multiple tools and avoids complexity as it grows.
We will use the Standard Go Project Layout for this purpose and include a few useful tools, such as a linter. As an example, we will name our project engine.
Create client connection definitions
This code defines two structs: Connection and Client. The Connection struct has two fields, Address and Token, both of type string. This struct is used to store information about the connection to an ArgoCD server, such as its address and authentication token.
The Client struct also has two fields: projectClient and clusterClient. These fields are of type project.ProjectServiceClient and cluster.ClusterServiceClient, respectively. This struct is used to perform operations related to projects and clusters on the ArgoCD API.
The NewClient function takes a pointer to a Connection struct as input and returns a pointer to a Client struct and an error (if any). This function creates a new ArgoCD API client using the apiclient.NewClient() function from the apiclient package. The values in the Connection struct are used to configure the clientās connection to the ArgoCD server.
Next, the NewProjectClient() and NewClusterClient() methods are called on the API client object to create clients for projects and clusters. These methods return a context, a client, and an error. The project and cluster clients are then used to initialize the Client struct.
Overall, this code demonstrates how to set up an ArgoCD API client using Go, allowing you to perform operations related to projects and clusters.
Hereās the code for the /internal/driver/argocd/client.go file:
Create cluster resource definitions
The Client struct has a method called GetClusters() that returns a slice of v1alpha1.Cluster objects and any errors encountered. This method takes no arguments.
To retrieve the list of available clusters, the method uses the clusterClient field of the Client struct to call the List() method from the cluster package.
The resulting cl object has an Items field, which contains the list of available clusters. The method returns this Items field as a slice of v1alpha1.Cluster objects, along with a nil error.
These steps demonstrate how to retrieve the list of available clusters from an ArgoCD server using Go.
Hereās the code for the /internal/driver/argocd/cluster.go file:
Create destination resource definitions
The Client struct has a method called AddDestination() that takes four arguments: projectName, server, namespace, and name.
The method first calls the GetProject() method from the project package, passing in the projectName argument. This method returns the project with the provided name.
Next, the GetProject() method updates the projectās destinations by creating a new v1alpha1.ApplicationDestination object and setting its fields to the values of the provided arguments.
Finally, the method calls the Update() method from the project package, passing in a new ProjectUpdateRequest object containing the updated project. This updates the projectās destinations to include the newly added destination.
These steps demonstrate how to add a destination to an ArgoCD project using Go.
Hereās the code for the /internal/driver/argocd/destination.go file:
Create project resource definitions
The Client struct, which is used to interact with the ArgoCD API, has several methods defined for managing projects.
The CreateProject method creates a new project with a given name and returns a pointer to the created AppProject object, along with any errors encountered. This is achieved by calling the Create() method from the project package, which takes a ProjectCreateRequest object containing the AppProject with its Name field set to the provided name.
The DeleteProject() method deletes a project with a given name by calling the Delete() method from the project package. This method returns an error if the project cannot be deleted.
The GetProject() method retrieves a project with a given name by calling the Get() method from the project package. This method returns a pointer to the AppProject object and any errors encountered.
These methods demonstrate how to interact with the ArgoCD project API using Go.
Hereās the code for the /internal/driver/argocd/project.go file:
Trying to execute some driver resource operations
In the main() function, we create an connection object with the ArgoCD serverās address and token. Then, using this connection object, we create an client object through which we can interact with the ArgoCD API.
The code continues by creating a new project named foo and displaying its unique identifier. It then adds a destination to the project and retrieves the projectās namespace field.
Finally, the code deletes the foo project and retrieves the names of all available clusters.
Overall, this code performs a set of operations on the ArgoCD server, demonstrating how to interact with it using the provided API methods.
Hereās the code for the /cmd/engine/main.go file:
Summary
In this project, we utilized some resource definitions as examples. You can perform any ArgoCD resource operations you desire using these code samples.
For example, I am trying these example PoC codes to develop the CD processes of a serverless FaaS project similar to OpenFaaS, which can also be used for SRE automations and other purposes.
You can access the full code here.
