github.com/huaweicloud/golangsdk@v0.0.0-20210831081626-d823fe11ceba/openstack/client.go (about)

     1  package openstack
     2  
     3  import (
     4  	"fmt"
     5  	"net/url"
     6  	"reflect"
     7  	"regexp"
     8  	"strings"
     9  
    10  	"github.com/huaweicloud/golangsdk"
    11  	tokens2 "github.com/huaweicloud/golangsdk/openstack/identity/v2/tokens"
    12  	"github.com/huaweicloud/golangsdk/openstack/identity/v3/catalog"
    13  	"github.com/huaweicloud/golangsdk/openstack/identity/v3/domains"
    14  	"github.com/huaweicloud/golangsdk/openstack/identity/v3/projects"
    15  	tokens3 "github.com/huaweicloud/golangsdk/openstack/identity/v3/tokens"
    16  	"github.com/huaweicloud/golangsdk/openstack/utils"
    17  	"github.com/huaweicloud/golangsdk/pagination"
    18  )
    19  
    20  const (
    21  	// v2 represents Keystone v2.
    22  	// It should never increase beyond 2.0.
    23  	v2 = "v2.0"
    24  
    25  	// v3 represents Keystone v3.
    26  	// The version can be anything from v3 to v3.x.
    27  	v3 = "v3"
    28  
    29  	// provider represents the suffix of endpoint url
    30  	provider = "myhuaweicloud.com"
    31  )
    32  
    33  /*
    34  NewClient prepares an unauthenticated ProviderClient instance.
    35  Most users will probably prefer using the AuthenticatedClient function
    36  instead.
    37  
    38  This is useful if you wish to explicitly control the version of the identity
    39  service that's used for authentication explicitly, for example.
    40  
    41  A basic example of using this would be:
    42  
    43  	ao, err := openstack.AuthOptionsFromEnv()
    44  	provider, err := openstack.NewClient(ao.IdentityEndpoint)
    45  	client, err := openstack.NewIdentityV3(provider, golangsdk.EndpointOpts{})
    46  */
    47  func NewClient(endpoint string) (*golangsdk.ProviderClient, error) {
    48  	u, err := url.Parse(endpoint)
    49  	if err != nil {
    50  		return nil, err
    51  	}
    52  
    53  	u.RawQuery, u.Fragment = "", ""
    54  
    55  	var base string
    56  	versionRe := regexp.MustCompile("v[0-9.]+/?")
    57  	if version := versionRe.FindString(u.Path); version != "" {
    58  		base = strings.Replace(u.String(), version, "", -1)
    59  	} else {
    60  		base = u.String()
    61  	}
    62  
    63  	endpoint = golangsdk.NormalizeURL(endpoint)
    64  	base = golangsdk.NormalizeURL(base)
    65  
    66  	p := new(golangsdk.ProviderClient)
    67  	p.IdentityBase = base
    68  	p.IdentityEndpoint = endpoint
    69  	p.UseTokenLock()
    70  
    71  	return p, nil
    72  }
    73  
    74  /*
    75  AuthenticatedClient logs in to an OpenStack cloud found at the identity endpoint
    76  specified by the options, acquires a token, and returns a Provider Client
    77  instance that's ready to operate.
    78  
    79  If the full path to a versioned identity endpoint was specified  (example:
    80  http://example.com:5000/v3), that path will be used as the endpoint to query.
    81  
    82  If a versionless endpoint was specified (example: http://example.com:5000/),
    83  the endpoint will be queried to determine which versions of the identity service
    84  are available, then chooses the most recent or most supported version.
    85  
    86  Example:
    87  
    88  	ao, err := openstack.AuthOptionsFromEnv()
    89  	provider, err := openstack.AuthenticatedClient(ao)
    90  	client, err := openstack.NewNetworkV2(client, golangsdk.EndpointOpts{
    91  		Region: os.Getenv("OS_REGION_NAME"),
    92  	})
    93  */
    94  func AuthenticatedClient(options golangsdk.AuthOptions) (*golangsdk.ProviderClient, error) {
    95  	client, err := NewClient(options.IdentityEndpoint)
    96  	if err != nil {
    97  		return nil, err
    98  	}
    99  
   100  	err = Authenticate(client, options)
   101  	if err != nil {
   102  		return nil, err
   103  	}
   104  	return client, nil
   105  }
   106  
   107  // Authenticate or re-authenticate against the most recent identity service
   108  // supported at the provided endpoint.
   109  func Authenticate(client *golangsdk.ProviderClient, options golangsdk.AuthOptionsProvider) error {
   110  	versions := []*utils.Version{
   111  		{ID: v2, Priority: 20, Suffix: "/v2.0/"},
   112  		{ID: v3, Priority: 30, Suffix: "/v3/"},
   113  	}
   114  
   115  	chosen, endpoint, err := utils.ChooseVersion(client, versions)
   116  	if err != nil {
   117  		return err
   118  	}
   119  
   120  	authOptions, isTokenAuthOptions := options.(golangsdk.AuthOptions)
   121  
   122  	if isTokenAuthOptions {
   123  		switch chosen.ID {
   124  		case v2:
   125  			return v2auth(client, endpoint, authOptions, golangsdk.EndpointOpts{})
   126  		case v3:
   127  			if authOptions.AgencyDomainName != "" && authOptions.AgencyName != "" {
   128  				return v3authWithAgency(client, endpoint, &authOptions, golangsdk.EndpointOpts{})
   129  			}
   130  			return v3auth(client, endpoint, &authOptions, golangsdk.EndpointOpts{})
   131  		default:
   132  			// The switch statement must be out of date from the versions list.
   133  			return fmt.Errorf("Unrecognized identity version: %s", chosen.ID)
   134  		}
   135  	} else {
   136  		akskAuthOptions, isAkSkOptions := options.(golangsdk.AKSKAuthOptions)
   137  
   138  		if isAkSkOptions {
   139  			if akskAuthOptions.AgencyDomainName != "" && akskAuthOptions.AgencyName != "" {
   140  				return authWithAgencyByAKSK(client, endpoint, akskAuthOptions, golangsdk.EndpointOpts{})
   141  			}
   142  			return v3AKSKAuth(client, endpoint, akskAuthOptions, golangsdk.EndpointOpts{})
   143  
   144  		}
   145  		return fmt.Errorf("Unrecognized auth options provider: %s", reflect.TypeOf(options))
   146  	}
   147  
   148  }
   149  
   150  // AuthenticateV2 explicitly authenticates against the identity v2 endpoint.
   151  func AuthenticateV2(client *golangsdk.ProviderClient, options golangsdk.AuthOptions, eo golangsdk.EndpointOpts) error {
   152  	return v2auth(client, "", options, eo)
   153  }
   154  
   155  func v2auth(client *golangsdk.ProviderClient, endpoint string, options golangsdk.AuthOptions, eo golangsdk.EndpointOpts) error {
   156  	v2Client, err := NewIdentityV2(client, eo)
   157  	if err != nil {
   158  		return err
   159  	}
   160  
   161  	if endpoint != "" {
   162  		v2Client.Endpoint = endpoint
   163  	}
   164  
   165  	v2Opts := tokens2.AuthOptions{
   166  		IdentityEndpoint: options.IdentityEndpoint,
   167  		Username:         options.Username,
   168  		Password:         options.Password,
   169  		TenantID:         options.TenantID,
   170  		TenantName:       options.TenantName,
   171  		AllowReauth:      options.AllowReauth,
   172  		TokenID:          options.TokenID,
   173  	}
   174  
   175  	result := tokens2.Create(v2Client, v2Opts)
   176  
   177  	token, err := result.ExtractToken()
   178  	if err != nil {
   179  		return err
   180  	}
   181  
   182  	catalog, err := result.ExtractServiceCatalog()
   183  	if err != nil {
   184  		return err
   185  	}
   186  
   187  	if options.AllowReauth {
   188  		client.ReauthFunc = func() error {
   189  			client.TokenID = ""
   190  			return v2auth(client, endpoint, options, eo)
   191  		}
   192  	}
   193  	client.TokenID = token.ID
   194  	client.ProjectID = token.Tenant.ID
   195  	client.EndpointLocator = func(opts golangsdk.EndpointOpts) (string, error) {
   196  		return V2EndpointURL(catalog, opts)
   197  	}
   198  
   199  	return nil
   200  }
   201  
   202  // AuthenticateV3 explicitly authenticates against the identity v3 service.
   203  func AuthenticateV3(client *golangsdk.ProviderClient, options tokens3.AuthOptionsBuilder, eo golangsdk.EndpointOpts) error {
   204  	return v3auth(client, "", options, eo)
   205  }
   206  
   207  func v3auth(client *golangsdk.ProviderClient, endpoint string, opts tokens3.AuthOptionsBuilder, eo golangsdk.EndpointOpts) error {
   208  	// Override the generated service endpoint with the one returned by the version endpoint.
   209  	v3Client, err := NewIdentityV3(client, eo)
   210  	if err != nil {
   211  		return err
   212  	}
   213  
   214  	if endpoint != "" {
   215  		v3Client.Endpoint = endpoint
   216  	}
   217  
   218  	result := tokens3.Create(v3Client, opts)
   219  
   220  	token, err := result.ExtractToken()
   221  	if err != nil {
   222  		return err
   223  	}
   224  
   225  	project, err := result.ExtractProject()
   226  	if err != nil {
   227  		return err
   228  	}
   229  
   230  	catalog, err := result.ExtractServiceCatalog()
   231  	if err != nil {
   232  		return err
   233  	}
   234  
   235  	client.TokenID = token.ID
   236  	if project != nil {
   237  		client.ProjectID = project.ID
   238  		client.DomainID = project.Domain.ID
   239  	}
   240  
   241  	if opts.CanReauth() {
   242  		client.ReauthFunc = func() error {
   243  			client.TokenID = ""
   244  			return v3auth(client, endpoint, opts, eo)
   245  		}
   246  	}
   247  	client.EndpointLocator = func(opts golangsdk.EndpointOpts) (string, error) {
   248  		return V3EndpointURL(catalog, opts)
   249  	}
   250  
   251  	return nil
   252  }
   253  
   254  func v3authWithAgency(client *golangsdk.ProviderClient, endpoint string, opts *golangsdk.AuthOptions, eo golangsdk.EndpointOpts) error {
   255  	if opts.TokenID == "" {
   256  		err := v3auth(client, endpoint, opts, eo)
   257  		if err != nil {
   258  			return err
   259  		}
   260  	} else {
   261  		client.TokenID = opts.TokenID
   262  	}
   263  
   264  	opts1 := golangsdk.AgencyAuthOptions{
   265  		AgencyName:       opts.AgencyName,
   266  		AgencyDomainName: opts.AgencyDomainName,
   267  		DelegatedProject: opts.DelegatedProject,
   268  	}
   269  
   270  	return v3auth(client, endpoint, &opts1, eo)
   271  }
   272  
   273  func getEntryByServiceId(entries []tokens3.CatalogEntry, serviceId string) *tokens3.CatalogEntry {
   274  	if entries == nil {
   275  		return nil
   276  	}
   277  
   278  	for idx := range entries {
   279  		if entries[idx].ID == serviceId {
   280  			return &entries[idx]
   281  		}
   282  	}
   283  
   284  	return nil
   285  }
   286  
   287  func getProjectID(client *golangsdk.ServiceClient, name string) (string, error) {
   288  	opts := projects.ListOpts{
   289  		Name: name,
   290  	}
   291  	allPages, err := projects.List(client, opts).AllPages()
   292  	if err != nil {
   293  		return "", err
   294  	}
   295  
   296  	projects, err := projects.ExtractProjects(allPages)
   297  
   298  	if err != nil {
   299  		return "", err
   300  	}
   301  
   302  	if len(projects) < 1 {
   303  		return "", fmt.Errorf("[DEBUG] cannot find the tenant: %s", name)
   304  	}
   305  
   306  	return projects[0].ID, nil
   307  }
   308  
   309  func v3AKSKAuth(client *golangsdk.ProviderClient, endpoint string, options golangsdk.AKSKAuthOptions, eo golangsdk.EndpointOpts) error {
   310  	v3Client, err := NewIdentityV3(client, eo)
   311  	if err != nil {
   312  		return err
   313  	}
   314  
   315  	// Override the generated service endpoint with the one returned by the version endpoint.
   316  	if endpoint != "" {
   317  		v3Client.Endpoint = endpoint
   318  	}
   319  
   320  	// update AKSKAuthOptions of ProviderClient
   321  	// ProviderClient(client) is a reference to the ServiceClient(v3Client)
   322  	defer func() {
   323  		client.AKSKAuthOptions.ProjectId = options.ProjectId
   324  		client.AKSKAuthOptions.DomainID = options.DomainID
   325  	}()
   326  
   327  	client.AKSKAuthOptions = options
   328  	client.AKSKAuthOptions.DomainID = ""
   329  
   330  	if options.ProjectId == "" && options.ProjectName != "" {
   331  		id, err := getProjectID(v3Client, options.ProjectName)
   332  		if err != nil {
   333  			return err
   334  		}
   335  		options.ProjectId = id
   336  		client.AKSKAuthOptions.ProjectId = options.ProjectId
   337  	}
   338  
   339  	if options.DomainID == "" && options.Domain != "" {
   340  		id, err := getDomainID(v3Client, options.Domain)
   341  		if err != nil {
   342  			return err
   343  		}
   344  		options.DomainID = id
   345  	}
   346  
   347  	if options.BssDomainID == "" && options.BssDomain != "" {
   348  		id, err := getDomainID(v3Client, options.BssDomain)
   349  		if err != nil {
   350  			return err
   351  		}
   352  		options.BssDomainID = id
   353  	}
   354  
   355  	client.ProjectID = options.ProjectId
   356  	client.DomainID = options.BssDomainID
   357  
   358  	if !options.WithUserCatalog {
   359  		var entries = make([]tokens3.CatalogEntry, 0, 1)
   360  		err = catalog.List(v3Client).EachPage(func(page pagination.Page) (bool, error) {
   361  			catalogList, err := catalog.ExtractServiceCatalog(page)
   362  			if err != nil {
   363  				return false, err
   364  			}
   365  
   366  			entries = append(entries, catalogList...)
   367  			return true, nil
   368  		})
   369  
   370  		if err != nil {
   371  			return err
   372  		}
   373  
   374  		client.EndpointLocator = func(opts golangsdk.EndpointOpts) (string, error) {
   375  			return V3EndpointURL(&tokens3.ServiceCatalog{
   376  				Entries: entries,
   377  			}, opts)
   378  		}
   379  	}
   380  
   381  	return nil
   382  }
   383  
   384  func authWithAgencyByAKSK(client *golangsdk.ProviderClient, endpoint string, opts golangsdk.AKSKAuthOptions, eo golangsdk.EndpointOpts) error {
   385  
   386  	err := v3AKSKAuth(client, endpoint, opts, eo)
   387  	if err != nil {
   388  		return err
   389  	}
   390  
   391  	v3Client, err := NewIdentityV3(client, eo)
   392  	if err != nil {
   393  		return err
   394  	}
   395  
   396  	if v3Client.AKSKAuthOptions.DomainID == "" {
   397  		return fmt.Errorf("Must config domain name")
   398  	}
   399  
   400  	opts2 := golangsdk.AgencyAuthOptions{
   401  		AgencyName:       opts.AgencyName,
   402  		AgencyDomainName: opts.AgencyDomainName,
   403  		DelegatedProject: opts.DelegatedProject,
   404  	}
   405  	result := tokens3.Create(v3Client, &opts2)
   406  	token, err := result.ExtractToken()
   407  	if err != nil {
   408  		return err
   409  	}
   410  
   411  	project, err := result.ExtractProject()
   412  	if err != nil {
   413  		return err
   414  	}
   415  
   416  	catalog, err := result.ExtractServiceCatalog()
   417  	if err != nil {
   418  		return err
   419  	}
   420  
   421  	client.TokenID = token.ID
   422  	if project != nil {
   423  		client.ProjectID = project.ID
   424  	}
   425  
   426  	client.ReauthFunc = func() error {
   427  		client.TokenID = ""
   428  		return authWithAgencyByAKSK(client, endpoint, opts, eo)
   429  	}
   430  
   431  	client.EndpointLocator = func(opts golangsdk.EndpointOpts) (string, error) {
   432  		return V3EndpointURL(catalog, opts)
   433  	}
   434  
   435  	client.AKSKAuthOptions.AccessKey = ""
   436  	return nil
   437  }
   438  
   439  func getDomainID(client *golangsdk.ServiceClient, name string) (string, error) {
   440  	old := client.Endpoint
   441  	defer func() { client.Endpoint = old }()
   442  
   443  	client.Endpoint = old + "auth/"
   444  
   445  	// the List request does not support query options
   446  	allPages, err := domains.List(client, nil).AllPages()
   447  	if err != nil {
   448  		return "", fmt.Errorf("List domains failed, err=%s", err)
   449  	}
   450  
   451  	all, err := domains.ExtractDomains(allPages)
   452  	if err != nil {
   453  		return "", fmt.Errorf("Extract domains failed, err=%s", err)
   454  	}
   455  
   456  	count := len(all)
   457  	switch count {
   458  	case 0:
   459  		err := &golangsdk.ErrResourceNotFound{}
   460  		err.ResourceType = "IAM domain ID"
   461  		err.Name = name
   462  		return "", err
   463  	case 1:
   464  		if name != "" && name != all[0].Name {
   465  			err := &golangsdk.ErrResourceNotFound{}
   466  			err.ResourceType = "IAM domain ID"
   467  			err.Name = name
   468  			return "", err
   469  		}
   470  		return all[0].ID, nil
   471  	default:
   472  		err := &golangsdk.ErrMultipleResourcesFound{}
   473  		err.ResourceType = "IAM domain ID"
   474  		err.Name = name
   475  		err.Count = count
   476  		return "", err
   477  	}
   478  }
   479  
   480  // NewIdentityV2 creates a ServiceClient that may be used to interact with the
   481  // v2 identity service.
   482  func NewIdentityV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   483  	endpoint := client.IdentityBase + "v2.0/"
   484  	clientType := "identity"
   485  	var err error
   486  	if !reflect.DeepEqual(eo, golangsdk.EndpointOpts{}) {
   487  		eo.ApplyDefaults(clientType)
   488  		endpoint, err = client.EndpointLocator(eo)
   489  		if err != nil {
   490  			return nil, err
   491  		}
   492  	}
   493  
   494  	return &golangsdk.ServiceClient{
   495  		ProviderClient: client,
   496  		Endpoint:       endpoint,
   497  		Type:           clientType,
   498  	}, nil
   499  }
   500  
   501  // NewIdentityV3 creates a ServiceClient that may be used to access the v3
   502  // identity service.
   503  func NewIdentityV3(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   504  	endpoint := client.IdentityBase + "v3/"
   505  	clientType := "identity"
   506  	var err error
   507  	if !reflect.DeepEqual(eo, golangsdk.EndpointOpts{}) {
   508  		eo.ApplyDefaults(clientType)
   509  		endpoint, err = client.EndpointLocator(eo)
   510  		if err != nil {
   511  			return nil, err
   512  		}
   513  	}
   514  
   515  	// Ensure endpoint still has a suffix of v3.
   516  	// This is because EndpointLocator might have found a versionless
   517  	// endpoint and requests will fail unless targeted at /v3.
   518  	if !strings.HasSuffix(endpoint, "v3/") {
   519  		endpoint = endpoint + "v3/"
   520  	}
   521  
   522  	return &golangsdk.ServiceClient{
   523  		ProviderClient: client,
   524  		Endpoint:       endpoint,
   525  		Type:           clientType,
   526  	}, nil
   527  }
   528  
   529  func initClientOpts(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts, clientType string) (*golangsdk.ServiceClient, error) {
   530  	sc := new(golangsdk.ServiceClient)
   531  	eo.ApplyDefaults(clientType)
   532  	url, err := client.EndpointLocator(eo)
   533  	if err != nil {
   534  		return sc, err
   535  	}
   536  	sc.ProviderClient = client
   537  	sc.Endpoint = url
   538  	sc.Type = clientType
   539  	return sc, nil
   540  }
   541  
   542  // initcommonServiceClient create a ServiceClient which can not get from clientType directly.
   543  // firstly, we initialize a service client by "volumev2" type, the endpoint likes https://evs.{region}.{xxx.com}/v2/{project_id}
   544  // then we replace the endpoint with the specified srv and version.
   545  func initcommonServiceClient(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts, srv string, version string) (*golangsdk.ServiceClient, error) {
   546  	sc, err := initClientOpts(client, eo, "volumev2")
   547  	if err != nil {
   548  		return nil, err
   549  	}
   550  
   551  	e := strings.Replace(sc.Endpoint, "v2", version, 1)
   552  	sc.Endpoint = strings.Replace(e, "evs", srv, 1)
   553  	sc.ResourceBase = sc.Endpoint
   554  	return sc, err
   555  }
   556  
   557  // InitServiceClientByName create a ServiceClient which was assembled by service and region name for huaweicloud.
   558  // the endpoint likes https://{eo.Name}.{eo.Region}.myhuaweicloud.com/{apiVersion}/{project_id}
   559  func InitServiceClientByName(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts, apiVersion string) (*golangsdk.ServiceClient, error) {
   560  	if eo.Name == "" || apiVersion == "" {
   561  		return nil, fmt.Errorf("must specify the service name and api version")
   562  	}
   563  
   564  	sc := new(golangsdk.ServiceClient)
   565  	sc.ProviderClient = client
   566  	sc.Endpoint = fmt.Sprintf("https://%s.%s.%s", eo.Name, eo.Region, provider)
   567  	sc.ResourceBase = fmt.Sprintf("%s/%s/%s/", sc.Endpoint, apiVersion, client.ProjectID)
   568  
   569  	return sc, nil
   570  }
   571  
   572  func NewSDKClient(c *golangsdk.ProviderClient, eo golangsdk.EndpointOpts, serviceType string) (*golangsdk.ServiceClient, error) {
   573  	switch serviceType {
   574  	case "mls":
   575  		return NewMLSV1(c, eo)
   576  	case "dws":
   577  		return NewDWSClient(c, eo)
   578  	case "nat":
   579  		return NewNatV2(c, eo)
   580  	}
   581  
   582  	return initClientOpts(c, eo, serviceType)
   583  }
   584  
   585  // ApiGateWayV1 creates a service client that is used for Huawei cloud for API gateway.
   586  // TODO: Need to change to apig client type from apig once available
   587  func ApiGateWayV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   588  	sc, err := initClientOpts(client, eo, "network")
   589  	sc.Endpoint = strings.Replace(sc.Endpoint, "vpc", "apig", 1)
   590  	sc.ResourceBase = sc.Endpoint + "v1.0/apigw/"
   591  	return sc, err
   592  }
   593  
   594  // NewComputeV2 creates a ServiceClient that may be used with the openstack nova compute v2 package.
   595  func NewComputeV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   596  	return initClientOpts(client, eo, "compute")
   597  }
   598  
   599  // NewComputeV1 creates a ServiceClient that may be used with the ecs v1 package.
   600  // Deprecated: use NewEcsV1 instead
   601  func NewComputeV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   602  	sc, err := initClientOpts(client, eo, "network")
   603  	sc.Endpoint = strings.Replace(sc.Endpoint, "vpc", "ecs", 1)
   604  	sc.Endpoint = sc.Endpoint + "v1/"
   605  	sc.ResourceBase = sc.Endpoint + client.ProjectID + "/"
   606  	return sc, err
   607  }
   608  
   609  // NewEcsV1 creates a ServiceClient that may be used with the ecs v1 package.
   610  func NewEcsV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   611  	sc, err := initClientOpts(client, eo, "ecs")
   612  	return sc, err
   613  }
   614  
   615  // NewComputeV11 creates a ServiceClient that may be used with the ecs v1.1 package.
   616  func NewComputeV11(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   617  	sc, err := initClientOpts(client, eo, "ecsv1.1")
   618  	return sc, err
   619  }
   620  
   621  // NewNetworkV2 creates a ServiceClient that may be used with the openstack neutron v2.0 package.
   622  func NewNetworkV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   623  	sc, err := initClientOpts(client, eo, "network")
   624  	sc.ResourceBase = sc.Endpoint + "v2.0/"
   625  	return sc, err
   626  }
   627  
   628  // NewNetworkV1 creates a ServiceClient that may be used with the vpc v1 package.
   629  func NewNetworkV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   630  	sc, err := initClientOpts(client, eo, "network")
   631  	sc.ResourceBase = sc.Endpoint + "v1/"
   632  	return sc, err
   633  }
   634  
   635  // NewVPCV1 creates a ServiceClient that may be used with the vpc v1 package.
   636  func NewVPCV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   637  	sc, err := initClientOpts(client, eo, "vpc")
   638  	return sc, err
   639  }
   640  
   641  // NewBlockStorageV1 creates a ServiceClient that may be used to access the v1
   642  // block storage service.
   643  func NewBlockStorageV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   644  	return initClientOpts(client, eo, "volume")
   645  }
   646  
   647  // NewBlockStorageV2 creates a ServiceClient that may be used to access the v2
   648  // block storage service.
   649  func NewBlockStorageV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   650  	return initClientOpts(client, eo, "volumev2")
   651  }
   652  
   653  // NewBlockStorageV3 creates a ServiceClient that may be used to access the v3 block storage service.
   654  func NewBlockStorageV3(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   655  	return initClientOpts(client, eo, "volumev3")
   656  }
   657  
   658  // NewSharedFileSystemV2 creates a ServiceClient that may be used to access the v2 shared file system service.
   659  func NewSharedFileSystemV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   660  	return initClientOpts(client, eo, "sharev2")
   661  }
   662  
   663  //NewHwSFSV2 creates a service client that is used for Huawei cloud  for SFS , it replaces the EVS type.
   664  //TODO: Need to change to sfs client type from evs once available
   665  func NewHwSFSV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   666  	sc, err := initClientOpts(client, eo, "network")
   667  	sc.Endpoint = strings.Replace(sc.Endpoint, "vpc", "sfs", 1)
   668  	sc.ResourceBase = sc.Endpoint + "v2/" + client.ProjectID + "/"
   669  	return sc, err
   670  }
   671  
   672  // NewObjectStorageV1 creates a ServiceClient that may be used with the v1
   673  // object storage package.
   674  func NewObjectStorageV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   675  	return initClientOpts(client, eo, "object-store")
   676  }
   677  
   678  // NewOBSService creates a ServiceClient that may be used to access the Object Storage Service.
   679  func NewOBSService(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   680  	sc, err := initClientOpts(client, eo, "object")
   681  	return sc, err
   682  }
   683  
   684  // NewImageServiceV1 creates a ServiceClient that may be used to access the v1
   685  // image service.
   686  func NewImageServiceV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   687  	sc, err := initClientOpts(client, eo, "image")
   688  	sc.ResourceBase = sc.Endpoint + "v1/"
   689  	return sc, err
   690  }
   691  
   692  // NewImageServiceV2 creates a ServiceClient that may be used to access the v2
   693  // image service.
   694  func NewImageServiceV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   695  	sc, err := initClientOpts(client, eo, "image")
   696  	sc.ResourceBase = sc.Endpoint + "v2/"
   697  	return sc, err
   698  }
   699  
   700  // NewLoadBalancerV2 creates a ServiceClient that may be used to access the v2
   701  // load balancer service.
   702  func NewLoadBalancerV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   703  	sc, err := initClientOpts(client, eo, "load-balancer")
   704  	sc.ResourceBase = sc.Endpoint + "v2.0/"
   705  	return sc, err
   706  }
   707  
   708  // NewElbV1 creates a ServiceClient that may be used with the v1 network package.
   709  func NewElbV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts, otctype string) (*golangsdk.ServiceClient, error) {
   710  	sc, err := initClientOpts(client, eo, "compute")
   711  	sc.Endpoint = strings.Replace(strings.Replace(sc.Endpoint, "ecs", otctype, 1), "/v2/", "/v1.0/", 1)
   712  	sc.ResourceBase = sc.Endpoint
   713  	sc.Type = otctype
   714  	return sc, err
   715  }
   716  
   717  // NewELBV1 creates a ServiceClient that may be used to access the ELB service.
   718  func NewELBV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   719  	sc, err := initClientOpts(client, eo, "elbv1")
   720  	return sc, err
   721  }
   722  
   723  func NewElasticLoadBalancer(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   724  	sc, err := initClientOpts(client, eo, "network")
   725  	if err != nil {
   726  		return sc, err
   727  	}
   728  	sc.Endpoint = strings.Replace(sc.Endpoint, "vpc", "elb", 1)
   729  	sc.Endpoint = strings.Replace(sc.Endpoint, "myhwclouds", "myhuaweicloud", 1)
   730  	sc.ResourceBase = sc.Endpoint + "v1.0/"
   731  	return sc, err
   732  }
   733  
   734  // NewDBV1 creates a ServiceClient that may be used to access the v1 DB service.
   735  func NewDBV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   736  	return initClientOpts(client, eo, "database")
   737  }
   738  
   739  // NewRDSV1 creates a ServiceClient that may be used to access the RDS service.
   740  func NewRDSV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   741  	sc, err := initClientOpts(client, eo, "rdsv1")
   742  	if err != nil {
   743  		return initcommonServiceClient(client, eo, "rds", "rds/v1")
   744  	}
   745  	return sc, nil
   746  }
   747  
   748  // NewRDSV3 creates a ServiceClient that may be used to access the RDS service.
   749  func NewRDSV3(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   750  	sc, err := initClientOpts(client, eo, "rdsv3")
   751  	return sc, err
   752  }
   753  
   754  //NewRdsServiceV1 creates the a ServiceClient that may be used to access the v1
   755  //rds service which is a service of db instances management.
   756  func NewRdsServiceV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   757  	newsc, err := initClientOpts(client, eo, "compute")
   758  	rdsendpoint := strings.Replace(strings.Replace(newsc.Endpoint, "ecs", "rds", 1), "/v2/", "/rds/v1/", 1)
   759  	newsc.Endpoint = rdsendpoint
   760  	newsc.ResourceBase = rdsendpoint
   761  	newsc.Type = "rds"
   762  	return newsc, err
   763  }
   764  
   765  func NewRdsTagV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   766  	sc, err := initClientOpts(client, eo, "network")
   767  	sc.Endpoint = strings.Replace(sc.Endpoint, "vpc", "rds", 1)
   768  	sc.Endpoint = sc.Endpoint + "v1/"
   769  	sc.ResourceBase = sc.Endpoint + client.ProjectID + "/rds/"
   770  	return sc, err
   771  }
   772  
   773  // NewCESClient creates a ServiceClient that may be used with the v1 CES service.
   774  func NewCESClient(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   775  	sc, err := initClientOpts(client, eo, "cesv1")
   776  	if err != nil {
   777  		return initcommonServiceClient(client, eo, "ces", "V1.0")
   778  	}
   779  	return sc, nil
   780  }
   781  
   782  // NewDRSServiceV2 creates a ServiceClient that may be used to access the v2 Data Replication Service.
   783  func NewDRSServiceV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   784  	sc, err := initClientOpts(client, eo, "volumev2")
   785  	return sc, err
   786  }
   787  
   788  //NewAutoScalingService creates a ServiceClient that may be used to access the
   789  //auto-scaling service of huawei public cloud
   790  func NewAutoScalingService(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   791  	sc, err := initClientOpts(client, eo, "asv1")
   792  	if err != nil {
   793  		return initcommonServiceClient(client, eo, "as", "autoscaling-api/v1")
   794  	}
   795  	return sc, nil
   796  }
   797  
   798  // NewKMSV1 creates a ServiceClient that may be used to access the KMS service.
   799  func NewKMSV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   800  	sc, err := initClientOpts(client, eo, "kms")
   801  	return sc, err
   802  }
   803  
   804  // NewKmsKeyV1 creates a ServiceClient that may be used to access the kms key service.
   805  // **only used for HCS**
   806  func NewKmsKeyV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   807  	sc, err := initClientOpts(client, eo, "compute")
   808  	sc.Endpoint = strings.Replace(sc.Endpoint, "ecs", "kms", 1)
   809  	sc.Endpoint = sc.Endpoint[:strings.LastIndex(sc.Endpoint, "v2")+3]
   810  	sc.Endpoint = strings.Replace(sc.Endpoint, "v2", "v1.0", 1)
   811  	sc.ResourceBase = sc.Endpoint
   812  	sc.Type = "kms"
   813  	return sc, err
   814  }
   815  
   816  // NewOrchestrationV1 creates a ServiceClient that may be used to access the v1
   817  // orchestration service.
   818  func NewOrchestrationV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   819  	return initClientOpts(client, eo, "orchestration")
   820  }
   821  
   822  // NewDNSV2 creates a ServiceClient that may be used to access the v2 DNS
   823  // service.
   824  func NewDNSV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   825  	sc, err := initClientOpts(client, eo, "dns")
   826  	sc.ResourceBase = sc.Endpoint + "v2/"
   827  	return sc, err
   828  }
   829  
   830  // NewNatV2 creates a ServiceClient that may be used with the v2 nat package.
   831  func NewNatV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   832  	sc, err := initClientOpts(client, eo, "network")
   833  	sc.Endpoint = strings.Replace(sc.Endpoint, "vpc", "nat", 1)
   834  	sc.Endpoint = strings.Replace(sc.Endpoint, "myhwclouds", "myhuaweicloud", 1)
   835  	sc.ResourceBase = sc.Endpoint + "v2.0/"
   836  	return sc, err
   837  }
   838  
   839  // MapReduceV1 creates a ServiceClient that may be used with the v1 MapReduce service.
   840  func MapReduceV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   841  	sc, err := initClientOpts(client, eo, "network")
   842  	sc.Endpoint = strings.Replace(sc.Endpoint, "vpc", "mrs", 1)
   843  	sc.Endpoint = sc.Endpoint + "v1.1/"
   844  	sc.ResourceBase = sc.Endpoint + client.ProjectID + "/"
   845  	return sc, err
   846  }
   847  
   848  // NewMapReduceV1 creates a ServiceClient that may be used with the v1 MapReduce service.
   849  func NewMapReduceV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   850  	sc, err := initClientOpts(client, eo, "mrs")
   851  	sc.ResourceBase = sc.Endpoint + client.ProjectID + "/"
   852  	return sc, err
   853  }
   854  
   855  // NewAntiDDoSV1 creates a ServiceClient that may be used with the v1 Anti DDoS Service package.
   856  func NewAntiDDoSV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   857  	sc, err := initClientOpts(client, eo, "antiddos")
   858  	if err != nil {
   859  		return initcommonServiceClient(client, eo, "antiddos", "v1")
   860  	}
   861  	return sc, nil
   862  }
   863  
   864  // NewAntiDDoSV2 creates a ServiceClient that may be used with the v2 Anti DDoS Service package.
   865  func NewAntiDDoSV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   866  	sc, err := initClientOpts(client, eo, "antiddos")
   867  	sc.ResourceBase = sc.Endpoint + "v2/" + client.ProjectID + "/"
   868  	return sc, err
   869  }
   870  
   871  // NewCCE creates a ServiceClient that may be used to access the CCE service.
   872  func NewCCE(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   873  	sc, err := initClientOpts(client, eo, "ccev2.0")
   874  	sc.ResourceBase = sc.Endpoint + "api/v3/projects/" + client.ProjectID + "/"
   875  	return sc, err
   876  }
   877  
   878  func NewCCEV3(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   879  	sc, err := initClientOpts(client, eo, "network")
   880  	sc.Endpoint = strings.Replace(sc.Endpoint, "vpc", "cce", 1)
   881  	sc.Endpoint = strings.Replace(sc.Endpoint, "myhwclouds", "myhuaweicloud", 1)
   882  	sc.ResourceBase = sc.Endpoint + "api/v3/projects/" + client.ProjectID + "/"
   883  	return sc, err
   884  }
   885  
   886  func NewCCEAddonV3(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   887  	sc, err := initClientOpts(client, eo, "network")
   888  	sc.Endpoint = strings.Replace(sc.Endpoint, "vpc", "cce", 1)
   889  	sc.Endpoint = strings.Replace(sc.Endpoint, "myhwclouds", "myhuaweicloud", 1)
   890  	sc.ResourceBase = sc.Endpoint + "api/v3/"
   891  	return sc, err
   892  }
   893  
   894  // NewDMSServiceV1 creates a ServiceClient that may be used to access the v1 Distributed Message Service.
   895  func NewDMSServiceV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   896  	sc, err := initClientOpts(client, eo, "network")
   897  	sc.Endpoint = strings.Replace(sc.Endpoint, "vpc", "dms", 1)
   898  	sc.ResourceBase = sc.Endpoint + "v1.0/" + client.ProjectID + "/"
   899  	return sc, err
   900  }
   901  
   902  // NewDCSServiceV1 creates a ServiceClient that may be used to access the v1 Distributed Cache Service.
   903  func NewDCSServiceV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   904  	sc, err := initClientOpts(client, eo, "network")
   905  	sc.Endpoint = strings.Replace(sc.Endpoint, "vpc", "dcs", 1)
   906  	sc.ResourceBase = sc.Endpoint + "v1.0/" + client.ProjectID + "/"
   907  	return sc, err
   908  }
   909  
   910  func NewBMSV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   911  	sc, err := initClientOpts(client, eo, "compute")
   912  	e := strings.Replace(sc.Endpoint, "v2", "v2.1", 1)
   913  	sc.Endpoint = e
   914  	sc.ResourceBase = e
   915  	return sc, err
   916  }
   917  
   918  // NewDeHServiceV1 creates a ServiceClient that may be used to access the v1 Dedicated Hosts service.
   919  func NewDeHServiceV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   920  	sc, err := initClientOpts(client, eo, "deh")
   921  	return sc, err
   922  }
   923  
   924  // NewCSBSService creates a ServiceClient that can be used to access the Cloud Server Backup service.
   925  func NewCSBSService(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   926  	sc, err := initClientOpts(client, eo, "data-protect")
   927  	return sc, err
   928  }
   929  
   930  // NewHwCSBSServiceV1 creates a ServiceClient that may be used to access the Huawei Cloud Server Backup service.
   931  func NewHwCSBSServiceV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   932  	sc, err := initClientOpts(client, eo, "compute")
   933  	sc.Endpoint = strings.Replace(sc.Endpoint, "ecs", "csbs", 1)
   934  	e := strings.Replace(sc.Endpoint, "v2", "v1", 1)
   935  	sc.Endpoint = e
   936  	sc.ResourceBase = e
   937  	return sc, err
   938  }
   939  
   940  func NewMLSV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   941  	sc, err := initClientOpts(client, eo, "network")
   942  	sc.Endpoint = strings.Replace(sc.Endpoint, "vpc", "mls", 1)
   943  	sc.ResourceBase = sc.Endpoint + "v1.0/" + client.ProjectID + "/"
   944  	return sc, err
   945  }
   946  
   947  func NewDWSClient(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   948  	sc, err := initcommonServiceClient(client, eo, "dws", "v1.0")
   949  	return sc, err
   950  }
   951  
   952  // NewVBSV2 creates a ServiceClient that may be used to access the VBS service
   953  func NewVBSV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   954  	sc, err := initClientOpts(client, eo, "vbsv2")
   955  	if err != nil {
   956  		return initcommonServiceClient(client, eo, "vbs", "v2")
   957  	}
   958  	return sc, nil
   959  }
   960  
   961  // NewCTSService creates a ServiceClient that can be used to access the Cloud Trace service.
   962  func NewCTSService(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   963  	sc, err := initClientOpts(client, eo, "cts")
   964  	return sc, err
   965  }
   966  
   967  // NewSMNV2 creates a ServiceClient that may be used to access the SMN service.
   968  func NewSMNV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   969  	sc, err := initClientOpts(client, eo, "smnv2")
   970  	if err != nil {
   971  		sc, err = initcommonServiceClient(client, eo, "smn", "v2")
   972  	}
   973  	sc.ResourceBase = sc.Endpoint + "notifications/"
   974  	return sc, err
   975  }
   976  
   977  // NewWAFV1 creates a ServiceClient that may be used to access the WAF service.
   978  func NewWAFV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   979  	sc, err := initClientOpts(client, eo, "waf")
   980  	sc.ResourceBase = sc.Endpoint + "v1/" + client.ProjectID + "/waf/"
   981  	return sc, err
   982  }
   983  
   984  // NewSDRSV1 creates a ServiceClient that may be used to access the SDRS service.
   985  func NewSDRSV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   986  	sc, err := initClientOpts(client, eo, "sdrs")
   987  	if err != nil {
   988  		return initcommonServiceClient(client, eo, "sdrs", "v1")
   989  	}
   990  	return sc, nil
   991  }
   992  
   993  // CCIV1 creates a ServiceClient that may be used with the v1 CCI service.
   994  func CCIV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   995  	sc, err := initClientOpts(client, eo, "network")
   996  	sc.Endpoint = strings.Replace(sc.Endpoint, "vpc", "cci", 1)
   997  	sc.Endpoint = sc.Endpoint + "apis/networking.cci.io/v1beta1/"
   998  	sc.ResourceBase = sc.Endpoint
   999  	return sc, err
  1000  }
  1001  
  1002  // NewBSSV1 creates a ServiceClient that may be used to access the BSS service.
  1003  func NewBSSV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
  1004  	sc, err := initClientOpts(client, eo, "bssv1")
  1005  	return sc, err
  1006  }
  1007  
  1008  // NewDDSV3 creates a ServiceClient that may be used to access the DDS service.
  1009  func NewDDSV3(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
  1010  	sc, err := initClientOpts(client, eo, "ddsv3")
  1011  	return sc, err
  1012  }
  1013  
  1014  // NewLTSV2 creates a ServiceClient that may be used to access the LTS service.
  1015  func NewLTSV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
  1016  	sc, err := initcommonServiceClient(client, eo, "lts", "v2.0")
  1017  	return sc, err
  1018  }
  1019  
  1020  // NewHuaweiLTSV2 creates a ServiceClient that may be used to access the Huawei Cloud LTS service.
  1021  func NewHuaweiLTSV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
  1022  	sc, err := initcommonServiceClient(client, eo, "lts", "v2")
  1023  	return sc, err
  1024  }
  1025  
  1026  // NewFGSV2 creates a ServiceClient that may be used with the v2 as
  1027  // package.
  1028  func NewFGSV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
  1029  	sc, err := initClientOpts(client, eo, "fgsv2")
  1030  	return sc, err
  1031  }
  1032  
  1033  // NewMAASV1 creates a ServiceClient that may be used to access the MAAS service.
  1034  func NewMAASV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
  1035  	sc, err := initClientOpts(client, eo, "maasv1")
  1036  	return sc, err
  1037  }
  1038  
  1039  // MAASV1 creates a ServiceClient that may be used with the v1 MAAS service.
  1040  func MAASV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
  1041  	sc, err := initClientOpts(client, eo, "network")
  1042  	sc.Endpoint = "https://oms.myhuaweicloud.com/v1/"
  1043  	sc.ResourceBase = sc.Endpoint + client.ProjectID + "/"
  1044  	return sc, err
  1045  }
  1046  
  1047  // NewCDNV1 creates a ServiceClient that may be used to access the v1
  1048  // CDN service.
  1049  func NewCDNV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
  1050  	sc, err := initClientOpts(client, eo, "network")
  1051  	sc.Endpoint = "https://cdn.myhuaweicloud.com/"
  1052  	sc.ResourceBase = sc.Endpoint + "v1.0/"
  1053  	return sc, err
  1054  }
  1055  
  1056  // TMSV1 creates a ServiceClient that may be used with the v1 TMS service.
  1057  func TMSV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
  1058  	sc, err := initClientOpts(client, eo, "network")
  1059  	sc.Endpoint = "https://tms.myhuaweicloud.com/v1.0/"
  1060  	sc.ResourceBase = sc.Endpoint
  1061  	return sc, err
  1062  }
  1063  
  1064  // NewGeminiDBV3 creates a ServiceClient that may be used with the GeminiDB service.
  1065  func NewGeminiDBV3(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
  1066  	sc := new(golangsdk.ServiceClient)
  1067  	sc.ProviderClient = client
  1068  	sc.Endpoint = fmt.Sprintf("https://gaussdb-nosql.%s.myhuaweicloud.com", eo.Region)
  1069  	sc.ResourceBase = fmt.Sprintf("%s/v3/%s/", sc.Endpoint, client.ProjectID)
  1070  
  1071  	return sc, nil
  1072  }
  1073  
  1074  //NewSberIamV3 creates a ServiceClient that may be used with SberCloud IAM client
  1075  func NewSberIamV3(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
  1076  	sc := new(golangsdk.ServiceClient)
  1077  	sc.ProviderClient = client
  1078  	sc.Endpoint = fmt.Sprintf("https://iam.%s.hc.sbercloud.ru/v3/", eo.Region)
  1079  	sc.ResourceBase = sc.Endpoint
  1080  
  1081  	return sc, nil
  1082  }
  1083  
  1084  //NewSberDNSV2 creates a ServiceClient that may be used with SberCloud DNS client
  1085  func NewSberDNSV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
  1086  	sc := new(golangsdk.ServiceClient)
  1087  	sc.ProviderClient = client
  1088  	sc.Endpoint = fmt.Sprintf("https://dns.%s.hc.sbercloud.ru/v2/", eo.Region)
  1089  	sc.ResourceBase = sc.Endpoint
  1090  
  1091  	return sc, nil
  1092  }