Skip to content

Commit

Permalink
feat: support proxy in our cluster (#342)
Browse files Browse the repository at this point in the history
  • Loading branch information
pasha-codefresh authored Oct 16, 2024
1 parent b8705bb commit ae9bb96
Show file tree
Hide file tree
Showing 11 changed files with 893 additions and 710 deletions.
8 changes: 8 additions & 0 deletions assets/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -7234,12 +7234,20 @@
"description": "Server requires Bearer authentication. This client will not attempt to use\nrefresh tokens for an OAuth2 flow.\nTODO: demonstrate an OAuth2 compatible client.",
"type": "string"
},
"disableCompression": {
"description": "DisableCompression bypasses automatic GZip compression requests to the server.",
"type": "boolean"
},
"execProviderConfig": {
"$ref": "#/definitions/v1alpha1ExecProviderConfig"
},
"password": {
"type": "string"
},
"proxyUrl": {
"type": "string",
"title": "ProxyURL is the URL to the proxy to be used for all requests send to the server"
},
"tlsClientConfig": {
"$ref": "#/definitions/v1alpha1TLSClientConfig"
},
Expand Down
41 changes: 37 additions & 4 deletions cmd/argocd/commands/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package commands

import (
"fmt"
"net/http"
"os"
"regexp"
"strings"
Expand Down Expand Up @@ -34,6 +35,10 @@ const (
clusterFieldName = "name"
// cluster field is 'namespaces'
clusterFieldNamespaces = "namespaces"
// cluster field is 'labels'
clusterFieldLabel = "labels"
// cluster field is 'annotations'
clusterFieldAnnotation = "annotations"
// indicates managing all namespaces
allNamespaces = "*"
)
Expand Down Expand Up @@ -102,6 +107,11 @@ func NewClusterAddCommand(clientOpts *argocdclient.ClientOptions, pathOpts *clie
contextName := args[0]
conf, err := getRestConfig(pathOpts, contextName)
errors.CheckError(err)
if clusterOpts.ProxyUrl != "" {
u, err := argoappv1.ParseProxyUrl(clusterOpts.ProxyUrl)
errors.CheckError(err)
conf.Proxy = http.ProxyURL(u)
}
clientset, err := kubernetes.NewForConfig(conf)
errors.CheckError(err)
managerBearerToken := ""
Expand Down Expand Up @@ -187,6 +197,7 @@ func NewClusterAddCommand(clientOpts *argocdclient.ClientOptions, pathOpts *clie
command.Flags().BoolVarP(&skipConfirmation, "yes", "y", false, "Skip explicit confirmation")
command.Flags().StringArrayVar(&labels, "label", nil, "Set metadata labels (e.g. --label key=value)")
command.Flags().StringArrayVar(&annotations, "annotation", nil, "Set metadata annotations (e.g. --annotation key=value)")
command.Flags().StringVar(&clusterOpts.ProxyUrl, "proxy-url", "", "use proxy to connect cluster")
cmdutil.AddClusterFlags(command, &clusterOpts)
return command
}
Expand Down Expand Up @@ -220,6 +231,8 @@ func NewClusterSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command
var (
clusterOptions cmdutil.ClusterOptions
clusterName string
labels []string
annotations []string
)
command := &cobra.Command{
Use: "set NAME",
Expand All @@ -238,17 +251,25 @@ func NewClusterSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command
conn, clusterIf := headless.NewClientOrDie(clientOpts, c).NewClusterClientOrDie()
defer io.Close(conn)
// checks the fields that needs to be updated
updatedFields := checkFieldsToUpdate(clusterOptions)
updatedFields := checkFieldsToUpdate(clusterOptions, labels, annotations)
namespaces := clusterOptions.Namespaces
// check if all namespaces have to be considered
if len(namespaces) == 1 && strings.EqualFold(namespaces[0], allNamespaces) {
namespaces[0] = ""
}
// parse the labels you're receiving from the label flag
labelsMap, err := label.Parse(labels)
errors.CheckError(err)
// parse the annotations you're receiving from the annotation flag
annotationsMap, err := label.Parse(annotations)
errors.CheckError(err)
if updatedFields != nil {
clusterUpdateRequest := clusterpkg.ClusterUpdateRequest{
Cluster: &argoappv1.Cluster{
Name: clusterOptions.Name,
Namespaces: namespaces,
Name: clusterOptions.Name,
Namespaces: namespaces,
Labels: labelsMap,
Annotations: annotationsMap,
},
UpdatedFields: updatedFields,
Id: &clusterpkg.ClusterID{
Expand All @@ -266,18 +287,26 @@ func NewClusterSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command
}
command.Flags().StringVar(&clusterOptions.Name, "name", "", "Overwrite the cluster name")
command.Flags().StringArrayVar(&clusterOptions.Namespaces, "namespace", nil, "List of namespaces which are allowed to manage. Specify '*' to manage all namespaces")
command.Flags().StringArrayVar(&labels, "label", nil, "Set metadata labels (e.g. --label key=value)")
command.Flags().StringArrayVar(&annotations, "annotation", nil, "Set metadata annotations (e.g. --annotation key=value)")
return command
}

// checkFieldsToUpdate returns the fields that needs to be updated
func checkFieldsToUpdate(clusterOptions cmdutil.ClusterOptions) []string {
func checkFieldsToUpdate(clusterOptions cmdutil.ClusterOptions, labels []string, annotations []string) []string {
var updatedFields []string
if clusterOptions.Name != "" {
updatedFields = append(updatedFields, clusterFieldName)
}
if clusterOptions.Namespaces != nil {
updatedFields = append(updatedFields, clusterFieldNamespaces)
}
if labels != nil {
updatedFields = append(updatedFields, clusterFieldLabel)
}
if annotations != nil {
updatedFields = append(updatedFields, clusterFieldAnnotation)
}
return updatedFields
}

Expand Down Expand Up @@ -341,6 +370,7 @@ func printClusterDetails(clusters []argoappv1.Cluster) {
fmt.Printf("Cluster information\n\n")
fmt.Printf(" Server URL: %s\n", cluster.Server)
fmt.Printf(" Server Name: %s\n", strWithDefault(cluster.Name, "-"))
// nolint:staticcheck
fmt.Printf(" Server Version: %s\n", cluster.ServerVersion)
fmt.Printf(" Namespaces: %s\n", formatNamespaces(cluster))
fmt.Printf("\nTLS configuration\n\n")
Expand All @@ -350,6 +380,8 @@ func printClusterDetails(clusters []argoappv1.Cluster) {
fmt.Printf(" Basic authentication: %v\n", cluster.Config.Username != "")
fmt.Printf(" oAuth authentication: %v\n", cluster.Config.BearerToken != "")
fmt.Printf(" AWS authentication: %v\n", cluster.Config.AWSAuthConfig != nil)
fmt.Printf("\nDisable compression: %v\n", cluster.Config.DisableCompression)
fmt.Printf("\nUse proxy: %v\n", cluster.Config.ProxyUrl != "")
fmt.Println()
}
}
Expand Down Expand Up @@ -433,6 +465,7 @@ func printClusterTable(clusters []argoappv1.Cluster) {
if len(c.Namespaces) > 0 {
server = fmt.Sprintf("%s (%d namespaces)", c.Server, len(c.Namespaces))
}
// nolint:staticcheck
_, _ = fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\n", server, c.Name, c.ServerVersion, c.ConnectionState.Status, c.ConnectionState.Message, c.Project)
}
_ = w.Flush()
Expand Down
12 changes: 11 additions & 1 deletion cmd/util/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,18 @@ func NewCluster(name string, namespaces []string, clusterResources bool, conf *r
TLSClientConfig: tlsClientConfig,
AWSAuthConfig: awsAuthConf,
ExecProviderConfig: execProviderConf,
DisableCompression: conf.DisableCompression,
},
Labels: labels,
Annotations: annotations,
}

// it's a tradeoff to get proxy url from rest config
// more detail: https://github.com/kubernetes/kubernetes/pull/81443
if conf.Proxy != nil {
if url, err := conf.Proxy(nil); err == nil {
clst.Config.ProxyUrl = url.String()
}
}
// Bearer token will preferentially be used for auth if present,
// Even in presence of key/cert credentials
// So set bearer token only if the key/cert data is absent
Expand Down Expand Up @@ -158,6 +165,8 @@ type ClusterOptions struct {
ExecProviderAPIVersion string
ExecProviderInstallHint string
ClusterEndpoint string
DisableCompression bool
ProxyUrl string
}

// InClusterEndpoint returns true if ArgoCD should reference the in-cluster
Expand All @@ -182,4 +191,5 @@ func AddClusterFlags(command *cobra.Command, opts *ClusterOptions) {
command.Flags().StringVar(&opts.ExecProviderAPIVersion, "exec-command-api-version", "", "Preferred input version of the ExecInfo for the --exec-command executable")
command.Flags().StringVar(&opts.ExecProviderInstallHint, "exec-command-install-hint", "", "Text shown to the user when the --exec-command executable doesn't seem to be present")
command.Flags().StringVar(&opts.ClusterEndpoint, "cluster-endpoint", "", "Cluster endpoint to use. Can be one of the following: 'kubeconfig', 'kube-public', or 'internal'.")
command.Flags().BoolVar(&opts.DisableCompression, "disable-compression", false, "Bypasses automatic GZip compression requests to the server")
}
2 changes: 2 additions & 0 deletions docs/operator-manual/declarative-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,8 @@ execProviderConfig:
}
apiVersion: string
installHint: string
# Proxy URL for the kubernetes client to use when connecting to the cluster api server
proxyUrl: string
# Transport layer security configuration settings
tlsClientConfig:
# Base64 encoded PEM-encoded bytes (typically read from a client certificate file).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ argocd admin cluster generate-spec CONTEXT [flags]
--bearer-token string Authentication token that should be used to access K8S API server
--cluster-endpoint string Cluster endpoint to use. Can be one of the following: 'kubeconfig', 'kube-public', or 'internal'.
--cluster-resources Indicates if cluster level resources should be managed. The setting is used only if list of managed namespaces is not empty.
--disable-compression Bypasses automatic GZip compression requests to the server
--exec-command string Command to run to provide client credentials to the cluster. You may need to build a custom ArgoCD image to ensure the command is available at runtime.
--exec-command-api-version string Preferred input version of the ExecInfo for the --exec-command executable
--exec-command-args stringArray Arguments to supply to the --exec-command executable
Expand Down
2 changes: 2 additions & 0 deletions docs/user-guide/commands/argocd_cluster_add.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ argocd cluster add CONTEXT [flags]
--aws-role-arn string Optional AWS role arn. If set then AWS IAM Authenticator assumes a role to perform cluster operations instead of the default AWS credential provider chain.
--cluster-endpoint string Cluster endpoint to use. Can be one of the following: 'kubeconfig', 'kube-public', or 'internal'.
--cluster-resources Indicates if cluster level resources should be managed. The setting is used only if list of managed namespaces is not empty.
--disable-compression Bypasses automatic GZip compression requests to the server
--exec-command string Command to run to provide client credentials to the cluster. You may need to build a custom ArgoCD image to ensure the command is available at runtime.
--exec-command-api-version string Preferred input version of the ExecInfo for the --exec-command executable
--exec-command-args stringArray Arguments to supply to the --exec-command executable
Expand All @@ -29,6 +30,7 @@ argocd cluster add CONTEXT [flags]
--name string Overwrite the cluster name
--namespace stringArray List of namespaces which are allowed to manage
--project string project of the cluster
--proxy-url string use proxy to connect cluster
--service-account string System namespace service account to use for kubernetes resource management. If not set then default "argocd-manager" SA will be created
--shard int Cluster shard number; inferred from hostname if not set (default -1)
--system-namespace string Use different system namespace (default "kube-system")
Expand Down
8 changes: 5 additions & 3 deletions docs/user-guide/commands/argocd_cluster_set.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ argocd cluster set NAME [flags]
### Options

```
-h, --help help for set
--name string Overwrite the cluster name
--namespace stringArray List of namespaces which are allowed to manage. Specify '*' to manage all namespaces
--annotation stringArray Set metadata annotations (e.g. --annotation key=value)
-h, --help help for set
--label stringArray Set metadata labels (e.g. --label key=value)
--name string Overwrite the cluster name
--namespace stringArray List of namespaces which are allowed to manage. Specify '*' to manage all namespaces
```

### Options inherited from parent commands
Expand Down
Loading

0 comments on commit ae9bb96

Please sign in to comment.