Last active
September 10, 2025 07:33
-
-
Save raihankhan/6566d32cac59aa674672c6560b47d70a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"context" | |
"encoding/json" | |
"flag" | |
"fmt" | |
"log" | |
"os" | |
// Official Argo CD API client | |
"github.com/argoproj/argo-cd/v2/pkg/apiclient" | |
applicationpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" | |
// Official Kubernetes API types | |
appsv1 "k8s.io/api/apps/v1" | |
) | |
func main() { | |
// ## 1. Configuration Setup | |
// Use command-line flags for easy configuration. | |
var argoServer, argoToken, appName string | |
var insecure bool | |
flag.StringVar(&argoServer, "argo-server", os.Getenv("ARGOCD_SERVER"), "Argo CD server address (e.g., 'localhost:8080'). Can also be set via ARGOCD_SERVER env var.") | |
flag.StringVar(&argoToken, "argo-token", os.Getenv("ARGOCD_TOKEN"), "Argo CD authentication token. Can also be set via ARGOCD_TOKEN env var.") | |
flag.StringVar(&appName, "app-name", "", "Name of the Argo CD application to inspect (e.g., 'nginx-deployment').") | |
flag.BoolVar(&insecure, "insecure", false, "Skip server certificate verification. Use only for testing.") | |
flag.Parse() | |
// Validate that required flags are provided. | |
if argoServer == "" || argoToken == "" || appName == "" { | |
log.Println("Error: --argo-server, --argo-token, and --app-name are required flags.") | |
flag.Usage() | |
os.Exit(1) | |
} | |
// ## 2. Argo CD API Client Initialization | |
log.Printf("Connecting to Argo CD server at %s...", argoServer) | |
apiClient, err := apiclient.NewClient(&apiclient.ClientOptions{ | |
ServerAddr: argoServer, | |
AuthToken: argoToken, | |
GRPCWeb: false, // Often required when connecting to Argo CD UI/API endpoint | |
Insecure: true, | |
}) | |
if err != nil { | |
log.Fatalf("Failed to create Argo CD API client: %v", err) | |
} | |
// The closer must be deferred to clean up the connection. | |
closer, appClient, err := apiClient.NewApplicationClient() | |
if err != nil { | |
log.Fatalf("Failed to create Argo CD application client: %v", err) | |
} | |
defer closer.Close() | |
ctx := context.Background() | |
// ## 3. Fetch Resource Tree | |
// Get the entire resource tree for the application. | |
log.Printf("Fetching resource tree for application: %s", appName) | |
resourceTree, err := appClient.ResourceTree(ctx, &applicationpkg.ResourcesQuery{ | |
ApplicationName: &appName, | |
}) | |
if err != nil { | |
log.Fatalf("Failed to fetch resource tree for application '%s': %v", appName, err) | |
} | |
foundReplicaSet := false | |
// ## 4. Find and Process the ReplicaSet | |
for _, res := range resourceTree.Nodes { | |
fmt.Println(res.Group, res.Kind, res.Name, res.Namespace, res.ResourceVersion) | |
// We are specifically looking for a ReplicaSet from the 'apps' API group. | |
if res.Group == "apps" && res.Kind == "ReplicaSet" { | |
foundReplicaSet = true | |
// Fetch the full manifest (live state) of this specific ReplicaSet. | |
resource, err := appClient.GetResource(ctx, &applicationpkg.ApplicationResourceRequest{ | |
Name: &appName, | |
ResourceName: &res.Name, | |
Namespace: &res.Namespace, | |
Group: &res.Group, | |
Kind: &res.Kind, | |
Version: &res.Version, | |
}) | |
if err != nil { | |
log.Printf("WARN: Could not fetch manifest for ReplicaSet %s: %v", res.Name, err) | |
continue | |
} | |
// ## 5. Parse Manifest into Native Kubernetes Object | |
var replicaSet appsv1.ReplicaSet | |
// The manifest from Argo CD is a JSON string. We unmarshal it directly | |
// into the corresponding Kubernetes Go struct from 'k8s.io/api/apps/v1'. | |
if err := json.Unmarshal([]byte(*resource.Manifest), &replicaSet); err != nil { | |
log.Printf("WARN: Failed to parse manifest for ReplicaSet %s: %v", res.Name, err) | |
continue | |
} | |
// ## 6. Print Desired Information | |
// The revision history is stored in this specific annotation by Deployments. | |
revisionHistory := replicaSet.Annotations["deployment.kubernetes.io/revision"] | |
if revisionHistory == "" { | |
revisionHistory = "N/A" | |
} | |
fmt.Println("-------------------------------------------") | |
fmt.Printf(" ReplicaSet Name: %s\n", replicaSet.Name) | |
fmt.Printf(" Namespace: %s\n", replicaSet.Namespace) | |
fmt.Printf(" Desired Replicas: %d\n", *replicaSet.Spec.Replicas) | |
fmt.Printf(" Current Replicas: %d\n", replicaSet.Status.Replicas) | |
fmt.Printf(" Ready Replicas: %d\n", replicaSet.Status.ReadyReplicas) | |
fmt.Printf(" Revision History: %s\n", revisionHistory) | |
fmt.Println("-------------------------------------------") | |
} | |
} | |
if !foundReplicaSet { | |
log.Printf("No ReplicaSet found for application '%s'. Make sure the application is synced and healthy.", appName) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Run with: