github.com/chnsz/golangsdk@v0.0.0-20240506093406-85a3fbfa605b/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/chnsz/golangsdk"
    11  	tokens2 "github.com/chnsz/golangsdk/openstack/identity/v2/tokens"
    12  	"github.com/chnsz/golangsdk/openstack/identity/v3/catalog"
    13  	"github.com/chnsz/golangsdk/openstack/identity/v3/domains"
    14  	"github.com/chnsz/golangsdk/openstack/identity/v3/projects"
    15  	tokens3 "github.com/chnsz/golangsdk/openstack/identity/v3/tokens"
    16  	"github.com/chnsz/golangsdk/openstack/utils"
    17  	"github.com/chnsz/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  	if err != nil {
   298  		return "", err
   299  	}
   300  
   301  	if len(projects) < 1 {
   302  		err := &golangsdk.ErrResourceNotFound{}
   303  		err.ResourceType = "IAM project ID"
   304  		err.Name = name
   305  		return "", err
   306  	}
   307  
   308  	return projects[0].ID, nil
   309  }
   310  
   311  func v3AKSKAuth(client *golangsdk.ProviderClient, endpoint string, options golangsdk.AKSKAuthOptions, eo golangsdk.EndpointOpts) error {
   312  	v3Client, err := NewIdentityV3(client, eo)
   313  	if err != nil {
   314  		return err
   315  	}
   316  
   317  	// Override the generated service endpoint with the one returned by the version endpoint.
   318  	if endpoint != "" {
   319  		v3Client.Endpoint = endpoint
   320  	}
   321  
   322  	// update AKSKAuthOptions of ProviderClient
   323  	// ProviderClient(client) is a reference to the ServiceClient(v3Client)
   324  	defer func() {
   325  		client.AKSKAuthOptions.ProjectId = options.ProjectId
   326  		client.AKSKAuthOptions.DomainID = options.DomainID
   327  	}()
   328  
   329  	client.AKSKAuthOptions = options
   330  	client.AKSKAuthOptions.DomainID = ""
   331  
   332  	if options.ProjectId == "" && options.ProjectName != "" {
   333  		id, err := getProjectID(v3Client, options.ProjectName)
   334  		if err != nil {
   335  			return err
   336  		}
   337  		options.ProjectId = id
   338  		client.AKSKAuthOptions.ProjectId = options.ProjectId
   339  	}
   340  
   341  	if options.DomainID == "" && options.Domain != "" {
   342  		id, err := getDomainID(v3Client, options.Domain)
   343  		if err != nil {
   344  			return err
   345  		}
   346  		options.DomainID = id
   347  	}
   348  
   349  	if options.BssDomainID == "" && options.BssDomain != "" {
   350  		id, err := getDomainID(v3Client, options.BssDomain)
   351  		if err != nil {
   352  			return err
   353  		}
   354  		options.BssDomainID = id
   355  	}
   356  
   357  	client.ProjectID = options.ProjectId
   358  	client.DomainID = options.BssDomainID
   359  
   360  	if !options.WithUserCatalog {
   361  		var entries = make([]tokens3.CatalogEntry, 0, 1)
   362  		err = catalog.List(v3Client).EachPage(func(page pagination.Page) (bool, error) {
   363  			catalogList, err := catalog.ExtractServiceCatalog(page)
   364  			if err != nil {
   365  				return false, err
   366  			}
   367  
   368  			entries = append(entries, catalogList...)
   369  			return true, nil
   370  		})
   371  
   372  		if err != nil {
   373  			return err
   374  		}
   375  
   376  		client.EndpointLocator = func(opts golangsdk.EndpointOpts) (string, error) {
   377  			return V3EndpointURL(&tokens3.ServiceCatalog{
   378  				Entries: entries,
   379  			}, opts)
   380  		}
   381  	}
   382  
   383  	return nil
   384  }
   385  
   386  func authWithAgencyByAKSK(client *golangsdk.ProviderClient, endpoint string, opts golangsdk.AKSKAuthOptions, eo golangsdk.EndpointOpts) error {
   387  
   388  	err := v3AKSKAuth(client, endpoint, opts, eo)
   389  	if err != nil {
   390  		return err
   391  	}
   392  
   393  	v3Client, err := NewIdentityV3(client, eo)
   394  	if err != nil {
   395  		return err
   396  	}
   397  
   398  	if v3Client.AKSKAuthOptions.DomainID == "" {
   399  		return fmt.Errorf("Must config domain name")
   400  	}
   401  
   402  	opts2 := golangsdk.AgencyAuthOptions{
   403  		AgencyName:       opts.AgencyName,
   404  		AgencyDomainName: opts.AgencyDomainName,
   405  		DelegatedProject: opts.DelegatedProject,
   406  	}
   407  	result := tokens3.Create(v3Client, &opts2)
   408  	token, err := result.ExtractToken()
   409  	if err != nil {
   410  		return err
   411  	}
   412  
   413  	project, err := result.ExtractProject()
   414  	if err != nil {
   415  		return err
   416  	}
   417  
   418  	catalog, err := result.ExtractServiceCatalog()
   419  	if err != nil {
   420  		return err
   421  	}
   422  
   423  	client.TokenID = token.ID
   424  	if project != nil {
   425  		client.ProjectID = project.ID
   426  	}
   427  
   428  	client.ReauthFunc = func() error {
   429  		client.TokenID = ""
   430  		return authWithAgencyByAKSK(client, endpoint, opts, eo)
   431  	}
   432  
   433  	client.EndpointLocator = func(opts golangsdk.EndpointOpts) (string, error) {
   434  		return V3EndpointURL(catalog, opts)
   435  	}
   436  
   437  	client.AKSKAuthOptions.AccessKey = ""
   438  	return nil
   439  }
   440  
   441  func getDomainID(client *golangsdk.ServiceClient, name string) (string, error) {
   442  	old := client.Endpoint
   443  	defer func() { client.Endpoint = old }()
   444  
   445  	client.Endpoint = old + "auth/"
   446  
   447  	// the List request does not support query options
   448  	allPages, err := domains.List(client, nil).AllPages()
   449  	if err != nil {
   450  		return "", fmt.Errorf("List domains failed, err=%s", err)
   451  	}
   452  
   453  	all, err := domains.ExtractDomains(allPages)
   454  	if err != nil {
   455  		return "", fmt.Errorf("Extract domains failed, err=%s", err)
   456  	}
   457  
   458  	count := len(all)
   459  	switch count {
   460  	case 0:
   461  		err := &golangsdk.ErrResourceNotFound{}
   462  		err.ResourceType = "IAM domain ID"
   463  		err.Name = name
   464  		return "", err
   465  	case 1:
   466  		if name != "" && name != all[0].Name {
   467  			err := &golangsdk.ErrResourceNotFound{}
   468  			err.ResourceType = "IAM domain ID"
   469  			err.Name = name
   470  			return "", err
   471  		}
   472  		return all[0].ID, nil
   473  	default:
   474  		err := &golangsdk.ErrMultipleResourcesFound{}
   475  		err.ResourceType = "IAM domain ID"
   476  		err.Name = name
   477  		err.Count = count
   478  		return "", err
   479  	}
   480  }
   481  
   482  // NewIdentityV2 creates a ServiceClient that may be used to interact with the
   483  // v2 identity service.
   484  func NewIdentityV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   485  	endpoint := client.IdentityBase + "v2.0/"
   486  	clientType := "identity"
   487  	var err error
   488  	if !reflect.DeepEqual(eo, golangsdk.EndpointOpts{}) {
   489  		eo.ApplyDefaults(clientType)
   490  		endpoint, err = client.EndpointLocator(eo)
   491  		if err != nil {
   492  			return nil, err
   493  		}
   494  	}
   495  
   496  	return &golangsdk.ServiceClient{
   497  		ProviderClient: client,
   498  		Endpoint:       endpoint,
   499  		Type:           clientType,
   500  	}, nil
   501  }
   502  
   503  // NewIdentityV3 creates a ServiceClient that may be used to access the v3
   504  // identity service.
   505  func NewIdentityV3(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   506  	endpoint := client.IdentityBase + "v3/"
   507  	clientType := "identity"
   508  	var err error
   509  	if !reflect.DeepEqual(eo, golangsdk.EndpointOpts{}) {
   510  		eo.ApplyDefaults(clientType)
   511  		endpoint, err = client.EndpointLocator(eo)
   512  		if err != nil {
   513  			return nil, err
   514  		}
   515  	}
   516  
   517  	// Ensure endpoint still has a suffix of v3.
   518  	// This is because EndpointLocator might have found a versionless
   519  	// endpoint and requests will fail unless targeted at /v3.
   520  	if !strings.HasSuffix(endpoint, "v3/") {
   521  		endpoint = endpoint + "v3/"
   522  	}
   523  
   524  	return &golangsdk.ServiceClient{
   525  		ProviderClient: client,
   526  		Endpoint:       endpoint,
   527  		Type:           clientType,
   528  	}, nil
   529  }
   530  
   531  func initClientOpts(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts, clientType string) (*golangsdk.ServiceClient, error) {
   532  	sc := new(golangsdk.ServiceClient)
   533  	eo.ApplyDefaults(clientType)
   534  	url, err := client.EndpointLocator(eo)
   535  	if err != nil {
   536  		return sc, err
   537  	}
   538  	sc.ProviderClient = client
   539  	sc.Endpoint = url
   540  	sc.Type = clientType
   541  	return sc, nil
   542  }
   543  
   544  // initcommonServiceClient create a ServiceClient which can not get from clientType directly.
   545  // firstly, we initialize a service client by "volumev2" type, the endpoint likes https://evs.{region}.{xxx.com}/v2/{project_id}
   546  // then we replace the endpoint with the specified srv and version.
   547  func initcommonServiceClient(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts, srv string, version string) (*golangsdk.ServiceClient, error) {
   548  	sc, err := initClientOpts(client, eo, "volumev2")
   549  	if err != nil {
   550  		return nil, err
   551  	}
   552  
   553  	e := strings.Replace(sc.Endpoint, "v2", version, 1)
   554  	sc.Endpoint = strings.Replace(e, "evs", srv, 1)
   555  	sc.ResourceBase = sc.Endpoint
   556  	return sc, err
   557  }
   558  
   559  // InitServiceClientByName create a ServiceClient which was assembled by service and region name for huaweicloud.
   560  // the endpoint likes https://{eo.Name}.{eo.Region}.myhuaweicloud.com/{apiVersion}/{project_id}
   561  func InitServiceClientByName(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts, apiVersion string) (*golangsdk.ServiceClient, error) {
   562  	if eo.Name == "" || apiVersion == "" {
   563  		return nil, fmt.Errorf("must specify the service name and api version")
   564  	}
   565  
   566  	sc := new(golangsdk.ServiceClient)
   567  	sc.ProviderClient = client
   568  	sc.Endpoint = fmt.Sprintf("https://%s.%s.%s", eo.Name, eo.Region, provider)
   569  	sc.ResourceBase = fmt.Sprintf("%s/%s/%s/", sc.Endpoint, apiVersion, client.ProjectID)
   570  
   571  	return sc, nil
   572  }
   573  
   574  func NewSDKClient(c *golangsdk.ProviderClient, eo golangsdk.EndpointOpts, serviceType string) (*golangsdk.ServiceClient, error) {
   575  	switch serviceType {
   576  	case "mls":
   577  		return NewMLSV1(c, eo)
   578  	case "dws":
   579  		return NewDWSClient(c, eo)
   580  	case "nat":
   581  		return NewNatV2(c, eo)
   582  	}
   583  
   584  	return initClientOpts(c, eo, serviceType)
   585  }
   586  
   587  // ApiGateWayV1 creates a service client that is used for Huawei cloud for API gateway.
   588  // TODO: Need to change to apig client type from apig once available
   589  func ApiGateWayV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   590  	sc, err := initClientOpts(client, eo, "network")
   591  	sc.Endpoint = strings.Replace(sc.Endpoint, "vpc", "apig", 1)
   592  	sc.ResourceBase = sc.Endpoint + "v1.0/apigw/"
   593  	return sc, err
   594  }
   595  
   596  // NewComputeV2 creates a ServiceClient that may be used with the openstack nova compute v2 package.
   597  func NewComputeV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   598  	return initClientOpts(client, eo, "compute")
   599  }
   600  
   601  // NewComputeV1 creates a ServiceClient that may be used with the ecs v1 package.
   602  // Deprecated: use NewEcsV1 instead
   603  func NewComputeV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   604  	sc, err := initClientOpts(client, eo, "network")
   605  	sc.Endpoint = strings.Replace(sc.Endpoint, "vpc", "ecs", 1)
   606  	sc.Endpoint = sc.Endpoint + "v1/"
   607  	sc.ResourceBase = sc.Endpoint + client.ProjectID + "/"
   608  	return sc, err
   609  }
   610  
   611  // NewEcsV1 creates a ServiceClient that may be used with the ecs v1 package.
   612  func NewEcsV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   613  	sc, err := initClientOpts(client, eo, "ecs")
   614  	return sc, err
   615  }
   616  
   617  // NewComputeV11 creates a ServiceClient that may be used with the ecs v1.1 package.
   618  func NewComputeV11(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   619  	sc, err := initClientOpts(client, eo, "ecsv1.1")
   620  	return sc, err
   621  }
   622  
   623  // NewNetworkV2 creates a ServiceClient that may be used with the openstack neutron v2.0 package.
   624  func NewNetworkV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   625  	sc, err := initClientOpts(client, eo, "network")
   626  	sc.ResourceBase = sc.Endpoint + "v2.0/"
   627  	return sc, err
   628  }
   629  
   630  // NewNetworkV1 creates a ServiceClient that may be used with the vpc v1 package.
   631  func NewNetworkV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   632  	sc, err := initClientOpts(client, eo, "network")
   633  	sc.ResourceBase = sc.Endpoint + "v1/"
   634  	return sc, err
   635  }
   636  
   637  // NewVPCV1 creates a ServiceClient that may be used with the vpc v1 package.
   638  func NewVPCV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   639  	sc, err := initClientOpts(client, eo, "vpc")
   640  	return sc, err
   641  }
   642  
   643  // NewBlockStorageV1 creates a ServiceClient that may be used to access the v1
   644  // block storage service.
   645  func NewBlockStorageV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   646  	return initClientOpts(client, eo, "volume")
   647  }
   648  
   649  // NewBlockStorageV2 creates a ServiceClient that may be used to access the v2
   650  // block storage service.
   651  func NewBlockStorageV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   652  	return initClientOpts(client, eo, "volumev2")
   653  }
   654  
   655  // NewBlockStorageV3 creates a ServiceClient that may be used to access the v3 block storage service.
   656  func NewBlockStorageV3(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   657  	return initClientOpts(client, eo, "volumev3")
   658  }
   659  
   660  // NewSharedFileSystemV2 creates a ServiceClient that may be used to access the v2 shared file system service.
   661  func NewSharedFileSystemV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   662  	return initClientOpts(client, eo, "sharev2")
   663  }
   664  
   665  // NewHwSFSV2 creates a service client that is used for Huawei cloud for SFS, it replaces the EVS type.
   666  // TODO: Need to change to sfs client type from evs once available
   667  func NewHwSFSV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   668  	sc, err := initClientOpts(client, eo, "network")
   669  	sc.Endpoint = strings.Replace(sc.Endpoint, "vpc", "sfs", 1)
   670  	sc.ResourceBase = sc.Endpoint + "v2/" + client.ProjectID + "/"
   671  	return sc, err
   672  }
   673  
   674  // NewHwSFSTurboV1 creates a service client that is used for Huawei cloud for SFS Turbo.
   675  func NewHwSFSTurboV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   676  	sc, err := initClientOpts(client, eo, "network")
   677  	sc.Endpoint = strings.Replace(sc.Endpoint, "vpc", "sfs-turbo", 1)
   678  	sc.ResourceBase = sc.Endpoint + "v1/" + client.ProjectID + "/"
   679  	return sc, err
   680  }
   681  
   682  // NewObjectStorageV1 creates a ServiceClient that may be used with the v1
   683  // object storage package.
   684  func NewObjectStorageV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   685  	return initClientOpts(client, eo, "object-store")
   686  }
   687  
   688  // NewOBSService creates a ServiceClient that may be used to access the Object Storage Service.
   689  func NewOBSService(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   690  	sc, err := initClientOpts(client, eo, "object")
   691  	return sc, err
   692  }
   693  
   694  // NewImageServiceV1 creates a ServiceClient that may be used to access the v1
   695  // image service.
   696  func NewImageServiceV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   697  	sc, err := initClientOpts(client, eo, "image")
   698  	sc.ResourceBase = sc.Endpoint + "v1/"
   699  	return sc, err
   700  }
   701  
   702  // NewImageServiceV2 creates a ServiceClient that may be used to access the v2
   703  // image service.
   704  func NewImageServiceV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   705  	sc, err := initClientOpts(client, eo, "image")
   706  	sc.ResourceBase = sc.Endpoint + "v2/"
   707  	return sc, err
   708  }
   709  
   710  // NewLoadBalancerV2 creates a ServiceClient that may be used to access the v2
   711  // load balancer service.
   712  func NewLoadBalancerV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   713  	sc, err := initClientOpts(client, eo, "load-balancer")
   714  	sc.ResourceBase = sc.Endpoint + "v2.0/"
   715  	return sc, err
   716  }
   717  
   718  // NewElbV1 creates a ServiceClient that may be used with the v1 network package.
   719  func NewElbV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts, otctype string) (*golangsdk.ServiceClient, error) {
   720  	sc, err := initClientOpts(client, eo, "compute")
   721  	sc.Endpoint = strings.Replace(strings.Replace(sc.Endpoint, "ecs", otctype, 1), "/v2/", "/v1.0/", 1)
   722  	sc.ResourceBase = sc.Endpoint
   723  	sc.Type = otctype
   724  	return sc, err
   725  }
   726  
   727  // NewELBV1 creates a ServiceClient that may be used to access the ELB service.
   728  func NewELBV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   729  	sc, err := initClientOpts(client, eo, "elbv1")
   730  	return sc, err
   731  }
   732  
   733  func NewElasticLoadBalancer(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   734  	sc, err := initClientOpts(client, eo, "network")
   735  	if err != nil {
   736  		return sc, err
   737  	}
   738  	sc.Endpoint = strings.Replace(sc.Endpoint, "vpc", "elb", 1)
   739  	sc.Endpoint = strings.Replace(sc.Endpoint, "myhwclouds", "myhuaweicloud", 1)
   740  	sc.ResourceBase = sc.Endpoint + "v1.0/"
   741  	return sc, err
   742  }
   743  
   744  // NewDBV1 creates a ServiceClient that may be used to access the v1 DB service.
   745  func NewDBV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   746  	return initClientOpts(client, eo, "database")
   747  }
   748  
   749  // NewRDSV1 creates a ServiceClient that may be used to access the RDS service.
   750  func NewRDSV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   751  	sc, err := initClientOpts(client, eo, "rdsv1")
   752  	if err != nil {
   753  		return initcommonServiceClient(client, eo, "rds", "rds/v1")
   754  	}
   755  	return sc, nil
   756  }
   757  
   758  // NewRDSV3 creates a ServiceClient that may be used to access the RDS service.
   759  func NewRDSV3(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   760  	sc, err := initClientOpts(client, eo, "rdsv3")
   761  	return sc, err
   762  }
   763  
   764  // NewRdsServiceV1 creates the a ServiceClient that may be used to access the v1
   765  // rds service which is a service of db instances management.
   766  func NewRdsServiceV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   767  	newsc, err := initClientOpts(client, eo, "compute")
   768  	rdsendpoint := strings.Replace(strings.Replace(newsc.Endpoint, "ecs", "rds", 1), "/v2/", "/rds/v1/", 1)
   769  	newsc.Endpoint = rdsendpoint
   770  	newsc.ResourceBase = rdsendpoint
   771  	newsc.Type = "rds"
   772  	return newsc, err
   773  }
   774  
   775  func NewRdsTagV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   776  	sc, err := initClientOpts(client, eo, "network")
   777  	sc.Endpoint = strings.Replace(sc.Endpoint, "vpc", "rds", 1)
   778  	sc.Endpoint = sc.Endpoint + "v1/"
   779  	sc.ResourceBase = sc.Endpoint + client.ProjectID + "/rds/"
   780  	return sc, err
   781  }
   782  
   783  // NewCESClient creates a ServiceClient that may be used with the v1 CES service.
   784  func NewCESClient(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   785  	sc, err := initClientOpts(client, eo, "cesv1")
   786  	if err != nil {
   787  		return initcommonServiceClient(client, eo, "ces", "V1.0")
   788  	}
   789  	return sc, nil
   790  }
   791  
   792  // NewDRSServiceV2 creates a ServiceClient that may be used to access the v2 Data Replication Service.
   793  func NewDRSServiceV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   794  	sc, err := initClientOpts(client, eo, "volumev2")
   795  	return sc, err
   796  }
   797  
   798  // NewAutoScalingService creates a ServiceClient that may be used to access the
   799  // auto-scaling service of huawei public cloud
   800  func NewAutoScalingService(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   801  	sc, err := initClientOpts(client, eo, "asv1")
   802  	if err != nil {
   803  		return initcommonServiceClient(client, eo, "as", "autoscaling-api/v1")
   804  	}
   805  	return sc, nil
   806  }
   807  
   808  // NewKMSV1 creates a ServiceClient that may be used to access the KMS service.
   809  func NewKMSV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   810  	sc, err := initClientOpts(client, eo, "kms")
   811  	return sc, err
   812  }
   813  
   814  // NewKmsKeyV1 creates a ServiceClient that may be used to access the kms key service.
   815  // **only used for HCS**
   816  func NewKmsKeyV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   817  	sc, err := initClientOpts(client, eo, "compute")
   818  	sc.Endpoint = strings.Replace(sc.Endpoint, "ecs", "kms", 1)
   819  	sc.Endpoint = sc.Endpoint[:strings.LastIndex(sc.Endpoint, "v2")+3]
   820  	sc.Endpoint = strings.Replace(sc.Endpoint, "v2", "v1.0", 1)
   821  	sc.ResourceBase = sc.Endpoint
   822  	sc.Type = "kms"
   823  	return sc, err
   824  }
   825  
   826  // NewOrchestrationV1 creates a ServiceClient that may be used to access the v1
   827  // orchestration service.
   828  func NewOrchestrationV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   829  	return initClientOpts(client, eo, "orchestration")
   830  }
   831  
   832  // NewDNSV2 creates a ServiceClient that may be used to access the v2 DNS
   833  // service.
   834  func NewDNSV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   835  	sc, err := initClientOpts(client, eo, "dns")
   836  	sc.ResourceBase = sc.Endpoint + "v2/"
   837  	return sc, err
   838  }
   839  
   840  // NewNatV2 creates a ServiceClient that may be used with the v2 nat package.
   841  func NewNatV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   842  	sc, err := initClientOpts(client, eo, "network")
   843  	sc.Endpoint = strings.Replace(sc.Endpoint, "vpc", "nat", 1)
   844  	sc.Endpoint = strings.Replace(sc.Endpoint, "myhwclouds", "myhuaweicloud", 1)
   845  	sc.ResourceBase = sc.Endpoint + "v2.0/"
   846  	return sc, err
   847  }
   848  
   849  // MapReduceV1 creates a ServiceClient that may be used with the v1 MapReduce service.
   850  func MapReduceV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   851  	sc, err := initClientOpts(client, eo, "network")
   852  	sc.Endpoint = strings.Replace(sc.Endpoint, "vpc", "mrs", 1)
   853  	sc.Endpoint = sc.Endpoint + "v1.1/"
   854  	sc.ResourceBase = sc.Endpoint + client.ProjectID + "/"
   855  	return sc, err
   856  }
   857  
   858  // NewMapReduceV1 creates a ServiceClient that may be used with the v1 MapReduce service.
   859  func NewMapReduceV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   860  	sc, err := initClientOpts(client, eo, "mrs")
   861  	sc.ResourceBase = sc.Endpoint + client.ProjectID + "/"
   862  	return sc, err
   863  }
   864  
   865  // NewAntiDDoSV1 creates a ServiceClient that may be used with the v1 Anti DDoS Service package.
   866  func NewAntiDDoSV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   867  	sc, err := initClientOpts(client, eo, "antiddos")
   868  	if err != nil {
   869  		return initcommonServiceClient(client, eo, "antiddos", "v1")
   870  	}
   871  	return sc, nil
   872  }
   873  
   874  // NewAntiDDoSV2 creates a ServiceClient that may be used with the v2 Anti DDoS Service package.
   875  func NewAntiDDoSV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   876  	sc, err := initClientOpts(client, eo, "antiddos")
   877  	sc.ResourceBase = sc.Endpoint + "v2/" + client.ProjectID + "/"
   878  	return sc, err
   879  }
   880  
   881  // NewCCE creates a ServiceClient that may be used to access the CCE service.
   882  func NewCCE(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   883  	sc, err := initClientOpts(client, eo, "ccev2.0")
   884  	sc.ResourceBase = sc.Endpoint + "api/v3/projects/" + client.ProjectID + "/"
   885  	return sc, err
   886  }
   887  
   888  func NewCCEV3(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   889  	sc, err := initClientOpts(client, eo, "network")
   890  	sc.Endpoint = strings.Replace(sc.Endpoint, "vpc", "cce", 1)
   891  	sc.Endpoint = strings.Replace(sc.Endpoint, "myhwclouds", "myhuaweicloud", 1)
   892  	sc.ResourceBase = sc.Endpoint + "api/v3/projects/" + client.ProjectID + "/"
   893  	return sc, err
   894  }
   895  
   896  func NewCCEAddonV3(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   897  	sc, err := initClientOpts(client, eo, "network")
   898  	sc.Endpoint = strings.Replace(sc.Endpoint, "vpc", "cce", 1)
   899  	sc.Endpoint = strings.Replace(sc.Endpoint, "myhwclouds", "myhuaweicloud", 1)
   900  	sc.ResourceBase = sc.Endpoint + "api/v3/"
   901  	return sc, err
   902  }
   903  
   904  // NewDMSServiceV1 creates a ServiceClient that may be used to access the v1 Distributed Message Service.
   905  func NewDMSServiceV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   906  	sc, err := initClientOpts(client, eo, "network")
   907  	sc.Endpoint = strings.Replace(sc.Endpoint, "vpc", "dms", 1)
   908  	sc.ResourceBase = sc.Endpoint + "v1.0/" + client.ProjectID + "/"
   909  	return sc, err
   910  }
   911  
   912  // NewDCSServiceV1 creates a ServiceClient that may be used to access the v1 Distributed Cache Service.
   913  func NewDCSServiceV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   914  	sc, err := initClientOpts(client, eo, "network")
   915  	sc.Endpoint = strings.Replace(sc.Endpoint, "vpc", "dcs", 1)
   916  	sc.ResourceBase = sc.Endpoint + "v1.0/" + client.ProjectID + "/"
   917  	return sc, err
   918  }
   919  
   920  func NewBMSV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   921  	sc, err := initClientOpts(client, eo, "compute")
   922  	e := strings.Replace(sc.Endpoint, "v2", "v2.1", 1)
   923  	sc.Endpoint = e
   924  	sc.ResourceBase = e
   925  	return sc, err
   926  }
   927  
   928  // NewDeHServiceV1 creates a ServiceClient that may be used to access the v1 Dedicated Hosts service.
   929  func NewDeHServiceV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   930  	sc, err := initClientOpts(client, eo, "deh")
   931  	return sc, err
   932  }
   933  
   934  // NewCSBSService creates a ServiceClient that can be used to access the Cloud Server Backup service.
   935  func NewCSBSService(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   936  	sc, err := initClientOpts(client, eo, "data-protect")
   937  	return sc, err
   938  }
   939  
   940  // NewHwCSBSServiceV1 creates a ServiceClient that may be used to access the Huawei Cloud Server Backup service.
   941  func NewHwCSBSServiceV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   942  	sc, err := initClientOpts(client, eo, "compute")
   943  	sc.Endpoint = strings.Replace(sc.Endpoint, "ecs", "csbs", 1)
   944  	e := strings.Replace(sc.Endpoint, "v2", "v1", 1)
   945  	sc.Endpoint = e
   946  	sc.ResourceBase = e
   947  	return sc, err
   948  }
   949  
   950  func NewMLSV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   951  	sc, err := initClientOpts(client, eo, "network")
   952  	sc.Endpoint = strings.Replace(sc.Endpoint, "vpc", "mls", 1)
   953  	sc.ResourceBase = sc.Endpoint + "v1.0/" + client.ProjectID + "/"
   954  	return sc, err
   955  }
   956  
   957  func NewDWSClient(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   958  	sc, err := initcommonServiceClient(client, eo, "dws", "v1.0")
   959  	return sc, err
   960  }
   961  
   962  // NewVBSV2 creates a ServiceClient that may be used to access the VBS service
   963  func NewVBSV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   964  	sc, err := initClientOpts(client, eo, "vbsv2")
   965  	if err != nil {
   966  		return initcommonServiceClient(client, eo, "vbs", "v2")
   967  	}
   968  	return sc, nil
   969  }
   970  
   971  // NewCTSService creates a ServiceClient that can be used to access the Cloud Trace service.
   972  func NewCTSService(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   973  	sc, err := initClientOpts(client, eo, "cts")
   974  	return sc, err
   975  }
   976  
   977  // NewSMNV2 creates a ServiceClient that may be used to access the SMN service.
   978  func NewSMNV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   979  	sc, err := initClientOpts(client, eo, "smnv2")
   980  	if err != nil {
   981  		sc, err = initcommonServiceClient(client, eo, "smn", "v2")
   982  	}
   983  	sc.ResourceBase = sc.Endpoint + "notifications/"
   984  	return sc, err
   985  }
   986  
   987  // NewWAFV1 creates a ServiceClient that may be used to access the WAF service.
   988  func NewWAFV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   989  	sc, err := initClientOpts(client, eo, "waf")
   990  	sc.ResourceBase = sc.Endpoint + "v1/" + client.ProjectID + "/waf/"
   991  	return sc, err
   992  }
   993  
   994  // NewSDRSV1 creates a ServiceClient that may be used to access the SDRS service.
   995  func NewSDRSV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
   996  	sc, err := initClientOpts(client, eo, "sdrs")
   997  	if err != nil {
   998  		return initcommonServiceClient(client, eo, "sdrs", "v1")
   999  	}
  1000  	return sc, nil
  1001  }
  1002  
  1003  // CCIV1 creates a ServiceClient that may be used with the v1 CCI service.
  1004  func CCIV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
  1005  	sc, err := initClientOpts(client, eo, "network")
  1006  	sc.Endpoint = strings.Replace(sc.Endpoint, "vpc", "cci", 1)
  1007  	sc.Endpoint = sc.Endpoint + "apis/networking.cci.io/v1beta1/"
  1008  	sc.ResourceBase = sc.Endpoint
  1009  	return sc, err
  1010  }
  1011  
  1012  // NewBSSV1 creates a ServiceClient that may be used to access the BSS service.
  1013  func NewBSSV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
  1014  	sc, err := initClientOpts(client, eo, "bssv1")
  1015  	return sc, err
  1016  }
  1017  
  1018  // NewDDSV3 creates a ServiceClient that may be used to access the DDS service.
  1019  func NewDDSV3(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
  1020  	sc, err := initClientOpts(client, eo, "ddsv3")
  1021  	return sc, err
  1022  }
  1023  
  1024  // NewLTSV2 creates a ServiceClient that may be used to access the LTS service.
  1025  func NewLTSV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
  1026  	sc, err := initcommonServiceClient(client, eo, "lts", "v2.0")
  1027  	return sc, err
  1028  }
  1029  
  1030  // NewHuaweiLTSV2 creates a ServiceClient that may be used to access the Huawei Cloud LTS service.
  1031  func NewHuaweiLTSV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
  1032  	sc, err := initcommonServiceClient(client, eo, "lts", "v2")
  1033  	return sc, err
  1034  }
  1035  
  1036  // NewFGSV2 creates a ServiceClient that may be used with the v2 as
  1037  // package.
  1038  func NewFGSV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
  1039  	sc, err := initClientOpts(client, eo, "fgsv2")
  1040  	return sc, err
  1041  }
  1042  
  1043  // NewMAASV1 creates a ServiceClient that may be used to access the MAAS service.
  1044  func NewMAASV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
  1045  	sc, err := initClientOpts(client, eo, "maasv1")
  1046  	return sc, err
  1047  }
  1048  
  1049  // MAASV1 creates a ServiceClient that may be used with the v1 MAAS service.
  1050  func MAASV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
  1051  	sc, err := initClientOpts(client, eo, "network")
  1052  	sc.Endpoint = "https://oms.myhuaweicloud.com/v1/"
  1053  	sc.ResourceBase = sc.Endpoint + client.ProjectID + "/"
  1054  	return sc, err
  1055  }
  1056  
  1057  // NewCDNV1 creates a ServiceClient that may be used to access the v1
  1058  // CDN service.
  1059  func NewCDNV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
  1060  	sc, err := initClientOpts(client, eo, "network")
  1061  	sc.Endpoint = "https://cdn.myhuaweicloud.com/"
  1062  	sc.ResourceBase = sc.Endpoint + "v1.0/"
  1063  	return sc, err
  1064  }
  1065  
  1066  // TMSV1 creates a ServiceClient that may be used with the v1 TMS service.
  1067  func TMSV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
  1068  	sc, err := initClientOpts(client, eo, "network")
  1069  	sc.Endpoint = "https://tms.myhuaweicloud.com/v1.0/"
  1070  	sc.ResourceBase = sc.Endpoint
  1071  	return sc, err
  1072  }
  1073  
  1074  // NewGeminiDBV3 creates a ServiceClient that may be used with the GeminiDB service.
  1075  func NewGeminiDBV3(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
  1076  	sc := new(golangsdk.ServiceClient)
  1077  	sc.ProviderClient = client
  1078  	sc.Endpoint = fmt.Sprintf("https://gaussdb-nosql.%s.myhuaweicloud.com", eo.Region)
  1079  	sc.ResourceBase = fmt.Sprintf("%s/v3/%s/", sc.Endpoint, client.ProjectID)
  1080  
  1081  	return sc, nil
  1082  }