From 74592962a9375dfe7efe822079bb5cd055320f77 Mon Sep 17 00:00:00 2001 From: divolgin Date: Wed, 29 Jul 2020 01:01:55 +0000 Subject: [PATCH] Set proxy env variables in kotsadm API --- cmd/kots/cli/install.go | 22 +++ cmd/kots/cli/pull.go | 22 +++ pkg/kotsadm/api_objects.go | 217 +++++++++++++++-------------- pkg/kotsadm/kotsadm_objects.go | 1 + pkg/kotsadm/proxy.go | 34 +++++ pkg/kotsadm/types/deployoptions.go | 3 + pkg/pull/pull.go | 6 + pkg/upstream/admin-console.go | 23 ++- pkg/upstream/types/types.go | 3 + pkg/upstream/write.go | 2 +- 10 files changed, 223 insertions(+), 110 deletions(-) create mode 100644 pkg/kotsadm/proxy.go diff --git a/cmd/kots/cli/install.go b/cmd/kots/cli/install.go index dc3c6a34e7..2c21663b56 100644 --- a/cmd/kots/cli/install.go +++ b/cmd/kots/cli/install.go @@ -124,6 +124,9 @@ func InstallCmd() *cobra.Command { IncludeMinio: v.GetBool("deploy-minio"), IncludeDockerDistribution: v.GetBool("deploy-dockerdistribution"), Timeout: time.Minute * 2, + HTTPProxyEnvValue: v.GetString("http-proxy"), + HTTPSProxyEnvValue: v.GetString("https-proxy"), + NoProxyEnvValue: v.GetString("no-proxy"), KotsadmOptions: kotsadmtypes.KotsadmOptions{ OverrideVersion: v.GetString("kotsadm-tag"), @@ -141,6 +144,21 @@ func InstallCmd() *cobra.Command { deployOptions.Timeout = timeout + if v.GetBool("copy-proxy-env") { + deployOptions.HTTPProxyEnvValue = os.Getenv("HTTP_PROXY") + if deployOptions.HTTPProxyEnvValue == "" { + deployOptions.HTTPProxyEnvValue = os.Getenv("http_proxy") + } + deployOptions.HTTPSProxyEnvValue = os.Getenv("HTTPS_PROXY") + if deployOptions.HTTPSProxyEnvValue == "" { + deployOptions.HTTPSProxyEnvValue = os.Getenv("https_proxy") + } + deployOptions.NoProxyEnvValue = os.Getenv("NO_PROXY") + if deployOptions.NoProxyEnvValue == "" { + deployOptions.NoProxyEnvValue = os.Getenv("no_proxy") + } + } + log.ActionWithoutSpinner("Deploying Admin Console") if err := kotsadm.Deploy(deployOptions); err != nil { if _, ok := errors.Cause(err).(*types.ErrorTimeout); ok { @@ -222,6 +240,10 @@ func InstallCmd() *cobra.Command { cmd.Flags().String("config-values", "", "path to a manifest containing config values (must be apiVersion: kots.io/v1beta1, kind: ConfigValues)") cmd.Flags().Bool("port-forward", true, "set to false to disable automatic port forward") cmd.Flags().String("wait-duration", "2m", "timeout out to be used while waiting for individual components to be ready. must be in Go duration format (eg: 10s, 2m)") + cmd.Flags().String("http-proxy", "", "sets HTTP_PROXY environment variable in all KOTS Admin Console components") + cmd.Flags().String("https-proxy", "", "sets HTTPS_PROXY environment variable in all KOTS Admin Console components") + cmd.Flags().String("no-proxy", "", "sets NO_PROXY environment variable in all KOTS Admin Console components") + cmd.Flags().Bool("copy-proxy-env", false, "copy proxy environment variables from current environment into all KOTS Admin Console components") cmd.Flags().String("repo", "", "repo uri to use when installing a helm chart") cmd.Flags().StringSlice("set", []string{}, "values to pass to helm when running helm template") diff --git a/cmd/kots/cli/pull.go b/cmd/kots/cli/pull.go index 4f2764655a..b8832c6e83 100644 --- a/cmd/kots/cli/pull.go +++ b/cmd/kots/cli/pull.go @@ -52,6 +52,24 @@ func PullCmd() *cobra.Command { Username: v.GetString("registry-username"), Password: v.GetString("registry-password"), }, + HTTPProxyEnvValue: v.GetString("http-proxy"), + HTTPSProxyEnvValue: v.GetString("https-proxy"), + NoProxyEnvValue: v.GetString("no-proxy"), + } + + if v.GetBool("copy-proxy-env") { + pullOptions.HTTPProxyEnvValue = os.Getenv("HTTP_PROXY") + if pullOptions.HTTPProxyEnvValue == "" { + pullOptions.HTTPProxyEnvValue = os.Getenv("http_proxy") + } + pullOptions.HTTPSProxyEnvValue = os.Getenv("HTTPS_PROXY") + if pullOptions.HTTPSProxyEnvValue == "" { + pullOptions.HTTPSProxyEnvValue = os.Getenv("https_proxy") + } + pullOptions.NoProxyEnvValue = os.Getenv("NO_PROXY") + if pullOptions.NoProxyEnvValue == "" { + pullOptions.NoProxyEnvValue = os.Getenv("no_proxy") + } } upstream := pull.RewriteUpstream(args[0]) @@ -86,6 +104,10 @@ func PullCmd() *cobra.Command { cmd.Flags().Bool("exclude-kots-kinds", true, "set to true to exclude rendering kots custom objects to the base directory") cmd.Flags().Bool("exclude-admin-console", false, "set to true to exclude the admin console (replicated apps only)") cmd.Flags().String("shared-password", "", "shared password to use when deploying the admin console") + cmd.Flags().String("http-proxy", "", "sets HTTP_PROXY environment variable in all KOTS Admin Console components") + cmd.Flags().String("https-proxy", "", "sets HTTPS_PROXY environment variable in all KOTS Admin Console components") + cmd.Flags().String("no-proxy", "", "sets NO_PROXY environment variable in all KOTS Admin Console components") + cmd.Flags().Bool("copy-proxy-env", false, "copy proxy environment variables from current environment into all KOTS Admin Console components") cmd.Flags().Bool("rewrite-images", false, "set to true to force all container images to be rewritten and pushed to a local registry") cmd.Flags().String("image-namespace", "", "the namespace/org in the docker registry to push images to (required when --rewrite-images is set)") cmd.Flags().String("registry-endpoint", "", "the endpoint of the local docker registry to use when pushing images (required when --rewrite-images is set)") diff --git a/pkg/kotsadm/api_objects.go b/pkg/kotsadm/api_objects.go index e98ab3556f..78f1328a20 100644 --- a/pkg/kotsadm/api_objects.go +++ b/pkg/kotsadm/api_objects.go @@ -226,6 +226,115 @@ func apiDeployment(deployOptions types.DeployOptions) *appsv1.Deployment { } } + env := []corev1.EnvVar{ + { + Name: "SHARED_PASSWORD_BCRYPT", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "kotsadm-password", + }, + Key: "passwordBcrypt", + }, + }, + }, + { + Name: "AUTO_CREATE_CLUSTER_TOKEN", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: types.ClusterTokenSecret, + }, + Key: types.ClusterTokenSecret, + }, + }, + }, + { + Name: "SHIP_API_ENDPOINT", + Value: fmt.Sprintf("http://kotsadm.%s.svc.cluster.local:3000", deployOptions.Namespace), + }, + { + Name: "SHIP_API_ADVERTISE_ENDPOINT", + Value: "http://localhost:8800", + }, + { + Name: "S3_ENDPOINT", + Value: "http://kotsadm-minio:9000", + }, + { + Name: "S3_BUCKET_NAME", + Value: "kotsadm", + }, + { + Name: "API_ENCRYPTION_KEY", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "kotsadm-encryption", + }, + Key: "encryptionKey", + }, + }, + }, + { + Name: "S3_ACCESS_KEY_ID", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "kotsadm-minio", + }, + Key: "accesskey", + }, + }, + }, + { + Name: "S3_SECRET_ACCESS_KEY", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "kotsadm-minio", + }, + Key: "secretkey", + }, + }, + }, + { + Name: "S3_BUCKET_ENDPOINT", + Value: "true", + }, + { + Name: "SESSION_KEY", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "kotsadm-session", + }, + Key: "key", + }, + }, + }, + { + Name: "POSTGRES_URI", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "kotsadm-postgres", + }, + Key: "uri", + }, + }, + }, + { + Name: "POD_NAMESPACE", + ValueFrom: &corev1.EnvVarSource{ + FieldRef: &corev1.ObjectFieldSelector{ + FieldPath: "metadata.namespace", + }, + }, + }, + } + env = append(env, getProxyEnv(deployOptions)...) + deployment := &appsv1.Deployment{ TypeMeta: metav1.TypeMeta{ APIVersion: "apps/v1", @@ -276,113 +385,7 @@ func apiDeployment(deployOptions types.DeployOptions) *appsv1.Deployment { }, }, }, - Env: []corev1.EnvVar{ - { - Name: "SHARED_PASSWORD_BCRYPT", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "kotsadm-password", - }, - Key: "passwordBcrypt", - }, - }, - }, - { - Name: "AUTO_CREATE_CLUSTER_TOKEN", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: types.ClusterTokenSecret, - }, - Key: types.ClusterTokenSecret, - }, - }, - }, - { - Name: "SHIP_API_ENDPOINT", - Value: fmt.Sprintf("http://kotsadm.%s.svc.cluster.local:3000", deployOptions.Namespace), - }, - { - Name: "SHIP_API_ADVERTISE_ENDPOINT", - Value: "http://localhost:8800", - }, - { - Name: "S3_ENDPOINT", - Value: "http://kotsadm-minio:9000", - }, - { - Name: "S3_BUCKET_NAME", - Value: "kotsadm", - }, - { - Name: "API_ENCRYPTION_KEY", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "kotsadm-encryption", - }, - Key: "encryptionKey", - }, - }, - }, - { - Name: "S3_ACCESS_KEY_ID", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "kotsadm-minio", - }, - Key: "accesskey", - }, - }, - }, - { - Name: "S3_SECRET_ACCESS_KEY", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "kotsadm-minio", - }, - Key: "secretkey", - }, - }, - }, - { - Name: "S3_BUCKET_ENDPOINT", - Value: "true", - }, - { - Name: "SESSION_KEY", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "kotsadm-session", - }, - Key: "key", - }, - }, - }, - { - Name: "POSTGRES_URI", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "kotsadm-postgres", - }, - Key: "uri", - }, - }, - }, - { - Name: "POD_NAMESPACE", - ValueFrom: &corev1.EnvVarSource{ - FieldRef: &corev1.ObjectFieldSelector{ - FieldPath: "metadata.namespace", - }, - }, - }, - }, + Env: env, }, }, }, diff --git a/pkg/kotsadm/kotsadm_objects.go b/pkg/kotsadm/kotsadm_objects.go index c44b537d0a..4d55b1ecb5 100644 --- a/pkg/kotsadm/kotsadm_objects.go +++ b/pkg/kotsadm/kotsadm_objects.go @@ -317,6 +317,7 @@ func kotsadmDeployment(deployOptions types.DeployOptions) *appsv1.Deployment { Value: "http://localhost:8800", }, } + env = append(env, getProxyEnv(deployOptions)...) if deployOptions.KotsadmOptions.OverrideRegistry != "" { env = append(env, corev1.EnvVar{ diff --git a/pkg/kotsadm/proxy.go b/pkg/kotsadm/proxy.go new file mode 100644 index 0000000000..7c78efc55e --- /dev/null +++ b/pkg/kotsadm/proxy.go @@ -0,0 +1,34 @@ +package kotsadm + +import ( + "github.com/replicatedhq/kots/pkg/kotsadm/types" + corev1 "k8s.io/api/core/v1" +) + +func getProxyEnv(deployOptions types.DeployOptions) []corev1.EnvVar { + result := []corev1.EnvVar{ + { + Name: "HTTP_PROXY", + Value: deployOptions.HTTPProxyEnvValue, + }, + { + Name: "HTTPS_PROXY", + Value: deployOptions.HTTPSProxyEnvValue, + }, + } + + kotsadmNoProxy := "kotsadm-postgres,kotsadm-minio,kotsadm-api-node" + if deployOptions.NoProxyEnvValue == "" { + result = append(result, corev1.EnvVar{ + Name: "NO_PROXY", + Value: kotsadmNoProxy, + }) + } else { + result = append(result, corev1.EnvVar{ + Name: "NO_PROXY", + Value: deployOptions.NoProxyEnvValue + "," + kotsadmNoProxy, + }) + } + + return result +} diff --git a/pkg/kotsadm/types/deployoptions.go b/pkg/kotsadm/types/deployoptions.go index 44e30b8e4a..9638ec0ee8 100644 --- a/pkg/kotsadm/types/deployoptions.go +++ b/pkg/kotsadm/types/deployoptions.go @@ -32,6 +32,9 @@ type DeployOptions struct { IncludeMinio bool IncludeDockerDistribution bool Timeout time.Duration + HTTPProxyEnvValue string + HTTPSProxyEnvValue string + NoProxyEnvValue string KotsadmOptions KotsadmOptions } diff --git a/pkg/pull/pull.go b/pkg/pull/pull.go index 4715ed2b18..7a42370de9 100644 --- a/pkg/pull/pull.go +++ b/pkg/pull/pull.go @@ -49,6 +49,9 @@ type PullOptions struct { AppSlug string AppSequence int64 IsGitOps bool + HTTPProxyEnvValue string + HTTPSProxyEnvValue string + NoProxyEnvValue string } type RewriteImageOptions struct { @@ -209,6 +212,9 @@ func Pull(upstreamURI string, pullOptions PullOptions) (string, error) { IncludeAdminConsole: includeAdminConsole, SharedPassword: pullOptions.SharedPassword, EncryptConfig: encryptConfig, + HTTPProxyEnvValue: pullOptions.HTTPProxyEnvValue, + HTTPSProxyEnvValue: pullOptions.HTTPSProxyEnvValue, + NoProxyEnvValue: pullOptions.NoProxyEnvValue, } if err := upstream.WriteUpstream(u, writeUpstreamOptions); err != nil { log.FinishSpinnerWithError() diff --git a/pkg/upstream/admin-console.go b/pkg/upstream/admin-console.go index 93646a2655..52a84ac82a 100644 --- a/pkg/upstream/admin-console.go +++ b/pkg/upstream/admin-console.go @@ -24,15 +24,21 @@ type UpstreamSettings struct { JWT string PostgresPassword string APIEncryptionKey string + HTTPProxyEnvValue string + HTTPSProxyEnvValue string + NoProxyEnvValue string AutoCreateClusterToken string } -func generateAdminConsoleFiles(renderDir string, sharedPassword string) ([]types.UpstreamFile, error) { +func generateAdminConsoleFiles(renderDir string, options types.WriteOptions) ([]types.UpstreamFile, error) { if _, err := os.Stat(path.Join(renderDir, "admin-console")); os.IsNotExist(err) { settings := &UpstreamSettings{ - SharedPassword: sharedPassword, + SharedPassword: options.SharedPassword, AutoCreateClusterToken: uuid.New().String(), + HTTPProxyEnvValue: options.HTTPProxyEnvValue, + HTTPSProxyEnvValue: options.HTTPSProxyEnvValue, + NoProxyEnvValue: options.NoProxyEnvValue, } return generateNewAdminConsoleFiles(settings) } @@ -49,6 +55,16 @@ func generateAdminConsoleFiles(renderDir string, sharedPassword string) ([]types return nil, errors.Wrap(err, "failed to find existing settings") } + if options.HTTPProxyEnvValue != "" { + settings.HTTPProxyEnvValue = options.HTTPProxyEnvValue + } + if options.HTTPSProxyEnvValue != "" { + settings.HTTPSProxyEnvValue = options.HTTPSProxyEnvValue + } + if options.NoProxyEnvValue != "" { + settings.NoProxyEnvValue = options.NoProxyEnvValue + } + return generateNewAdminConsoleFiles(settings) } @@ -115,6 +131,9 @@ func generateNewAdminConsoleFiles(settings *UpstreamSettings) ([]types.UpstreamF PostgresPassword: settings.PostgresPassword, APIEncryptionKey: settings.APIEncryptionKey, AutoCreateClusterToken: settings.AutoCreateClusterToken, + HTTPProxyEnvValue: settings.HTTPProxyEnvValue, + HTTPSProxyEnvValue: settings.HTTPSProxyEnvValue, + NoProxyEnvValue: settings.NoProxyEnvValue, } if deployOptions.SharedPasswordBcrypt == "" && deployOptions.SharedPassword == "" { diff --git a/pkg/upstream/types/types.go b/pkg/upstream/types/types.go index 051bd93bc3..a187498da0 100644 --- a/pkg/upstream/types/types.go +++ b/pkg/upstream/types/types.go @@ -32,6 +32,9 @@ type WriteOptions struct { RootDir string CreateAppDir bool IncludeAdminConsole bool + HTTPProxyEnvValue string + HTTPSProxyEnvValue string + NoProxyEnvValue string // This should be set to true when updating due to license sync, config update, registry settings update. // and should be false when it's an upstream update. // When true, the channel name in Installation yaml will not be changed. diff --git a/pkg/upstream/write.go b/pkg/upstream/write.go index 2c9cc0c334..db4ac20510 100644 --- a/pkg/upstream/write.go +++ b/pkg/upstream/write.go @@ -26,7 +26,7 @@ func WriteUpstream(u *types.Upstream, options types.WriteOptions) error { renderDir = path.Join(renderDir, "upstream") if options.IncludeAdminConsole { - adminConsoleFiles, err := generateAdminConsoleFiles(renderDir, options.SharedPassword) + adminConsoleFiles, err := generateAdminConsoleFiles(renderDir, options) if err != nil { return errors.Wrap(err, "failed to generate admin console") }