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 }