@@ -26,6 +26,10 @@ const (
2626 // HostEnvVar is the environment variable that contains the host.
2727 HostEnvVar = "OXIDE_HOST"
2828
29+ // ProfileEnvVar is the environment variable that contains the credentials
30+ // profile to use.
31+ ProfileEnvVar = "OXIDE_PROFILE"
32+
2933 // credentialsFile is the name of the file the Oxide CLI stores credentials in.
3034 credentialsFile = "credentials.toml"
3135
@@ -89,47 +93,42 @@ type authCredentials struct {
8993}
9094
9195// NewClient creates a new client for the Oxide API. To authenticate with
92- // environment variables, set OXIDE_HOST and OXIDE_TOKEN accordingly. Pass in a
93- // non-nil *Config to set the various configuration options on a Client. When
94- // setting the host and token through the *Config, these will override any set
95- // environment variables. The Profile and UseDefaultProfile fields will pull
96- // authentication information from the credentials.toml file generated by
97- // the Oxide CLI. These are mutally exclusive with each other and the Host and
98- // Token fields.
96+ // environment variables, set either OXIDE_HOST and OXIDE_TOKEN, or
97+ // OXIDE_PROFILE accordingly. Pass in a non-nil *Config to set the various
98+ // configuration options on a Client. When setting the host, token, or profile
99+ // through the *Config, these will override any set environment variables. The
100+ // Profile and UseDefaultProfile fields will pull authentication information
101+ // from the credentials.toml file generated by the Oxide CLI. These are
102+ // mutually exclusive with each other and the Host and Token fields.
99103func NewClient (cfg * Config ) (* Client , error ) {
100104 token := os .Getenv (TokenEnvVar )
101105 host := os .Getenv (HostEnvVar )
106+ profile := os .Getenv (ProfileEnvVar )
107+ useDefaultProfile := false
102108 userAgent := defaultUserAgent ()
103109 httpClient := & http.Client {
104110 Timeout : 600 * time .Second ,
105111 }
106112
107- // Layer in the user-provided configuration if provided.
113+ // Layer in the user-provided configuration if provided and override
114+ // environment variables when needed.
108115 if cfg != nil {
109- if cfg .Profile != "" || cfg .UseDefaultProfile {
110- if cfg .Profile != "" && cfg .UseDefaultProfile {
111- return nil , errors .New ("cannot authenticate with both default profile and a defined profile" )
112- }
113-
114- if cfg .Host != "" || cfg .Token != "" {
115- return nil , errors .New ("cannot authenticate with both a profile and host/token" )
116- }
117-
118- fileCreds , err := getProfile (* cfg )
119- if err != nil {
120- return nil , fmt .Errorf ("unable to retrieve profile: %w" , err )
121- }
122-
123- token = fileCreds .token
124- host = fileCreds .host
125- }
116+ useDefaultProfile = cfg .UseDefaultProfile
126117
127118 if cfg .Host != "" {
128119 host = cfg .Host
120+ profile = cfg .Profile // Ignore OXIDE_PROFILE.
129121 }
130122
131123 if cfg .Token != "" {
132124 token = cfg .Token
125+ profile = cfg .Profile // Ignore OXIDE_PROFILE.
126+ }
127+
128+ if cfg .Profile != "" {
129+ profile = cfg .Profile
130+ host = cfg .Host // Ignore OXIDE_HOST.
131+ token = cfg .Token // Ignore OXIDE_TOKEN.
133132 }
134133
135134 if cfg .UserAgent != "" {
@@ -141,6 +140,33 @@ func NewClient(cfg *Config) (*Client, error) {
141140 }
142141 }
143142
143+ if (profile != "" || useDefaultProfile ) && (host != "" || token != "" ) {
144+ return nil , errors .New ("cannot authenticate with both a profile and host/token" )
145+ }
146+ if profile != "" && useDefaultProfile {
147+ return nil , errors .New ("cannot authenticate with both default profile and a defined profile" )
148+ }
149+ if profile != "" || useDefaultProfile {
150+ var configDir string
151+ if cfg != nil && cfg .ConfigDir != "" {
152+ configDir = cfg .ConfigDir
153+ } else {
154+ homeDir , err := os .UserHomeDir ()
155+ if err != nil {
156+ return nil , fmt .Errorf ("unable to find user's home directory: %w" , err )
157+ }
158+ configDir = filepath .Join (homeDir , defaultConfigDir )
159+ }
160+
161+ authCredentials , err := getProfile (configDir , profile , useDefaultProfile )
162+ if err != nil {
163+ return nil , fmt .Errorf ("unable to retrieve profile: %w" , err )
164+ }
165+
166+ host = authCredentials .host
167+ token = authCredentials .token
168+ }
169+
144170 errs := make ([]error , 0 )
145171 host , err := parseBaseURL (host )
146172 if err != nil {
@@ -173,20 +199,9 @@ func defaultUserAgent() string {
173199
174200// getProfile determines the path of the user's credentials file
175201// and returns the host and token for the requested profile.
176- func getProfile (cfg Config ) (* authCredentials , error ) {
177- configDir := cfg .ConfigDir
178- if configDir == "" {
179- homeDir , err := os .UserHomeDir ()
180- if err != nil {
181- return nil , fmt .Errorf ("unable to find user's home directory: %w" , err )
182- }
183- configDir = filepath .Join (homeDir , defaultConfigDir )
184- }
185-
186- profile := cfg .Profile
187-
202+ func getProfile (configDir string , profile string , useDefault bool ) (* authCredentials , error ) {
188203 // Use explicitly configured profile over default when both are set.
189- if cfg . UseDefaultProfile && profile == "" {
204+ if useDefault && profile == "" {
190205 configPath := filepath .Join (configDir , configFile )
191206
192207 var err error
0 commit comments