Add support for default_profile in [__settings__] section#1534
Add support for default_profile in [__settings__] section#1534simonfaltum wants to merge 7 commits intomainfrom
Conversation
When no profile is explicitly configured, the SDK now checks for a [__settings__].default_profile key in .databrickscfg before falling back to the DEFAULT section. This aligns the SDK with the CLI's 'databricks auth switch' command, which writes the user's chosen default profile to this section. Profile resolution order: 1. Explicit profile (--profile flag, env var, or programmatic) 2. [__settings__].default_profile (new) 3. [DEFAULT] section (legacy fallback) The [__settings__] section is never treated as a profile. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: simon <simon.faltum@databricks.com>
Signed-off-by: simon <simon.faltum@databricks.com>
- Reject default_profile = __settings__ (self-reference falls through to DEFAULT instead of trying to load __settings__ as a profile) - Add test for the self-reference guard with dedicated fixture - Differentiate TestConfigFile_DefaultProfileResolves from the precedence test by using a fixture without a [DEFAULT] section - Strengthen TestConfigFile_SettingsSectionNotAProfile to verify __settings__ is present in SectionStrings (documenting that callers must filter it) and that resolveDefaultProfile still rejects it
Persist the resolved profile name and reject the reserved settings section as a profile target so OAuth cache keys and CLI auth keep using the selected profile.
|
If integration tests don't run automatically, an authorized user can run them manually by following the instructions below: Trigger: Inputs:
Checks will be approved automatically on success. |
|
I think the logic in Also, unless I'm missing something, the branch where What would you think of introducing a small typed enum for the profile source, and moving all the resolution logic into a single function? type profileSource int
const (
profileSourceDefault profileSource = iota // legacy [DEFAULT] fallback
profileSourceSettings // from [__settings__].default_profile
profileSourceExplicit // --profile flag / env / programmatic
)
func resolveProfile(cfg *Config, f *File) (string, profileSource) {
if cfg.Profile != "" {
return cfg.Profile, profileSourceExplicit
}
section, err := f.GetSection(settingsSection)
if err == nil {
key, err := section.GetKey("default_profile")
if err == nil {
v := strings.TrimSpace(key.String())
if v != "" {
return v, profileSourceSettings
}
}
}
return "DEFAULT", profileSourceDefault
}Then profile, source := resolveProfile(cfg, configFile)
if profile == settingsSection {
return fmt.Errorf("%s has no %s profile configured", configFile.Path(), profile)
}
profileValues := configFile.Section(profile)
if len(profileValues.Keys()) == 0 {
if source == profileSourceDefault {
logger.Debugf(context.Background(), "%s has no %s profile configured", configFile.Path(), profile)
return nil
}
return fmt.Errorf("%s has no %s profile configured", configFile.Path(), profile)
}
err := cfg.loadProfileFromSection(profileValues)
if err != nil {
return fmt.Errorf("%s %s profile: %w", configFile.Path(), profile, err)
}
if source == profileSourceSettings {
cfg.Profile = profile
}
return nil
|
Changes
When no profile is explicitly configured, the SDK now checks for a
[__settings__].default_profilekey in.databrickscfgbefore fallingback to the
DEFAULTsection. This aligns the SDK with the CLI'sdatabricks auth switchcommand, which writes the user's chosendefault profile to this section.
Profile resolution order:
--profileflag, env var, or programmatic setting)[__settings__].default_profile(new)[DEFAULT]section (legacy fallback)The
[__settings__]section is never treated as a profile.Backwards compatible: existing configs without
[__settings__]behave identically.Tests
Seven test scenarios covering:
default_profileresolves correctlydefault_profiletakes precedence over[DEFAULT][__settings__]default_profileis empty[__settings__]is not a profile--profileoverridesdefault_profiledefault_profilepointing to nonexistent section returns error