5
5
"fmt"
6
6
"log"
7
7
"net/http"
8
+ "net/url"
8
9
"os"
9
10
10
11
"github.com/gophercloud/gophercloud/v2"
@@ -246,20 +247,40 @@ func (c *Config) Authenticate(ctx context.Context) error {
246
247
247
248
// DetermineEndpoint is a helper method to determine if the user wants to
248
249
// override an endpoint returned from the catalog.
249
- func (c * Config ) DetermineEndpoint (client * gophercloud.ServiceClient , service string ) * gophercloud.ServiceClient {
250
- finalEndpoint := client .ResourceBaseURL ()
251
-
252
- if v , ok := c .EndpointOverrides [service ]; ok {
253
- if endpoint , ok := v .(string ); ok && endpoint != "" {
254
- finalEndpoint = endpoint
255
- client .Endpoint = endpoint
256
- client .ResourceBase = ""
257
- }
250
+ func (c * Config ) DetermineEndpoint (client * gophercloud.ServiceClient , eo gophercloud.EndpointOpts , service string ) (* gophercloud.ServiceClient , error ) {
251
+ v , ok := c .EndpointOverrides [service ]
252
+ if ! ok {
253
+ return client , nil
254
+ }
255
+ val , ok := v .(string )
256
+ if ! ok || val == "" {
257
+ return client , nil
258
+ }
259
+
260
+ // overriden endpoint is a URL
261
+ if u , err := url .Parse (val ); err == nil && u .Scheme != "" && u .Host != "" {
262
+ eo .ApplyDefaults (service )
263
+ client .ProviderClient = c .OsClient
264
+ client .Endpoint = val
265
+ client .ResourceBase = ""
266
+ client .Type = service
267
+ log .Printf ("[DEBUG] OpenStack Endpoint for %s: %s" , service , val )
268
+ return client , nil
258
269
}
259
270
260
- log .Printf ("[DEBUG] OpenStack Endpoint for %s: %s" , service , finalEndpoint )
271
+ // overriden endpoint is a new service type
272
+ eo .ApplyDefaults (val )
273
+ url , err := c .OsClient .EndpointLocator (eo )
274
+ if err != nil {
275
+ log .Printf ("[DEBUG] Cannot set a new OpenStack Endpoint %s alias: %v" , val , err )
276
+ return client , err
277
+ }
278
+ client .ProviderClient = c .OsClient
279
+ client .Endpoint = url
280
+ client .Type = val
261
281
262
- return client
282
+ log .Printf ("[DEBUG] OpenStack Endpoint for %s alias: %s" , val , url )
283
+ return client , nil
263
284
}
264
285
265
286
// DetermineRegion is a helper method to determine the region based on
@@ -285,19 +306,25 @@ func (c *Config) CommonServiceClientInit(ctx context.Context, newClient commonCo
285
306
return nil , err
286
307
}
287
308
288
- client , err := newClient ( c . OsClient , gophercloud.EndpointOpts {
309
+ eo := gophercloud.EndpointOpts {
289
310
Region : c .DetermineRegion (region ),
290
311
Availability : clientconfig .GetEndpointType (c .EndpointType ),
291
- })
292
-
293
- if err != nil {
312
+ }
313
+ client , err := newClient (c .OsClient , eo )
314
+ if err , ok := err .(* gophercloud.ErrEndpointNotFound ); ok && client != nil {
315
+ client , e := c .DetermineEndpoint (client , eo , service )
316
+ if e != nil {
317
+ return client , e
318
+ }
319
+ // if the endpoint is still not found, return the original error
320
+ if client .ProviderClient == nil {
321
+ return client , err
322
+ }
323
+ } else if err != nil {
294
324
return client , err
295
325
}
296
326
297
- // Check if an endpoint override was specified for the volume service.
298
- client = c .DetermineEndpoint (client , service )
299
-
300
- return client , nil
327
+ return c .DetermineEndpoint (client , eo , service )
301
328
}
302
329
303
330
func (c * Config ) BlockStorageV1Client (ctx context.Context , region string ) (* gophercloud.ServiceClient , error ) {
@@ -328,85 +355,76 @@ func (c *Config) ImageV2Client(ctx context.Context, region string) (*gophercloud
328
355
return c .CommonServiceClientInit (ctx , openstack .NewImageV2 , region , "image" )
329
356
}
330
357
331
- func (c * Config ) MessagingV2Client (ctx context.Context , region string ) (* gophercloud.ServiceClient , error ) {
358
+ func (c * Config ) MessagingV2Client (ctx context.Context , clientID string , region string ) (* gophercloud.ServiceClient , error ) {
332
359
if err := c .Authenticate (ctx ); err != nil {
333
360
return nil , err
334
361
}
335
362
336
- client , err := openstack . NewMessagingV2 ( c . OsClient , "" , gophercloud.EndpointOpts {
363
+ eo := gophercloud.EndpointOpts {
337
364
Region : c .DetermineRegion (region ),
338
365
Availability : clientconfig .GetEndpointType (c .EndpointType ),
339
- })
340
-
341
- if err != nil {
366
+ }
367
+ client , err := openstack .NewMessagingV2 (c .OsClient , clientID , eo )
368
+ if err , ok := err .(* gophercloud.ErrEndpointNotFound ); ok && client != nil {
369
+ client , e := c .DetermineEndpoint (client , eo , "messaging" )
370
+ if e != nil {
371
+ return client , e
372
+ }
373
+ // if the endpoint is still not found, return the original error
374
+ if client .ProviderClient == nil {
375
+ return client , err
376
+ }
377
+ } else if err != nil {
342
378
return client , err
343
379
}
344
380
345
- // Check if an endpoint override was specified for the messaging service.
346
- client = c .DetermineEndpoint (client , "message" )
347
-
348
- return client , nil
381
+ return c .DetermineEndpoint (client , eo , "messaging" )
349
382
}
350
383
351
384
func (c * Config ) NetworkingV2Client (ctx context.Context , region string ) (* gophercloud.ServiceClient , error ) {
352
385
return c .CommonServiceClientInit (ctx , openstack .NewNetworkV2 , region , "network" )
353
386
}
354
387
355
388
func (c * Config ) ObjectStorageV1Client (ctx context.Context , region string ) (* gophercloud.ServiceClient , error ) {
356
- var client * gophercloud.ServiceClient
357
- var err error
389
+ if ! c .Swauth {
390
+ return c .CommonServiceClientInit (ctx , openstack .NewObjectStorageV1 , region , "object-store" )
391
+ }
358
392
359
393
// If Swift Authentication is being used, return a swauth client.
360
394
// Otherwise, use a Keystone-based client.
361
- if c .Swauth {
362
- if ! c .DelayedAuth {
363
- client , err = swauth .NewObjectStorageV1 (ctx , c .OsClient , swauth.AuthOpts {
395
+ var client * gophercloud.ServiceClient
396
+ var err error
397
+ if ! c .DelayedAuth {
398
+ client , err = swauth .NewObjectStorageV1 (ctx , c .OsClient , swauth.AuthOpts {
399
+ User : c .Username ,
400
+ Key : c .Password ,
401
+ })
402
+ if err != nil {
403
+ return nil , err
404
+ }
405
+ } else {
406
+ c .MutexKV .Lock ("SwAuth" )
407
+ defer c .MutexKV .Unlock ("SwAuth" )
408
+
409
+ if c .swAuthFailed != nil {
410
+ return nil , c .swAuthFailed
411
+ }
412
+
413
+ if c .swClient == nil {
414
+ c .swClient , err = swauth .NewObjectStorageV1 (ctx , c .OsClient , swauth.AuthOpts {
364
415
User : c .Username ,
365
416
Key : c .Password ,
366
417
})
418
+
367
419
if err != nil {
420
+ c .swAuthFailed = err
368
421
return nil , err
369
422
}
370
- } else {
371
- c .MutexKV .Lock ("SwAuth" )
372
- defer c .MutexKV .Unlock ("SwAuth" )
373
-
374
- if c .swAuthFailed != nil {
375
- return nil , c .swAuthFailed
376
- }
377
-
378
- if c .swClient == nil {
379
- c .swClient , err = swauth .NewObjectStorageV1 (ctx , c .OsClient , swauth.AuthOpts {
380
- User : c .Username ,
381
- Key : c .Password ,
382
- })
383
-
384
- if err != nil {
385
- c .swAuthFailed = err
386
- return nil , err
387
- }
388
- }
389
-
390
- client = c .swClient
391
- }
392
- } else {
393
- if err := c .Authenticate (ctx ); err != nil {
394
- return nil , err
395
423
}
396
424
397
- client , err = openstack .NewObjectStorageV1 (c .OsClient , gophercloud.EndpointOpts {
398
- Region : c .DetermineRegion (region ),
399
- Availability : clientconfig .GetEndpointType (c .EndpointType ),
400
- })
401
-
402
- if err != nil {
403
- return client , err
404
- }
425
+ client = c .swClient
405
426
}
406
427
407
- // Check if an endpoint override was specified for the object-store service.
408
- client = c .DetermineEndpoint (client , "object-store" )
409
-
410
428
return client , nil
411
429
}
412
430
0 commit comments