github.com/opentelekomcloud/gophertelekomcloud@v0.9.3/acceptance/clients/clients.go (about)

     1  // Package clients contains functions for creating OpenStack service clients
     2  // for use in acceptance tests. It also manages the required environment
     3  // variables to run the tests.
     4  package clients
     5  
     6  import (
     7  	"encoding/json"
     8  	"fmt"
     9  	"strings"
    10  
    11  	golangsdk "github.com/opentelekomcloud/gophertelekomcloud"
    12  	"github.com/opentelekomcloud/gophertelekomcloud/openstack"
    13  	"github.com/opentelekomcloud/gophertelekomcloud/openstack/identity/v3/credentials"
    14  	"github.com/opentelekomcloud/gophertelekomcloud/openstack/obs"
    15  )
    16  
    17  const envPrefix = "OS_"
    18  
    19  var EnvOS = openstack.NewEnv(envPrefix)
    20  
    21  // NewAutoscalingV1Client returns authenticated AutoScaling v1 client
    22  func NewAutoscalingV1Client() (*golangsdk.ServiceClient, error) {
    23  	cc, err := CloudAndClient()
    24  	if err != nil {
    25  		return nil, err
    26  	}
    27  
    28  	return openstack.NewAutoScalingV1(cc.ProviderClient, golangsdk.EndpointOpts{
    29  		Region: cc.RegionName,
    30  	})
    31  }
    32  
    33  // NewAutoscalingV2Client returns authenticated AutoScaling v2 client
    34  func NewAutoscalingV2Client() (*golangsdk.ServiceClient, error) {
    35  	cc, err := CloudAndClient()
    36  	if err != nil {
    37  		return nil, err
    38  	}
    39  
    40  	return openstack.NewAutoScalingV2(cc.ProviderClient, golangsdk.EndpointOpts{
    41  		Region: cc.RegionName,
    42  	})
    43  }
    44  
    45  // NewBlockStorageV1Client returns a *ServiceClient for making calls
    46  // to the OpenStack Block Storage v1 API. An error will be returned
    47  // if authentication or client creation was not possible.
    48  func NewBlockStorageV1Client() (*golangsdk.ServiceClient, error) {
    49  	cc, err := CloudAndClient()
    50  	if err != nil {
    51  		return nil, err
    52  	}
    53  
    54  	return openstack.NewBlockStorageV1(cc.ProviderClient, golangsdk.EndpointOpts{
    55  		Region: cc.RegionName,
    56  	})
    57  }
    58  
    59  // NewBlockStorageV2Client returns a *ServiceClient for making calls
    60  // to the OpenStack Block Storage v2 API. An error will be returned
    61  // if authentication or client creation was not possible.
    62  func NewBlockStorageV2Client() (*golangsdk.ServiceClient, error) {
    63  	cc, err := CloudAndClient()
    64  	if err != nil {
    65  		return nil, err
    66  	}
    67  
    68  	return openstack.NewBlockStorageV2(cc.ProviderClient, golangsdk.EndpointOpts{
    69  		Region: cc.RegionName,
    70  	})
    71  }
    72  
    73  // NewBlockStorageV3Client returns a *ServiceClient for making calls
    74  // to the OpenStack Block Storage v3 API. An error will be returned
    75  // if authentication or client creation was not possible.
    76  func NewBlockStorageV3Client() (*golangsdk.ServiceClient, error) {
    77  	cc, err := CloudAndClient()
    78  	if err != nil {
    79  		return nil, err
    80  	}
    81  
    82  	return openstack.NewBlockStorageV3(cc.ProviderClient, golangsdk.EndpointOpts{
    83  		Region: cc.RegionName,
    84  	})
    85  }
    86  
    87  // NewComputeV2Client returns a *ServiceClient for making calls
    88  // to the OpenStack Compute v2 API. An error will be returned
    89  // if authentication or client creation was not possible.
    90  func NewComputeV2Client() (*golangsdk.ServiceClient, error) {
    91  	cc, err := CloudAndClient()
    92  	if err != nil {
    93  		return nil, err
    94  	}
    95  
    96  	return openstack.NewComputeV2(cc.ProviderClient, golangsdk.EndpointOpts{
    97  		Region: cc.RegionName,
    98  	})
    99  }
   100  
   101  // NewComputeV1Client returns a *ServiceClient for making calls
   102  // to the OpenStack Compute v1 API. An error will be returned
   103  // if authentication or client creation was not possible.
   104  func NewComputeV1Client() (*golangsdk.ServiceClient, error) {
   105  	cc, err := CloudAndClient()
   106  	if err != nil {
   107  		return nil, err
   108  	}
   109  
   110  	return openstack.NewComputeV1(cc.ProviderClient, golangsdk.EndpointOpts{
   111  		Region: cc.RegionName,
   112  	})
   113  }
   114  
   115  func NewCTSV1Client() (*golangsdk.ServiceClient, error) {
   116  	cc, err := CloudAndClient()
   117  	if err != nil {
   118  		return nil, err
   119  	}
   120  
   121  	return openstack.NewCTSV1(cc.ProviderClient, golangsdk.EndpointOpts{
   122  		Region: cc.RegionName,
   123  	})
   124  }
   125  
   126  func NewCTSV2Client() (*golangsdk.ServiceClient, error) {
   127  	cc, err := CloudAndClient()
   128  	if err != nil {
   129  		return nil, err
   130  	}
   131  
   132  	return openstack.NewCTSV2(cc.ProviderClient, golangsdk.EndpointOpts{
   133  		Region: cc.RegionName,
   134  	})
   135  }
   136  
   137  func NewCTSV3Client() (*golangsdk.ServiceClient, error) {
   138  	cc, err := CloudAndClient()
   139  	if err != nil {
   140  		return nil, err
   141  	}
   142  
   143  	return openstack.NewCTSV3(cc.ProviderClient, golangsdk.EndpointOpts{
   144  		Region: cc.RegionName,
   145  	})
   146  }
   147  
   148  // NewDCaaSV2Client returns a *ServiceClient for making calls
   149  // to the OpenStack v2 API. An error will be returned
   150  // if authentication or client creation was not possible.
   151  func NewDCaaSV2Client() (*golangsdk.ServiceClient, error) {
   152  	cc, err := CloudAndClient()
   153  	if err != nil {
   154  		return nil, err
   155  	}
   156  
   157  	return openstack.NewDCaaSV2(cc.ProviderClient, golangsdk.EndpointOpts{
   158  		Region: cc.RegionName,
   159  	})
   160  }
   161  
   162  // NewDNSV2Client returns a *ServiceClient for making calls
   163  // to the OpenStack Compute v2 API. An error will be returned
   164  // if authentication or client creation was not possible.
   165  func NewDNSV2Client() (*golangsdk.ServiceClient, error) {
   166  	cc, err := CloudAndClient()
   167  	if err != nil {
   168  		return nil, err
   169  	}
   170  
   171  	return openstack.NewDNSV2(cc.ProviderClient, golangsdk.EndpointOpts{
   172  		Region: cc.RegionName,
   173  	})
   174  }
   175  
   176  func NewDWSV1Client() (*golangsdk.ServiceClient, error) {
   177  	cc, err := CloudAndClient()
   178  	if err != nil {
   179  		return nil, err
   180  	}
   181  
   182  	return openstack.NewDWSV1(cc.ProviderClient, golangsdk.EndpointOpts{
   183  		Region: cc.RegionName,
   184  	})
   185  }
   186  
   187  // NewIdentityV3Client returns a *ServiceClient for making calls
   188  // to the OpenStack Identity v3 API on a `project` level. An error will be returned
   189  // if authentication or client creation was not possible.
   190  func NewIdentityV3Client() (*golangsdk.ServiceClient, error) {
   191  	cc, err := CloudAndClient()
   192  	if err != nil {
   193  		return nil, err
   194  	}
   195  
   196  	return openstack.NewIdentityV3(cc.ProviderClient, golangsdk.EndpointOpts{
   197  		Region: cc.RegionName,
   198  	})
   199  }
   200  
   201  // NewIdentityV30AdminClient returns a *ServiceClient for making calls
   202  // to the OpenStack Identity v3 API on a `domain` level with v3.0 IAM endpoint.
   203  // An error will be returned if authentication or client creation was not possible.
   204  func NewIdentityV30AdminClient() (*golangsdk.ServiceClient, error) {
   205  	cloud, err := EnvOS.Cloud()
   206  	if err != nil {
   207  		return nil, fmt.Errorf("error constructing cloud configuration: %w", err)
   208  	}
   209  
   210  	opts := golangsdk.AuthOptions{
   211  		IdentityEndpoint: cloud.AuthInfo.AuthURL,
   212  		Username:         cloud.AuthInfo.Username,
   213  		Password:         cloud.AuthInfo.Password,
   214  		DomainName:       cloud.AuthInfo.UserDomainName,
   215  		TenantID:         cloud.AuthInfo.ProjectID,
   216  	}
   217  
   218  	pClient, err := openstack.AuthenticatedClient(opts)
   219  	if err != nil {
   220  		return nil, fmt.Errorf("error creating provider client: %w", err)
   221  	}
   222  	client, err := openstack.NewIdentityV3(pClient, golangsdk.EndpointOpts{})
   223  
   224  	if err != nil {
   225  		return nil, err
   226  	}
   227  
   228  	client.Endpoint = strings.Replace(client.Endpoint, "v3", "v3.0", 1)
   229  	return client, err
   230  }
   231  
   232  // NewIdentityV3AdminClient returns a *ServiceClient for making calls
   233  // to the OpenStack Identity v3 API on a `domain` level with v3 IAM endpoint.
   234  // An error will be returned if authentication or client creation was not possible.
   235  func NewIdentityV3AdminClient() (*golangsdk.ServiceClient, error) {
   236  	cloud, err := EnvOS.Cloud()
   237  	if err != nil {
   238  		return nil, fmt.Errorf("error constructing cloud configuration: %w", err)
   239  	}
   240  
   241  	opts := golangsdk.AuthOptions{
   242  		IdentityEndpoint: cloud.AuthInfo.AuthURL,
   243  		Username:         cloud.AuthInfo.Username,
   244  		Password:         cloud.AuthInfo.Password,
   245  		DomainName:       cloud.AuthInfo.UserDomainName,
   246  		TenantID:         cloud.AuthInfo.ProjectID,
   247  	}
   248  
   249  	pClient, err := openstack.AuthenticatedClient(opts)
   250  	if err != nil {
   251  		return nil, fmt.Errorf("error creating provider client: %w", err)
   252  	}
   253  	client, err := openstack.NewIdentityV3(pClient, golangsdk.EndpointOpts{})
   254  
   255  	if err != nil {
   256  		return nil, err
   257  	}
   258  
   259  	return client, err
   260  }
   261  
   262  // NewIdentityV3UnauthenticatedClient returns an unauthenticated *ServiceClient
   263  // for the OpenStack Identity v3 API. An error  will be returned if
   264  // authentication or client creation was not possible.
   265  func NewIdentityV3UnauthenticatedClient() (*golangsdk.ServiceClient, error) {
   266  	cloud, err := EnvOS.Cloud()
   267  	if err != nil {
   268  		return nil, err
   269  	}
   270  
   271  	client, err := openstack.NewClient(cloud.AuthInfo.AuthURL)
   272  	if err != nil {
   273  		return nil, err
   274  	}
   275  
   276  	return openstack.NewIdentityV3(client, golangsdk.EndpointOpts{})
   277  }
   278  
   279  func NewIMSV1Client() (*golangsdk.ServiceClient, error) {
   280  	cc, err := CloudAndClient()
   281  	if err != nil {
   282  		return nil, err
   283  	}
   284  
   285  	return openstack.NewIMSV1(cc.ProviderClient, golangsdk.EndpointOpts{})
   286  }
   287  
   288  func NewIMSV2Client() (*golangsdk.ServiceClient, error) {
   289  	cc, err := CloudAndClient()
   290  	if err != nil {
   291  		return nil, err
   292  	}
   293  
   294  	return openstack.NewIMSV2(cc.ProviderClient, golangsdk.EndpointOpts{})
   295  }
   296  
   297  // NewNetworkV1Client returns a *ServiceClient for making calls to the
   298  // OpenStack Networking v1 API. An error will be returned if authentication
   299  // or client creation was not possible.
   300  func NewNetworkV1Client() (*golangsdk.ServiceClient, error) {
   301  	cc, err := CloudAndClient()
   302  	if err != nil {
   303  		return nil, err
   304  	}
   305  
   306  	return openstack.NewNetworkV1(cc.ProviderClient, golangsdk.EndpointOpts{
   307  		Region: cc.RegionName,
   308  	})
   309  }
   310  
   311  func NewVPCEndpointV1Client() (*golangsdk.ServiceClient, error) {
   312  	cc, err := CloudAndClient()
   313  	if err != nil {
   314  		return nil, err
   315  	}
   316  
   317  	return openstack.NewVpcEpV1(cc.ProviderClient, golangsdk.EndpointOpts{
   318  		Region: cc.RegionName,
   319  	})
   320  }
   321  
   322  func NewVPCV3Client() (*golangsdk.ServiceClient, error) {
   323  	cc, err := CloudAndClient()
   324  	if err != nil {
   325  		return nil, err
   326  	}
   327  
   328  	return openstack.NewVpcV3(cc.ProviderClient, golangsdk.EndpointOpts{
   329  		Region: cc.RegionName,
   330  	})
   331  }
   332  
   333  // NewPeerNetworkV1Client returns a *ServiceClient for making calls to the
   334  // OpenStack Networking v1 API for VPC peer. An error will be returned if authentication
   335  // or client creation was not possible.
   336  func NewPeerNetworkV1Client() (*golangsdk.ServiceClient, error) {
   337  	cc, err := CloudAndClient()
   338  	if err != nil {
   339  		return nil, err
   340  	}
   341  
   342  	err = UpdatePeerTenantDetails(cc.Cloud)
   343  	if err != nil {
   344  		return nil, err
   345  	}
   346  
   347  	return openstack.NewNetworkV1(cc.ProviderClient, golangsdk.EndpointOpts{
   348  		Region: cc.RegionName,
   349  	})
   350  }
   351  
   352  // NewNetworkV2Client returns a *ServiceClient for making calls to the
   353  // OpenStack Networking v2 API. An error will be returned if authentication
   354  // or client creation was not possible.
   355  func NewNetworkV2Client() (*golangsdk.ServiceClient, error) {
   356  	cc, err := CloudAndClient()
   357  	if err != nil {
   358  		return nil, err
   359  	}
   360  
   361  	return openstack.NewNetworkV2(cc.ProviderClient, golangsdk.EndpointOpts{
   362  		Region: cc.RegionName,
   363  	})
   364  }
   365  
   366  // NewElbV2Client returns authenticated ELB v2 client
   367  func NewElbV2Client() (*golangsdk.ServiceClient, error) {
   368  	cc, err := CloudAndClient()
   369  	if err != nil {
   370  		return nil, err
   371  	}
   372  
   373  	return openstack.NewELBV2(cc.ProviderClient, golangsdk.EndpointOpts{
   374  		Region: cc.RegionName,
   375  	})
   376  }
   377  
   378  // NewElbV3Client returns authenticated ELB v3 client
   379  func NewElbV3Client() (*golangsdk.ServiceClient, error) {
   380  	cc, err := CloudAndClient()
   381  	if err != nil {
   382  		return nil, err
   383  	}
   384  
   385  	return openstack.NewELBV3(cc.ProviderClient, golangsdk.EndpointOpts{
   386  		Region: cc.RegionName,
   387  	})
   388  }
   389  
   390  // NewNatV2Client returns authenticated NAT v2 client
   391  func NewNatV2Client() (*golangsdk.ServiceClient, error) {
   392  	cc, err := CloudAndClient()
   393  	if err != nil {
   394  		return nil, err
   395  	}
   396  
   397  	return openstack.NewNatV2(cc.ProviderClient, golangsdk.EndpointOpts{
   398  		Region: cc.RegionName,
   399  	})
   400  }
   401  
   402  // NewPeerNetworkV2Client returns a *ServiceClient for making calls to the
   403  // OpenStack Networking v2 API for Peer. An error will be returned if authentication
   404  // or client creation was not possible.
   405  func NewPeerNetworkV2Client() (*golangsdk.ServiceClient, error) {
   406  	cc, err := CloudAndClient()
   407  	if err != nil {
   408  		return nil, err
   409  	}
   410  	err = UpdatePeerTenantDetails(cc.Cloud)
   411  	if err != nil {
   412  		return nil, err
   413  	}
   414  
   415  	return openstack.NewNetworkV2(cc.ProviderClient, golangsdk.EndpointOpts{
   416  		Region: cc.RegionName,
   417  	})
   418  }
   419  
   420  func NewOBSClient() (*obs.ObsClient, error) {
   421  	cc, err := CloudAndClient()
   422  	if err != nil {
   423  		return nil, err
   424  	}
   425  
   426  	if err := setupTemporaryAKSK(cc); err != nil {
   427  		return nil, fmt.Errorf("failed to construct OBS client without AK/SK: %s", err)
   428  	}
   429  
   430  	client, err := openstack.NewOBSService(cc.ProviderClient, golangsdk.EndpointOpts{
   431  		Region: cc.RegionName,
   432  	})
   433  	if err != nil {
   434  		return nil, err
   435  	}
   436  	opts := cc.AKSKAuthOptions
   437  	return obs.New(
   438  		opts.AccessKey, opts.SecretKey, client.Endpoint,
   439  		obs.WithSecurityToken(opts.SecurityToken), obs.WithSignature(obs.SignatureObs),
   440  	)
   441  }
   442  
   443  func NewOBSClientWithoutHeader() (*obs.ObsClient, error) {
   444  	cc, err := CloudAndClient()
   445  	if err != nil {
   446  		return nil, err
   447  	}
   448  
   449  	if err := setupTemporaryAKSK(cc); err != nil {
   450  		return nil, fmt.Errorf("failed to construct OBS client without AK/SK: %s", err)
   451  	}
   452  
   453  	client, err := openstack.NewOBSService(cc.ProviderClient, golangsdk.EndpointOpts{
   454  		Region: cc.RegionName,
   455  	})
   456  	if err != nil {
   457  		return nil, err
   458  	}
   459  	opts := cc.AKSKAuthOptions
   460  	return obs.New(
   461  		opts.AccessKey, opts.SecretKey, client.Endpoint,
   462  		obs.WithSecurityToken(opts.SecurityToken),
   463  	)
   464  }
   465  
   466  // NewSharedFileSystemV2Client returns a *ServiceClient for making calls
   467  // to the OpenStack Shared File System v2 API. An error will be returned
   468  // if authentication or client creation was not possible.
   469  func NewSharedFileSystemV2Client() (*golangsdk.ServiceClient, error) {
   470  	cc, err := CloudAndClient()
   471  	if err != nil {
   472  		return nil, err
   473  	}
   474  	return openstack.NewSharedFileSystemV2(cc.ProviderClient, golangsdk.EndpointOpts{
   475  		Region: cc.RegionName,
   476  	})
   477  }
   478  
   479  func NewKMSV1Client() (*golangsdk.ServiceClient, error) {
   480  	cc, err := CloudAndClient()
   481  	if err != nil {
   482  		return nil, err
   483  	}
   484  	return openstack.NewKMSV1(cc.ProviderClient, golangsdk.EndpointOpts{
   485  		Region: cc.RegionName,
   486  	})
   487  }
   488  
   489  // NewSharedFileSystemTurboV1Client returns a *ServiceClient for making calls
   490  // to the OpenStack Shared File System Turbo v1 API. An error will be returned
   491  // if authentication or client creation was not possible.
   492  func NewSharedFileSystemTurboV1Client() (*golangsdk.ServiceClient, error) {
   493  	cc, err := CloudAndClient()
   494  	if err != nil {
   495  		return nil, err
   496  	}
   497  	return openstack.NewSharedFileSystemTurboV1(cc.ProviderClient, golangsdk.EndpointOpts{
   498  		Region: cc.RegionName,
   499  	})
   500  }
   501  
   502  // NewRdsV3 returns authenticated RDS v3 client
   503  func NewRdsV3() (*golangsdk.ServiceClient, error) {
   504  	cc, err := CloudAndClient()
   505  	if err != nil {
   506  		return nil, err
   507  	}
   508  	return openstack.NewRDSV3(cc.ProviderClient, golangsdk.EndpointOpts{
   509  		Region: cc.RegionName,
   510  	})
   511  }
   512  
   513  // NewMrsV1 returns authenticated MRS v1 client
   514  func NewMrsV1() (*golangsdk.ServiceClient, error) {
   515  	cc, err := CloudAndClient()
   516  	if err != nil {
   517  		return nil, err
   518  	}
   519  	return openstack.NewMapReduceV1(cc.ProviderClient, golangsdk.EndpointOpts{
   520  		Region: cc.RegionName,
   521  	})
   522  }
   523  
   524  // NewSDRSV1 returns authenticated SDRS v3 client
   525  func NewSDRSV1() (*golangsdk.ServiceClient, error) {
   526  	cc, err := CloudAndClient()
   527  	if err != nil {
   528  		return nil, err
   529  	}
   530  	return openstack.NewSDRSV1(cc.ProviderClient, golangsdk.EndpointOpts{
   531  		Region: cc.RegionName,
   532  	})
   533  }
   534  
   535  // NewWafV1Client returns authenticated WAF v1 client
   536  func NewWafV1Client() (*golangsdk.ServiceClient, error) {
   537  	cc, err := CloudAndClient()
   538  	if err != nil {
   539  		return nil, err
   540  	}
   541  	return openstack.NewWAFV1(cc.ProviderClient, golangsdk.EndpointOpts{Region: cc.RegionName})
   542  }
   543  
   544  // NewWafdV1Client returns authenticated WAF premium v1 client
   545  func NewWafdV1Client() (*golangsdk.ServiceClient, error) {
   546  	cc, err := CloudAndClient()
   547  	if err != nil {
   548  		return nil, err
   549  	}
   550  	if cc.RegionName != "eu-ch2" {
   551  		return openstack.NewWAFDV1(cc.ProviderClient, golangsdk.EndpointOpts{Region: cc.RegionName})
   552  	} else {
   553  		return openstack.NewWAFDSwissV1(cc.ProviderClient, golangsdk.EndpointOpts{Region: cc.RegionName})
   554  	}
   555  }
   556  
   557  // NewCsbsV1Client returns authenticated CSBS v1 client
   558  func NewCsbsV1Client() (*golangsdk.ServiceClient, error) {
   559  	cc, err := CloudAndClient()
   560  	if err != nil {
   561  		return nil, err
   562  	}
   563  	return openstack.NewCSBSService(cc.ProviderClient, golangsdk.EndpointOpts{
   564  		Region: cc.RegionName,
   565  	})
   566  }
   567  
   568  // NewCssV1Client returns authenticated CSS v1 client
   569  func NewCssV1Client() (*golangsdk.ServiceClient, error) {
   570  	cc, err := CloudAndClient()
   571  	if err != nil {
   572  		return nil, err
   573  	}
   574  	return openstack.NewCSSService(cc.ProviderClient, golangsdk.EndpointOpts{
   575  		Region: cc.RegionName,
   576  	})
   577  }
   578  
   579  func NewCceV1Client() (*golangsdk.ServiceClient, error) {
   580  	cc, err := CloudAndClient()
   581  	if err != nil {
   582  		return nil, err
   583  	}
   584  	return openstack.NewCCEv1(cc.ProviderClient, golangsdk.EndpointOpts{
   585  		Region: cc.RegionName,
   586  	})
   587  }
   588  
   589  func NewCceV3Client() (*golangsdk.ServiceClient, error) {
   590  	cc, err := CloudAndClient()
   591  	if err != nil {
   592  		return nil, err
   593  	}
   594  	return openstack.NewCCE(cc.ProviderClient, golangsdk.EndpointOpts{Region: cc.RegionName})
   595  }
   596  
   597  func NewCceV3AddonClient() (*golangsdk.ServiceClient, error) {
   598  	cc, err := CloudAndClient()
   599  	if err != nil {
   600  		return nil, err
   601  	}
   602  	client, err := openstack.NewCCE(cc.ProviderClient, golangsdk.EndpointOpts{Region: cc.RegionName})
   603  	if err != nil {
   604  		return nil, err
   605  	}
   606  	client.ResourceBase = fmt.Sprintf("%sapi/v3/", client.Endpoint)
   607  	return client, nil
   608  }
   609  
   610  func NewCbrV3Client() (*golangsdk.ServiceClient, error) {
   611  	cc, err := CloudAndClient()
   612  	if err != nil {
   613  		return nil, err
   614  	}
   615  	return openstack.NewCBRService(cc.ProviderClient, golangsdk.EndpointOpts{
   616  		Region: cc.RegionName,
   617  	})
   618  }
   619  
   620  func NewVbsV2Client() (*golangsdk.ServiceClient, error) {
   621  	cc, err := CloudAndClient()
   622  	if err != nil {
   623  		return nil, err
   624  	}
   625  	return openstack.NewVBSServiceV2(cc.ProviderClient, golangsdk.EndpointOpts{
   626  		Region: cc.RegionName,
   627  	})
   628  }
   629  
   630  // NewDataArtsV11Client returns authenticated DataArts v1.1 client
   631  func NewDataArtsV11Client() (*golangsdk.ServiceClient, error) {
   632  	cc, err := CloudAndClient()
   633  	if err != nil {
   634  		return nil, err
   635  	}
   636  	return openstack.NewDataArtsV11(cc.ProviderClient, golangsdk.EndpointOpts{
   637  		Region: cc.RegionName,
   638  	})
   639  }
   640  
   641  // NewDdsV3Client returns authenticated DDS v3 client
   642  func NewDdsV3Client() (*golangsdk.ServiceClient, error) {
   643  	cc, err := CloudAndClient()
   644  	if err != nil {
   645  		return nil, err
   646  	}
   647  	return openstack.NewDDSServiceV3(cc.ProviderClient, golangsdk.EndpointOpts{
   648  		Region: cc.RegionName,
   649  	})
   650  }
   651  
   652  // NewDrsV3Client returns authenticated DDS v3 client
   653  func NewDrsV3Client() (*golangsdk.ServiceClient, error) {
   654  	cc, err := CloudAndClient()
   655  	if err != nil {
   656  		return nil, err
   657  	}
   658  	return openstack.NewDRSServiceV3(cc.ProviderClient, golangsdk.EndpointOpts{
   659  		Region: cc.RegionName,
   660  	})
   661  }
   662  
   663  // NewDcsV1Client returns authenticated DCS v1 client
   664  func NewDcsV1Client() (*golangsdk.ServiceClient, error) {
   665  	cc, err := CloudAndClient()
   666  	if err != nil {
   667  		return nil, err
   668  	}
   669  	return openstack.NewDCSServiceV1(cc.ProviderClient, golangsdk.EndpointOpts{
   670  		Region: cc.RegionName,
   671  	})
   672  }
   673  
   674  // NewDmsV1Client returns authenticated DMS v1 client
   675  func NewDmsV1Client() (*golangsdk.ServiceClient, error) {
   676  	cc, err := CloudAndClient()
   677  	if err != nil {
   678  		return nil, err
   679  	}
   680  	return openstack.NewDMSServiceV1(cc.ProviderClient, golangsdk.EndpointOpts{
   681  		Region: cc.RegionName,
   682  	})
   683  }
   684  
   685  func NewDisV2Client() (*golangsdk.ServiceClient, error) {
   686  	cc, err := CloudAndClient()
   687  	if err != nil {
   688  		return nil, err
   689  	}
   690  	return openstack.NewDISServiceV2(cc.ProviderClient, golangsdk.EndpointOpts{
   691  		Region: cc.RegionName,
   692  	})
   693  }
   694  
   695  func NewDmsV11Client() (*golangsdk.ServiceClient, error) {
   696  	cc, err := CloudAndClient()
   697  	if err != nil {
   698  		return nil, err
   699  	}
   700  	return openstack.NewDMSServiceV11(cc.ProviderClient, golangsdk.EndpointOpts{
   701  		Region: cc.RegionName,
   702  	})
   703  }
   704  
   705  // NewDmsV2Client returns authenticated DMS v2 client
   706  func NewDmsV2Client() (*golangsdk.ServiceClient, error) {
   707  	cc, err := CloudAndClient()
   708  	if err != nil {
   709  		return nil, err
   710  	}
   711  	return openstack.NewDMSServiceV2(cc.ProviderClient, golangsdk.EndpointOpts{
   712  		Region: cc.RegionName,
   713  	})
   714  }
   715  
   716  // NewSwrV2Client returns authenticated SWR v2 client
   717  func NewSwrV2Client() (client *golangsdk.ServiceClient, err error) {
   718  	cc, err := CloudAndClient()
   719  	if err != nil {
   720  		return nil, err
   721  	}
   722  	return openstack.NewSWRV2(cc.ProviderClient, golangsdk.EndpointOpts{
   723  		Region: cc.RegionName,
   724  	})
   725  }
   726  
   727  // NewSmnV2Client returns authenticated SMN v2 client
   728  func NewSmnV2Client() (client *golangsdk.ServiceClient, err error) {
   729  	cc, err := CloudAndClient()
   730  	if err != nil {
   731  		return nil, err
   732  	}
   733  	return openstack.NewSMNV2(cc.ProviderClient, golangsdk.EndpointOpts{
   734  		Region: cc.RegionName,
   735  	})
   736  }
   737  
   738  // NewSmnV2TagsClient returns authenticated SMN v2 tags client
   739  func NewSmnV2TagsClient() (client *golangsdk.ServiceClient, err error) {
   740  	cc, err := CloudAndClient()
   741  	if err != nil {
   742  		return nil, err
   743  	}
   744  	return openstack.NewSMNV2Tags(cc.ProviderClient, golangsdk.EndpointOpts{
   745  		Region: cc.RegionName,
   746  	})
   747  }
   748  
   749  // NewTmsV1Client returns authenticated TMS v1.0 client
   750  func NewTmsV1Client() (client *golangsdk.ServiceClient, err error) {
   751  	iamClient, err := NewIdentityV3AdminClient()
   752  	if err != nil {
   753  		return nil, err
   754  	}
   755  
   756  	iamClient.Endpoint = strings.Replace(iamClient.Endpoint, "v3", "v1.0", 1)
   757  	iamClient.Endpoint = strings.Replace(iamClient.Endpoint, "iam", "tms", 1)
   758  	return iamClient, err
   759  }
   760  
   761  // NewCesV1Client returns authenticated CES v1 client
   762  func NewCesV1Client() (client *golangsdk.ServiceClient, err error) {
   763  	cc, err := CloudAndClient()
   764  	if err != nil {
   765  		return nil, err
   766  	}
   767  	return openstack.NewCESClient(cc.ProviderClient, golangsdk.EndpointOpts{
   768  		Region: cc.RegionName,
   769  	})
   770  }
   771  
   772  // NewLtsV2Client returns authenticated LTS v2 client
   773  func NewLtsV2Client() (client *golangsdk.ServiceClient, err error) {
   774  	cc, err := CloudAndClient()
   775  	if err != nil {
   776  		return nil, err
   777  	}
   778  	return openstack.NewLTSV2(cc.ProviderClient, golangsdk.EndpointOpts{
   779  		Region: cc.RegionName,
   780  	})
   781  }
   782  
   783  func NewGaussDBClient() (client *golangsdk.ServiceClient, err error) {
   784  	cc, err := CloudAndClient()
   785  	if err != nil {
   786  		return nil, err
   787  	}
   788  
   789  	return openstack.NewGaussDBV3(cc.ProviderClient, golangsdk.EndpointOpts{})
   790  }
   791  
   792  // NewAPIGWClient returns authenticated APIGW v2 client
   793  func NewAPIGWClient() (client *golangsdk.ServiceClient, err error) {
   794  	cc, err := CloudAndClient()
   795  	if err != nil {
   796  		return nil, err
   797  	}
   798  	return openstack.NewAPIGW(cc.ProviderClient, golangsdk.EndpointOpts{
   799  		Region: cc.RegionName,
   800  	})
   801  }
   802  
   803  // NewFuncGraphClient returns authenticated FGS v2 client
   804  func NewFuncGraphClient() (client *golangsdk.ServiceClient, err error) {
   805  	cc, err := CloudAndClient()
   806  	if err != nil {
   807  		return nil, err
   808  	}
   809  	return openstack.NewFuncGraph(cc.ProviderClient, golangsdk.EndpointOpts{
   810  		Region: cc.RegionName,
   811  	})
   812  }
   813  
   814  func UpdatePeerTenantDetails(cloud *openstack.Cloud) error {
   815  	if id := EnvOS.GetEnv("Peer_Tenant_ID"); id != "" {
   816  		cloud.AuthInfo.ProjectID = id
   817  		cloud.AuthInfo.ProjectName = ""
   818  		return nil
   819  
   820  	}
   821  	if name := EnvOS.GetEnv("Peer_Tenant_Name"); name != "" {
   822  		cloud.AuthInfo.ProjectID = ""
   823  		cloud.AuthInfo.ProjectName = name
   824  		return nil
   825  	}
   826  	return fmt.Errorf("you're missing some important setup:\n OS_Peer_Tenant_ID or OS_Peer_Tenant_Name env variables must be provided")
   827  }
   828  
   829  // copyCloud makes a deep copy of cloud
   830  func copyCloud(src *openstack.Cloud) (*openstack.Cloud, error) {
   831  	srcJson, err := json.Marshal(src)
   832  	if err != nil {
   833  		return nil, fmt.Errorf("error marshalling cloud: %s", err)
   834  	}
   835  	res := new(openstack.Cloud)
   836  	if err := json.Unmarshal(srcJson, res); err != nil {
   837  		return nil, fmt.Errorf("error unmarshalling cloud: %s", err)
   838  	}
   839  	return res, nil
   840  }
   841  
   842  // cc stands for `cloud` & `client`
   843  type cc struct {
   844  	*openstack.Cloud
   845  	*golangsdk.ProviderClient
   846  }
   847  
   848  // CloudAndClient returns copy of cloud configuration and authenticated client for OS_ environment
   849  func CloudAndClient() (*cc, error) {
   850  	cloud, err := EnvOS.Cloud()
   851  	if err != nil {
   852  		return nil, fmt.Errorf("error constructing cloud configuration: %w", err)
   853  	}
   854  	cloud, err = copyCloud(cloud)
   855  	if err != nil {
   856  		return nil, fmt.Errorf("error copying cloud: %w", err)
   857  	}
   858  	client, err := EnvOS.AuthenticatedClient()
   859  	if err != nil {
   860  		return nil, err
   861  	}
   862  	return &cc{cloud, client}, nil
   863  }
   864  
   865  func setupTemporaryAKSK(config *cc) error {
   866  	if config.AKSKAuthOptions.AccessKey != "" {
   867  		return nil
   868  	}
   869  
   870  	client, err := NewIdentityV3Client()
   871  	if err != nil {
   872  		return fmt.Errorf("error creating identity v3 domain client: %s", err)
   873  	}
   874  	credential, err := credentials.CreateTemporary(client, credentials.CreateTemporaryOpts{
   875  		Methods: []string{"token"},
   876  		Token:   client.Token(),
   877  	}).Extract()
   878  	if err != nil {
   879  		return fmt.Errorf("error creating temporary AK/SK: %s", err)
   880  	}
   881  
   882  	config.AKSKAuthOptions.AccessKey = credential.AccessKey
   883  	config.AKSKAuthOptions.SecretKey = credential.SecretKey
   884  	config.AKSKAuthOptions.SecurityToken = credential.SecurityToken
   885  	return nil
   886  }