Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ require (
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/chai2010/gettext-go v1.0.2 // indirect
github.com/cloudflare/circl v1.3.7 // indirect
github.com/coreos/go-oidc/v3 v3.11.0 // indirect
github.com/cyphar/filepath-securejoin v0.3.6 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
Expand All @@ -47,11 +48,13 @@ require (
github.com/evanphx/json-patch v5.9.0+incompatible // indirect
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
github.com/fatih/camelcase v1.0.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/go-errors/errors v1.4.2 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.6.2 // indirect
github.com/go-git/go-git/v5 v5.13.2 // indirect
github.com/go-jose/go-jose/v4 v4.0.2 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
Expand All @@ -76,6 +79,8 @@ require (
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
github.com/imdario/mergo v0.3.16 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
Expand Down
18 changes: 18 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,8 @@ github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWH
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/coreos/go-oidc/v3 v3.11.0 h1:Ia3MxdwpSw702YW0xgfmP1GVCMA9aEFWu12XUZ3/OtI=
github.com/coreos/go-oidc/v3 v3.11.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDhf0r5lltWI0=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
Expand Down Expand Up @@ -742,7 +744,11 @@ github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwC
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8=
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0=
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
Expand Down Expand Up @@ -775,6 +781,8 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k=
github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
github.com/go-jose/go-jose/v4 v4.0.2 h1:R3l3kkBds16bO7ZFAEEcofK0MkrAJt3jlJznWZG0nvk=
github.com/go-jose/go-jose/v4 v4.0.2/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U=
github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81/go.mod h1:SX0U8uGpxhq9o2S/CELCSUxEWWAuoCUcVCQWv7G2OCk=
Expand Down Expand Up @@ -947,6 +955,12 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w=
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU=
github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
Expand Down Expand Up @@ -1012,8 +1026,12 @@ github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuz
github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY=
github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE=
Expand Down
164 changes: 164 additions & 0 deletions pkg/argocd/app_query.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
package argocd

import (
"context"
"encoding/json"
"fmt"
"os"

"github.com/argoproj/argo-cd/v2/pkg/apiclient"
"github.com/argoproj/argo-cd/v2/pkg/apiclient/application"
"github.com/argoproj/argo-cd/v2/pkg/apiclient/cluster"
"github.com/argoproj/argo-cd/v2/pkg/apiclient/project"
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
"gopkg.in/yaml.v2"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)

type appClient struct {
client apiclient.Client
}

type ClientOptions struct {
ServerAddr string
Insecure bool
Plaintext bool
Certfile string
GRPCWeb bool
GRPCWebRootPath string
AuthToken string
}

func NewAPIClient(opts *ClientOptions) (appClient, error) {
envAuthToken := os.Getenv("ARGOCD_TOKEN")
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than taking the token as env. Can we try using the SA token by giving Argo CD RBAC access to that SA. There is a security concern as well in passing tokens as env variables.

if envAuthToken != "" && opts.AuthToken == "" {
opts.AuthToken = envAuthToken
}

rOpts := &apiclient.ClientOptions{
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this work with TLS enabled ? and using the 443 port. Probably you need to initialize the TLS client certificates and CA bundle.

ServerAddr: opts.ServerAddr,
PlainText: opts.Plaintext,
Insecure: opts.Insecure,
CertFile: opts.Certfile,
GRPCWeb: opts.GRPCWeb,
GRPCWebRootPath: opts.GRPCWebRootPath,
AuthToken: opts.AuthToken,
}
client, err := apiclient.NewClient(rOpts)
if err != nil {
return appClient{}, fmt.Errorf("failed to create ArgoCD client: %w", err)
}
return appClient{client}, nil
}

func (a *appClient) GetApplicationChildManifests(ctx context.Context, app *v1alpha1.Application, proj *v1alpha1.AppProject) ([]*unstructured.Unstructured, error) {
query := &application.ApplicationManifestQuery{
Name: &app.Name,
AppNamespace: &app.Namespace,
}

fmt.Printf("Querying manifests for app: %s, namespace: %s\n", app.Name, app.Namespace)
conn, appSetClient, err := a.client.NewApplicationClient()
if err != nil {
return nil, fmt.Errorf("failed to create Application client: %w", err)
}
defer conn.Close()
response, err := appSetClient.GetManifests(ctx, query)
if err != nil {
return nil, fmt.Errorf("failed to get manifests: %w", err)
}
// print pretty the manifests for debugging
for _, manifest := range response.Manifests {
fmt.Printf("Manifest for app %s:\n%s\n", app.Name, manifest)
}

for i, manifest := range response.Manifests {
var parsed interface{}
err := yaml.Unmarshal([]byte(manifest), &parsed)
if err != nil {
fmt.Printf("Error parsing manifest %d: %v\n", i+1, err)
continue
}

formatted, err := yaml.Marshal(parsed)
if err != nil {
fmt.Printf("Error formatting manifest %d: %v\n", i+1, err)
continue
}
fmt.Printf("\n--- Manifest %d for app '%s' ---\n%s\n", i+1, app.Name, string(formatted))
}
return unmarshalManifests(response.Manifests)
}

func (a *appClient) GetApplication(ctx context.Context, appName, appNamespace string) (*v1alpha1.Application, error) {
conn, appSetClient, err := a.client.NewApplicationClient()
if err != nil {
return nil, fmt.Errorf("failed to create Application client: %w", err)
}
defer conn.Close()
query := &application.ApplicationQuery{
Name: &appName,
AppNamespace: &appNamespace,
}

return appSetClient.Get(ctx, query)
}

func (a *appClient) ListApplications(ctx context.Context, controllerNamespace string) ([]v1alpha1.Application, error) {
var applications []v1alpha1.Application
conn, appSetClient, err := a.client.NewApplicationClient()
if err != nil {
return nil, fmt.Errorf("failed to create Application client: %w", err)
}
defer conn.Close()
appList, err := appSetClient.List(ctx, &application.ApplicationQuery{})
if err != nil {
return nil, fmt.Errorf("failed to list applications: %w", err)
}
for _, app := range appList.Items {
if app.Status.ControllerNamespace == controllerNamespace {
applications = append(applications, app)
}
}
return applications, nil
}

func (a *appClient) GetAppProject(ctx context.Context, name string) (*v1alpha1.AppProject, error) {
conn, projectClient, err := a.client.NewProjectClient()
if err != nil {
return nil, fmt.Errorf("failed to create Project client: %w", err)
}
defer conn.Close()

return projectClient.Get(ctx, &project.ProjectQuery{Name: name})
}

func unmarshalManifests(manifests []string) ([]*unstructured.Unstructured, error) {
targetObjs := make([]*unstructured.Unstructured, 0)
for _, manifest := range manifests {
if manifest == "" || manifest == "null" {
return nil, nil
}
var obj unstructured.Unstructured
err := json.Unmarshal([]byte(manifest), &obj)
if err != nil {
return nil, err
}
targetObjs = append(targetObjs, &obj)
}
return targetObjs, nil
}

func (a *appClient) GetApplicationDestinationServer(ctx context.Context, destinationServer, destinationName string) (*v1alpha1.Cluster, error) {
conn, clusterClient, err := a.client.NewClusterClient()
if err != nil {
return nil, fmt.Errorf("failed to create Application client: %w", err)
}
defer conn.Close()

return clusterClient.Get(ctx, &cluster.ClusterQuery{
Name: destinationName,
Server: destinationServer,
})

}
12 changes: 0 additions & 12 deletions pkg/argocd/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,18 +186,6 @@ func getApplicationChildManifests(ctx context.Context, application *appsv1alpha1
return targetObjs, cluster.RESTConfig(), nil
}

func unmarshalManifests(manifests []string) ([]*unstructured.Unstructured, error) {
targetObjs := make([]*unstructured.Unstructured, 0)
for _, manifest := range manifests {
obj, err := appsv1alpha1.UnmarshalToUnstructured(manifest)
if err != nil {
return nil, err
}
targetObjs = append(targetObjs, obj)
}
return targetObjs, nil
}

// getClusterAPIDetails retrieves the server version and API resources from the Kubernetes cluster
func getClusterAPIDetails(config *rest.Config, kubectl kube.Kubectl) (*clusterAPIDetails, error) {
// Retrieve the server version
Expand Down
12 changes: 12 additions & 0 deletions pkg/env/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package env

import (
"os"
"strings"
)

// Package env provides some utility functions to interact with the environment
Expand All @@ -16,3 +17,14 @@ func GetStringVal(envVar string, defaultValue string) string {
return defaultValue
}
}

func GetBoolVal(envVar string, defaultValue bool) bool {
if val := os.Getenv(envVar); val != "" {
if strings.ToLower(val) == "true" {
return true
} else if strings.ToLower(val) == "false" {
return false
}
}
return defaultValue
}