Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: manage clusters via proxy #342

Merged
merged 1 commit into from
Oct 16, 2024
Merged
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
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
Loading