From c461d624b4c02452e85821361bb1c4c2d2e487b7 Mon Sep 17 00:00:00 2001 From: ryota-sakamoto Date: Fri, 4 Jun 2021 16:01:42 +0900 Subject: [PATCH] feat: support plaintext connection to repo-server (#296) Signed-off-by: Ryota Sakamoto --- cmd/controller.go | 26 +-- cmd/tools/tools.go | 8 +- docs/troubleshooting-commands.md | 168 +++++++++--------- ...d-notifications-controller-deployment.yaml | 13 ++ manifests/install-bot.yaml | 13 ++ manifests/install.yaml | 13 ++ shared/argocd/service.go | 23 ++- 7 files changed, 169 insertions(+), 95 deletions(-) diff --git a/cmd/controller.go b/cmd/controller.go index b3c44267..98cffa80 100644 --- a/cmd/controller.go +++ b/cmd/controller.go @@ -28,16 +28,18 @@ const ( func newControllerCommand() *cobra.Command { var ( - clientConfig clientcmd.ClientConfig - processorsCount int - namespace string - appLabelSelector string - logLevel string - logFormat string - metricsPort int - argocdRepoServer string - configMapName string - secretName string + clientConfig clientcmd.ClientConfig + processorsCount int + namespace string + appLabelSelector string + logLevel string + logFormat string + metricsPort int + argocdRepoServer string + argocdRepoServerPlaintext bool + argocdRepoServerStrictTLS bool + configMapName string + secretName string ) var command = cobra.Command{ Use: "controller", @@ -78,7 +80,7 @@ func newControllerCommand() *cobra.Command { return fmt.Errorf("Unknown log format '%s'", logFormat) } - argocdService, err := argocd.NewArgoCDService(k8sClient, namespace, argocdRepoServer) + argocdService, err := argocd.NewArgoCDService(k8sClient, namespace, argocdRepoServer, argocdRepoServerPlaintext, argocdRepoServerStrictTLS) if err != nil { return err } @@ -115,6 +117,8 @@ func newControllerCommand() *cobra.Command { command.Flags().StringVar(&logFormat, "logformat", "text", "Set the logging format. One of: text|json") command.Flags().IntVar(&metricsPort, "metrics-port", defaultMetricsPort, "Metrics port") command.Flags().StringVar(&argocdRepoServer, "argocd-repo-server", "argocd-repo-server:8081", "Argo CD repo server address") + command.Flags().BoolVar(&argocdRepoServerPlaintext, "argocd-repo-server-plaintext", false, "Use a plaintext client (non-TLS) to connect to repository server") + command.Flags().BoolVar(&argocdRepoServerStrictTLS, "argocd-repo-server-strict-tls", false, "Perform strict validation of TLS certificates when connecting to repo server") command.Flags().StringVar(&configMapName, "config-map-name", "argocd-notifications-cm", "Set notifications ConfigMap name") command.Flags().StringVar(&secretName, "secret-name", "argocd-notifications-secret", "Set notifications Secret name") return &command diff --git a/cmd/tools/tools.go b/cmd/tools/tools.go index bcf2b0a8..4f9f8cb4 100644 --- a/cmd/tools/tools.go +++ b/cmd/tools/tools.go @@ -15,7 +15,9 @@ import ( func NewToolsCommand() *cobra.Command { var ( - argocdRepoServer string + argocdRepoServer string + argocdRepoServerPlaintext bool + argocdRepoServerStrictTLS bool ) var argocdService argocd.Service @@ -32,11 +34,13 @@ func NewToolsCommand() *cobra.Command { if err != nil { log.Fatalf("Failed to parse k8s config: %v", err) } - argocdService, err = argocd.NewArgoCDService(kubernetes.NewForConfigOrDie(k8sCfg), ns, argocdRepoServer) + argocdService, err = argocd.NewArgoCDService(kubernetes.NewForConfigOrDie(k8sCfg), ns, argocdRepoServer, argocdRepoServerPlaintext, argocdRepoServerStrictTLS) if err != nil { log.Fatalf("Failed to initalize Argo CD service: %v", err) } }) toolsCommand.PersistentFlags().StringVar(&argocdRepoServer, "argocd-repo-server", "argocd-repo-server:8081", "Argo CD repo server address") + toolsCommand.PersistentFlags().BoolVar(&argocdRepoServerPlaintext, "argocd-repo-server-plaintext", false, "Use a plaintext client (non-TLS) to connect to repository server") + toolsCommand.PersistentFlags().BoolVar(&argocdRepoServerStrictTLS, "argocd-repo-server-strict-tls", false, "Perform strict validation of TLS certificates when connecting to repo server") return toolsCommand } diff --git a/docs/troubleshooting-commands.md b/docs/troubleshooting-commands.md index 3bfcca0d..42b89c7e 100644 --- a/docs/troubleshooting-commands.md +++ b/docs/troubleshooting-commands.md @@ -27,26 +27,28 @@ argocd-notifications template get app-sync-succeeded -o=yaml ### Options inherited from parent commands ``` - --argocd-repo-server string Argo CD repo server address (default "argocd-repo-server:8081") - --as string Username to impersonate for the operation - --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. - --certificate-authority string Path to a cert file for the certificate authority - --client-certificate string Path to a client certificate file for TLS - --client-key string Path to a client key file for TLS - --cluster string The name of the kubeconfig cluster to use - --config-map string argocd-notifications-cm.yaml file path - --context string The name of the kubeconfig context to use - --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure - --kubeconfig string Path to a kube config. Only required if out-of-cluster - -n, --namespace string If present, the namespace scope for this CLI request - --password string Password for basic authentication to the API server - --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") - --secret string argocd-notifications-secret.yaml file path. Use empty secret if provided value is ':empty' - --server string The address and port of the Kubernetes API server - --tls-server-name string If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used. - --token string Bearer token for authentication to the API server - --user string The name of the kubeconfig user to use - --username string Username for basic authentication to the API server + --argocd-repo-server string Argo CD repo server address (default "argocd-repo-server:8081") + --argocd-repo-server-plaintext Use a plaintext client (non-TLS) to connect to repository server + --argocd-repo-server-strict-tls Perform strict validation of TLS certificates when connecting to repo server + --as string Username to impersonate for the operation + --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --certificate-authority string Path to a cert file for the certificate authority + --client-certificate string Path to a client certificate file for TLS + --client-key string Path to a client key file for TLS + --cluster string The name of the kubeconfig cluster to use + --config-map string argocd-notifications-cm.yaml file path + --context string The name of the kubeconfig context to use + --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kubeconfig string Path to a kube config. Only required if out-of-cluster + -n, --namespace string If present, the namespace scope for this CLI request + --password string Password for basic authentication to the API server + --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") + --secret string argocd-notifications-secret.yaml file path. Use empty secret if provided value is ':empty' + --server string The address and port of the Kubernetes API server + --tls-server-name string If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used. + --token string Bearer token for authentication to the API server + --user string The name of the kubeconfig user to use + --username string Username for basic authentication to the API server ``` ## argocd-notifications template notify @@ -79,26 +81,28 @@ argocd-notifications template notify app-sync-succeeded guestbook ### Options inherited from parent commands ``` - --argocd-repo-server string Argo CD repo server address (default "argocd-repo-server:8081") - --as string Username to impersonate for the operation - --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. - --certificate-authority string Path to a cert file for the certificate authority - --client-certificate string Path to a client certificate file for TLS - --client-key string Path to a client key file for TLS - --cluster string The name of the kubeconfig cluster to use - --config-map string argocd-notifications-cm.yaml file path - --context string The name of the kubeconfig context to use - --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure - --kubeconfig string Path to a kube config. Only required if out-of-cluster - -n, --namespace string If present, the namespace scope for this CLI request - --password string Password for basic authentication to the API server - --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") - --secret string argocd-notifications-secret.yaml file path. Use empty secret if provided value is ':empty' - --server string The address and port of the Kubernetes API server - --tls-server-name string If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used. - --token string Bearer token for authentication to the API server - --user string The name of the kubeconfig user to use - --username string Username for basic authentication to the API server + --argocd-repo-server string Argo CD repo server address (default "argocd-repo-server:8081") + --argocd-repo-server-plaintext Use a plaintext client (non-TLS) to connect to repository server + --argocd-repo-server-strict-tls Perform strict validation of TLS certificates when connecting to repo server + --as string Username to impersonate for the operation + --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --certificate-authority string Path to a cert file for the certificate authority + --client-certificate string Path to a client certificate file for TLS + --client-key string Path to a client key file for TLS + --cluster string The name of the kubeconfig cluster to use + --config-map string argocd-notifications-cm.yaml file path + --context string The name of the kubeconfig context to use + --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kubeconfig string Path to a kube config. Only required if out-of-cluster + -n, --namespace string If present, the namespace scope for this CLI request + --password string Password for basic authentication to the API server + --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") + --secret string argocd-notifications-secret.yaml file path. Use empty secret if provided value is ':empty' + --server string The address and port of the Kubernetes API server + --tls-server-name string If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used. + --token string Bearer token for authentication to the API server + --user string The name of the kubeconfig user to use + --username string Username for basic authentication to the API server ``` ## argocd-notifications trigger get @@ -130,26 +134,28 @@ argocd-notifications trigger get on-sync-failed -o=yaml ### Options inherited from parent commands ``` - --argocd-repo-server string Argo CD repo server address (default "argocd-repo-server:8081") - --as string Username to impersonate for the operation - --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. - --certificate-authority string Path to a cert file for the certificate authority - --client-certificate string Path to a client certificate file for TLS - --client-key string Path to a client key file for TLS - --cluster string The name of the kubeconfig cluster to use - --config-map string argocd-notifications-cm.yaml file path - --context string The name of the kubeconfig context to use - --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure - --kubeconfig string Path to a kube config. Only required if out-of-cluster - -n, --namespace string If present, the namespace scope for this CLI request - --password string Password for basic authentication to the API server - --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") - --secret string argocd-notifications-secret.yaml file path. Use empty secret if provided value is ':empty' - --server string The address and port of the Kubernetes API server - --tls-server-name string If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used. - --token string Bearer token for authentication to the API server - --user string The name of the kubeconfig user to use - --username string Username for basic authentication to the API server + --argocd-repo-server string Argo CD repo server address (default "argocd-repo-server:8081") + --argocd-repo-server-plaintext Use a plaintext client (non-TLS) to connect to repository server + --argocd-repo-server-strict-tls Perform strict validation of TLS certificates when connecting to repo server + --as string Username to impersonate for the operation + --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --certificate-authority string Path to a cert file for the certificate authority + --client-certificate string Path to a client certificate file for TLS + --client-key string Path to a client key file for TLS + --cluster string The name of the kubeconfig cluster to use + --config-map string argocd-notifications-cm.yaml file path + --context string The name of the kubeconfig context to use + --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kubeconfig string Path to a kube config. Only required if out-of-cluster + -n, --namespace string If present, the namespace scope for this CLI request + --password string Password for basic authentication to the API server + --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") + --secret string argocd-notifications-secret.yaml file path. Use empty secret if provided value is ':empty' + --server string The address and port of the Kubernetes API server + --tls-server-name string If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used. + --token string Bearer token for authentication to the API server + --user string The name of the kubeconfig user to use + --username string Username for basic authentication to the API server ``` ## argocd-notifications trigger run @@ -181,25 +187,27 @@ argocd-notifications trigger run on-sync-status-unknown ./sample-app.yaml \ ### Options inherited from parent commands ``` - --argocd-repo-server string Argo CD repo server address (default "argocd-repo-server:8081") - --as string Username to impersonate for the operation - --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. - --certificate-authority string Path to a cert file for the certificate authority - --client-certificate string Path to a client certificate file for TLS - --client-key string Path to a client key file for TLS - --cluster string The name of the kubeconfig cluster to use - --config-map string argocd-notifications-cm.yaml file path - --context string The name of the kubeconfig context to use - --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure - --kubeconfig string Path to a kube config. Only required if out-of-cluster - -n, --namespace string If present, the namespace scope for this CLI request - --password string Password for basic authentication to the API server - --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") - --secret string argocd-notifications-secret.yaml file path. Use empty secret if provided value is ':empty' - --server string The address and port of the Kubernetes API server - --tls-server-name string If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used. - --token string Bearer token for authentication to the API server - --user string The name of the kubeconfig user to use - --username string Username for basic authentication to the API server + --argocd-repo-server string Argo CD repo server address (default "argocd-repo-server:8081") + --argocd-repo-server-plaintext Use a plaintext client (non-TLS) to connect to repository server + --argocd-repo-server-strict-tls Perform strict validation of TLS certificates when connecting to repo server + --as string Username to impersonate for the operation + --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --certificate-authority string Path to a cert file for the certificate authority + --client-certificate string Path to a client certificate file for TLS + --client-key string Path to a client key file for TLS + --cluster string The name of the kubeconfig cluster to use + --config-map string argocd-notifications-cm.yaml file path + --context string The name of the kubeconfig context to use + --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kubeconfig string Path to a kube config. Only required if out-of-cluster + -n, --namespace string If present, the namespace scope for this CLI request + --password string Password for basic authentication to the API server + --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") + --secret string argocd-notifications-secret.yaml file path. Use empty secret if provided value is ':empty' + --server string The address and port of the Kubernetes API server + --tls-server-name string If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used. + --token string Bearer token for authentication to the API server + --user string The name of the kubeconfig user to use + --username string Username for basic authentication to the API server ``` diff --git a/manifests/controller/argocd-notifications-controller-deployment.yaml b/manifests/controller/argocd-notifications-controller-deployment.yaml index 43973644..eacbea18 100644 --- a/manifests/controller/argocd-notifications-controller-deployment.yaml +++ b/manifests/controller/argocd-notifications-controller-deployment.yaml @@ -17,6 +17,17 @@ spec: - name: tls-certs configMap: name: argocd-tls-certs-cm + - name: argocd-repo-server-tls + secret: + secretName: argocd-repo-server-tls + optional: true + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt containers: - command: - /app/argocd-notifications-backend @@ -31,6 +42,8 @@ spec: volumeMounts: - name: tls-certs mountPath: /app/config/tls + - name: argocd-repo-server-tls + mountPath: /app/config/reposerver/tls serviceAccountName: argocd-notifications-controller securityContext: runAsNonRoot: true diff --git a/manifests/install-bot.yaml b/manifests/install-bot.yaml index 9eecab97..2d933591 100644 --- a/manifests/install-bot.yaml +++ b/manifests/install-bot.yaml @@ -191,6 +191,8 @@ spec: volumeMounts: - mountPath: /app/config/tls name: tls-certs + - mountPath: /app/config/reposerver/tls + name: argocd-repo-server-tls workingDir: /app securityContext: runAsNonRoot: true @@ -199,3 +201,14 @@ spec: - configMap: name: argocd-tls-certs-cm name: tls-certs + - name: argocd-repo-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-repo-server-tls diff --git a/manifests/install.yaml b/manifests/install.yaml index 3be45eb2..c8553a5a 100644 --- a/manifests/install.yaml +++ b/manifests/install.yaml @@ -111,6 +111,8 @@ spec: volumeMounts: - mountPath: /app/config/tls name: tls-certs + - mountPath: /app/config/reposerver/tls + name: argocd-repo-server-tls workingDir: /app securityContext: runAsNonRoot: true @@ -119,3 +121,14 @@ spec: - configMap: name: argocd-tls-certs-cm name: tls-certs + - name: argocd-repo-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-repo-server-tls diff --git a/shared/argocd/service.go b/shared/argocd/service.go index 6ae3bdab..cbc1c670 100644 --- a/shared/argocd/service.go +++ b/shared/argocd/service.go @@ -2,12 +2,16 @@ package argocd import ( "context" + "fmt" "github.com/argoproj-labs/argocd-notifications/expr/shared" + "github.com/argoproj/argo-cd/v2/common" "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" "github.com/argoproj/argo-cd/v2/reposerver/apiclient" "github.com/argoproj/argo-cd/v2/util/db" + "github.com/argoproj/argo-cd/v2/util/env" "github.com/argoproj/argo-cd/v2/util/settings" + "github.com/argoproj/argo-cd/v2/util/tls" log "github.com/sirupsen/logrus" "k8s.io/client-go/kubernetes" ) @@ -19,10 +23,25 @@ type Service interface { GetAppDetails(ctx context.Context, appSource *v1alpha1.ApplicationSource) (*shared.AppDetail, error) } -func NewArgoCDService(clientset kubernetes.Interface, namespace string, repoServerAddress string) (*argoCDService, error) { +func NewArgoCDService(clientset kubernetes.Interface, namespace string, repoServerAddress string, disableTLS bool, strictValidation bool) (*argoCDService, error) { ctx, cancel := context.WithCancel(context.Background()) settingsMgr := settings.NewSettingsManager(ctx, clientset, namespace) - repoClientset := apiclient.NewRepoServerClientset(repoServerAddress, 5, apiclient.TLSConfiguration{}) + tlsConfig := apiclient.TLSConfiguration{ + DisableTLS: disableTLS, + StrictValidation: strictValidation, + } + if !disableTLS && strictValidation { + pool, err := tls.LoadX509CertPool( + fmt.Sprintf("%s/reposerver/tls/tls.crt", env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath)), + fmt.Sprintf("%s/reposerver/tls/ca.crt", env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath)), + ) + if err != nil { + cancel() + return nil, err + } + tlsConfig.Certificates = pool + } + repoClientset := apiclient.NewRepoServerClientset(repoServerAddress, 5, tlsConfig) closer, repoClient, err := repoClientset.NewRepoServerClient() if err != nil { cancel()