huawei client update

This commit is contained in:
tb365
2021-07-26 19:47:42 +08:00
parent b35e9d7a9a
commit 2996dfcd7a
251 changed files with 25357 additions and 391 deletions
+3
View File
@@ -37,6 +37,7 @@ func init() {
cmd.CreateWithKeyword("create-aws", &options.SAWSCloudAccountCreateOptions{})
cmd.CreateWithKeyword("create-openstack", &options.SOpenStackCloudAccountCreateOptions{})
cmd.CreateWithKeyword("create-huawei", &options.SHuaweiCloudAccountCreateOptions{})
cmd.CreateWithKeyword("create-huaweicloudstack", &options.SHuaweiCloudStackAccountCreateOptions{})
cmd.CreateWithKeyword("create-ucloud", &options.SUcloudCloudAccountCreateOptions{})
cmd.CreateWithKeyword("create-zstack", &options.SZStackCloudAccountCreateOptions{})
cmd.CreateWithKeyword("create-s3", &options.SS3CloudAccountCreateOptions{})
@@ -54,6 +55,7 @@ func init() {
cmd.UpdateWithKeyword("update-aws", &options.SAWSCloudAccountUpdateOptions{})
cmd.UpdateWithKeyword("update-openstack", &options.SOpenStackCloudAccountUpdateOptions{})
cmd.UpdateWithKeyword("update-huawei", &options.SHuaweiCloudAccountUpdateOptions{})
cmd.UpdateWithKeyword("update-huaweicloudstack", &options.SHuaweiCloudStackAccountUpdateOptions{})
cmd.UpdateWithKeyword("update-ucloud", &options.SUcloudCloudAccountUpdateOptions{})
cmd.UpdateWithKeyword("update-zstack", &options.SZStackCloudAccountUpdateOptions{})
cmd.UpdateWithKeyword("update-s3", &options.SS3CloudAccountUpdateOptions{})
@@ -69,6 +71,7 @@ func init() {
cmd.PerformWithKeyword("update-credential-aws", "update-credential", &options.SAWSCloudAccountUpdateCredentialOptions{})
cmd.PerformWithKeyword("update-credential-openstack", "update-credential", &options.SOpenStackCloudAccountUpdateCredentialOptions{})
cmd.PerformWithKeyword("update-credential-huawei", "update-credential", &options.SHuaweiCloudAccountUpdateCredentialOptions{})
cmd.PerformWithKeyword("update-credential-huaweicloudstack", "update-credential", &options.SHuaweiCloudStackAccountUpdateCredentialOptions{})
cmd.PerformWithKeyword("update-credential-ucloud", "update-credential", &options.SUcloudCloudAccountUpdateCredentialOptions{})
cmd.PerformWithKeyword("update-credential-zstack", "update-credential", &options.SZStackCloudAccountUpdateCredentialOptions{})
cmd.PerformWithKeyword("update-credential-s3", "update-credential", &options.SS3CloudAccountUpdateCredentialOptions{})
+147
View File
@@ -0,0 +1,147 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"fmt"
"os"
"yunion.io/x/structarg"
"yunion.io/x/onecloud/pkg/cloudprovider"
huawei "yunion.io/x/onecloud/pkg/multicloud/huaweistack"
_ "yunion.io/x/onecloud/pkg/multicloud/huaweistack/shell"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
type BaseOptions struct {
cloudprovider.SHuaweiCloudStackEndpoints
Help bool `help:"Show help" default:"false"`
Debug bool `help:"Show debug" default:"false"`
AccessKey string `help:"Access key" default:"$HUAWEI_ACCESS_KEY" metavar:"HUAWEI_ACCESS_KEY"`
Secret string `help:"Secret" default:"$HUAWEI_SECRET" metavar:"HUAWEI_SECRET"`
RegionId string `help:"RegionId" default:"$HUAWEI_REGION" metavar:"HUAWEI_REGION"`
ProjectId string `help:"ProjectId" default:"$HUAWEI_PROJECT" metavar:"HUAWEI_PROJECT"`
SUBCOMMAND string `help:"huaweicli subcommand" subcommand:"true"`
}
func getSubcommandParser() (*structarg.ArgumentParser, error) {
parse, e := structarg.NewArgumentParser(&BaseOptions{},
"huaweicli",
"Command-line interface to huawei API.",
`See "huaweicli help COMMAND" for help on a specific command.`)
if e != nil {
return nil, e
}
subcmd := parse.GetSubcommand()
if subcmd == nil {
return nil, fmt.Errorf("No subcommand argument.")
}
type HelpOptions struct {
SUBCOMMAND string `help:"sub-command name"`
}
shellutils.R(&HelpOptions{}, "help", "Show help of a subcommand", func(args *HelpOptions) error {
helpstr, e := subcmd.SubHelpString(args.SUBCOMMAND)
if e != nil {
return e
} else {
fmt.Print(helpstr)
return nil
}
})
for _, v := range shellutils.CommandTable {
_, e := subcmd.AddSubParser(v.Options, v.Command, v.Desc, v.Callback)
if e != nil {
return nil, e
}
}
return parse, nil
}
func showErrorAndExit(e error) {
fmt.Fprintf(os.Stderr, "%s", e)
fmt.Fprintln(os.Stderr)
os.Exit(1)
}
func newClient(options *BaseOptions) (*huawei.SRegion, error) {
if len(options.AccessKey) == 0 {
return nil, fmt.Errorf("Missing accessKey")
}
if len(options.Secret) == 0 {
return nil, fmt.Errorf("Missing secret")
}
cli, err := huawei.NewHuaweiClient(
huawei.NewHuaweiClientConfig(
options.AccessKey,
options.Secret,
options.ProjectId,
&options.SHuaweiCloudStackEndpoints,
).Debug(options.Debug),
)
if err != nil {
return nil, err
}
region := cli.GetRegion(options.RegionId)
if region == nil {
return nil, fmt.Errorf("No such region %s", options.RegionId)
}
return region, nil
}
func main() {
parser, e := getSubcommandParser()
if e != nil {
showErrorAndExit(e)
}
e = parser.ParseArgs(os.Args[1:], false)
options := parser.Options().(*BaseOptions)
if options.Help {
fmt.Print(parser.HelpString())
} else {
subcmd := parser.GetSubcommand()
subparser := subcmd.GetSubParser()
if e != nil {
if subparser != nil {
fmt.Print(subparser.Usage())
} else {
fmt.Print(parser.Usage())
}
showErrorAndExit(e)
} else {
suboptions := subparser.Options()
if options.SUBCOMMAND == "help" {
e = subcmd.Invoke(suboptions)
} else {
var region *huawei.SRegion
region, e = newClient(options)
if e != nil {
showErrorAndExit(e)
}
e = subcmd.Invoke(region, suboptions)
}
if e != nil {
showErrorAndExit(e)
}
}
}
}
+7 -1
View File
@@ -36,6 +36,7 @@ const (
CLOUD_PROVIDER_SYNC_STATUS_IDLE = "idle"
CLOUD_PROVIDER_SYNC_STATUS_ERROR = "error"
CLOUD_PROVIDER_ONECLOUD = "OneCloud"
CLOUD_PROVIDER_VMWARE = "VMware"
CLOUD_PROVIDER_ALIYUN = "Aliyun"
@@ -44,6 +45,7 @@ const (
CLOUD_PROVIDER_AZURE = "Azure"
CLOUD_PROVIDER_AWS = "Aws"
CLOUD_PROVIDER_HUAWEI = "Huawei"
CLOUD_PROVIDER_HUAWEI_CLOUD_STACK = "HuaweiCloudStack"
CLOUD_PROVIDER_OPENSTACK = "OpenStack"
CLOUD_PROVIDER_UCLOUD = "Ucloud"
CLOUD_PROVIDER_ZSTACK = "ZStack"
@@ -94,7 +96,7 @@ const (
var (
CLOUD_PROVIDER_VALID_STATUS = []string{CLOUD_PROVIDER_CONNECTED}
CLOUD_PROVIDER_VALID_HEALTH_STATUS = []string{CLOUD_PROVIDER_HEALTH_NORMAL, CLOUD_PROVIDER_HEALTH_NO_PERMISSION}
PRIVATE_CLOUD_PROVIDERS = []string{CLOUD_PROVIDER_ZSTACK, CLOUD_PROVIDER_OPENSTACK, CLOUD_PROVIDER_APSARA}
PRIVATE_CLOUD_PROVIDERS = []string{CLOUD_PROVIDER_ZSTACK, CLOUD_PROVIDER_OPENSTACK, CLOUD_PROVIDER_APSARA, CLOUD_PROVIDER_HUAWEI_CLOUD_STACK}
CLOUD_PROVIDERS = []string{
CLOUD_PROVIDER_ONECLOUD,
@@ -105,6 +107,7 @@ var (
CLOUD_PROVIDER_AZURE,
CLOUD_PROVIDER_AWS,
CLOUD_PROVIDER_HUAWEI,
CLOUD_PROVIDER_HUAWEI_CLOUD_STACK,
CLOUD_PROVIDER_OPENSTACK,
CLOUD_PROVIDER_UCLOUD,
CLOUD_PROVIDER_ZSTACK,
@@ -140,6 +143,9 @@ var (
CLOUD_PROVIDER_HUAWEI: []string{
HOST_TYPE_HUAWEI,
},
CLOUD_PROVIDER_HUAWEI_CLOUD_STACK: {
HOST_TYPE_HUAWEI_CLOUD_STACK,
},
CLOUD_PROVIDER_OPENSTACK: []string{
HOST_TYPE_OPENSTACK,
},
+5
View File
@@ -159,6 +159,7 @@ const (
HYPERVISOR_AZURE = "azure"
HYPERVISOR_AWS = "aws"
HYPERVISOR_HUAWEI = "huawei"
HYPERVISOR_HUAWEI_CLOUD_STACK = "huaweicloudstack"
HYPERVISOR_OPENSTACK = "openstack"
HYPERVISOR_UCLOUD = "ucloud"
HYPERVISOR_ZSTACK = "zstack"
@@ -189,6 +190,7 @@ var HYPERVISORS = []string{
HYPERVISOR_AWS,
HYPERVISOR_QCLOUD,
HYPERVISOR_HUAWEI,
HYPERVISOR_HUAWEI_CLOUD_STACK,
HYPERVISOR_OPENSTACK,
HYPERVISOR_UCLOUD,
HYPERVISOR_ZSTACK,
@@ -219,6 +221,7 @@ var PRIVATE_CLOUD_HYPERVISORS = []string{
HYPERVISOR_ZSTACK,
HYPERVISOR_OPENSTACK,
HYPERVISOR_APSARA,
HYPERVISOR_HUAWEI_CLOUD_STACK,
}
// var HYPERVISORS = []string{HYPERVISOR_ALIYUN}
@@ -234,6 +237,7 @@ var HYPERVISOR_HOSTTYPE = map[string]string{
HYPERVISOR_AWS: HOST_TYPE_AWS,
HYPERVISOR_QCLOUD: HOST_TYPE_QCLOUD,
HYPERVISOR_HUAWEI: HOST_TYPE_HUAWEI,
HYPERVISOR_HUAWEI_CLOUD_STACK: HOST_TYPE_HUAWEI_CLOUD_STACK,
HYPERVISOR_OPENSTACK: HOST_TYPE_OPENSTACK,
HYPERVISOR_UCLOUD: HOST_TYPE_UCLOUD,
HYPERVISOR_ZSTACK: HOST_TYPE_ZSTACK,
@@ -253,6 +257,7 @@ var HOSTTYPE_HYPERVISOR = map[string]string{
HOST_TYPE_AWS: HYPERVISOR_AWS,
HOST_TYPE_QCLOUD: HYPERVISOR_QCLOUD,
HOST_TYPE_HUAWEI: HYPERVISOR_HUAWEI,
HOST_TYPE_HUAWEI_CLOUD_STACK: HYPERVISOR_HUAWEI_CLOUD_STACK,
HOST_TYPE_OPENSTACK: HYPERVISOR_OPENSTACK,
HOST_TYPE_UCLOUD: HYPERVISOR_UCLOUD,
HOST_TYPE_ZSTACK: HYPERVISOR_ZSTACK,
+2
View File
@@ -29,6 +29,7 @@ const (
HOST_TYPE_QCLOUD = "qcloud"
HOST_TYPE_AZURE = "azure"
HOST_TYPE_HUAWEI = "huawei"
HOST_TYPE_HUAWEI_CLOUD_STACK = "huaweicloudstack"
HOST_TYPE_OPENSTACK = "openstack"
HOST_TYPE_UCLOUD = "ucloud"
HOST_TYPE_ZSTACK = "zstack"
@@ -109,6 +110,7 @@ var HOST_TYPES = []string{
HOST_TYPE_AWS,
HOST_TYPE_QCLOUD,
HOST_TYPE_HUAWEI,
HOST_TYPE_HUAWEI_CLOUD_STACK,
HOST_TYPE_OPENSTACK,
HOST_TYPE_UCLOUD,
HOST_TYPE_ZSTACK,
+1
View File
@@ -59,6 +59,7 @@ var (
REGIONAL_NETWORK_PROVIDERS = []string{
CLOUD_PROVIDER_HUAWEI,
CLOUD_PROVIDER_HUAWEI_CLOUD_STACK,
CLOUD_PROVIDER_CTYUN,
CLOUD_PROVIDER_UCLOUD,
CLOUD_PROVIDER_GOOGLE,
+4
View File
@@ -96,6 +96,9 @@ type SCloudaccountCredential struct {
// 阿里云专有云Endpoints
*SApsaraEndpoints
// Huawei Cloud Stack Online
*SHuaweiCloudStackEndpoints
}
type SCloudaccount struct {
@@ -158,6 +161,7 @@ type ProviderConfig struct {
AccountId string
SApsaraEndpoints
SHuaweiCloudStackEndpoints
ProxyFunc httputils.TransportProxyFunc
}
+106
View File
@@ -14,6 +14,13 @@
package cloudprovider
import (
"reflect"
"strings"
"yunion.io/x/pkg/utils"
)
type SApsaraEndpoints struct {
EcsEndpoint string `default:"$APSARA_ECS_ENDPOINT" metavar:"APSARA_ECS_ENDPOINT"`
RdsEndpoint string `default:"$APSARA_RDS_ENDPOINT"`
@@ -27,3 +34,102 @@ type SApsaraEndpoints struct {
MetricsEndpoint string `default:"$APSRRA_METRICS_ENDPOINT"`
ResourcemanagerEndpoint string `default:"$APSARA_RESOURCEMANAGER_ENDPOINT"`
}
// SHuaweiCloudStackEndpoints 华为私有云endpoints配置
/*
endpoint获取方式优先级:
通过参数明确指定使用指定endpoint。否则,程序根据华为云endpoint命名规则自动拼接endpoint
*/
type SHuaweiCloudStackEndpoints struct {
caches map[string]string
// 华为私有云Endpoint域名
// example: hcso.com.cn
// required:true
EndpointDomain string `default:"$HUAWEI_ENDPOINT_DOMAIN" metavar:"HUAWEI_ENDPOINT_DOMAIN"`
// 可用区ID
// example: cn-north-2
// required: true
DefaultRegion string `default:"$HUAWEI_DEFAULT_REGION" metavar:"$HUAWEI_DEFAULT_REGION"`
// 弹性云服务
Ecs string `default:"$HUAWEI_ECS_ENDPOINT"`
// 云容器服务
Cce string `default:"$HUAWEI_CCE_ENDPOINT"`
// 弹性伸缩服务
As string `default:"$HUAWEI_AS_ENDPOINT"`
// 统一身份认证服务
Iam string `default:"$HUAWEI_IAM_ENDPOINT"`
// 镜像服务
Ims string `default:"$HUAWEI_IMS_ENDPOINT"`
// 云服务器备份服务
Csbs string `default:"$HUAWEI_CSBS_ENDPOINT"`
// 云容器实例 CCI
Cci string `default:"$HUAWEI_CCI_ENDPOINT"`
// 裸金属服务器
Bms string `default:"$HUAWEI_BMS_ENDPOINT"`
// 云硬盘 EVS
Evs string `default:"$HUAWEI_EVS_ENDPOINT"`
// 云硬盘备份 VBS
Vbs string `default:"$HUAWEI_VBS_ENDPOINT"`
// 对象存储服务 OBS
Obs string `default:"$HUAWEI_OBS_ENDPOINT"`
// 虚拟私有云 VPC
Vpc string `default:"$HUAWEI_VPC_ENDPOINT"`
// 弹性负载均衡 ELB
Elb string `default:"$HUAWEI_ELB_ENDPOINT"`
// 合作伙伴运营能力
Bss string `default:"$HUAWEI_BSS_ENDPOINT"`
// Nat网关 NAT
Nat string `default:"$HUAWEI_NAT_ENDPOINT"`
// 分布式缓存服务
Dcs string `default:"$HUAWEI_DCS_ENDPOINT"`
// 关系型数据库 RDS
Rds string `default:"$HUAWEI_RDS_ENDPOINT"`
// 云审计服务
Cts string `default:"$HUAWEI_CTS_ENDPOINT"`
// 监控服务 CloudEye
Ces string `default:"$HUAWEI_CES_ENDPOINT"`
// 企业项目
Eps string `default:"$HUAWEI_EPS_ENDPOINT"`
// 文件系统
SfsTurbo string `default:"$HUAWEI_SFS_TURBO_ENDPOINT"`
}
func (self *SHuaweiCloudStackEndpoints) GetEndpoint(serviceName string, region string) string {
sn := utils.Kebab2Camel(serviceName, "-")
if self.caches == nil {
self.caches = make(map[string]string, 0)
}
key := self.DefaultRegion + "." + sn
if len(region) > 0 {
key = region + "." + sn
}
if endpoint, ok := self.caches[key]; ok && len(endpoint) > 0 {
return endpoint
}
var endpoint string
fileds := reflect.Indirect(reflect.ValueOf(self))
f := fileds.FieldByNameFunc(func(c string) bool {
return strings.ToLower(c) == sn
})
if f.Kind() == reflect.String {
endpoint = f.String()
}
if len(endpoint) == 0 {
endpoint = strings.Join([]string{serviceName, self.DefaultRegion, self.EndpointDomain}, ".")
}
if len(region) > 0 {
endpoint = strings.Replace(endpoint, self.DefaultRegion, region, 1)
}
self.caches[key] = endpoint
return endpoint
}
+157
View File
@@ -0,0 +1,157 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package guestdrivers
import (
"fmt"
"yunion.io/x/pkg/utils"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/billing"
"yunion.io/x/onecloud/pkg/util/rbacutils"
)
type SHuaweiCloudStackGuestDriver struct {
SManagedVirtualizedGuestDriver
}
func init() {
driver := SHuaweiCloudStackGuestDriver{}
models.RegisterGuestDriver(&driver)
}
func (self *SHuaweiCloudStackGuestDriver) GetHypervisor() string {
return api.HYPERVISOR_HUAWEI_CLOUD_STACK
}
func (self *SHuaweiCloudStackGuestDriver) GetProvider() string {
return api.CLOUD_PROVIDER_HUAWEI_CLOUD_STACK
}
func (self *SHuaweiCloudStackGuestDriver) GetComputeQuotaKeys(scope rbacutils.TRbacScope, ownerId mcclient.IIdentityProvider, brand string) models.SComputeResourceKeys {
keys := models.SComputeResourceKeys{}
keys.SBaseProjectQuotaKeys = quotas.OwnerIdProjectQuotaKeys(scope, ownerId)
keys.CloudEnv = api.CLOUD_ENV_PRIVATE_CLOUD
keys.Provider = api.CLOUD_PROVIDER_HUAWEI_CLOUD_STACK
keys.Brand = api.CLOUD_PROVIDER_HUAWEI_CLOUD_STACK
keys.Hypervisor = api.HYPERVISOR_HUAWEI_CLOUD_STACK
return keys
}
func (self *SHuaweiCloudStackGuestDriver) GetDefaultSysDiskBackend() string {
return api.STORAGE_HUAWEI_SAS
}
func (self *SHuaweiCloudStackGuestDriver) GetMinimalSysDiskSizeGb() int {
return 40
}
func (self *SHuaweiCloudStackGuestDriver) GetStorageTypes() []string {
return []string{api.STORAGE_HUAWEI_SATA, api.STORAGE_HUAWEI_SAS, api.STORAGE_HUAWEI_SSD}
}
func (self *SHuaweiCloudStackGuestDriver) ChooseHostStorage(host *models.SHost, guest *models.SGuest, diskConfig *api.DiskConfig, storageIds []string) (*models.SStorage, error) {
return self.chooseHostStorage(self, host, diskConfig.Backend, storageIds), nil
}
func (self *SHuaweiCloudStackGuestDriver) GetDetachDiskStatus() ([]string, error) {
return []string{api.VM_READY, api.VM_RUNNING}, nil
}
func (self *SHuaweiCloudStackGuestDriver) GetAttachDiskStatus() ([]string, error) {
return []string{api.VM_READY, api.VM_RUNNING}, nil
}
func (self *SHuaweiCloudStackGuestDriver) GetRebuildRootStatus() ([]string, error) {
return []string{api.VM_READY, api.VM_RUNNING}, nil
}
func (self *SHuaweiCloudStackGuestDriver) GetChangeConfigStatus(guest *models.SGuest) ([]string, error) {
return []string{api.VM_READY}, nil
}
func (self *SHuaweiCloudStackGuestDriver) GetDeployStatus() ([]string, error) {
return []string{api.VM_READY, api.VM_RUNNING}, nil
}
func (self *SHuaweiCloudStackGuestDriver) ValidateResizeDisk(guest *models.SGuest, disk *models.SDisk, storage *models.SStorage) error {
if !utils.IsInStringArray(guest.Status, []string{api.VM_RUNNING, api.VM_READY}) {
return fmt.Errorf("Cannot resize disk when guest in status %s", guest.Status)
}
if !utils.IsInStringArray(storage.StorageType, []string{api.STORAGE_HUAWEI_SATA, api.STORAGE_HUAWEI_SAS, api.STORAGE_HUAWEI_SSD}) {
return fmt.Errorf("Cannot resize disk with unsupported volumes type %s", storage.StorageType)
}
return nil
}
func (self *SHuaweiCloudStackGuestDriver) GetGuestInitialStateAfterCreate() string {
return api.VM_RUNNING
}
func (self *SHuaweiCloudStackGuestDriver) GetGuestInitialStateAfterRebuild() string {
return api.VM_RUNNING
}
func (self *SHuaweiCloudStackGuestDriver) GetInstanceCapability() cloudprovider.SInstanceCapability {
return cloudprovider.SInstanceCapability{
Hypervisor: self.GetHypervisor(),
Provider: self.GetProvider(),
DefaultAccount: cloudprovider.SDefaultAccount{
Linux: cloudprovider.SOsDefaultAccount{
DefaultAccount: api.VM_DEFAULT_LINUX_LOGIN_USER,
},
Windows: cloudprovider.SOsDefaultAccount{
DefaultAccount: api.VM_DEFAULT_WINDOWS_LOGIN_USER,
},
},
Storages: cloudprovider.Storage{
DataDisk: []cloudprovider.StorageInfo{
cloudprovider.StorageInfo{StorageType: api.STORAGE_HUAWEI_SSD, MaxSizeGb: 32768, MinSizeGb: 10, StepSizeGb: 1, Resizable: true},
cloudprovider.StorageInfo{StorageType: api.STORAGE_HUAWEI_SATA, MaxSizeGb: 32768, MinSizeGb: 10, StepSizeGb: 1, Resizable: true},
cloudprovider.StorageInfo{StorageType: api.STORAGE_HUAWEI_SAS, MaxSizeGb: 32768, MinSizeGb: 10, StepSizeGb: 1, Resizable: true},
cloudprovider.StorageInfo{StorageType: api.STORAGE_HUAWEI_GPSSD, MaxSizeGb: 32768, MinSizeGb: 10, StepSizeGb: 1, Resizable: true},
},
SysDisk: []cloudprovider.StorageInfo{
cloudprovider.StorageInfo{StorageType: api.STORAGE_HUAWEI_SSD, MaxSizeGb: 1024, MinSizeGb: 40, StepSizeGb: 1, Resizable: false},
cloudprovider.StorageInfo{StorageType: api.STORAGE_HUAWEI_SATA, MaxSizeGb: 1024, MinSizeGb: 40, StepSizeGb: 1, Resizable: false},
cloudprovider.StorageInfo{StorageType: api.STORAGE_HUAWEI_SAS, MaxSizeGb: 1024, MinSizeGb: 40, StepSizeGb: 1, Resizable: false},
cloudprovider.StorageInfo{StorageType: api.STORAGE_HUAWEI_GPSSD, MaxSizeGb: 1024, MinSizeGb: 40, StepSizeGb: 1, Resizable: false},
},
},
}
}
func (self *SHuaweiCloudStackGuestDriver) IsSupportedBillingCycle(bc billing.SBillingCycle) bool {
months := bc.GetMonths()
if (months >= 1 && months <= 9) || (months == 12) || (months == 24) || (months == 36) {
return true
}
return false
}
func (self *SHuaweiCloudStackGuestDriver) IsNeedInjectPasswordByCloudInit(desc *cloudprovider.SManagedVMCreateConfig) bool {
return true
}
func (self *SHuaweiCloudStackGuestDriver) IsSupportSetAutoRenew() bool {
return true
}
+73
View File
@@ -0,0 +1,73 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package hostdrivers
import (
"context"
"fmt"
"yunion.io/x/jsonutils"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
)
type SHuaweiCloudStackHostDriver struct {
SManagedVirtualizationHostDriver
}
func init() {
driver := SHuaweiCloudStackHostDriver{}
models.RegisterHostDriver(&driver)
}
func (self *SHuaweiCloudStackHostDriver) GetHostType() string {
return api.HOST_TYPE_HUAWEI_CLOUD_STACK
}
func (self *SHuaweiCloudStackHostDriver) GetHypervisor() string {
return api.HYPERVISOR_HUAWEI_CLOUD_STACK
}
// 系统盘必须至少40G
func (self *SHuaweiCloudStackHostDriver) ValidateDiskSize(storage *models.SStorage, sizeGb int) error {
switch storage.StorageType {
case api.STORAGE_HUAWEI_SSD, api.STORAGE_HUAWEI_SATA, api.STORAGE_HUAWEI_SAS:
if sizeGb < 10 || sizeGb > 32768 {
return fmt.Errorf("The %s disk size must be in the range of 10G ~ 32768GB", storage.StorageType)
}
default:
return fmt.Errorf("Not support create %s disk", storage.StorageType)
}
return nil
}
func (self *SHuaweiCloudStackHostDriver) ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, snapshot *models.SSnapshot, guests []models.SGuest, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
if len(guests) >= 1 {
if disk.DiskType == api.DISK_TYPE_SYS {
for _, g := range guests {
if g.Status != api.VM_READY {
return nil, httperrors.NewBadRequestError("Server %s must in status ready", g.GetName())
}
}
} else {
return nil, httperrors.NewBadRequestError("Disk must be detached")
}
}
return data, nil
}
+1 -1
View File
@@ -54,7 +54,7 @@ func (self *SManagedVirtualizationHostDriver) CheckAndSetCacheImage(ctx context.
}
providerName := storageCache.GetProviderName()
if utils.IsInStringArray(providerName, []string{api.CLOUD_PROVIDER_HUAWEI, api.CLOUD_PROVIDER_UCLOUD}) {
if utils.IsInStringArray(providerName, []string{api.CLOUD_PROVIDER_HUAWEI, api.CLOUD_PROVIDER_HUAWEI_CLOUD_STACK, api.CLOUD_PROVIDER_UCLOUD}) {
image.OsVersion, _ = params.GetString("os_full_version")
}
+26 -8
View File
@@ -436,13 +436,25 @@ func (manager *SCloudaccountManager) validateCreateData(
input.Zone = obj.GetId()
}
var endpointOptions jsonutils.JSONObject
endpoints := cloudprovider.SApsaraEndpoints{}
if input.SCloudaccountCredential.SApsaraEndpoints != nil {
endpoints = *input.SCloudaccountCredential.SApsaraEndpoints
endpointOptions = jsonutils.Marshal(input.SCloudaccountCredential.SApsaraEndpoints)
}
hcsoEndpoints := cloudprovider.SHuaweiCloudStackEndpoints{}
if input.SCloudaccountCredential.SHuaweiCloudStackEndpoints != nil {
hcsoEndpoints = *input.SCloudaccountCredential.SHuaweiCloudStackEndpoints
endpointOptions = jsonutils.Marshal(input.SCloudaccountCredential.SHuaweiCloudStackEndpoints)
}
if endpointOptions != nil {
if input.Options == nil {
input.Options = jsonutils.NewDict()
}
endpoints = *input.SCloudaccountCredential.SApsaraEndpoints
input.Options.Update(jsonutils.Marshal(input.SCloudaccountCredential.SApsaraEndpoints))
input.Options.Update(endpointOptions)
}
input.SCloudaccount, err = providerDriver.ValidateCreateCloudaccountData(ctx, userCred, input.SCloudaccountCredential)
@@ -499,7 +511,8 @@ func (manager *SCloudaccountManager) validateCreateData(
Secret: input.Secret,
ProxyFunc: proxyFunc,
SApsaraEndpoints: endpoints,
SApsaraEndpoints: endpoints,
SHuaweiCloudStackEndpoints: hcsoEndpoints,
})
if err != nil {
if err == cloudprovider.ErrNoSuchProvder {
@@ -903,8 +916,13 @@ func (self *SCloudaccount) getProviderInternal() (cloudprovider.ICloudProvider,
return nil, fmt.Errorf("Invalid password %s", err)
}
endpoints := cloudprovider.SApsaraEndpoints{}
if self.Provider == api.CLOUD_PROVIDER_APSARA && self.Options != nil {
self.Options.Unmarshal(&endpoints)
hcsoEndpoints := cloudprovider.SHuaweiCloudStackEndpoints{}
if self.Options != nil {
if self.Provider == api.CLOUD_PROVIDER_HUAWEI_CLOUD_STACK {
self.Options.Unmarshal(&hcsoEndpoints)
} else if self.Provider == api.CLOUD_PROVIDER_APSARA {
self.Options.Unmarshal(&endpoints)
}
}
return cloudprovider.GetProvider(cloudprovider.ProviderConfig{
Id: self.Id,
@@ -914,9 +932,9 @@ func (self *SCloudaccount) getProviderInternal() (cloudprovider.ICloudProvider,
Account: self.Account,
Secret: secret,
SApsaraEndpoints: endpoints,
ProxyFunc: self.proxyFunc(),
SApsaraEndpoints: endpoints,
SHuaweiCloudStackEndpoints: hcsoEndpoints,
ProxyFunc: self.proxyFunc(),
})
}
+8 -2
View File
@@ -875,8 +875,13 @@ func (self *SCloudprovider) GetProvider() (cloudprovider.ICloudProvider, error)
account := self.GetCloudaccount()
endpoints := cloudprovider.SApsaraEndpoints{}
hscsoEndpoints := cloudprovider.SHuaweiCloudStackEndpoints{}
if account.Options != nil {
account.Options.Unmarshal(&endpoints)
if self.Provider == api.CLOUD_PROVIDER_HUAWEI_CLOUD_STACK {
account.Options.Unmarshal(&hscsoEndpoints)
} else if self.Provider == api.CLOUD_PROVIDER_APSARA {
account.Options.Unmarshal(&endpoints)
}
}
return cloudprovider.GetProvider(cloudprovider.ProviderConfig{
@@ -888,7 +893,8 @@ func (self *SCloudprovider) GetProvider() (cloudprovider.ICloudProvider, error)
Secret: passwd,
ProxyFunc: account.proxyFunc(),
SApsaraEndpoints: endpoints,
SApsaraEndpoints: endpoints,
SHuaweiCloudStackEndpoints: hscsoEndpoints,
})
}
+1 -1
View File
@@ -615,7 +615,7 @@ func (self *SSecurityGroupCache) StartSecurityGroupCacheDeleteTask(ctx context.C
}
func (manager *SSecurityGroupCacheManager) InitializeData() error {
providerIds := CloudproviderManager.Query("id").In("provider", []string{api.CLOUD_PROVIDER_HUAWEI, api.CLOUD_PROVIDER_CTYUN, api.CLOUD_PROVIDER_QCLOUD}).SubQuery()
providerIds := CloudproviderManager.Query("id").In("provider", []string{api.CLOUD_PROVIDER_HUAWEI, api.CLOUD_PROVIDER_HUAWEI_CLOUD_STACK, api.CLOUD_PROVIDER_CTYUN, api.CLOUD_PROVIDER_QCLOUD}).SubQuery()
deprecatedSecgroups := []SSecurityGroupCache{}
q := manager.Query().In("manager_id", providerIds).NotEquals("vpc_id", api.NORMAL_VPC_ID)
+19
View File
@@ -0,0 +1,19 @@
package regiondrivers
import (
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/compute/models"
)
type SHuaweiCloudStackRegionDriver struct {
SHuaWeiRegionDriver
}
func init() {
driver := SHuaweiCloudStackRegionDriver{}
models.RegisterRegionDriver(&driver)
}
func (self *SHuaweiCloudStackRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_HUAWEI_CLOUD_STACK
}
+30
View File
@@ -271,6 +271,18 @@ func (opts *SHuaweiCloudAccountCreateOptions) Params() (jsonutils.JSONObject, er
return params, nil
}
type SHuaweiCloudStackAccountCreateOptions struct {
SCloudAccountCreateBaseOptions
cloudprovider.SHuaweiCloudStackEndpoints
SAccessKeyCredential
}
func (opts *SHuaweiCloudStackAccountCreateOptions) Params() (jsonutils.JSONObject, error) {
params := jsonutils.Marshal(opts)
params.(*jsonutils.JSONDict).Add(jsonutils.NewString("HuaweiCloudStack"), "provider")
return params, nil
}
type SUcloudCloudAccountCreateOptions struct {
SCloudAccountCreateBaseOptions
SAccessKeyCredential
@@ -425,6 +437,16 @@ func (opts *SHuaweiCloudAccountUpdateCredentialOptions) Params() (jsonutils.JSON
return jsonutils.Marshal(opts), nil
}
type SHuaweiCloudStackAccountUpdateCredentialOptions struct {
SCloudAccountIdOptions
cloudprovider.SHuaweiCloudStackEndpoints
SAccessKeyCredential
}
func (opts *SHuaweiCloudStackAccountUpdateCredentialOptions) Params() (jsonutils.JSONObject, error) {
return jsonutils.Marshal(opts), nil
}
type SUcloudCloudAccountUpdateCredentialOptions struct {
SCloudAccountIdOptions
SAccessKeyCredential
@@ -728,6 +750,14 @@ func (opts *SHuaweiCloudAccountUpdateOptions) Params() (jsonutils.JSONObject, er
return params, nil
}
type SHuaweiCloudStackAccountUpdateOptions struct {
SCloudAccountUpdateBaseOptions
}
func (opts *SHuaweiCloudStackAccountUpdateOptions) Params() (jsonutils.JSONObject, error) {
return jsonutils.Marshal(opts), nil
}
type SUcloudCloudAccountUpdateOptions struct {
SCloudAccountUpdateBaseOptions
}
+117 -90
View File
@@ -23,13 +23,7 @@ import (
)
type Client struct {
signer auth.Signer
regionId string
domainId string
projectId string
debug bool
cfg *SClientConfig
// 标记初始化状态
init bool
@@ -92,6 +86,40 @@ type Client struct {
SfsTurbos *modules.SfsTurboManager
}
type SClientConfig struct {
signer auth.Signer
endpoint string // myhuaweicloud.com
regionId string
domainId string
projectId string
debug bool
}
func (self *SClientConfig) GetSigner() auth.Signer {
return self.signer
}
func (self *SClientConfig) GetEndpoint() string {
return self.endpoint
}
func (self *SClientConfig) GetRegionId() string {
return self.regionId
}
func (self *SClientConfig) GetDomainId() string {
return self.domainId
}
func (self *SClientConfig) GetProjectId() string {
return self.projectId
}
func (self *SClientConfig) GetDebug() bool {
return self.debug
}
func (self *Client) SetHttpClient(httpClient *http.Client) {
self.Credentials.SetHttpClient(httpClient)
self.Servers.SetHttpClient(httpClient)
@@ -150,103 +178,102 @@ func (self *Client) SetHttpClient(httpClient *http.Client) {
self.SfsTurbos.SetHttpClient(httpClient)
}
func (self *Client) InitWithOptions(regionId, domainId, projectId string, credential auth.Credential) error {
// 从signer中初始化
signer, err := auth.NewSignerWithCredential(credential)
if err != nil {
return err
}
self.signer = signer
self.regionId = regionId
self.projectId = projectId
self.domainId = domainId
// 初始化 resource manager
self.initManagers()
return err
}
func (self *Client) InitWithAccessKey(regionId, domainId, projectId, accessKey, secretKey string) error {
func (self *Client) InitWithAccessKey(endpoint, regionId, domainId, projectId, accessKey, secretKey string, debug bool) error {
// accessKey signer
credential := &credentials.AccessKeyCredential{
AccessKeyId: accessKey,
AccessKeySecret: secretKey,
}
return self.InitWithOptions(regionId, domainId, projectId, credential)
// 从signer中初始化
signer, err := auth.NewSignerWithCredential(credential)
if err != nil {
return err
}
self.cfg = &SClientConfig{
signer: signer,
endpoint: endpoint,
regionId: regionId,
domainId: domainId,
projectId: projectId,
debug: debug,
}
// 初始化 resource manager
self.initManagers()
return err
}
func (self *Client) initManagers() {
if !self.init {
self.Servers = modules.NewServerManager(self.regionId, self.projectId, self.signer, self.debug)
self.ServersV2 = modules.NewServerV2Manager(self.regionId, self.projectId, self.signer, self.debug)
self.NovaServers = modules.NewNovaServerManager(self.regionId, self.projectId, self.signer, self.debug)
self.Snapshots = modules.NewSnapshotManager(self.regionId, self.projectId, self.signer, self.debug)
self.OsSnapshots = modules.NewOsSnapshotManager(self.regionId, self.projectId, self.signer, self.debug)
self.Images = modules.NewImageManager(self.regionId, self.projectId, self.signer, self.debug)
self.OpenStackImages = modules.NewOpenstackImageManager(self.regionId, self.projectId, self.signer, self.debug)
self.Projects = modules.NewProjectManager(self.signer, self.debug)
self.Regions = modules.NewRegionManager(self.signer, self.debug)
self.Zones = modules.NewZoneManager(self.regionId, self.projectId, self.signer, self.debug)
self.Vpcs = modules.NewVpcManager(self.regionId, self.projectId, self.signer, self.debug)
self.Eips = modules.NewEipManager(self.regionId, self.projectId, self.signer, self.debug)
self.Elasticcache = modules.NewElasticcacheManager(self.regionId, self.projectId, self.signer, self.debug)
self.DcsAvailableZone = modules.NewDcsAvailableZoneManager(self.regionId, self.signer, self.debug)
self.Disks = modules.NewDiskManager(self.regionId, self.projectId, self.signer, self.debug)
self.Domains = modules.NewDomainManager(self.signer, self.debug)
self.Keypairs = modules.NewKeypairManager(self.regionId, self.projectId, self.signer, self.debug)
self.Elb = modules.NewLoadbalancerManager(self.regionId, self.projectId, self.signer, self.debug)
self.ElbBackend = modules.NewElbBackendManager(self.regionId, self.projectId, self.signer, self.debug)
self.ElbBackendGroup = modules.NewElbBackendGroupManager(self.regionId, self.projectId, self.signer, self.debug)
self.ElbListeners = modules.NewElbListenersManager(self.regionId, self.projectId, self.signer, self.debug)
self.ElbCertificates = modules.NewElbCertificatesManager(self.regionId, self.projectId, self.signer, self.debug)
self.ElbHealthCheck = modules.NewElbHealthCheckManager(self.regionId, self.projectId, self.signer, self.debug)
self.ElbL7policies = modules.NewElbL7policiesManager(self.regionId, self.projectId, self.signer, self.debug)
self.ElbPolicies = modules.NewElbPoliciesManager(self.regionId, self.projectId, self.signer, self.debug)
self.ElbWhitelist = modules.NewElbWhitelistManager(self.regionId, self.projectId, self.signer, self.debug)
self.Orders = modules.NewOrderManager(self.signer, self.debug)
self.SecurityGroupRules = modules.NewSecgroupRuleManager(self.regionId, self.projectId, self.signer, self.debug)
self.SecurityGroups = modules.NewSecurityGroupManager(self.regionId, self.projectId, self.signer, self.debug)
self.NovaSecurityGroups = modules.NewNovaSecurityGroupManager(self.regionId, self.projectId, self.signer, self.debug)
self.Subnets = modules.NewSubnetManager(self.regionId, self.projectId, self.signer, self.debug)
self.Users = modules.NewUserManager(self.signer, self.debug)
self.Users.SetDomainId(self.domainId)
self.Interface = modules.NewInterfaceManager(self.regionId, self.projectId, self.signer, self.debug)
self.Jobs = modules.NewJobManager(self.regionId, self.projectId, self.signer, self.debug)
self.Balances = modules.NewBalanceManager(self.signer, self.debug)
self.Bandwidths = modules.NewBandwidthManager(self.regionId, self.projectId, self.signer, self.debug)
self.Credentials = modules.NewCredentialManager(self.signer, self.debug)
self.Port = modules.NewPortManager(self.regionId, self.projectId, self.signer, self.debug)
self.Flavors = modules.NewFlavorManager(self.regionId, self.projectId, self.signer, self.debug)
self.VpcRoutes = modules.NewVpcRouteManager(self.regionId, self.projectId, self.signer, self.debug)
self.SNatRules = modules.NewNatSManager(self.regionId, self.projectId, self.signer, self.debug)
self.DNatRules = modules.NewNatDManager(self.regionId, self.projectId, self.signer, self.debug)
self.NatGateways = modules.NewNatGatewayManager(self.regionId, self.projectId, self.signer, self.debug)
self.VpcPeerings = modules.NewVpcPeeringManager(self.regionId, self.projectId, self.signer, self.debug)
self.DBInstance = modules.NewDBInstanceManager(self.regionId, self.projectId, self.signer, self.debug)
self.DBInstanceBackup = modules.NewDBInstanceBackupManager(self.regionId, self.projectId, self.signer, self.debug)
self.DBInstanceFlavor = modules.NewDBInstanceFlavorManager(self.regionId, self.projectId, self.signer, self.debug)
self.DBInstanceJob = modules.NewDBInstanceJobManager(self.regionId, self.projectId, self.signer, self.debug)
self.Traces = modules.NewTraceManager(self.regionId, self.projectId, self.signer, self.debug)
self.CloudEye = modules.NewCloudEyeManager(self.regionId, self.projectId, self.signer, self.debug)
self.Quotas = modules.NewQuotaManager(self.regionId, self.projectId, self.signer, self.debug)
self.EnterpriseProjects = modules.NewEnterpriseProjectManager(self.regionId, self.projectId, self.signer, self.debug)
self.EnterpriseProjects.SetDomainId(self.domainId)
self.Roles = modules.NewRoleManager(self.signer, self.debug)
self.Roles.SetDomainId(self.domainId)
self.Groups = modules.NewGroupManager(self.signer, self.debug)
self.Groups.SetDomainId(self.domainId)
self.SAMLProviders = modules.NewSAMLProviderManager(self.signer, self.debug)
self.SAMLProviders.SetDomainId(self.domainId)
self.SAMLProviderMappings = modules.NewSAMLProviderMappingManager(self.signer, self.debug)
self.SAMLProviderMappings.SetDomainId(self.domainId)
self.SfsTurbos = modules.NewSfsTurboManager(self.regionId, self.projectId, self.signer, self.debug)
self.Servers = modules.NewServerManager(self.cfg)
self.ServersV2 = modules.NewServerV2Manager(self.cfg)
self.NovaServers = modules.NewNovaServerManager(self.cfg)
self.Snapshots = modules.NewSnapshotManager(self.cfg)
self.OsSnapshots = modules.NewOsSnapshotManager(self.cfg)
self.Images = modules.NewImageManager(self.cfg)
self.OpenStackImages = modules.NewOpenstackImageManager(self.cfg)
self.Projects = modules.NewProjectManager(self.cfg)
self.Regions = modules.NewRegionManager(self.cfg)
self.Zones = modules.NewZoneManager(self.cfg)
self.Vpcs = modules.NewVpcManager(self.cfg)
self.Eips = modules.NewEipManager(self.cfg)
self.Elasticcache = modules.NewElasticcacheManager(self.cfg)
self.DcsAvailableZone = modules.NewDcsAvailableZoneManager(self.cfg)
self.Disks = modules.NewDiskManager(self.cfg)
self.Domains = modules.NewDomainManager(self.cfg)
self.Keypairs = modules.NewKeypairManager(self.cfg)
self.Elb = modules.NewLoadbalancerManager(self.cfg)
self.ElbBackend = modules.NewElbBackendManager(self.cfg)
self.ElbBackendGroup = modules.NewElbBackendGroupManager(self.cfg)
self.ElbListeners = modules.NewElbListenersManager(self.cfg)
self.ElbCertificates = modules.NewElbCertificatesManager(self.cfg)
self.ElbHealthCheck = modules.NewElbHealthCheckManager(self.cfg)
self.ElbL7policies = modules.NewElbL7policiesManager(self.cfg)
self.ElbPolicies = modules.NewElbPoliciesManager(self.cfg)
self.ElbWhitelist = modules.NewElbWhitelistManager(self.cfg)
self.Orders = modules.NewOrderManager(self.cfg)
self.SecurityGroupRules = modules.NewSecgroupRuleManager(self.cfg)
self.SecurityGroups = modules.NewSecurityGroupManager(self.cfg)
self.NovaSecurityGroups = modules.NewNovaSecurityGroupManager(self.cfg)
self.Subnets = modules.NewSubnetManager(self.cfg)
self.Users = modules.NewUserManager(self.cfg)
self.Interface = modules.NewInterfaceManager(self.cfg)
self.Jobs = modules.NewJobManager(self.cfg)
self.Balances = modules.NewBalanceManager(self.cfg)
self.Bandwidths = modules.NewBandwidthManager(self.cfg)
self.Credentials = modules.NewCredentialManager(self.cfg)
self.Port = modules.NewPortManager(self.cfg)
self.Flavors = modules.NewFlavorManager(self.cfg)
self.VpcRoutes = modules.NewVpcRouteManager(self.cfg)
self.SNatRules = modules.NewNatSManager(self.cfg)
self.DNatRules = modules.NewNatDManager(self.cfg)
self.NatGateways = modules.NewNatGatewayManager(self.cfg)
self.VpcPeerings = modules.NewVpcPeeringManager(self.cfg)
self.DBInstance = modules.NewDBInstanceManager(self.cfg)
self.DBInstanceBackup = modules.NewDBInstanceBackupManager(self.cfg)
self.DBInstanceFlavor = modules.NewDBInstanceFlavorManager(self.cfg)
self.DBInstanceJob = modules.NewDBInstanceJobManager(self.cfg)
self.Traces = modules.NewTraceManager(self.cfg)
self.CloudEye = modules.NewCloudEyeManager(self.cfg)
self.Quotas = modules.NewQuotaManager(self.cfg)
self.EnterpriseProjects = modules.NewEnterpriseProjectManager(self.cfg)
self.Roles = modules.NewRoleManager(self.cfg)
self.Groups = modules.NewGroupManager(self.cfg)
self.SAMLProviders = modules.NewSAMLProviderManager(self.cfg)
self.SAMLProviderMappings = modules.NewSAMLProviderMappingManager(self.cfg)
self.SfsTurbos = modules.NewSfsTurboManager(self.cfg)
}
self.init = true
}
func NewClientWithAccessKey(regionId, domainId, projectId, accessKey, secretKey string, debug bool) (*Client, error) {
c := &Client{debug: debug}
err := c.InitWithAccessKey(regionId, domainId, projectId, accessKey, secretKey)
func NewClientWithAccessKey(endpoint, regionId, domainId, projectId, accessKey, secretKey string, debug bool) (*Client, error) {
c := &Client{}
err := c.InitWithAccessKey(endpoint, regionId, domainId, projectId, accessKey, secretKey, debug)
return c, err
}
func NewPublicCloudClientWithAccessKey(regionId, domainId, projectId, accessKey, secretKey string, debug bool) (*Client, error) {
return NewClientWithAccessKey("myhuaweicloud.com", regionId, domainId, projectId, accessKey, secretKey, debug)
}
@@ -17,6 +17,7 @@ package manager
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/responses"
)
@@ -69,3 +70,12 @@ type IManager interface {
// 执行操作 POST <base_url>/cloudservers/<cloudserver_id>/<action>
PerformAction(action string, id string, params jsonutils.JSONObject) (jsonutils.JSONObject, error)
}
type IManagerConfig interface {
GetSigner() auth.Signer
GetEndpoint() string
GetRegionId() string
GetDomainId() string
GetProjectId() string
GetDebug() bool
}
@@ -29,6 +29,7 @@ import (
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/requests"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/responses"
"yunion.io/x/onecloud/pkg/util/httputils"
@@ -39,7 +40,7 @@ type IRequestHook interface {
}
type SBaseManager struct {
signer auth.Signer
cfg manager.IManagerConfig
httpClient *http.Client
requestHook IRequestHook // 用于对request做特殊处理。非必要请不要使用!!!。目前只有port接口用到。
@@ -74,17 +75,21 @@ func (t *sThrottlingThreshold) Lock() {
var ThrottlingLock = sThrottlingThreshold{locked: false, lockTime: time.Time{}}
func NewBaseManager2(signer auth.Signer, debug bool, requesthk IRequestHook) SBaseManager {
func NewBaseManager2(cfg manager.IManagerConfig, requesthk IRequestHook) SBaseManager {
return SBaseManager{
signer: signer,
cfg: cfg,
httpClient: httputils.GetDefaultClient(),
debug: debug,
debug: cfg.GetDebug(),
requestHook: requesthk,
}
}
func NewBaseManager(signer auth.Signer, debug bool) SBaseManager {
return NewBaseManager2(signer, debug, nil)
func NewBaseManager(cfg manager.IManagerConfig) SBaseManager {
return NewBaseManager2(cfg, nil)
}
func (self *SBaseManager) GetEndpoint() string {
return self.cfg.GetEndpoint()
}
func (self *SBaseManager) GetColumns() []string {
@@ -195,7 +200,7 @@ func (self *SBaseManager) jsonRequest(request requests.IRequest) (http.Header, j
self.requestHook.Process(request)
}
// 拼接、编译、签名 requests here。
err := self.buildRequestWithSigner(request, self.signer)
err := self.buildRequestWithSigner(request, self.cfg.GetSigner())
if err != nil {
return nil, nil, err
}
@@ -135,7 +135,7 @@ func (self *SResourceManager) getReourcePath(ctx manager.IManagerContext, rid st
func (self *SResourceManager) newRequest(method, rid, spec string, ctx manager.IManagerContext) *requests.SRequest {
resourcePath := self.getReourcePath(ctx, rid, spec)
return requests.NewResourceRequest(method, string(self.ServiceName), self.version, self.Region, self.ProjectId, resourcePath)
return requests.NewResourceRequest(self.GetEndpoint(), method, string(self.ServiceName), self.version, self.Region, self.ProjectId, resourcePath)
}
func (self *SResourceManager) List(queries map[string]string) (*responses.ListResult, error) {
@@ -17,7 +17,7 @@ package modules
import (
"fmt"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/responses"
)
@@ -44,9 +44,9 @@ func (self *balanceCtx) GetPath() string {
}
// 这个manager非常特殊。只有List 和 SetDomainId方法可用。其他方法未验证
func NewBalanceManager(signer auth.Signer, debug bool) *SBalanceManager {
func NewBalanceManager(cfg manager.IManagerConfig) *SBalanceManager {
return &SBalanceManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameBSS,
Region: "cn-north-1",
ProjectId: "",
@@ -15,19 +15,19 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SBandwidthManager struct {
SResourceManager
}
func NewBandwidthManager(regionId string, projectId string, signer auth.Signer, debug bool) *SBandwidthManager {
func NewBandwidthManager(cfg manager.IManagerConfig) *SBandwidthManager {
return &SBandwidthManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameVPC,
Region: regionId,
ProjectId: projectId,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v1",
Keyword: "bandwidth",
KeywordPlural: "bandwidths",
@@ -21,7 +21,7 @@ import (
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/requests"
)
@@ -29,12 +29,12 @@ type SCloudEyeManager struct {
SResourceManager
}
func NewCloudEyeManager(regionId string, projectId string, signer auth.Signer, debug bool) *SCloudEyeManager {
func NewCloudEyeManager(cfg manager.IManagerConfig) *SCloudEyeManager {
return &SCloudEyeManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameCES,
Region: regionId,
ProjectId: projectId,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "V1.0",
Keyword: "",
KeywordPlural: "metrics",
@@ -93,7 +93,7 @@ func (ces *SCloudEyeManager) ListMetrics() ([]SMetricMeta, error) {
}
func (ces *SCloudEyeManager) listMetricsInternal(start string) (string, []SMetricMeta, error) {
request := requests.NewResourceRequest("GET", string(ces.ServiceName), ces.version, ces.Region, ces.ProjectId, ces.ResourceKeyword)
request := requests.NewResourceRequest(ces.GetEndpoint(), "GET", string(ces.ServiceName), ces.version, ces.Region, ces.ProjectId, ces.ResourceKeyword)
request.AddQueryParam("limit", "1000")
if len(start) > 0 {
request.AddQueryParam("start", start)
@@ -128,7 +128,7 @@ func (ces *SCloudEyeManager) GetMetricsData(metrics []SMetricMeta, since time.Ti
for i := range metrics {
metricReq[i] = metrics[i].SMetric
}
request := requests.NewResourceRequest("POST", string(ces.ServiceName), ces.version, ces.Region, ces.ProjectId, "batch-query-metric-data")
request := requests.NewResourceRequest(ces.GetEndpoint(), "POST", string(ces.ServiceName), ces.version, ces.Region, ces.ProjectId, "batch-query-metric-data")
input := SBatchQueryMetricDataInput{
Metrics: metricReq,
From: since.Unix() * 1000,
@@ -1,16 +1,16 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SCredentialManager struct {
SResourceManager
}
func NewCredentialManager(signer auth.Signer, debug bool) *SCredentialManager {
func NewCredentialManager(cfg manager.IManagerConfig) *SCredentialManager {
return &SCredentialManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameIAM,
Region: "",
ProjectId: "",
@@ -20,7 +20,7 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/responses"
)
@@ -28,12 +28,12 @@ type SDBInstanceManager struct {
SResourceManager
}
func NewDBInstanceManager(regionId string, projectId string, signer auth.Signer, debug bool) *SDBInstanceManager {
func NewDBInstanceManager(cfg manager.IManagerConfig) *SDBInstanceManager {
return &SDBInstanceManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameRDS,
Region: regionId,
ProjectId: projectId,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v3",
Keyword: "",
KeywordPlural: "instances",
@@ -15,19 +15,19 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SDBInstanceBackupManager struct {
SResourceManager
}
func NewDBInstanceBackupManager(regionId string, projectId string, signer auth.Signer, debug bool) *SDBInstanceBackupManager {
func NewDBInstanceBackupManager(cfg manager.IManagerConfig) *SDBInstanceBackupManager {
return &SDBInstanceBackupManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameRDS,
Region: regionId,
ProjectId: projectId,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v3",
Keyword: "backup",
KeywordPlural: "backups",
@@ -15,19 +15,19 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SDBInstanceFlavorManager struct {
SResourceManager
}
func NewDBInstanceFlavorManager(regionId string, projectId string, signer auth.Signer, debug bool) *SDBInstanceFlavorManager {
func NewDBInstanceFlavorManager(cfg manager.IManagerConfig) *SDBInstanceFlavorManager {
return &SDBInstanceFlavorManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameRDS,
Region: regionId,
ProjectId: projectId,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v3",
Keyword: "flavor",
KeywordPlural: "flavor",
@@ -17,19 +17,19 @@ package modules
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SDBInstanceJobManager struct {
SResourceManager
}
func NewDBInstanceJobManager(regionId string, projectId string, signer auth.Signer, debug bool) *SDBInstanceJobManager {
func NewDBInstanceJobManager(cfg manager.IManagerConfig) *SDBInstanceJobManager {
return &SDBInstanceJobManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameRDS,
Region: regionId,
ProjectId: projectId,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v3",
Keyword: "",
KeywordPlural: "",
@@ -18,7 +18,7 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/responses"
)
@@ -26,12 +26,12 @@ type SDiskManager struct {
SResourceManager
}
func NewDiskManager(regionId string, projectId string, signer auth.Signer, debug bool) *SDiskManager {
func NewDiskManager(cfg manager.IManagerConfig) *SDiskManager {
return &SDiskManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameEVS,
Region: regionId,
ProjectId: projectId,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v2",
Keyword: "volume",
KeywordPlural: "volumes",
@@ -15,18 +15,18 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SNatDRuleManager struct {
SResourceManager
}
func NewNatDManager(regionId string, projectId string, signer auth.Signer, debug bool) *SNatDRuleManager {
func NewNatDManager(cfg manager.IManagerConfig) *SNatDRuleManager {
man := &SNatDRuleManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameNAT,
Region: regionId,
Region: cfg.GetRegionId(),
ProjectId: "",
version: "v2.0",
Keyword: "dnat_rule",
@@ -34,8 +34,8 @@ func NewNatDManager(regionId string, projectId string, signer auth.Signer, debug
ResourceKeyword: "dnat_rules",
}}
if len(projectId) > 0 {
man.requestHook = &sProjectHook{projectId}
if len(cfg.GetProjectId()) > 0 {
man.requestHook = &sProjectHook{cfg.GetProjectId()}
}
return man
}
@@ -15,16 +15,16 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SDomainManager struct {
SResourceManager
}
func NewDomainManager(signer auth.Signer, debug bool) *SDomainManager {
func NewDomainManager(cfg manager.IManagerConfig) *SDomainManager {
return &SDomainManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameIAM,
Region: "",
ProjectId: "",
@@ -17,19 +17,19 @@ package modules
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SEipManager struct {
SResourceManager
}
func NewEipManager(regionId string, projectId string, signer auth.Signer, debug bool) *SEipManager {
func NewEipManager(cfg manager.IManagerConfig) *SEipManager {
return &SEipManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameVPC,
Region: regionId,
ProjectId: projectId,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v1",
Keyword: "publicip",
KeywordPlural: "publicips",
@@ -19,7 +19,7 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/responses"
)
@@ -31,12 +31,12 @@ type SDcsAvailableZoneManager struct {
SResourceManager
}
func NewElasticcacheManager(regionId string, projectId string, signer auth.Signer, debug bool) *SElasticcacheManager {
func NewElasticcacheManager(cfg manager.IManagerConfig) *SElasticcacheManager {
return &SElasticcacheManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameDCS,
Region: regionId,
ProjectId: projectId,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v1.0",
Keyword: "",
KeywordPlural: "instances",
@@ -103,11 +103,11 @@ func (self *SElasticcacheManager) ChangeInstanceSpec(instanceId string, specCode
return self.CreateInContextWithSpec(nil, fmt.Sprintf("%s/extend", instanceId), params, "")
}
func NewDcsAvailableZoneManager(regionId string, signer auth.Signer, debug bool) *SDcsAvailableZoneManager {
func NewDcsAvailableZoneManager(cfg manager.IManagerConfig) *SDcsAvailableZoneManager {
return &SDcsAvailableZoneManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameDCS,
Region: regionId,
Region: cfg.GetRegionId(),
ProjectId: "",
version: "v1.0",
Keyword: "available_zone",
@@ -15,16 +15,16 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SEnterpriseProjectManager struct {
SResourceManager
}
func NewEnterpriseProjectManager(regionId string, projectId string, signer auth.Signer, debug bool) *SEnterpriseProjectManager {
return &SEnterpriseProjectManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
func NewEnterpriseProjectManager(cfg manager.IManagerConfig) *SEnterpriseProjectManager {
m := &SEnterpriseProjectManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameEPS,
Region: "",
ProjectId: "",
@@ -34,4 +34,6 @@ func NewEnterpriseProjectManager(regionId string, projectId string, signer auth.
ResourceKeyword: "enterprise-projects",
}}
m.SetDomainId(cfg.GetDomainId())
return m
}
@@ -15,19 +15,19 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SFlavorManager struct {
SResourceManager
}
func NewFlavorManager(regionId string, projectId string, signer auth.Signer, debug bool) *SFlavorManager {
func NewFlavorManager(cfg manager.IManagerConfig) *SFlavorManager {
return &SFlavorManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameECS,
Region: regionId,
ProjectId: projectId,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v1",
Keyword: "flavor",
KeywordPlural: "flavors",
@@ -20,7 +20,7 @@ import (
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/responses"
)
@@ -28,9 +28,9 @@ type SGroupManager struct {
SResourceManager
}
func NewGroupManager(signer auth.Signer, debug bool) *SGroupManager {
return &SGroupManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
func NewGroupManager(cfg manager.IManagerConfig) *SGroupManager {
m := &SGroupManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameIAM,
Region: "",
ProjectId: "",
@@ -40,6 +40,8 @@ func NewGroupManager(signer auth.Signer, debug bool) *SGroupManager {
ResourceKeyword: "groups",
}}
m.SetDomainId(cfg.GetDomainId())
return m
}
func (manager *SGroupManager) ListRoles(domainId string, groupId string) (*responses.ListResult, error) {
@@ -18,7 +18,7 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/requests"
)
@@ -36,16 +36,16 @@ func (self *imageProject) Process(request requests.IRequest) {
request.AddHeaderParam("X-Project-Id", self.projectId)
}
func NewImageManager(regionId string, projectId string, signer auth.Signer, debug bool) *SImageManager {
func NewImageManager(cfg manager.IManagerConfig) *SImageManager {
var requestHook imageProject
if len(projectId) > 0 {
requestHook = imageProject{projectId: projectId}
if len(cfg.GetProjectId()) > 0 {
requestHook = imageProject{projectId: cfg.GetProjectId()}
}
return &SImageManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager2(signer, debug, &requestHook),
SBaseManager: NewBaseManager2(cfg, &requestHook),
ServiceName: ServiceNameIMS,
Region: regionId,
Region: cfg.GetRegionId(),
ProjectId: "",
version: "v2",
Keyword: "image",
@@ -81,16 +81,16 @@ func (self *SImageManager) Get(id string, querys map[string]string) (jsonutils.J
// https://support.huaweicloud.com/api-ims/zh-cn_topic_0020092108.html
// 删除image只能用这个manager
func NewOpenstackImageManager(regionId string, projectId string, signer auth.Signer, debug bool) *SImageManager {
func NewOpenstackImageManager(cfg manager.IManagerConfig) *SImageManager {
var requestHook imageProject
if len(projectId) > 0 {
requestHook = imageProject{projectId: projectId}
if len(cfg.GetProjectId()) > 0 {
requestHook = imageProject{projectId: cfg.GetProjectId()}
}
return &SImageManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager2(signer, debug, &requestHook),
SBaseManager: NewBaseManager2(cfg, &requestHook),
ServiceName: ServiceNameIMS,
Region: regionId,
Region: cfg.GetRegionId(),
ProjectId: "",
version: "v2",
Keyword: "image",
@@ -15,7 +15,7 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SInterfaceManager struct {
@@ -23,12 +23,12 @@ type SInterfaceManager struct {
}
// 不建议使用
func NewInterfaceManager(regionId, projectId string, signer auth.Signer, debug bool) *SInterfaceManager {
func NewInterfaceManager(cfg manager.IManagerConfig) *SInterfaceManager {
return &SInterfaceManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameECS,
Region: regionId,
ProjectId: projectId,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v2",
Keyword: "interfaceAttachment",
KeywordPlural: "interfaceAttachments",
@@ -19,7 +19,7 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/responses"
)
@@ -27,12 +27,12 @@ type SJobManager struct {
SResourceManager
}
func NewJobManager(regionId string, projectId string, signer auth.Signer, debug bool) *SJobManager {
func NewJobManager(cfg manager.IManagerConfig) *SJobManager {
return &SJobManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: "",
Region: regionId,
ProjectId: projectId,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v1",
Keyword: "",
KeywordPlural: "",
@@ -15,19 +15,19 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SKeypairManager struct {
SResourceManager
}
func NewKeypairManager(regionId string, projectId string, signer auth.Signer, debug bool) *SKeypairManager {
func NewKeypairManager(cfg manager.IManagerConfig) *SKeypairManager {
return &SKeypairManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameECS,
Region: regionId,
ProjectId: projectId,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v2",
Keyword: "keypair",
KeywordPlural: "keypairs",
@@ -17,7 +17,7 @@ package modules
import (
"fmt"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SElbBackendManager struct {
@@ -33,16 +33,16 @@ func (self *backendCtx) GetPath() string {
return fmt.Sprintf("pools/%s", self.backendGroupId)
}
func NewElbBackendManager(regionId string, projectId string, signer auth.Signer, debug bool) *SElbBackendManager {
func NewElbBackendManager(cfg manager.IManagerConfig) *SElbBackendManager {
var requestHook portProject
if len(projectId) > 0 {
requestHook = portProject{projectId: projectId}
if len(cfg.GetProjectId()) > 0 {
requestHook = portProject{projectId: cfg.GetProjectId()}
}
return &SElbBackendManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager2(signer, debug, &requestHook),
SBaseManager: NewBaseManager2(cfg, &requestHook),
ServiceName: ServiceNameELB,
Region: regionId,
Region: cfg.GetRegionId(),
ProjectId: "",
version: "v2.0/lbaas",
Keyword: "member",
@@ -15,23 +15,23 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SElbBackendGroupManager struct {
SResourceManager
}
func NewElbBackendGroupManager(regionId string, projectId string, signer auth.Signer, debug bool) *SElbBackendGroupManager {
func NewElbBackendGroupManager(cfg manager.IManagerConfig) *SElbBackendGroupManager {
var requestHook portProject
if len(projectId) > 0 {
requestHook = portProject{projectId: projectId}
if len(cfg.GetProjectId()) > 0 {
requestHook = portProject{projectId: cfg.GetProjectId()}
}
return &SElbBackendGroupManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager2(signer, debug, &requestHook),
SBaseManager: NewBaseManager2(cfg, &requestHook),
ServiceName: ServiceNameELB,
Region: regionId,
Region: cfg.GetRegionId(),
ProjectId: "",
version: "v2.0",
Keyword: "pool",
@@ -15,23 +15,23 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SElbCertificatesManager struct {
SResourceManager
}
func NewElbCertificatesManager(regionId string, projectId string, signer auth.Signer, debug bool) *SElbCertificatesManager {
func NewElbCertificatesManager(cfg manager.IManagerConfig) *SElbCertificatesManager {
var requestHook portProject
if len(projectId) > 0 {
requestHook = portProject{projectId: projectId}
if len(cfg.GetProjectId()) > 0 {
requestHook = portProject{projectId: cfg.GetProjectId()}
}
return &SElbCertificatesManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager2(signer, debug, &requestHook),
SBaseManager: NewBaseManager2(cfg, &requestHook),
ServiceName: ServiceNameELB,
Region: regionId,
Region: cfg.GetRegionId(),
ProjectId: "",
version: "v2.0",
Keyword: "",
@@ -17,23 +17,23 @@ package modules
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SElbHealthCheckManager struct {
SResourceManager
}
func NewElbHealthCheckManager(regionId string, projectId string, signer auth.Signer, debug bool) *SElbHealthCheckManager {
func NewElbHealthCheckManager(cfg manager.IManagerConfig) *SElbHealthCheckManager {
var requestHook portProject
if len(projectId) > 0 {
requestHook = portProject{projectId: projectId}
if len(cfg.GetProjectId()) > 0 {
requestHook = portProject{projectId: cfg.GetProjectId()}
}
return &SElbHealthCheckManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager2(signer, debug, &requestHook),
SBaseManager: NewBaseManager2(cfg, &requestHook),
ServiceName: ServiceNameELB,
Region: regionId,
Region: cfg.GetRegionId(),
ProjectId: "",
version: "v2.0",
Keyword: "healthmonitor",
@@ -15,23 +15,23 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SElbListenersManager struct {
SResourceManager
}
func NewElbListenersManager(regionId string, projectId string, signer auth.Signer, debug bool) *SElbListenersManager {
func NewElbListenersManager(cfg manager.IManagerConfig) *SElbListenersManager {
var requestHook portProject
if len(projectId) > 0 {
requestHook = portProject{projectId: projectId}
if len(cfg.GetProjectId()) > 0 {
requestHook = portProject{projectId: cfg.GetProjectId()}
}
return &SElbListenersManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager2(signer, debug, &requestHook),
SBaseManager: NewBaseManager2(cfg, &requestHook),
ServiceName: ServiceNameELB,
Region: regionId,
Region: cfg.GetRegionId(),
ProjectId: "",
version: "v2.0",
Keyword: "listener",
@@ -15,23 +15,23 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SElbL7policiesManager struct {
SResourceManager
}
func NewElbL7policiesManager(regionId string, projectId string, signer auth.Signer, debug bool) *SElbL7policiesManager {
func NewElbL7policiesManager(cfg manager.IManagerConfig) *SElbL7policiesManager {
var requestHook portProject
if len(projectId) > 0 {
requestHook = portProject{projectId: projectId}
if len(cfg.GetProjectId()) > 0 {
requestHook = portProject{projectId: cfg.GetProjectId()}
}
return &SElbL7policiesManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager2(signer, debug, &requestHook),
SBaseManager: NewBaseManager2(cfg, &requestHook),
ServiceName: ServiceNameELB,
Region: regionId,
Region: cfg.GetRegionId(),
ProjectId: "",
version: "v2.0",
Keyword: "l7policy",
@@ -17,7 +17,7 @@ package modules
import (
"fmt"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SElbPoliciesManager struct {
@@ -33,16 +33,16 @@ func (self *policyCtx) GetPath() string {
return fmt.Sprintf("l7policies/%s", self.l7policyId)
}
func NewElbPoliciesManager(regionId string, projectId string, signer auth.Signer, debug bool) *SElbPoliciesManager {
func NewElbPoliciesManager(cfg manager.IManagerConfig) *SElbPoliciesManager {
var requestHook portProject
if len(projectId) > 0 {
requestHook = portProject{projectId: projectId}
if len(cfg.GetProjectId()) > 0 {
requestHook = portProject{projectId: cfg.GetProjectId()}
}
return &SElbPoliciesManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager2(signer, debug, &requestHook),
SBaseManager: NewBaseManager2(cfg, &requestHook),
ServiceName: ServiceNameELB,
Region: regionId,
Region: cfg.GetRegionId(),
ProjectId: "",
version: "v2.0/lbaas",
Keyword: "rule",
@@ -15,23 +15,23 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SElbWhitelistManager struct {
SResourceManager
}
func NewElbWhitelistManager(regionId string, projectId string, signer auth.Signer, debug bool) *SElbWhitelistManager {
func NewElbWhitelistManager(cfg manager.IManagerConfig) *SElbWhitelistManager {
var requestHook portProject
if len(projectId) > 0 {
requestHook = portProject{projectId: projectId}
if len(cfg.GetProjectId()) > 0 {
requestHook = portProject{projectId: cfg.GetProjectId()}
}
return &SElbWhitelistManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager2(signer, debug, &requestHook),
SBaseManager: NewBaseManager2(cfg, &requestHook),
ServiceName: ServiceNameELB,
Region: regionId,
Region: cfg.GetRegionId(),
ProjectId: "",
version: "v2.0",
Keyword: "whitelist",
@@ -15,23 +15,23 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SLoadbalancerManager struct {
SResourceManager
}
func NewLoadbalancerManager(regionId string, projectId string, signer auth.Signer, debug bool) *SLoadbalancerManager {
func NewLoadbalancerManager(cfg manager.IManagerConfig) *SLoadbalancerManager {
var requestHook portProject
if len(projectId) > 0 {
requestHook = portProject{projectId: projectId}
if len(cfg.GetProjectId()) > 0 {
requestHook = portProject{projectId: cfg.GetProjectId()}
}
return &SLoadbalancerManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager2(signer, debug, &requestHook),
SBaseManager: NewBaseManager2(cfg, &requestHook),
ServiceName: ServiceNameELB,
Region: regionId,
Region: cfg.GetRegionId(),
ProjectId: "",
version: "v2.0",
Keyword: "loadbalancer",
@@ -15,16 +15,16 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SAMLProviderMappingManager struct {
SResourceManager
}
func NewSAMLProviderMappingManager(signer auth.Signer, debug bool) *SAMLProviderMappingManager {
return &SAMLProviderMappingManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
func NewSAMLProviderMappingManager(cfg manager.IManagerConfig) *SAMLProviderMappingManager {
m := &SAMLProviderMappingManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameIAM,
Region: "",
ProjectId: "",
@@ -34,4 +34,6 @@ func NewSAMLProviderMappingManager(signer auth.Signer, debug bool) *SAMLProvider
ResourceKeyword: "mappings",
}}
m.SetDomainId(cfg.GetDomainId())
return m
}
@@ -15,7 +15,7 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/requests"
)
@@ -31,11 +31,11 @@ func (self *sProjectHook) Process(request requests.IRequest) {
request.AddHeaderParam("X-Project-Id", self.projectId)
}
func NewNatGatewayManager(regionId string, projectId string, signer auth.Signer, debug bool) *SNatGatewayManager {
func NewNatGatewayManager(cfg manager.IManagerConfig) *SNatGatewayManager {
man := &SNatGatewayManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameNAT,
Region: regionId,
Region: cfg.GetRegionId(),
ProjectId: "",
version: "v2.0",
Keyword: "nat_gateway",
@@ -43,8 +43,8 @@ func NewNatGatewayManager(regionId string, projectId string, signer auth.Signer,
ResourceKeyword: "nat_gateways",
}}
if len(projectId) > 0 {
man.requestHook = &sProjectHook{projectId}
if len(cfg.GetProjectId()) > 0 {
man.requestHook = &sProjectHook{cfg.GetProjectId()}
}
return man
}
@@ -19,7 +19,6 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/responses"
)
@@ -42,9 +41,9 @@ func (self *orderCtx) GetPath() string {
// 客户运营能力API的Endpoint为“bss.cn-north-1.myhuaweicloud.com”。该Endpoint为全局Endpoint,中国站所有区域均可使用。
// https://support.huaweicloud.com/api-oce/zh-cn_topic_0084961226.html
func NewOrderManager(signer auth.Signer, debug bool) *SOrderManager {
func NewOrderManager(cfg manager.IManagerConfig) *SOrderManager {
return &SOrderManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameBSS,
Region: "cn-north-1",
ProjectId: "",
@@ -15,7 +15,7 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/requests"
)
@@ -33,17 +33,17 @@ func (self *portProject) Process(request requests.IRequest) {
request.AddHeaderParam("X-Project-Id", self.projectId)
}
func NewPortManager(regionId string, projectId string, signer auth.Signer, debug bool) *SPortManager {
func NewPortManager(cfg manager.IManagerConfig) *SPortManager {
var requestHook portProject
if len(projectId) > 0 {
requestHook = portProject{projectId: projectId}
if len(cfg.GetProjectId()) > 0 {
requestHook = portProject{projectId: cfg.GetProjectId()}
}
return &SPortManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager2(signer, debug, &requestHook),
SBaseManager: NewBaseManager2(cfg, &requestHook),
ServiceName: ServiceNameVPC,
Region: regionId,
ProjectId: projectId,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v1",
Keyword: "port",
KeywordPlural: "ports",
@@ -15,16 +15,16 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SProjectManager struct {
SResourceManager
}
func NewProjectManager(signer auth.Signer, debug bool) *SProjectManager {
func NewProjectManager(cfg manager.IManagerConfig) *SProjectManager {
return &SProjectManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameIAM,
Region: "",
ProjectId: "",
@@ -15,19 +15,19 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SQuotaManager struct {
SResourceManager
}
func NewQuotaManager(regionId string, projectId string, signer auth.Signer, debug bool) *SQuotaManager {
func NewQuotaManager(cfg manager.IManagerConfig) *SQuotaManager {
return &SQuotaManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameEVS,
Region: regionId,
ProjectId: projectId,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v1",
Keyword: "quotas",
KeywordPlural: "quotas",
@@ -15,16 +15,16 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SRegionManager struct {
SResourceManager
}
func NewRegionManager(signer auth.Signer, debug bool) *SRegionManager {
func NewRegionManager(cfg manager.IManagerConfig) *SRegionManager {
return &SRegionManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameIAM,
Region: "",
ProjectId: "",
@@ -15,16 +15,16 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SRoleManager struct {
SResourceManager
}
func NewRoleManager(signer auth.Signer, debug bool) *SRoleManager {
return &SRoleManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
func NewRoleManager(cfg manager.IManagerConfig) *SRoleManager {
m := &SRoleManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameIAM,
Region: "",
ProjectId: "",
@@ -34,4 +34,6 @@ func NewRoleManager(signer auth.Signer, debug bool) *SRoleManager {
ResourceKeyword: "roles",
}}
m.SetDomainId(cfg.GetDomainId())
return m
}
@@ -15,16 +15,16 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SAMLProviderManager struct {
SResourceManager
}
func NewSAMLProviderManager(signer auth.Signer, debug bool) *SAMLProviderManager {
return &SAMLProviderManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
func NewSAMLProviderManager(cfg manager.IManagerConfig) *SAMLProviderManager {
m := &SAMLProviderManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameIAM,
Region: "",
ProjectId: "",
@@ -34,4 +34,6 @@ func NewSAMLProviderManager(signer auth.Signer, debug bool) *SAMLProviderManager
ResourceKeyword: "identity_providers",
}}
m.SetDomainId(cfg.GetDomainId())
return m
}
@@ -15,19 +15,19 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SSecgroupRuleManager struct {
SResourceManager
}
func NewSecgroupRuleManager(regionId string, projectId string, signer auth.Signer, debug bool) *SSecgroupRuleManager {
func NewSecgroupRuleManager(cfg manager.IManagerConfig) *SSecgroupRuleManager {
return &SSecgroupRuleManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameVPC,
Region: regionId,
ProjectId: projectId,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v1",
Keyword: "security_group_rule",
KeywordPlural: "security_group_rules",
@@ -15,19 +15,19 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SSecurityGroupManager struct {
SResourceManager
}
func NewSecurityGroupManager(regionId string, projectId string, signer auth.Signer, debug bool) *SSecurityGroupManager {
func NewSecurityGroupManager(cfg manager.IManagerConfig) *SSecurityGroupManager {
return &SSecurityGroupManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameVPC,
Region: regionId,
ProjectId: projectId,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v1",
Keyword: "security_group",
KeywordPlural: "security_groups",
@@ -36,12 +36,12 @@ func NewSecurityGroupManager(regionId string, projectId string, signer auth.Sign
}}
}
func NewNovaSecurityGroupManager(regionId string, projectId string, signer auth.Signer, debug bool) *SSecurityGroupManager {
func NewNovaSecurityGroupManager(cfg manager.IManagerConfig) *SSecurityGroupManager {
return &SSecurityGroupManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameECS,
Region: regionId,
ProjectId: projectId,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v2.1",
Keyword: "security_group",
KeywordPlural: "security_groups",
@@ -21,7 +21,7 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/responses"
)
@@ -31,12 +31,12 @@ type SServerManager struct {
// https://support.huaweicloud.com/api-ecs/zh-cn_topic_0020212668.html
// v.1.1 新增支持创建包年/包月的弹性云服务器。!!但是不支持查询等调用 https://support.huaweicloud.com/api-ecs/zh-cn_topic_0093055772.html
func NewServerManager(regionId, projectId string, signer auth.Signer, debug bool) *SServerManager {
func NewServerManager(cfg manager.IManagerConfig) *SServerManager {
return &SServerManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameECS,
Region: regionId,
ProjectId: projectId,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v1",
Keyword: "server",
KeywordPlural: "servers",
@@ -94,12 +94,12 @@ func (self *SServerManager) Create(params jsonutils.JSONObject) (jsonutils.JSONO
}
// 不推荐使用这个manager
func NewNovaServerManager(regionId, projectId string, signer auth.Signer, debug bool) *SServerManager {
func NewNovaServerManager(cfg manager.IManagerConfig) *SServerManager {
return &SServerManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameECS,
Region: regionId,
ProjectId: projectId,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v2.1",
Keyword: "server",
KeywordPlural: "servers",
@@ -109,12 +109,12 @@ func NewNovaServerManager(regionId, projectId string, signer auth.Signer, debug
}
// 重装弹性云服务器操作系统(安装Cloud-init,请用这个manager
func NewServerV2Manager(regionId, projectId string, signer auth.Signer, debug bool) *SServerManager {
func NewServerV2Manager(cfg manager.IManagerConfig) *SServerManager {
return &SServerManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameECS,
Region: regionId,
ProjectId: projectId,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v2",
Keyword: "server",
KeywordPlural: "servers",
@@ -17,7 +17,7 @@ package modules
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/responses"
)
@@ -25,12 +25,12 @@ type SfsTurboManager struct {
SResourceManager
}
func NewSfsTurboManager(regionId, projectId string, signer auth.Signer, debug bool) *SfsTurboManager {
func NewSfsTurboManager(cfg manager.IManagerConfig) *SfsTurboManager {
return &SfsTurboManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameSFSTurbo,
Region: regionId,
ProjectId: projectId,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v1",
Keyword: "",
KeywordPlural: "shares",
@@ -15,7 +15,7 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/responses"
)
@@ -23,12 +23,12 @@ type SSnapshotManager struct {
SResourceManager
}
func NewSnapshotManager(regionId, projectId string, signer auth.Signer, debug bool) *SSnapshotManager {
func NewSnapshotManager(cfg manager.IManagerConfig) *SSnapshotManager {
return &SSnapshotManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameEVS,
Region: regionId,
ProjectId: projectId,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v2",
Keyword: "snapshot",
KeywordPlural: "snapshots",
@@ -44,12 +44,12 @@ func (self *SSnapshotManager) List(querys map[string]string) (*responses.ListRes
// https://support.huaweicloud.com/api-evs/zh-cn_topic_0051408629.html
// 回滚快照只能用这个manger。其他情况请不要使用
// 另外,香港-亚太还支持另外一个接口。https://support.huaweicloud.com/api-evs/zh-cn_topic_0142374138.html
func NewOsSnapshotManager(regionId string, projectId string, signer auth.Signer, debug bool) *SSnapshotManager {
func NewOsSnapshotManager(cfg manager.IManagerConfig) *SSnapshotManager {
return &SSnapshotManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameEVS,
Region: regionId,
ProjectId: projectId,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v2",
Keyword: "snapshot",
KeywordPlural: "snapshots",
@@ -15,18 +15,18 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SNatSRuleManager struct {
SResourceManager
}
func NewNatSManager(regionId string, projectId string, signer auth.Signer, debug bool) *SNatSRuleManager {
func NewNatSManager(cfg manager.IManagerConfig) *SNatSRuleManager {
man := &SNatSRuleManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameNAT,
Region: regionId,
Region: cfg.GetRegionId(),
ProjectId: "",
version: "v2.0",
Keyword: "snat_rule",
@@ -34,8 +34,8 @@ func NewNatSManager(regionId string, projectId string, signer auth.Signer, debug
ResourceKeyword: "snat_rules",
}}
if len(projectId) > 0 {
man.requestHook = &sProjectHook{projectId}
if len(cfg.GetProjectId()) > 0 {
man.requestHook = &sProjectHook{cfg.GetProjectId()}
}
return man
}
@@ -15,19 +15,19 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SSubnetManager struct {
SResourceManager
}
func NewSubnetManager(regionId string, projectId string, signer auth.Signer, debug bool) *SSubnetManager {
func NewSubnetManager(cfg manager.IManagerConfig) *SSubnetManager {
return &SSubnetManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameVPC,
Region: regionId,
ProjectId: projectId,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v1",
Keyword: "subnet",
KeywordPlural: "subnets",
@@ -15,19 +15,19 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type STraceManager struct {
SResourceManager
}
func NewTraceManager(regionId string, projectId string, signer auth.Signer, debug bool) *STraceManager {
func NewTraceManager(cfg manager.IManagerConfig) *STraceManager {
return &STraceManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameCTS,
Region: regionId,
ProjectId: projectId,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v2.0",
Keyword: "trace",
KeywordPlural: "traces",
@@ -19,7 +19,7 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/responses"
)
@@ -27,9 +27,9 @@ type SUserManager struct {
SResourceManager
}
func NewUserManager(signer auth.Signer, debug bool) *SUserManager {
return &SUserManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
func NewUserManager(cfg manager.IManagerConfig) *SUserManager {
user := &SUserManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameIAM,
Region: "",
ProjectId: "",
@@ -39,6 +39,8 @@ func NewUserManager(signer auth.Signer, debug bool) *SUserManager {
ResourceKeyword: "users",
}}
user.SetDomainId(cfg.GetDomainId())
return user
}
func (self *SUserManager) List(querys map[string]string) (*responses.ListResult, error) {
@@ -15,18 +15,18 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SVpcPeeringManager struct {
SResourceManager
}
func NewVpcPeeringManager(regionId string, projectId string, signer auth.Signer, debug bool) *SVpcPeeringManager {
func NewVpcPeeringManager(cfg manager.IManagerConfig) *SVpcPeeringManager {
return &SVpcPeeringManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameVPC,
Region: regionId,
Region: cfg.GetRegionId(),
ProjectId: "",
version: "v2.0",
Keyword: "peering",
@@ -15,18 +15,18 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SVpcRouteManager struct {
SResourceManager
}
func NewVpcRouteManager(regionId string, projectId string, signer auth.Signer, debug bool) *SVpcRouteManager {
func NewVpcRouteManager(cfg manager.IManagerConfig) *SVpcRouteManager {
return &SVpcRouteManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameVPC,
Region: regionId,
Region: cfg.GetRegionId(),
// the url should not include the field "projectid" in huawei cloud api v2.0
ProjectId: "",
version: "v2.0",
@@ -15,19 +15,19 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SVpcManager struct {
SResourceManager
}
func NewVpcManager(regionId string, projectId string, signer auth.Signer, debug bool) *SVpcManager {
func NewVpcManager(cfg manager.IManagerConfig) *SVpcManager {
return &SVpcManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameVPC,
Region: regionId,
ProjectId: projectId,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v1",
Keyword: "vpc",
KeywordPlural: "vpcs",
@@ -15,19 +15,19 @@
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/manager"
)
type SZoneManager struct {
SResourceManager
}
func NewZoneManager(regionId string, projectId string, signer auth.Signer, debug bool) *SZoneManager {
func NewZoneManager(cfg manager.IManagerConfig) *SZoneManager {
return &SZoneManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameECS,
Region: regionId,
ProjectId: projectId,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v2",
Keyword: "availabilityZoneInfo",
KeywordPlural: "availabilityZoneInfo",
@@ -259,11 +259,11 @@ func defaultRequest() (request *SRequest) {
return
}
func NewResourceRequest(method, product, version, region, project, resourcePath string) *SRequest {
func NewResourceRequest(domain, method, product, version, region, project, resourcePath string) *SRequest {
return &SRequest{
Scheme: "HTTPS",
Method: method,
Domain: "myhuaweicloud.com",
Domain: domain,
product: product,
RegionId: region,
version: version,
+2 -2
View File
@@ -153,7 +153,7 @@ func (self *SHuaweiClient) initSigner() error {
}
func (self *SHuaweiClient) newRegionAPIClient(regionId string) (*client.Client, error) {
cli, err := client.NewClientWithAccessKey(regionId, self.ownerId, self.projectId, self.accessKey, self.accessSecret, self.debug)
cli, err := client.NewPublicCloudClientWithAccessKey(regionId, self.ownerId, self.projectId, self.accessKey, self.accessSecret, self.debug)
if err != nil {
return nil, err
}
@@ -165,7 +165,7 @@ func (self *SHuaweiClient) newRegionAPIClient(regionId string) (*client.Client,
}
func (self *SHuaweiClient) newGeneralAPIClient() (*client.Client, error) {
cli, err := client.NewClientWithAccessKey("", self.ownerId, "", self.accessKey, self.accessSecret, self.debug)
cli, err := client.NewPublicCloudClientWithAccessKey("", self.ownerId, "", self.accessKey, self.accessSecret, self.debug)
if err != nil {
return nil, err
}
+765
View File
@@ -0,0 +1,765 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package huaweistack
import (
"context"
"fmt"
"io"
"net/http"
"strconv"
"strings"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/utils"
"yunion.io/x/s3cli"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud"
"yunion.io/x/onecloud/pkg/multicloud/huawei/obs"
)
type SBucket struct {
multicloud.SBaseBucket
multicloud.HuaweiTags
region *SRegion
Name string
Location string
CreationDate time.Time
}
func (b *SBucket) GetProjectId() string {
resp, err := b.region.HeadBucket(b.Name)
if err != nil {
return ""
}
epid, _ := resp.ResponseHeaders["epid"]
if len(epid) > 0 {
return epid[0]
}
return ""
}
func (b *SBucket) GetGlobalId() string {
return b.Name
}
func (b *SBucket) GetName() string {
return b.Name
}
func (b *SBucket) GetLocation() string {
return b.Location
}
func (b *SBucket) GetIRegion() cloudprovider.ICloudRegion {
return b.region
}
func (b *SBucket) GetCreateAt() time.Time {
return b.CreationDate
}
func (b *SBucket) GetStorageClass() string {
obscli, err := b.region.getOBSClient()
if err != nil {
log.Errorf("b.region.getOBSClient error %s", err)
return ""
}
output, err := obscli.GetBucketStoragePolicy(b.Name)
if err != nil {
log.Errorf("obscli.GetBucketStoragePolicy error %s", err)
}
return output.StorageClass
}
func obsAcl2CannedAcl(acls []obs.Grant) cloudprovider.TBucketACLType {
switch {
case len(acls) == 1:
if acls[0].Grantee.URI == "" && acls[0].Permission == s3cli.PERMISSION_FULL_CONTROL {
return cloudprovider.ACLPrivate
}
case len(acls) == 2:
for _, g := range acls {
if g.Grantee.URI == s3cli.GRANTEE_GROUP_URI_AUTH_USERS && g.Permission == s3cli.PERMISSION_READ {
return cloudprovider.ACLAuthRead
}
if g.Grantee.URI == s3cli.GRANTEE_GROUP_URI_ALL_USERS && g.Permission == s3cli.PERMISSION_READ {
return cloudprovider.ACLPublicRead
}
}
case len(acls) == 3:
for _, g := range acls {
if g.Grantee.URI == s3cli.GRANTEE_GROUP_URI_ALL_USERS && g.Permission == s3cli.PERMISSION_WRITE {
return cloudprovider.ACLPublicReadWrite
}
}
}
return cloudprovider.ACLUnknown
}
func (b *SBucket) GetAcl() cloudprovider.TBucketACLType {
acl := cloudprovider.ACLPrivate
obscli, err := b.region.getOBSClient()
if err != nil {
log.Errorf("b.region.getOBSClient error %s", err)
return acl
}
output, err := obscli.GetBucketAcl(b.Name)
if err != nil {
log.Errorf("obscli.GetBucketAcl error %s", err)
return acl
}
acl = obsAcl2CannedAcl(output.Grants)
return acl
}
func (b *SBucket) SetAcl(acl cloudprovider.TBucketACLType) error {
obscli, err := b.region.getOBSClient()
if err != nil {
return errors.Wrap(err, "b.region.getOBSClient")
}
input := &obs.SetBucketAclInput{}
input.Bucket = b.Name
input.ACL = obs.AclType(string(acl))
_, err = obscli.SetBucketAcl(input)
if err != nil {
return errors.Wrap(err, "obscli.SetBucketAcl")
}
return nil
}
func (b *SBucket) GetAccessUrls() []cloudprovider.SBucketAccessUrl {
return []cloudprovider.SBucketAccessUrl{
{
Url: fmt.Sprintf("https://%s.%s", b.Name, b.region.getOBSEndpoint()),
Description: "bucket url",
Primary: true,
},
{
Url: fmt.Sprintf("https://%s/%s", b.region.getOBSEndpoint(), b.Name),
Description: "obs url",
},
}
}
func (b *SBucket) GetStats() cloudprovider.SBucketStats {
stats := cloudprovider.SBucketStats{}
obscli, err := b.region.getOBSClient()
if err != nil {
log.Errorf("b.region.getOBSClient error %s", err)
stats.SizeBytes = -1
stats.ObjectCount = -1
return stats
}
output, err := obscli.GetBucketStorageInfo(b.Name)
if err != nil {
log.Errorf("obscli.GetBucketStorageInfo error %s", err)
stats.SizeBytes = -1
stats.ObjectCount = -1
return stats
}
stats.SizeBytes = output.Size
stats.ObjectCount = output.ObjectNumber
return stats
}
func (b *SBucket) ListObjects(prefix string, marker string, delimiter string, maxCount int) (cloudprovider.SListObjectResult, error) {
result := cloudprovider.SListObjectResult{}
obscli, err := b.region.getOBSClient()
if err != nil {
return result, errors.Wrap(err, "GetOBSClient")
}
input := &obs.ListObjectsInput{}
input.Bucket = b.Name
if len(prefix) > 0 {
input.Prefix = prefix
}
if len(marker) > 0 {
input.Marker = marker
}
if len(delimiter) > 0 {
input.Delimiter = delimiter
}
if maxCount > 0 {
input.MaxKeys = maxCount
}
oResult, err := obscli.ListObjects(input)
if err != nil {
return result, errors.Wrap(err, "ListObjects")
}
result.Objects = make([]cloudprovider.ICloudObject, 0)
for _, object := range oResult.Contents {
obj := &SObject{
bucket: b,
SBaseCloudObject: cloudprovider.SBaseCloudObject{
StorageClass: string(object.StorageClass),
Key: object.Key,
SizeBytes: object.Size,
ETag: object.ETag,
LastModified: object.LastModified,
},
}
result.Objects = append(result.Objects, obj)
}
if oResult.CommonPrefixes != nil {
result.CommonPrefixes = make([]cloudprovider.ICloudObject, 0)
for _, commonPrefix := range oResult.CommonPrefixes {
obj := &SObject{
bucket: b,
SBaseCloudObject: cloudprovider.SBaseCloudObject{
Key: commonPrefix,
},
}
result.CommonPrefixes = append(result.CommonPrefixes, obj)
}
}
result.IsTruncated = oResult.IsTruncated
result.NextMarker = oResult.NextMarker
return result, nil
}
func (b *SBucket) PutObject(ctx context.Context, key string, reader io.Reader, sizeBytes int64, cannedAcl cloudprovider.TBucketACLType, storageClassStr string, meta http.Header) error {
obscli, err := b.region.getOBSClient()
if err != nil {
return errors.Wrap(err, "GetOBSClient")
}
input := &obs.PutObjectInput{}
input.Bucket = b.Name
input.Key = key
input.Body = reader
if sizeBytes > 0 {
input.ContentLength = sizeBytes
}
if len(storageClassStr) > 0 {
input.StorageClass, err = str2StorageClass(storageClassStr)
if err != nil {
return err
}
}
if len(cannedAcl) == 0 {
cannedAcl = b.GetAcl()
}
input.ACL = obs.AclType(string(cannedAcl))
if meta != nil {
val := meta.Get(cloudprovider.META_HEADER_CONTENT_TYPE)
if len(val) > 0 {
input.ContentType = val
}
val = meta.Get(cloudprovider.META_HEADER_CONTENT_MD5)
if len(val) > 0 {
input.ContentMD5 = val
}
extraMeta := make(map[string]string)
for k, v := range meta {
if utils.IsInStringArray(k, []string{
cloudprovider.META_HEADER_CONTENT_TYPE,
cloudprovider.META_HEADER_CONTENT_MD5,
}) {
continue
}
if len(v[0]) > 0 {
extraMeta[k] = v[0]
}
}
input.Metadata = extraMeta
}
_, err = obscli.PutObject(input)
if err != nil {
return errors.Wrap(err, "PutObject")
}
return nil
}
func (b *SBucket) NewMultipartUpload(ctx context.Context, key string, cannedAcl cloudprovider.TBucketACLType, storageClassStr string, meta http.Header) (string, error) {
obscli, err := b.region.getOBSClient()
if err != nil {
return "", errors.Wrap(err, "GetOBSClient")
}
input := &obs.InitiateMultipartUploadInput{}
input.Bucket = b.Name
input.Key = key
if meta != nil {
val := meta.Get(cloudprovider.META_HEADER_CONTENT_TYPE)
if len(val) > 0 {
input.ContentType = val
}
extraMeta := make(map[string]string)
for k, v := range meta {
if utils.IsInStringArray(k, []string{
cloudprovider.META_HEADER_CONTENT_TYPE,
}) {
continue
}
if len(v[0]) > 0 {
extraMeta[k] = v[0]
}
}
input.Metadata = extraMeta
}
if len(cannedAcl) == 0 {
cannedAcl = b.GetAcl()
}
input.ACL = obs.AclType(string(cannedAcl))
if len(storageClassStr) > 0 {
input.StorageClass, err = str2StorageClass(storageClassStr)
if err != nil {
return "", errors.Wrap(err, "str2StorageClass")
}
}
output, err := obscli.InitiateMultipartUpload(input)
if err != nil {
return "", errors.Wrap(err, "InitiateMultipartUpload")
}
return output.UploadId, nil
}
func (b *SBucket) UploadPart(ctx context.Context, key string, uploadId string, partIndex int, part io.Reader, partSize int64, offset, totalSize int64) (string, error) {
obscli, err := b.region.getOBSClient()
if err != nil {
return "", errors.Wrap(err, "GetOBSClient")
}
input := &obs.UploadPartInput{}
input.Bucket = b.Name
input.Key = key
input.UploadId = uploadId
input.PartNumber = partIndex
input.PartSize = partSize
input.Body = part
output, err := obscli.UploadPart(input)
if err != nil {
return "", errors.Wrap(err, "UploadPart")
}
return output.ETag, nil
}
func (b *SBucket) CompleteMultipartUpload(ctx context.Context, key string, uploadId string, partEtags []string) error {
obscli, err := b.region.getOBSClient()
if err != nil {
return errors.Wrap(err, "GetOBSClient")
}
input := &obs.CompleteMultipartUploadInput{}
input.Bucket = b.Name
input.Key = key
input.UploadId = uploadId
parts := make([]obs.Part, len(partEtags))
for i := range partEtags {
parts[i] = obs.Part{
PartNumber: i + 1,
ETag: partEtags[i],
}
}
input.Parts = parts
_, err = obscli.CompleteMultipartUpload(input)
if err != nil {
return errors.Wrap(err, "CompleteMultipartUpload")
}
return nil
}
func (b *SBucket) AbortMultipartUpload(ctx context.Context, key string, uploadId string) error {
obscli, err := b.region.getOBSClient()
if err != nil {
return errors.Wrap(err, "GetOBSClient")
}
input := &obs.AbortMultipartUploadInput{}
input.Bucket = b.Name
input.Key = key
input.UploadId = uploadId
_, err = obscli.AbortMultipartUpload(input)
if err != nil {
return errors.Wrap(err, "AbortMultipartUpload")
}
return nil
}
func (b *SBucket) DeleteObject(ctx context.Context, key string) error {
obscli, err := b.region.getOBSClient()
if err != nil {
return errors.Wrap(err, "GetOBSClient")
}
input := &obs.DeleteObjectInput{}
input.Bucket = b.Name
input.Key = key
_, err = obscli.DeleteObject(input)
if err != nil {
return errors.Wrap(err, "DeleteObject")
}
return nil
}
func (b *SBucket) GetTempUrl(method string, key string, expire time.Duration) (string, error) {
obscli, err := b.region.getOBSClient()
if err != nil {
return "", errors.Wrap(err, "GetOBSClient")
}
input := obs.CreateSignedUrlInput{}
input.Bucket = b.Name
input.Key = key
input.Expires = int(expire / time.Second)
switch method {
case "GET":
input.Method = obs.HttpMethodGet
case "PUT":
input.Method = obs.HttpMethodPut
case "DELETE":
input.Method = obs.HttpMethodDelete
default:
return "", errors.Error("unsupported method")
}
output, err := obscli.CreateSignedUrl(&input)
return output.SignedUrl, nil
}
func (b *SBucket) LimitSupport() cloudprovider.SBucketStats {
return cloudprovider.SBucketStats{
SizeBytes: 1,
ObjectCount: -1,
}
}
func (b *SBucket) GetLimit() cloudprovider.SBucketStats {
stats := cloudprovider.SBucketStats{}
obscli, err := b.region.getOBSClient()
if err != nil {
log.Errorf("getOBSClient error %s", err)
return stats
}
output, err := obscli.GetBucketQuota(b.Name)
if err != nil {
return stats
}
stats.SizeBytes = output.Quota
return stats
}
func (b *SBucket) SetLimit(limit cloudprovider.SBucketStats) error {
obscli, err := b.region.getOBSClient()
if err != nil {
return errors.Wrap(err, "getOBSClient")
}
input := &obs.SetBucketQuotaInput{}
input.Bucket = b.Name
input.Quota = limit.SizeBytes
_, err = obscli.SetBucketQuota(input)
if err != nil {
return errors.Wrap(err, "SetBucketQuota")
}
return nil
}
func (b *SBucket) CopyObject(ctx context.Context, destKey string, srcBucket, srcKey string, cannedAcl cloudprovider.TBucketACLType, storageClassStr string, meta http.Header) error {
obscli, err := b.region.getOBSClient()
if err != nil {
return errors.Wrap(err, "GetOBSClient")
}
input := &obs.CopyObjectInput{}
input.Bucket = b.Name
input.Key = destKey
input.CopySourceBucket = srcBucket
input.CopySourceKey = srcKey
if len(storageClassStr) > 0 {
input.StorageClass, err = str2StorageClass(storageClassStr)
if err != nil {
return err
}
}
if len(cannedAcl) == 0 {
cannedAcl = b.GetAcl()
}
input.ACL = obs.AclType(string(cannedAcl))
if meta != nil {
val := meta.Get(cloudprovider.META_HEADER_CONTENT_TYPE)
if len(val) > 0 {
input.ContentType = val
}
extraMeta := make(map[string]string)
for k, v := range meta {
if utils.IsInStringArray(k, []string{
cloudprovider.META_HEADER_CONTENT_TYPE,
}) {
continue
}
if len(v[0]) > 0 {
extraMeta[k] = v[0]
}
}
input.Metadata = extraMeta
input.MetadataDirective = obs.ReplaceMetadata
} else {
input.MetadataDirective = obs.CopyMetadata
}
_, err = obscli.CopyObject(input)
if err != nil {
return errors.Wrap(err, "obscli.CopyObject")
}
return nil
}
func (b *SBucket) GetObject(ctx context.Context, key string, rangeOpt *cloudprovider.SGetObjectRange) (io.ReadCloser, error) {
obscli, err := b.region.getOBSClient()
if err != nil {
return nil, errors.Wrap(err, "GetOBSClient")
}
input := &obs.GetObjectInput{}
input.Bucket = b.Name
input.Key = key
if rangeOpt != nil {
input.RangeStart = rangeOpt.Start
input.RangeEnd = rangeOpt.End
}
output, err := obscli.GetObject(input)
if err != nil {
return nil, errors.Wrap(err, "obscli.GetObject")
}
return output.Body, nil
}
func (b *SBucket) CopyPart(ctx context.Context, key string, uploadId string, partIndex int, srcBucket string, srcKey string, srcOffset int64, srcLength int64) (string, error) {
obscli, err := b.region.getOBSClient()
if err != nil {
return "", errors.Wrap(err, "GetOBSClient")
}
input := &obs.CopyPartInput{}
input.Bucket = b.Name
input.Key = key
input.UploadId = uploadId
input.PartNumber = partIndex
input.CopySourceBucket = srcBucket
input.CopySourceKey = srcKey
input.CopySourceRangeStart = srcOffset
input.CopySourceRangeEnd = srcOffset + srcLength - 1
output, err := obscli.CopyPart(input)
if err != nil {
return "", errors.Wrap(err, "CopyPart")
}
return output.ETag, nil
}
func (b *SBucket) SetWebsite(websitConf cloudprovider.SBucketWebsiteConf) error {
obscli, err := b.region.getOBSClient()
if err != nil {
return errors.Wrap(err, "GetOBSClient")
}
obsWebConf := obs.SetBucketWebsiteConfigurationInput{}
obsWebConf.Bucket = b.Name
obsWebConf.BucketWebsiteConfiguration = obs.BucketWebsiteConfiguration{
IndexDocument: obs.IndexDocument{Suffix: websitConf.Index},
ErrorDocument: obs.ErrorDocument{Key: websitConf.ErrorDocument},
}
_, err = obscli.SetBucketWebsiteConfiguration(&obsWebConf)
if err != nil {
return errors.Wrap(err, "obscli.SetBucketWebsiteConfiguration(&obsWebConf)")
}
return nil
}
func (b *SBucket) GetWebsiteConf() (cloudprovider.SBucketWebsiteConf, error) {
result := cloudprovider.SBucketWebsiteConf{}
obscli, err := b.region.getOBSClient()
if err != nil {
return result, errors.Wrap(err, "GetOBSClient")
}
out, err := obscli.GetBucketWebsiteConfiguration(b.Name)
if out == nil {
return result, nil
}
result.Index = out.IndexDocument.Suffix
result.ErrorDocument = out.ErrorDocument.Key
result.Url = fmt.Sprintf("https://%s.obs-website.%s.myhuaweicloud.com", b.Name, b.region.GetId())
return result, nil
}
func (b *SBucket) DeleteWebSiteConf() error {
obscli, err := b.region.getOBSClient()
if err != nil {
return errors.Wrap(err, "GetOBSClient")
}
_, err = obscli.DeleteBucketWebsiteConfiguration(b.Name)
if err != nil {
return errors.Wrapf(err, "obscli.DeleteBucketWebsiteConfiguration(%s)", b.Name)
}
return nil
}
func (b *SBucket) SetCORS(rules []cloudprovider.SBucketCORSRule) error {
obscli, err := b.region.getOBSClient()
if err != nil {
return errors.Wrap(err, "GetOBSClient")
}
opts := []obs.CorsRule{}
for i := range rules {
opts = append(opts, obs.CorsRule{
AllowedOrigin: rules[i].AllowedOrigins,
AllowedMethod: rules[i].AllowedMethods,
AllowedHeader: rules[i].AllowedHeaders,
MaxAgeSeconds: rules[i].MaxAgeSeconds,
ExposeHeader: rules[i].ExposeHeaders,
})
}
input := obs.SetBucketCorsInput{}
input.Bucket = b.Name
input.BucketCors.CorsRules = opts
_, err = obscli.SetBucketCors(&input)
if err != nil {
return errors.Wrapf(err, "obscli.SetBucketCors(%s)", jsonutils.Marshal(input).String())
}
return nil
}
func (b *SBucket) GetCORSRules() ([]cloudprovider.SBucketCORSRule, error) {
obscli, err := b.region.getOBSClient()
if err != nil {
return nil, errors.Wrap(err, "GetOBSClient")
}
conf, err := obscli.GetBucketCors(b.Name)
if err != nil {
if !strings.Contains(err.Error(), "NoSuchCORSConfiguration") {
return nil, errors.Wrapf(err, "obscli.GetBucketCors(%s)", b.Name)
}
}
if conf == nil {
return nil, nil
}
result := []cloudprovider.SBucketCORSRule{}
for i := range conf.CorsRules {
result = append(result, cloudprovider.SBucketCORSRule{
AllowedOrigins: conf.CorsRules[i].AllowedOrigin,
AllowedMethods: conf.CorsRules[i].AllowedMethod,
AllowedHeaders: conf.CorsRules[i].AllowedHeader,
MaxAgeSeconds: conf.CorsRules[i].MaxAgeSeconds,
ExposeHeaders: conf.CorsRules[i].ExposeHeader,
Id: strconv.Itoa(i),
})
}
return result, nil
}
func (b *SBucket) DeleteCORS() error {
obscli, err := b.region.getOBSClient()
if err != nil {
return errors.Wrap(err, "GetOBSClient")
}
_, err = obscli.DeleteBucketCors(b.Name)
if err != nil {
return errors.Wrapf(err, "obscli.DeleteBucketCors(%s)", b.Name)
}
return nil
}
func (b *SBucket) GetTags() (map[string]string, error) {
obscli, err := b.region.getOBSClient()
if err != nil {
return nil, errors.Wrap(err, "GetOBSClient")
}
tagresult, err := obscli.GetBucketTagging(b.Name)
if err != nil {
if strings.Contains(err.Error(), "404") {
return nil, nil
}
return nil, errors.Wrapf(err, "osscli.GetBucketTagging(%s)", b.Name)
}
result := map[string]string{}
for i := range tagresult.Tags {
result[tagresult.Tags[i].Key] = tagresult.Tags[i].Value
}
return result, nil
}
func (b *SBucket) SetTags(tags map[string]string, replace bool) error {
obscli, err := b.region.getOBSClient()
if err != nil {
return errors.Wrap(err, "GetOBSClient")
}
_, err = obscli.DeleteBucketTagging(b.Name)
if err != nil {
return errors.Wrapf(err, "DeleteBucketTagging")
}
if len(tags) == 0 {
return nil
}
input := obs.SetBucketTaggingInput{BucketTagging: obs.BucketTagging{}}
input.Bucket = b.Name
for k, v := range tags {
input.BucketTagging.Tags = append(input.BucketTagging.Tags, obs.Tag{Key: k, Value: v})
}
_, err = obscli.SetBucketTagging(&input)
if err != nil {
return errors.Wrapf(err, "obscli.SetBucketTagging(%s)", jsonutils.Marshal(input).String())
}
return nil
}
func (b *SBucket) ListMultipartUploads() ([]cloudprovider.SBucketMultipartUploads, error) {
obscli, err := b.region.getOBSClient()
if err != nil {
return nil, errors.Wrap(err, "GetOBSClient")
}
result := []cloudprovider.SBucketMultipartUploads{}
input := obs.ListMultipartUploadsInput{Bucket: b.Name}
keyMarker := ""
uploadIDMarker := ""
for {
if len(keyMarker) > 0 {
input.KeyMarker = keyMarker
}
if len(uploadIDMarker) > 0 {
input.UploadIdMarker = uploadIDMarker
}
output, err := obscli.ListMultipartUploads(&input)
if err != nil {
return nil, errors.Wrap(err, " coscli.Bucket.ListMultipartUploads(context.Background(), &input)")
}
for i := range output.Uploads {
temp := cloudprovider.SBucketMultipartUploads{
ObjectName: output.Uploads[i].Key,
UploadID: output.Uploads[i].UploadId,
Initiator: output.Uploads[i].Initiator.DisplayName,
Initiated: output.Uploads[i].Initiated,
}
result = append(result, temp)
}
keyMarker = output.NextKeyMarker
uploadIDMarker = output.NextUploadIdMarker
if !output.IsTruncated {
break
}
}
return result, nil
}
@@ -0,0 +1,18 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package auth
type Credential interface {
}
@@ -0,0 +1,27 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package credentials
type AccessKeyCredential struct {
AccessKeyId string
AccessKeySecret string
}
func NewAccessKeyCredential(accessKeyId, accessKeySecret string) *AccessKeyCredential {
return &AccessKeyCredential{
AccessKeyId: accessKeyId,
AccessKeySecret: accessKeySecret,
}
}
@@ -0,0 +1,15 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package credentials // import "yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/auth/credentials"
@@ -0,0 +1,15 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package auth // import "yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/auth"
@@ -0,0 +1,214 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package auth
import (
"crypto/md5"
"crypto/sha256"
"encoding/hex"
"fmt"
"io/ioutil"
"sort"
"strings"
"time"
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/auth/credentials"
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/auth/signers"
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/requests"
)
type Signer interface {
GetName() string // 签名算法名称
GetAccessKeyId() (accessKeyId string, err error) // 签名access key
GetSecretKey() (secretKey string, err error) // access secret
Sign(stringToSign, secretSuffix string) string // 生成签名结果
}
func NewSignerWithCredential(credential Credential) (signer Signer, err error) {
switch instance := credential.(type) {
case *credentials.AccessKeyCredential:
return signers.NewAccessKeySigner(instance), nil
default:
return nil, fmt.Errorf("unsupported credential error")
}
}
// 对request进行签名
func Sign(request requests.IRequest, signer Signer) (err error) {
return signRequest(request, signer)
}
func signRequest(request requests.IRequest, signer Signer) error {
// https://support.huaweicloud.com/api-dis/dis_02_0508.html
// requestTime
reqTime := time.Now()
// 添加 必须的Headers
fillRequiredHeaders(request, reqTime)
// 计算CanonicalRequest
canonicalRequest := canonicalRequest(request)
// stringToSign
credentialScope := strings.Join([]string{
formattedSignTime(reqTime, "Date"),
request.GetRegionId(),
request.GetProduct(),
"sdk_request",
}, "/")
stringToSign := strings.Join([]string{"SDK-HMAC-SHA256",
formattedSignTime(reqTime, "DateTime"),
credentialScope,
hashSha256([]byte(canonicalRequest)),
}, "\n")
// 计算SigningKey
secret, _ := signer.GetSecretKey()
signKey := getSigningKey(secret, formattedSignTime(reqTime, "Date"),
request.GetRegionId(), request.GetProduct())
// 计算Signature
signature := signer.Sign(stringToSign, signKey)
accesskey, _ := signer.GetAccessKeyId()
addAuthorizationHeader(request, accesskey, credentialScope, signature)
return nil
}
// https://support.huaweicloud.com/api-vpc/zh-cn_topic_0132456728.html
// X-Project-Id 如果是专属云场景采用AK/SK 认证方式的接口请求或者多project场景采用AK/SK认证的接口请求则该字段必选。
func fillRequiredHeaders(request requests.IRequest, t time.Time) {
request.AddHeaderParam("HOST", request.GetHost())
request.AddHeaderParam("X-Sdk-Date", formattedSignTime(t, "DateTime"))
if len(request.GetProjectId()) > 0 {
request.AddHeaderParam("X-Project-Id", request.GetProjectId())
}
return
}
func buildRequestStringToSign(request requests.IRequest) string {
return ""
}
func formattedSignTime(t time.Time, format string) string {
switch format {
case "Date":
return t.UTC().Format("20060102")
case "DateTime":
return t.UTC().Format("20060102T150405Z")
default:
return t.UTC().Format("20060102T150405Z")
}
}
func contentSha256(request requests.IRequest) string {
method := strings.ToUpper(request.GetMethod())
content := []byte{}
body := request.GetBodyReader()
content, _ = ioutil.ReadAll(body)
if method == "POST" {
if len(content) == 0 {
// other http method use query as content
content = []byte(request.BuildQueries())
}
}
return hashSha256(content)
}
func hashSha256(msg []byte) string {
sh256 := sha256.New()
sh256.Write(msg)
return hex.EncodeToString(sh256.Sum(nil))
}
func canonicalRequest(request requests.IRequest) string {
sha256 := contentSha256(request)
uri := request.GetURI()
if !strings.HasSuffix(uri, "/") {
uri = uri + "/"
}
return strings.Join([]string{
request.GetMethod(),
uri,
canonicalQueryString(request),
canonicalHeaders(request),
canonicalHeaderNames(request),
sha256,
}, "\n")
}
func sortedHeaderNames(request requests.IRequest) []string {
headers := request.GetHeaders()
keys := make([]string, 0)
for k := range headers {
keys = append(keys, k)
}
sort.Slice(keys, func(i, j int) bool {
return strings.ToLower(keys[i]) < strings.ToLower(keys[j])
})
return keys
}
func canonicalQueryString(request requests.IRequest) string {
if strings.ToUpper(request.GetMethod()) != "POST" {
return request.BuildQueries()
}
return ""
}
func canonicalHeaders(request requests.IRequest) string {
keys := sortedHeaderNames(request)
headers := request.GetHeaders()
ret := []string{}
for _, k := range keys {
ret = append(ret, strings.ToLower(k)+":"+strings.TrimSpace(headers[k]))
}
return strings.Join(ret, "\n") + "\n"
}
func canonicalHeaderNames(request requests.IRequest) string {
keys := sortedHeaderNames(request)
ret := strings.Join(keys, ";")
return strings.ToLower(ret)
}
var SigningKeyCache = map[string][]byte{}
func getSigningKey(secretKey, date, regionId, service string) string {
joinedKey := strings.Join([]string{secretKey, date, regionId, service}, "")
cacheKey := fmt.Sprintf("%x", md5.Sum([]byte(joinedKey)))
if v, ok := SigningKeyCache[cacheKey]; ok {
return string(v)
}
ret := []byte("SDK" + secretKey)
for _, k := range []string{date, regionId, service, "sdk_request"} {
ret = signers.HmacSha256(k, ret)
}
SigningKeyCache[cacheKey] = ret
return string(ret)
}
func addAuthorizationHeader(request requests.IRequest, accessKey, credentialScope, signature string) {
auth := "SDK-HMAC-SHA256" + " " + strings.Join([]string{
"Credential=" + accessKey + "/" + credentialScope,
"SignedHeaders=" + canonicalHeaderNames(request),
"Signature=" + signature,
}, ", ")
request.AddHeaderParam("Authorization", auth)
}
@@ -0,0 +1,15 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package signers // import "yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/auth/signers"
@@ -0,0 +1,55 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package signers
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/auth/credentials"
)
type AccessKeySigner struct {
credential *credentials.AccessKeyCredential
}
func (signer *AccessKeySigner) GetName() string {
return "HmacSha256"
}
func (signer *AccessKeySigner) GetAccessKeyId() (accessKeyId string, err error) {
return signer.credential.AccessKeyId, nil
}
func (signer *AccessKeySigner) GetSecretKey() (secretKey string, err error) {
return signer.credential.AccessKeySecret, nil
}
func (signer *AccessKeySigner) Sign(stringToSign, secretSuffix string) string {
return hex.EncodeToString(HmacSha256(stringToSign, []byte(secretSuffix)))
}
func HmacSha256(data string, key []byte) []byte {
mac := hmac.New(sha256.New, key)
mac.Write([]byte(data))
return mac.Sum(nil)
}
func NewAccessKeySigner(credential *credentials.AccessKeyCredential) *AccessKeySigner {
return &AccessKeySigner{
credential: credential,
}
}
+282
View File
@@ -0,0 +1,282 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package client
import (
"net/http"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/auth/credentials"
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/modules"
)
type Client struct {
cfg *SClientConfig
// 标记初始化状态
init bool
Balances *modules.SBalanceManager
Bandwidths *modules.SBandwidthManager
Credentials *modules.SCredentialManager
Disks *modules.SDiskManager
Domains *modules.SDomainManager
Eips *modules.SEipManager
Endpoints *modules.SEndpointManager
Services *modules.SServiceManager
Elasticcache *modules.SElasticcacheManager
DcsAvailableZone *modules.SDcsAvailableZoneManager
Flavors *modules.SFlavorManager
Images *modules.SImageManager
OpenStackImages *modules.SImageManager
Interface *modules.SInterfaceManager
Jobs *modules.SJobManager
Keypairs *modules.SKeypairManager
Elb *modules.SLoadbalancerManager
ElbBackend *modules.SElbBackendManager
ElbBackendGroup *modules.SElbBackendGroupManager
ElbListeners *modules.SElbListenersManager
ElbCertificates *modules.SElbCertificatesManager
ElbHealthCheck *modules.SElbHealthCheckManager
ElbL7policies *modules.SElbL7policiesManager
ElbPolicies *modules.SElbPoliciesManager
ElbWhitelist *modules.SElbWhitelistManager
Orders *modules.SOrderManager
Port *modules.SPortManager
Projects *modules.SProjectManager
Regions *modules.SRegionManager
SecurityGroupRules *modules.SSecgroupRuleManager
SecurityGroups *modules.SSecurityGroupManager
NovaSecurityGroups *modules.SSecurityGroupManager
Servers *modules.SServerManager
ServersV2 *modules.SServerManager
NovaServers *modules.SServerManager
Snapshots *modules.SSnapshotManager
OsSnapshots *modules.SSnapshotManager
Subnets *modules.SSubnetManager
Users *modules.SUserManager
Vpcs *modules.SVpcManager
Zones *modules.SZoneManager
VpcRoutes *modules.SVpcRouteManager
SNatRules *modules.SNatSRuleManager
DNatRules *modules.SNatDRuleManager
NatGateways *modules.SNatGatewayManager
VpcPeerings *modules.SVpcPeeringManager
DBInstance *modules.SDBInstanceManager
DBInstanceBackup *modules.SDBInstanceBackupManager
DBInstanceFlavor *modules.SDBInstanceFlavorManager
DBInstanceJob *modules.SDBInstanceJobManager
Traces *modules.STraceManager
CloudEye *modules.SCloudEyeManager
Quotas *modules.SQuotaManager
EnterpriseProjects *modules.SEnterpriseProjectManager
Roles *modules.SRoleManager
Groups *modules.SGroupManager
SAMLProviders *modules.SAMLProviderManager
SAMLProviderMappings *modules.SAMLProviderMappingManager
SfsTurbos *modules.SfsTurboManager
}
type SClientConfig struct {
signer auth.Signer
endpoints *cloudprovider.SHuaweiCloudStackEndpoints
regionId string
domainId string
projectId string
debug bool
}
func (self *SClientConfig) GetSigner() auth.Signer {
return self.signer
}
func (self *SClientConfig) GetEndpoints() *cloudprovider.SHuaweiCloudStackEndpoints {
return self.endpoints
}
func (self *SClientConfig) GetRegionId() string {
return self.regionId
}
func (self *SClientConfig) GetDomainId() string {
return self.domainId
}
func (self *SClientConfig) GetProjectId() string {
return self.projectId
}
func (self *SClientConfig) GetDebug() bool {
return self.debug
}
func (self *Client) SetHttpClient(httpClient *http.Client) {
self.Credentials.SetHttpClient(httpClient)
self.Servers.SetHttpClient(httpClient)
self.ServersV2.SetHttpClient(httpClient)
self.NovaServers.SetHttpClient(httpClient)
self.Snapshots.SetHttpClient(httpClient)
self.OsSnapshots.SetHttpClient(httpClient)
self.Images.SetHttpClient(httpClient)
self.OpenStackImages.SetHttpClient(httpClient)
self.Projects.SetHttpClient(httpClient)
self.Regions.SetHttpClient(httpClient)
self.Zones.SetHttpClient(httpClient)
self.Vpcs.SetHttpClient(httpClient)
self.Eips.SetHttpClient(httpClient)
self.Elasticcache.SetHttpClient(httpClient)
self.DcsAvailableZone.SetHttpClient(httpClient)
self.Disks.SetHttpClient(httpClient)
self.Domains.SetHttpClient(httpClient)
self.Keypairs.SetHttpClient(httpClient)
self.Elb.SetHttpClient(httpClient)
self.ElbBackend.SetHttpClient(httpClient)
self.ElbBackendGroup.SetHttpClient(httpClient)
self.ElbListeners.SetHttpClient(httpClient)
self.ElbCertificates.SetHttpClient(httpClient)
self.ElbHealthCheck.SetHttpClient(httpClient)
self.ElbL7policies.SetHttpClient(httpClient)
self.ElbPolicies.SetHttpClient(httpClient)
self.ElbWhitelist.SetHttpClient(httpClient)
self.Orders.SetHttpClient(httpClient)
self.SecurityGroupRules.SetHttpClient(httpClient)
self.SecurityGroups.SetHttpClient(httpClient)
self.NovaSecurityGroups.SetHttpClient(httpClient)
self.Subnets.SetHttpClient(httpClient)
self.Users.SetHttpClient(httpClient)
self.Interface.SetHttpClient(httpClient)
self.Jobs.SetHttpClient(httpClient)
self.Balances.SetHttpClient(httpClient)
self.Bandwidths.SetHttpClient(httpClient)
self.Port.SetHttpClient(httpClient)
self.Flavors.SetHttpClient(httpClient)
self.VpcRoutes.SetHttpClient(httpClient)
self.SNatRules.SetHttpClient(httpClient)
self.DNatRules.SetHttpClient(httpClient)
self.NatGateways.SetHttpClient(httpClient)
self.DBInstance.SetHttpClient(httpClient)
self.DBInstanceBackup.SetHttpClient(httpClient)
self.DBInstanceFlavor.SetHttpClient(httpClient)
self.DBInstanceJob.SetHttpClient(httpClient)
self.Traces.SetHttpClient(httpClient)
self.CloudEye.SetHttpClient(httpClient)
self.EnterpriseProjects.SetHttpClient(httpClient)
self.Roles.SetHttpClient(httpClient)
self.Groups.SetHttpClient(httpClient)
self.SAMLProviders.SetHttpClient(httpClient)
self.SAMLProviderMappings.SetHttpClient(httpClient)
self.SfsTurbos.SetHttpClient(httpClient)
self.Endpoints.SetHttpClient(httpClient)
self.Services.SetHttpClient(httpClient)
}
func (self *Client) InitWithAccessKey(regionId, domainId, projectId, accessKey, secretKey string, debug bool, endpoints *cloudprovider.SHuaweiCloudStackEndpoints) error {
// accessKey signer
credential := &credentials.AccessKeyCredential{
AccessKeyId: accessKey,
AccessKeySecret: secretKey,
}
// 从signer中初始化
signer, err := auth.NewSignerWithCredential(credential)
if err != nil {
return err
}
self.cfg = &SClientConfig{
signer: signer,
endpoints: endpoints,
regionId: regionId,
domainId: domainId,
projectId: projectId,
debug: debug,
}
// 初始化 resource manager
self.initManagers()
return err
}
func (self *Client) initManagers() {
if !self.init {
self.Servers = modules.NewServerManager(self.cfg)
self.ServersV2 = modules.NewServerV2Manager(self.cfg)
self.NovaServers = modules.NewNovaServerManager(self.cfg)
self.Snapshots = modules.NewSnapshotManager(self.cfg)
self.OsSnapshots = modules.NewOsSnapshotManager(self.cfg)
self.Images = modules.NewImageManager(self.cfg)
self.OpenStackImages = modules.NewOpenstackImageManager(self.cfg)
self.Projects = modules.NewProjectManager(self.cfg)
self.Regions = modules.NewRegionManager(self.cfg)
self.Zones = modules.NewZoneManager(self.cfg)
self.Vpcs = modules.NewVpcManager(self.cfg)
self.Eips = modules.NewEipManager(self.cfg)
self.Elasticcache = modules.NewElasticcacheManager(self.cfg)
self.DcsAvailableZone = modules.NewDcsAvailableZoneManager(self.cfg)
self.Disks = modules.NewDiskManager(self.cfg)
self.Domains = modules.NewDomainManager(self.cfg)
self.Keypairs = modules.NewKeypairManager(self.cfg)
self.Elb = modules.NewLoadbalancerManager(self.cfg)
self.ElbBackend = modules.NewElbBackendManager(self.cfg)
self.ElbBackendGroup = modules.NewElbBackendGroupManager(self.cfg)
self.ElbListeners = modules.NewElbListenersManager(self.cfg)
self.ElbCertificates = modules.NewElbCertificatesManager(self.cfg)
self.ElbHealthCheck = modules.NewElbHealthCheckManager(self.cfg)
self.ElbL7policies = modules.NewElbL7policiesManager(self.cfg)
self.ElbPolicies = modules.NewElbPoliciesManager(self.cfg)
self.ElbWhitelist = modules.NewElbWhitelistManager(self.cfg)
self.Orders = modules.NewOrderManager(self.cfg)
self.SecurityGroupRules = modules.NewSecgroupRuleManager(self.cfg)
self.SecurityGroups = modules.NewSecurityGroupManager(self.cfg)
self.NovaSecurityGroups = modules.NewNovaSecurityGroupManager(self.cfg)
self.Subnets = modules.NewSubnetManager(self.cfg)
self.Users = modules.NewUserManager(self.cfg)
self.Interface = modules.NewInterfaceManager(self.cfg)
self.Jobs = modules.NewJobManager(self.cfg)
self.Balances = modules.NewBalanceManager(self.cfg)
self.Bandwidths = modules.NewBandwidthManager(self.cfg)
self.Credentials = modules.NewCredentialManager(self.cfg)
self.Port = modules.NewPortManager(self.cfg)
self.Flavors = modules.NewFlavorManager(self.cfg)
self.VpcRoutes = modules.NewVpcRouteManager(self.cfg)
self.SNatRules = modules.NewNatSManager(self.cfg)
self.DNatRules = modules.NewNatDManager(self.cfg)
self.NatGateways = modules.NewNatGatewayManager(self.cfg)
self.VpcPeerings = modules.NewVpcPeeringManager(self.cfg)
self.DBInstance = modules.NewDBInstanceManager(self.cfg)
self.DBInstanceBackup = modules.NewDBInstanceBackupManager(self.cfg)
self.DBInstanceFlavor = modules.NewDBInstanceFlavorManager(self.cfg)
self.DBInstanceJob = modules.NewDBInstanceJobManager(self.cfg)
self.Traces = modules.NewTraceManager(self.cfg)
self.CloudEye = modules.NewCloudEyeManager(self.cfg)
self.Quotas = modules.NewQuotaManager(self.cfg)
self.EnterpriseProjects = modules.NewEnterpriseProjectManager(self.cfg)
self.Roles = modules.NewRoleManager(self.cfg)
self.Groups = modules.NewGroupManager(self.cfg)
self.SAMLProviders = modules.NewSAMLProviderManager(self.cfg)
self.SAMLProviderMappings = modules.NewSAMLProviderMappingManager(self.cfg)
self.SfsTurbos = modules.NewSfsTurboManager(self.cfg)
self.Endpoints = modules.NewEndpointManager(self.cfg)
self.Services = modules.NewServiceManager(self.cfg)
}
self.init = true
}
func NewClientWithAccessKey(regionId, domainId, projectId, accessKey, secretKey string, debug bool, endpoints *cloudprovider.SHuaweiCloudStackEndpoints) (*Client, error) {
c := &Client{}
err := c.InitWithAccessKey(regionId, domainId, projectId, accessKey, secretKey, debug, endpoints)
return c, err
}
+15
View File
@@ -0,0 +1,15 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package client // import "yunion.io/x/onecloud/pkg/multicloud/huaweistack/client"
@@ -0,0 +1,15 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package manager // import "yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/manager"
@@ -0,0 +1,82 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package manager
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/responses"
)
type IManagerContext interface {
GetPath() string
}
type IBaseManager interface {
Version() string
KeyString() string
ServiceType() string
GetColumns() []string
}
type IManager interface {
IBaseManager
// 获取资源列表 GET <base_url>/cloudservers/?<queries>
List(queries map[string]string) (*responses.ListResult, error)
// 根据上文获取资源列表 GET <base_url>/cloudservers/<cloudserver_id>/nics?<queries>
ListInContext(ctx IManagerContext, queries map[string]string) (*responses.ListResult, error)
ListInContextWithSpec(ctx IManagerContext, spec string, queries map[string]string, responseKey string) (*responses.ListResult, error)
// 查询单个资源 GET <base_url>/cloudservers/<cloudserver_id>?<queries>
Get(id string, queries map[string]string) (jsonutils.JSONObject, error)
// 根据上文获取资源查询单个资源 GET <base_url>/cloudservers/<cloudserver_id>/nics/<nic_id>?<queries>
GetInContext(ctx IManagerContext, id string, queries map[string]string) (jsonutils.JSONObject, error)
// 创建单个资源 POST <base_url>/cloudservers
Create(params jsonutils.JSONObject) (jsonutils.JSONObject, error)
// 根据上文创建单个资源 POST <base_url>/cloudservers/<cloudserver_id>/nics/<nic_id>
CreateInContext(ctx IManagerContext, params jsonutils.JSONObject) (jsonutils.JSONObject, error)
// 异步任务创建 POST <base_url>/cloudservers. 返回异步任务 job_id。 todo:// 后续考虑返回一个task对象
AsyncCreate(params jsonutils.JSONObject) (string, error)
// 更新单个资源 PUT <base_url>/cloudservers/<cloudserver_id>
Update(id string, params jsonutils.JSONObject) (jsonutils.JSONObject, error)
// 根据上文更新单个资源 PUT <base_url>/cloudservers/<cloudserver_id>/nics/<nic_id>
UpdateInContext(ctx IManagerContext, id string, params jsonutils.JSONObject) (jsonutils.JSONObject, error)
// 根据上文和spec更新单个资源 PUT /v2.1/{project_id}/servers/{server_id}/os-reset-password
UpdateInContextWithSpec(ctx IManagerContext, id string, spec string, params jsonutils.JSONObject, responseKey string) (jsonutils.JSONObject, error)
// 删除单个资源 DELETE <base_url>/cloudservers/<cloudserver_id>
Delete(id string, params jsonutils.JSONObject) (jsonutils.JSONObject, error)
// 根据上文删除单个资源 DELETE <base_url>/cloudservers/<cloudserver_id>/nics/<nic_id>
DeleteInContext(ctx IManagerContext, id string, params jsonutils.JSONObject) (jsonutils.JSONObject, error)
// 根据上文和spec删除单个资源
DeleteInContextWithSpec(ctx IManagerContext, id string, spec string, queries map[string]string, params jsonutils.JSONObject, responseKey string) (jsonutils.JSONObject, error)
// 批量执行操作 POST <base_url>/cloudservers/<action>
// BatchPerformAction(action string, params jsonutils.JSONObject) (jsonutils.JSONObject, error)
// 执行操作 POST <base_url>/cloudservers/<cloudserver_id>/<action>
PerformAction(action string, id string, params jsonutils.JSONObject) (jsonutils.JSONObject, error)
}
type IManagerConfig interface {
GetSigner() auth.Signer
GetEndpoints() *cloudprovider.SHuaweiCloudStackEndpoints
GetRegionId() string
GetDomainId() string
GetProjectId() string
GetDebug() bool
}
@@ -0,0 +1,15 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package modules // import "yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/modules"
@@ -0,0 +1,266 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package modules
import (
"context"
"fmt"
"net/http"
"strconv"
"strings"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/manager"
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/requests"
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/responses"
"yunion.io/x/onecloud/pkg/util/httputils"
)
type IRequestHook interface {
Process(r requests.IRequest)
}
type SBaseManager struct {
cfg manager.IManagerConfig
httpClient *http.Client
requestHook IRequestHook // 用于对request做特殊处理。非必要请不要使用!!!。目前只有port接口用到。
columns []string
debug bool
}
type sThrottlingThreshold struct {
locked bool
lockTime time.Time
}
func (t *sThrottlingThreshold) CheckingLock() {
if !t.locked {
return
}
for {
if t.lockTime.Sub(time.Now()).Seconds() < 0 {
return
}
log.Debugf("throttling threshold has been reached. release at %s", t.lockTime)
time.Sleep(5 * time.Second)
}
}
func (t *sThrottlingThreshold) Lock() {
// 锁定至少15秒
t.locked = true
t.lockTime = time.Now().Add(15 * time.Second)
}
var ThrottlingLock = sThrottlingThreshold{locked: false, lockTime: time.Time{}}
func NewBaseManager2(cfg manager.IManagerConfig, requesthk IRequestHook) SBaseManager {
return SBaseManager{
cfg: cfg,
httpClient: httputils.GetDefaultClient(),
debug: cfg.GetDebug(),
requestHook: requesthk,
}
}
func NewBaseManager(cfg manager.IManagerConfig) SBaseManager {
return NewBaseManager2(cfg, nil)
}
func (self *SBaseManager) GetColumns() []string {
return self.columns
}
func (self *SBaseManager) SetHttpClient(httpClient *http.Client) {
self.httpClient = httpClient
}
func (self *SBaseManager) _list(request requests.IRequest, responseKey string) (*responses.ListResult, error) {
_, body, err := self.jsonRequest(request)
if err != nil {
return nil, err
}
if body == nil {
log.Warningf("empty response")
return &responses.ListResult{}, nil
}
rets, err := body.GetArray(responseKey)
if err != nil {
return nil, err
}
total, _ := body.Int("count")
// if err != nil {
// total = int64(len(rets))
//}
//if total == 0 {
// total = int64(len(rets))
//}
limit := 0
if v, exists := request.GetQueryParams()["limit"]; exists {
limit, _ = strconv.Atoi(v)
}
offset := 0
if v, exists := request.GetQueryParams()["offset"]; exists {
offset, _ = strconv.Atoi(v)
}
return &responses.ListResult{
Data: rets,
Total: int(total),
Limit: limit,
Offset: offset,
}, nil
}
func (self *SBaseManager) _do(request requests.IRequest, responseKey string) (jsonutils.JSONObject, error) {
_, resp, e := self.jsonRequest(request)
if e != nil {
return nil, e
}
if resp == nil { // no reslt
return jsonutils.NewDict(), nil
}
if len(responseKey) == 0 {
return resp, nil
}
ret, e := resp.Get(responseKey)
if e != nil {
return nil, e
}
return ret, nil
}
func (self *SBaseManager) _get(request requests.IRequest, responseKey string) (jsonutils.JSONObject, error) {
return self._do(request, responseKey)
}
type HuaweiClientError struct {
Code int
Errorcode []string
err error
Details string
ErrorCode string
}
func (ce *HuaweiClientError) Error() string {
return jsonutils.Marshal(ce).String()
}
func (ce *HuaweiClientError) ParseErrorFromJsonResponse(statusCode int, body jsonutils.JSONObject) error {
if body != nil {
body.Unmarshal(ce)
}
if ce.Code == 0 {
ce.Code = statusCode
}
if len(ce.Details) == 0 && body != nil {
ce.Details = body.String()
}
return ce
}
func (self *SBaseManager) jsonRequest(request requests.IRequest) (http.Header, jsonutils.JSONObject, error) {
ThrottlingLock.CheckingLock()
ctx := context.Background()
// hook request
if self.requestHook != nil {
self.requestHook.Process(request)
}
// 拼接、编译、签名 requests here。
err := self.buildRequestWithSigner(request, self.cfg.GetSigner())
if err != nil {
return nil, nil, err
}
header := http.Header{}
for k, v := range request.GetHeaders() {
header.Set(k, v)
}
var jsonBody jsonutils.JSONObject
content := request.GetContent()
if len(content) > 0 {
jsonBody, err = jsonutils.Parse(content)
if err != nil {
return nil, nil, fmt.Errorf("not a json body")
}
}
client := httputils.NewJsonClient(self.httpClient)
req := httputils.NewJsonRequest(httputils.THttpMethod(request.GetMethod()), request.BuildUrl(), jsonBody)
req.SetHeader(header)
resp := &HuaweiClientError{}
const MAX_RETRY = 3
retry := MAX_RETRY
for {
h, b, e := client.Send(ctx, req, resp, self.debug)
if e == nil {
return h, b, nil
}
log.Errorf("[%s] %s body: %v error: %v", req.GetHttpMethod(), req.GetUrl(), jsonBody, e)
switch err := e.(type) {
case *HuaweiClientError:
if err.ErrorCode == "APIGW.0301" {
return h, b, errors.Wrapf(httperrors.ErrInvalidAccessKey, e.Error())
} else if err.Code == 499 && retry > 0 && request.GetMethod() == "GET" {
retry -= 1
time.Sleep(3 * time.Second * time.Duration(MAX_RETRY-retry))
} else if (err.Code == 404 || strings.Contains(err.Details, "could not be found") || strings.Contains(err.Details, "does not exist")) && request.GetMethod() != "POST" {
return h, b, errors.Wrap(cloudprovider.ErrNotFound, err.Error())
} else if err.Code == 429 && retry > 0 {
// 当前请求过多。
ThrottlingLock.Lock()
retry -= 1
time.Sleep(15 * time.Second)
} else {
return h, b, e
}
default:
return h, b, e
}
}
}
func (self *SBaseManager) rawRequest(request requests.IRequest) (*http.Response, error) {
ctx := context.Background()
// 拼接、编译requests here。
header := http.Header{}
for k, v := range request.GetHeaders() {
header.Set(k, v)
}
return httputils.Request(self.httpClient, ctx, httputils.THttpMethod(request.GetMethod()), request.BuildUrl(), header, request.GetBodyReader(), self.debug)
}
func (self *SBaseManager) buildRequestWithSigner(request requests.IRequest, signer auth.Signer) error {
return auth.Sign(request, signer)
}
@@ -0,0 +1,300 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package modules
import (
"fmt"
"net/url"
"strings"
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/manager"
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/requests"
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/responses"
)
type ServiceNameType string
const HuaWeiDefaultDomain = "myhuaweicloud.com"
const (
ServiceNameECS ServiceNameType = "ecs" // 弹性云服务
ServiceNameCCE ServiceNameType = "cce" // 云容器服务
ServiceNameAS ServiceNameType = "as" // 弹性伸缩服务
ServiceNameIAM ServiceNameType = "iam-pub" // 统一身份认证服务
ServiceNameIMS ServiceNameType = "ims" // 镜像服务
ServiceNameCSBS ServiceNameType = "csbs" // 云服务器备份服务
ServiceNameCCI ServiceNameType = "cci" // 云容器实例 CCI
ServiceNameBMS ServiceNameType = "bms" // 裸金属服务器
ServiceNameEVS ServiceNameType = "evs" // 云硬盘 EVS
ServiceNameVBS ServiceNameType = "vbs" // 云硬盘备份 VBS
ServiceNameOBS ServiceNameType = "obs" // 对象存储服务 OBS
ServiceNameVPC ServiceNameType = "vpc" // 虚拟私有云 VPC
ServiceNameELB ServiceNameType = "elb" // 弹性负载均衡 ELB
ServiceNameBSS ServiceNameType = "bss" // 合作伙伴运营能力
ServiceNameNAT ServiceNameType = "nat" // Nat网关 NAT
ServiceNameDCS ServiceNameType = "dcs" // 分布式缓存服务
ServiceNameRDS ServiceNameType = "rds" // 关系型数据库 RDS
ServiceNameCTS ServiceNameType = "cts" // 云审计服务
ServiceNameCES ServiceNameType = "ces" // 监控服务 CloudEye
ServiceNameEPS ServiceNameType = "eps" // 企业项目
ServiceNameSFSTurbo ServiceNameType = "sfs-turbo" // 文件系统
)
type SManagerContext struct {
InstanceManager manager.IManager
InstanceId string
}
func (self *SManagerContext) GetPath() string {
path := self.InstanceManager.KeyString()
if len(self.InstanceId) > 0 {
path += fmt.Sprintf("/%s", url.PathEscape(self.InstanceId))
}
return path
}
type SResourceManager struct {
SBaseManager
ctx manager.IManagerContext
ServiceName ServiceNameType // 服务名称: ecs
Region string // 区域: cn-north-1
DomainId string
ProjectId string // 项目ID uuid
version string // api 版本号
Keyword string // 资源名称单数。构建URL时使用
KeywordPlural string // 资源名称复数形式。构建URL时使用
ResourceKeyword string // 资源名称。url中使用
}
func getContent(params jsonutils.JSONObject) string {
if params == nil {
return ""
}
return params.String()
}
func (self *SResourceManager) Version() string {
return self.version
}
func (self *SResourceManager) KeyString() string {
return self.ResourceKeyword
}
func (self *SResourceManager) ServiceType() string {
return string(self.ServiceName)
}
func (self *SResourceManager) GetEndpoint() string {
return self.cfg.GetEndpoints().GetEndpoint(self.ServiceType(), self.Region)
}
func (self *SResourceManager) GetColumns() []string {
return []string{}
}
func (self *SResourceManager) SetDomainId(domainId string) {
self.DomainId = domainId
}
func (self *SResourceManager) getReourcePath(ctx manager.IManagerContext, rid string, spec string) string {
segs := []string{}
if ctx != nil {
segs = append(segs, ctx.GetPath())
}
segs = append(segs, self.KeyString())
if len(rid) > 0 {
segs = append(segs, url.PathEscape(rid))
}
if len(spec) > 0 {
specSegs := strings.Split(spec, "/")
for _, specSeg := range specSegs {
segs = append(segs, url.PathEscape(specSeg))
}
}
return strings.Join(segs, "/")
}
func (self *SResourceManager) newRequest(method, rid, spec string, ctx manager.IManagerContext) *requests.SRequest {
resourcePath := self.getReourcePath(ctx, rid, spec)
return requests.NewResourceRequest(self.GetEndpoint(), method, string(self.ServiceName), self.version, self.Region, self.ProjectId, resourcePath)
}
func (self *SResourceManager) List(queries map[string]string) (*responses.ListResult, error) {
return self.ListInContext(self.ctx, queries)
}
func (self *SResourceManager) ListInContext(ctx manager.IManagerContext, queries map[string]string) (*responses.ListResult, error) {
return self.ListInContextWithSpec(ctx, "", queries, self.KeywordPlural)
}
func (self *SResourceManager) ListInContextWithSpec(ctx manager.IManagerContext, spec string, queries map[string]string, responseKey string) (*responses.ListResult, error) {
request := self.newRequest("GET", "", spec, ctx)
for k, v := range queries {
request.AddQueryParam(k, v)
}
if len(self.DomainId) > 0 {
request.AddHeaderParam("X-Domain-Id", self.DomainId)
}
return self._list(request, responseKey)
}
func (self *SResourceManager) Get(id string, queries map[string]string) (jsonutils.JSONObject, error) {
return self.GetInContext(self.ctx, id, queries)
}
func (self *SResourceManager) GetInContext(ctx manager.IManagerContext, id string, queries map[string]string) (jsonutils.JSONObject, error) {
return self.GetInContextWithSpec(ctx, id, "", queries, self.Keyword)
}
func (self *SResourceManager) GetInContextWithSpec(ctx manager.IManagerContext, id string, spec string, queries map[string]string, responseKey string) (jsonutils.JSONObject, error) {
request := self.newRequest("GET", id, spec, ctx)
for k, v := range queries {
request.AddQueryParam(k, v)
}
if len(self.DomainId) > 0 {
request.AddHeaderParam("X-Domain-Id", self.DomainId)
}
return self._get(request, responseKey)
}
func (self *SResourceManager) Create(params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
return self.CreateInContext(self.ctx, params)
}
func (self *SResourceManager) CreateInContext(ctx manager.IManagerContext, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
return self.CreateInContextWithSpec(ctx, "", params, self.Keyword)
}
func (self *SResourceManager) CreateInContextWithSpec(ctx manager.IManagerContext, spec string, params jsonutils.JSONObject, responseKey string) (jsonutils.JSONObject, error) {
request := self.newRequest("POST", "", spec, ctx)
request.SetContent([]byte(params.String()))
if len(self.DomainId) > 0 {
request.AddHeaderParam("X-Domain-Id", self.DomainId)
}
return self._do(request, responseKey)
}
func (self *SResourceManager) AsyncCreate(params jsonutils.JSONObject) (string, error) {
return "", fmt.Errorf("not supported")
}
func (self *SResourceManager) Update(id string, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
return self.UpdateInContext(self.ctx, id, params)
}
func (self *SResourceManager) UpdateInContext(ctx manager.IManagerContext, id string, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
return self.UpdateInContextWithSpec(ctx, id, "", params, self.Keyword)
}
func (self *SResourceManager) UpdateInContextWithSpec(ctx manager.IManagerContext, id string, spec string, params jsonutils.JSONObject, responseKey string) (jsonutils.JSONObject, error) {
request := self.newRequest("PUT", id, spec, ctx)
content := getContent(params)
if len(content) > 0 {
request.SetContent([]byte(content))
}
if len(self.DomainId) > 0 {
request.AddHeaderParam("X-Domain-Id", self.DomainId)
}
return self._do(request, responseKey)
}
func (self *SResourceManager) Patch(id string, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
return self.PatchInContext(self.ctx, id, params)
}
func (self *SResourceManager) PatchInContext(ctx manager.IManagerContext, id string, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
return self.PatchInContextWithSpec(ctx, id, "", params, self.Keyword)
}
func (self *SResourceManager) PatchInContextWithSpec(ctx manager.IManagerContext, id string, spec string, params jsonutils.JSONObject, responseKey string) (jsonutils.JSONObject, error) {
request := self.newRequest("PATCH", id, spec, ctx)
content := getContent(params)
if len(content) > 0 {
request.SetContent([]byte(content))
}
if len(self.DomainId) > 0 {
request.AddHeaderParam("X-Domain-Id", self.DomainId)
}
return self._do(request, responseKey)
}
func (self *SResourceManager) Delete(id string, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
return self.DeleteInContext(self.ctx, id, params)
}
func (self *SResourceManager) DeleteInContext(ctx manager.IManagerContext, id string, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
return self.DeleteInContextWithSpec(ctx, id, "", nil, params, "")
}
func (self *SResourceManager) DeleteInContextWithSpec(ctx manager.IManagerContext, id string, spec string, queries map[string]string, params jsonutils.JSONObject, responseKey string) (jsonutils.JSONObject, error) {
request := self.newRequest("DELETE", id, spec, ctx)
for k, v := range queries {
request.AddQueryParam(k, v)
}
content := getContent(params)
if len(content) > 0 {
request.SetContent([]byte(content))
}
if len(self.DomainId) > 0 {
request.AddHeaderParam("X-Domain-Id", self.DomainId)
}
return self._do(request, responseKey)
}
func (self *SResourceManager) PerformAction(action string, id string, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
return self.PerformAction2(action, id, params, self.Keyword)
}
func (self *SResourceManager) PerformAction2(action string, id string, params jsonutils.JSONObject, responseKey string) (jsonutils.JSONObject, error) {
request := self.newRequest("POST", id, action, nil)
request.SetContent([]byte(getContent(params)))
if len(self.DomainId) > 0 {
request.AddHeaderParam("X-Domain-Id", self.DomainId)
}
return self._do(request, responseKey)
}
func (self *SResourceManager) SetVersion(v string) {
self.version = v
}
func (self *SResourceManager) versionedURL(path string) string {
return ""
}
// todo: Init a manager with environment variables
func (self *SResourceManager) Init() error {
return nil
}
@@ -0,0 +1,72 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package modules
import (
"fmt"
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/manager"
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/responses"
)
/*
https://support.huaweicloud.com/api-oce/zh-cn_topic_0075195195.html
客户运营能力API的Endpoint为bss.cn-north-1.myhuaweicloud.com该Endpoint为全局Endpoint中国站所有区域均可使用
如何获取合作伙伴ID https://support.huaweicloud.com/bpconsole_faq/zh-cn_topic_0081005893.html
注意事项
客户查询自身的账户余额的时候只允许使用客户自身的AK/SK或者Token调用
*/
type SBalanceManager struct {
domainId string // 租户ID
SResourceManager
}
type balanceCtx struct {
domainId string
}
// https://support.huaweicloud.com/api-bpconsole/zh-cn_topic_0075213309.html
// 这个manager非常特殊。url hardcode
func (self *balanceCtx) GetPath() string {
return fmt.Sprintf("%s/customer/account-mgr", self.domainId)
}
// 这个manager非常特殊。只有List 和 SetDomainId方法可用。其他方法未验证
func NewBalanceManager(cfg manager.IManagerConfig) *SBalanceManager {
return &SBalanceManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameBSS,
Region: "cn-north-1",
ProjectId: "",
version: "v1.0",
Keyword: "account_balance",
KeywordPlural: "account_balances",
ResourceKeyword: "balances",
}}
}
func (self *SBalanceManager) List(querys map[string]string) (*responses.ListResult, error) {
if len(self.domainId) == 0 {
return nil, fmt.Errorf("domainId is emtpy.Use SetDomainId method to set.")
}
ctx := &balanceCtx{domainId: self.domainId}
return self.ListInContext(ctx, querys)
}
func (self *SBalanceManager) SetDomainId(domainId string) {
self.domainId = domainId
}
@@ -0,0 +1,37 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/manager"
)
type SBandwidthManager struct {
SResourceManager
}
func NewBandwidthManager(cfg manager.IManagerConfig) *SBandwidthManager {
return &SBandwidthManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameVPC,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v1",
Keyword: "bandwidth",
KeywordPlural: "bandwidths",
ResourceKeyword: "bandwidths",
}}
}
@@ -0,0 +1,152 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package modules
import (
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/manager"
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/requests"
)
type SCloudEyeManager struct {
SResourceManager
}
func NewCloudEyeManager(cfg manager.IManagerConfig) *SCloudEyeManager {
return &SCloudEyeManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameCES,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "V1.0",
Keyword: "",
KeywordPlural: "metrics",
ResourceKeyword: "metrics",
}}
}
type SMetricDimension struct {
Name string `json:"name"`
Value string `json:"value"`
}
type SDatapoint struct {
Timestamp int64 `json:"timestamp"`
Max float64 `json:"max,omitzero"`
Min float64 `json:"min,omitzero"`
Average float64 `json:"average,omitzero"`
Sum float64 `json:"sum,omitzero"`
Variance float64 `json:"variance,omitzero"`
}
type SMetricData struct {
SMetricMeta
Datapoints []SDatapoint
}
type SMetricMeta struct {
SMetric
Unit string `json:"unit"`
}
type SMetric struct {
MetricName string `json:"metric_name"`
Namespace string `json:"namespace"`
Dimensions []SMetricDimension `json:"dimensions"`
}
func (ces *SCloudEyeManager) ListMetrics() ([]SMetricMeta, error) {
metrics := make([]SMetricMeta, 0)
next := ""
for {
marker, data, err := ces.listMetricsInternal(next)
if err != nil {
return nil, errors.Wrap(err, "ces.listMetricsInternal")
}
if len(data) == 0 {
break
}
metrics = append(metrics, data...)
next = marker
}
return metrics, nil
}
func (ces *SCloudEyeManager) listMetricsInternal(start string) (string, []SMetricMeta, error) {
request := requests.NewResourceRequest(ces.GetEndpoint(), "GET", string(ces.ServiceName), ces.version, ces.Region, ces.ProjectId, ces.ResourceKeyword)
request.AddQueryParam("limit", "1000")
if len(start) > 0 {
request.AddQueryParam("start", start)
}
_, resp, err := ces.jsonRequest(request)
if err != nil {
return "", nil, errors.Wrap(err, "ces.jsonRequest")
}
marker, _ := resp.GetString("meta_data", "marker")
metrics := make([]SMetricMeta, 0)
err = resp.Unmarshal(&metrics, "metrics")
if err != nil {
return "", nil, errors.Wrap(err, "resp.Unmarshal metrics")
}
return marker, metrics, nil
}
type SBatchQueryMetricDataInput struct {
Metrics []SMetric `json:"metrics"`
From int64 `json:"from"`
To int64 `json:"to"`
Period string `json:"period"`
Filter string `json:"filter"`
}
func (ces *SCloudEyeManager) GetMetricsData(metrics []SMetricMeta, since time.Time, until time.Time) ([]SMetricData, error) {
if len(metrics) > 10 {
return nil, errors.Wrap(httperrors.ErrTooLarge, "request more than 10 metrics")
}
metricReq := make([]SMetric, len(metrics))
for i := range metrics {
metricReq[i] = metrics[i].SMetric
}
request := requests.NewResourceRequest(ces.GetEndpoint(), "POST", string(ces.ServiceName), ces.version, ces.Region, ces.ProjectId, "batch-query-metric-data")
input := SBatchQueryMetricDataInput{
Metrics: metricReq,
From: since.Unix() * 1000,
To: until.Unix() * 1000,
Period: "1",
Filter: "average",
}
body := jsonutils.Marshal(&input).String()
request.SetContent([]byte(body))
_, resp, err := ces.jsonRequest(request)
if err != nil {
return nil, errors.Wrap(err, "ces.jsonRequest")
}
//log.Debugf("%s", resp)
result := make([]SMetricData, 0)
err = resp.Unmarshal(&result, "metrics")
if err != nil {
return nil, errors.Wrap(err, "resp.Unmarshal")
}
return result, nil
}
@@ -0,0 +1,37 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/manager"
)
type SCredentialManager struct {
SResourceManager
}
func NewCredentialManager(cfg manager.IManagerConfig) *SCredentialManager {
return &SCredentialManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameIAM,
Region: cfg.GetRegionId(),
ProjectId: "",
version: "v3.0",
Keyword: "credential",
KeywordPlural: "credentials",
ResourceKeyword: "OS-CREDENTIAL/credentials",
}}
}
@@ -0,0 +1,103 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package modules
import (
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/manager"
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/responses"
)
type SDBInstanceManager struct {
SResourceManager
}
func NewDBInstanceManager(cfg manager.IManagerConfig) *SDBInstanceManager {
return &SDBInstanceManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameRDS,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v3",
Keyword: "",
KeywordPlural: "instances",
ResourceKeyword: "instances",
}}
}
func (self *SDBInstanceManager) Get(id string, querys map[string]string) (jsonutils.JSONObject, error) {
if len(id) == 0 {
return nil, cloudprovider.ErrNotFound
}
resp, err := self.GetInContextWithSpec(nil, "", "", map[string]string{"id": id}, "")
if err != nil {
return nil, err
}
instances, err := resp.GetArray("instances")
if err != nil {
return nil, err
}
if len(instances) == 0 {
return nil, cloudprovider.ErrNotFound
} else if len(instances) == 1 {
return instances[0], nil
}
return nil, cloudprovider.ErrDuplicateId
}
func (self *SDBInstanceManager) ListParameters(queries map[string]string) (*responses.ListResult, error) {
id, _ := queries["instance_id"]
if len(id) == 0 {
return nil, fmt.Errorf("SDBInstanceManager.ListParameters missing parameter instance_id")
}
delete(queries, "instance_id")
return self.ListInContextWithSpec(nil, fmt.Sprintf("%s/configurations", id), queries, "configuration_parameters")
}
func (self *SDBInstanceManager) ListDatabases(queries map[string]string) (*responses.ListResult, error) {
id, _ := queries["instance_id"]
if len(id) == 0 {
return nil, fmt.Errorf("SDBInstanceManager.ListDatabases missing parameter instance_id")
}
delete(queries, "instance_id")
return self.ListInContextWithSpec(nil, fmt.Sprintf("%s/database/detail", id), queries, "databases")
}
func (self *SDBInstanceManager) ListAccounts(queries map[string]string) (*responses.ListResult, error) {
id, _ := queries["instance_id"]
if len(id) == 0 {
return nil, fmt.Errorf("SDBInstanceManager.ListAccounts missing parameter instance_id")
}
delete(queries, "instance_id")
return self.ListInContextWithSpec(nil, fmt.Sprintf("%s/db_user/detail", id), queries, "users")
}
func (self *SDBInstanceManager) ListPrivileges(queries map[string]string) (*responses.ListResult, error) {
id, _ := queries["instance_id"]
if len(id) == 0 {
return nil, fmt.Errorf("SDBInstanceManager.ListPrivileges missing parameter instance_id")
}
delete(queries, "instance_id")
return self.ListInContextWithSpec(nil, fmt.Sprintf("%s/db_user/database", id), queries, "databases")
}
@@ -0,0 +1,37 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/manager"
)
type SDBInstanceBackupManager struct {
SResourceManager
}
func NewDBInstanceBackupManager(cfg manager.IManagerConfig) *SDBInstanceBackupManager {
return &SDBInstanceBackupManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameRDS,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v3",
Keyword: "backup",
KeywordPlural: "backups",
ResourceKeyword: "backups",
}}
}
@@ -0,0 +1,37 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/manager"
)
type SDBInstanceFlavorManager struct {
SResourceManager
}
func NewDBInstanceFlavorManager(cfg manager.IManagerConfig) *SDBInstanceFlavorManager {
return &SDBInstanceFlavorManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameRDS,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v3",
Keyword: "flavor",
KeywordPlural: "flavor",
ResourceKeyword: "flavors",
}}
}
@@ -0,0 +1,43 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package modules
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/manager"
)
type SDBInstanceJobManager struct {
SResourceManager
}
func NewDBInstanceJobManager(cfg manager.IManagerConfig) *SDBInstanceJobManager {
return &SDBInstanceJobManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameRDS,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v3",
Keyword: "",
KeywordPlural: "",
ResourceKeyword: "jobs",
}}
}
func (self *SDBInstanceJobManager) Get(id string, querys map[string]string) (jsonutils.JSONObject, error) {
return self.GetInContextWithSpec(nil, "", "", map[string]string{"id": id}, "job")
}
@@ -0,0 +1,76 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package modules
import (
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/manager"
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/responses"
)
type SDiskManager struct {
SResourceManager
}
func NewDiskManager(cfg manager.IManagerConfig) *SDiskManager {
return &SDiskManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameEVS,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v2",
Keyword: "volume",
KeywordPlural: "volumes",
ResourceKeyword: "cloudvolumes",
}}
}
func (self *SDiskManager) List(querys map[string]string) (*responses.ListResult, error) {
return self.ListInContextWithSpec(nil, "detail", querys, self.KeywordPlural)
}
// https://support.huaweicloud.com/api-evs/evs_04_2003.html
func (self *SDiskManager) AsyncCreate(params jsonutils.JSONObject) (string, error) {
origin_version := self.version
self.version = "v2.1"
defer func() { self.version = origin_version }()
ret, err := self.CreateInContextWithSpec(nil, "", params, "")
if err != nil {
log.Debugf("AsyncCreate %s", err)
return "", err
}
log.Debugf("AsyncCreate result %s", ret.String())
// 按需机器
jobId, err := ret.GetString("job_id")
if err == nil {
return jobId, nil
}
// 包年包月机器
return ret.GetString("order_id")
}
// https://support.huaweicloud.com/api-evs/evs_04_2003.html
func (self *SDiskManager) GetDiskTypes() (*responses.ListResult, error) {
originKeyword := self.ResourceKeyword
self.ResourceKeyword = ""
defer func() { self.ResourceKeyword = originKeyword }()
return self.ListInContextWithSpec(self.ctx, "types", nil, "volume_types")
}
@@ -0,0 +1,41 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/manager"
)
type SNatDRuleManager struct {
SResourceManager
}
func NewNatDManager(cfg manager.IManagerConfig) *SNatDRuleManager {
man := &SNatDRuleManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameNAT,
Region: cfg.GetRegionId(),
ProjectId: "",
version: "v2.0",
Keyword: "dnat_rule",
KeywordPlural: "dnat_rules",
ResourceKeyword: "dnat_rules",
}}
if len(cfg.GetProjectId()) > 0 {
man.requestHook = &sProjectHook{cfg.GetProjectId()}
}
return man
}
@@ -0,0 +1,37 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/manager"
)
type SDomainManager struct {
SResourceManager
}
func NewDomainManager(cfg manager.IManagerConfig) *SDomainManager {
return &SDomainManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameIAM,
Region: cfg.GetRegionId(),
ProjectId: "",
version: "v3/auth",
Keyword: "domain",
KeywordPlural: "domains",
ResourceKeyword: "domains",
}}
}
@@ -0,0 +1,44 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package modules
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/manager"
)
type SEipManager struct {
SResourceManager
}
func NewEipManager(cfg manager.IManagerConfig) *SEipManager {
return &SEipManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(cfg),
ServiceName: ServiceNameVPC,
Region: cfg.GetRegionId(),
ProjectId: cfg.GetProjectId(),
version: "v1",
Keyword: "publicip",
KeywordPlural: "publicips",
ResourceKeyword: "publicips",
}}
}
// https://support.huaweicloud.com/api-eip/eip_api_0005.html
func (self *SEipManager) Delete(id string, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
return self.DeleteInContextWithSpec(self.ctx, id, "", nil, params, "")
}

Some files were not shown because too many files have changed in this diff Show More