diff --git a/cmd/root/root.go b/cmd/root/root.go index 980478165..31f13ef38 100644 --- a/cmd/root/root.go +++ b/cmd/root/root.go @@ -9,6 +9,7 @@ import ( "os" "os/exec" "runtime" + "slices" "strings" "time" @@ -138,6 +139,31 @@ func Execute(ctx context.Context, cmd *cobra.Command) error { return err } +func inheritEnvVars() []string { + base := os.Environ() + out := []string{} + authEnvVars := auth.EnvVars() + + // Remove any existing auth environment variables. This is important because + // the CLI offers multiple levels of configuring authentication like `--profile` + // or `DATABRICKS_CONFIG_PROFILE` or `profile: ` in the bundle config file. + // + // Each of these have different priorities and thus we don't want any auth configuration + // to piggyback into the child process environment. + for _, v := range base { + k, _, found := strings.Cut(v, "=") + if !found { + continue + } + if slices.Contains(authEnvVars, k) { + continue + } + out = append(out, v) + } + + return out +} + func uploadTelemetry(ctx context.Context, cmdStr string, start, end time.Time, exitCode int) { // Nothing to upload. if !telemetry.HasLogs(ctx) { @@ -165,7 +191,7 @@ func uploadTelemetry(ctx context.Context, cmdStr string, start, end time.Time, e log.Debugf(ctx, "failed to get executable path: %s", err) } telemetryCmd := exec.Command(execPath, "telemetry", "upload") - telemetryCmd.Env = os.Environ() + telemetryCmd.Env = inheritEnvVars() for k, v := range auth.Env(ConfigUsed(ctx)) { telemetryCmd.Env = append(telemetryCmd.Env, fmt.Sprintf("%s=%s", k, v)) } diff --git a/libs/auth/env.go b/libs/auth/env.go index c58cc53e3..66744d6a1 100644 --- a/libs/auth/env.go +++ b/libs/auth/env.go @@ -24,3 +24,17 @@ func Env(cfg *config.Config) map[string]string { return out } + +func EnvVars() []string { + out := []string{} + + for _, attr := range config.ConfigAttributes { + if len(attr.EnvVars) == 0 { + continue + } + + out = append(out, attr.EnvVars[0]) + } + + return out +} diff --git a/libs/auth/env_test.go b/libs/auth/env_test.go index be1cfc7ac..515ecb55b 100644 --- a/libs/auth/env_test.go +++ b/libs/auth/env_test.go @@ -40,3 +40,40 @@ func TestAuthEnv(t *testing.T) { out := Env(in) assert.Equal(t, expected, out) } + +func TestAUthEnvVars(t *testing.T) { + expected := []string{ + "DATABRICKS_HOST", + "DATABRICKS_CLUSTER_ID", + "DATABRICKS_WAREHOUSE_ID", + "DATABRICKS_SERVERLESS_COMPUTE_ID", + "DATABRICKS_METADATA_SERVICE_URL", + "DATABRICKS_ACCOUNT_ID", + "DATABRICKS_TOKEN", + "DATABRICKS_USERNAME", + "DATABRICKS_PASSWORD", + "DATABRICKS_CONFIG_PROFILE", + "DATABRICKS_CONFIG_FILE", + "DATABRICKS_GOOGLE_SERVICE_ACCOUNT", + "GOOGLE_CREDENTIALS", + "DATABRICKS_AZURE_RESOURCE_ID", + "ARM_USE_MSI", + "ARM_CLIENT_SECRET", + "ARM_CLIENT_ID", + "ARM_TENANT_ID", + "ACTIONS_ID_TOKEN_REQUEST_URL", + "ACTIONS_ID_TOKEN_REQUEST_TOKEN", + "ARM_ENVIRONMENT", + "DATABRICKS_AZURE_LOGIN_APP_ID", + "DATABRICKS_CLIENT_ID", + "DATABRICKS_CLIENT_SECRET", + "DATABRICKS_CLI_PATH", + "DATABRICKS_AUTH_TYPE", + "DATABRICKS_DEBUG_TRUNCATE_BYTES", + "DATABRICKS_DEBUG_HEADERS", + "DATABRICKS_RATE_LIMIT", + } + + out := EnvVars() + assert.Equal(t, expected, out) +}