From a8522f56fd150f5f34815314f374486d47ce069e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=94=90?= Date: Wed, 26 Apr 2023 10:32:32 +0800 Subject: [PATCH] =?UTF-8?q?feat(bingocloud)=EF=BC=9Aimprove=20bingocloud?= =?UTF-8?q?=20driver?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/bingocli/main.go | 11 +- pkg/cloudprovider/cloudprovider.go | 2 + pkg/cloudprovider/disk.go | 1 + pkg/cloudprovider/resources.go | 2 + pkg/cloudprovider/subaccount.go | 3 + pkg/multicloud/aliyun/region.go | 6 +- pkg/multicloud/aliyun/vpc.go | 4 + pkg/multicloud/apsara/region.go | 6 +- pkg/multicloud/apsara/vpc.go | 4 + pkg/multicloud/aws/region.go | 6 +- pkg/multicloud/aws/vpc.go | 4 + pkg/multicloud/azure/classic_vpc.go | 4 + pkg/multicloud/azure/region.go | 6 +- pkg/multicloud/azure/vpc.go | 4 + pkg/multicloud/bingocloud/account.go | 67 ++++++++- pkg/multicloud/bingocloud/bingo.go | 140 +++++++++++------- pkg/multicloud/bingocloud/disk.go | 33 ++++- pkg/multicloud/bingocloud/eip.go | 94 +++++++++++- pkg/multicloud/bingocloud/image.go | 26 +++- pkg/multicloud/bingocloud/instance.go | 112 +++++++++++--- .../bingocloud/instance_snapshot.go | 132 +++++++++-------- pkg/multicloud/bingocloud/instancenic.go | 12 +- pkg/multicloud/bingocloud/monitor.go | 9 +- .../bingocloud/provider/provider.go | 24 ++- pkg/multicloud/bingocloud/quotas.go | 9 -- pkg/multicloud/bingocloud/region.go | 51 +++++-- pkg/multicloud/bingocloud/securitygroup.go | 41 +++-- pkg/multicloud/bingocloud/snapshot.go | 12 +- pkg/multicloud/bingocloud/vpc.go | 66 ++++++++- pkg/multicloud/ctyun/region.go | 4 + pkg/multicloud/ctyun/vpc.go | 4 + pkg/multicloud/ecloud/region.go | 4 + pkg/multicloud/ecloud/vpc.go | 4 + pkg/multicloud/esxi/manager.go | 4 + pkg/multicloud/google/region.go | 4 + pkg/multicloud/google/vpc.go | 4 + pkg/multicloud/hcso/region.go | 4 + pkg/multicloud/hcso/vpc.go | 4 + pkg/multicloud/huawei/region.go | 4 + pkg/multicloud/huawei/vpc.go | 4 + pkg/multicloud/jdcloud/region.go | 4 + pkg/multicloud/jdcloud/vpc.go | 4 + pkg/multicloud/nutanix/region.go | 4 + pkg/multicloud/nutanix/vpc.go | 4 + pkg/multicloud/objectstore/objectstore.go | 4 + pkg/multicloud/openstack/region.go | 4 + pkg/multicloud/openstack/vpc.go | 4 + pkg/multicloud/proxmox/region.go | 4 + pkg/multicloud/proxmox/vpc.go | 4 + pkg/multicloud/qcloud/region.go | 4 + pkg/multicloud/qcloud/vpc.go | 4 + pkg/multicloud/remotefile/region.go | 4 + pkg/multicloud/remotefile/vpc.go | 4 + pkg/multicloud/ucloud/region.go | 4 + pkg/multicloud/ucloud/vpc.go | 4 + pkg/multicloud/zstack/region.go | 4 + pkg/multicloud/zstack/vpc.go | 4 + 57 files changed, 785 insertions(+), 218 deletions(-) diff --git a/cmd/bingocli/main.go b/cmd/bingocli/main.go index b29b63558..573a38491 100644 --- a/cmd/bingocli/main.go +++ b/cmd/bingocli/main.go @@ -96,12 +96,11 @@ func newClient(options *BaseOptions) (*bingocloud.SRegion, error) { options.Endpoint, options.AccessKey, options.SecretKey, - ).Debug(options.Debug). - CloudproviderConfig( - cloudprovider.ProviderConfig{ - ProxyFunc: proxyFunc, - }, - ), + ).Debug(options.Debug).SetCloudproviderConfig( + cloudprovider.ProviderConfig{ + ProxyFunc: proxyFunc, + }, + ), ) if err != nil { return nil, err diff --git a/pkg/cloudprovider/cloudprovider.go b/pkg/cloudprovider/cloudprovider.go index 3b2737d5a..4068f337e 100644 --- a/pkg/cloudprovider/cloudprovider.go +++ b/pkg/cloudprovider/cloudprovider.go @@ -174,6 +174,8 @@ type ProviderConfig struct { AliyunResourceGroupIds []string + ManagerProviderConfig *ProviderConfig + UpdatePermission func(service, permission string) } diff --git a/pkg/cloudprovider/disk.go b/pkg/cloudprovider/disk.go index 13f904ca7..98fccef5f 100644 --- a/pkg/cloudprovider/disk.go +++ b/pkg/cloudprovider/disk.go @@ -19,4 +19,5 @@ type DiskCreateConfig struct { SizeGb int Desc string ProjectId string + ZoneId string } diff --git a/pkg/cloudprovider/resources.go b/pkg/cloudprovider/resources.go index 2f7f3b1d2..df7adc342 100644 --- a/pkg/cloudprovider/resources.go +++ b/pkg/cloudprovider/resources.go @@ -86,6 +86,7 @@ type ICloudRegion interface { GetISecurityGroupById(secgroupId string) (ICloudSecurityGroup, error) GetISecurityGroupByName(opts *SecurityGroupFilterOptions) (ICloudSecurityGroup, error) CreateISecurityGroup(conf *SecurityGroupCreateInput) (ICloudSecurityGroup, error) + GetISecurityGroups() ([]ICloudSecurityGroup, error) CreateIVpc(opts *VpcCreateOptions) (ICloudVpc, error) CreateInternetGateway() (ICloudInternetGateway, error) @@ -607,6 +608,7 @@ type ICloudVpc interface { ProposeJoinICloudInterVpcNetwork(opts *SVpcJointInterVpcNetworkOption) error GetICloudIPv6Gateways() ([]ICloudIPv6Gateway, error) + IsPublic() bool } type ICloudInternetGateway interface { diff --git a/pkg/cloudprovider/subaccount.go b/pkg/cloudprovider/subaccount.go index c2939f744..bda0de77c 100644 --- a/pkg/cloudprovider/subaccount.go +++ b/pkg/cloudprovider/subaccount.go @@ -22,13 +22,16 @@ import ( ) type SSubAccount struct { + Id string // ID // 若Account不为空,可不传 Name string // 描述信息 Desc string // 输入必填,若为空,需要指定子账号名称 Account string + Secret string // 子账号SK HealthStatus string // 云端服务健康状态。例如欠费、项目冻结都属于不健康状态。 + IsSubAccount bool // 是否子账号 DefaultProjectId string // 默认云订阅项目Id } diff --git a/pkg/multicloud/aliyun/region.go b/pkg/multicloud/aliyun/region.go index cd38ad350..62da04831 100644 --- a/pkg/multicloud/aliyun/region.go +++ b/pkg/multicloud/aliyun/region.go @@ -125,6 +125,10 @@ func (self *SRegion) GetOssClient() (*oss.Client, error) { return self.ossClient, nil } +func (self *SRegion) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) { + return nil, nil +} + func (self *SRegion) ecsRequest(apiName string, params map[string]string) (jsonutils.JSONObject, error) { client, err := self.getSdkClient() if err != nil { @@ -297,7 +301,7 @@ func (self *SRegion) _lbRequest(client *sdk.Client, apiName string, domain strin return jsonRequest(client, domain, ALIYUN_API_VERSION_LB, apiName, params, self.client.debug) } -///////////////////////////////////////////////////////////////////////////// +// /////////////////////////////////////////////////////////////////////////// func (self *SRegion) GetId() string { return self.RegionId } diff --git a/pkg/multicloud/aliyun/vpc.go b/pkg/multicloud/aliyun/vpc.go index 119270dad..4bcd948c3 100644 --- a/pkg/multicloud/aliyun/vpc.go +++ b/pkg/multicloud/aliyun/vpc.go @@ -84,6 +84,10 @@ func (self *SVpc) IsEmulated() bool { return false } +func (self *SVpc) IsPublic() bool { + return false +} + func (self *SVpc) GetIsDefault() bool { return self.IsDefault } diff --git a/pkg/multicloud/apsara/region.go b/pkg/multicloud/apsara/region.go index f543a4df7..10de2c51e 100644 --- a/pkg/multicloud/apsara/region.go +++ b/pkg/multicloud/apsara/region.go @@ -149,6 +149,10 @@ func (self *SRegion) tagRequest(serviceType string, action string, params map[st } } +func (self *SRegion) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) { + return nil, nil +} + func (self *SRegion) lbRequest(apiName string, params map[string]string) (jsonutils.JSONObject, error) { client, err := self.getSdkClient() if err != nil { @@ -158,7 +162,7 @@ func (self *SRegion) lbRequest(apiName string, params map[string]string) (jsonut return self.productRequest(client, APSARA_PRODUCT_SLB, domain, APSARA_API_VERSION_LB, apiName, params, self.client.debug) } -///////////////////////////////////////////////////////////////////////////// +// /////////////////////////////////////////////////////////////////////////// func (self *SRegion) GetId() string { return self.RegionId } diff --git a/pkg/multicloud/apsara/vpc.go b/pkg/multicloud/apsara/vpc.go index b5a97a14a..930ebdfc4 100644 --- a/pkg/multicloud/apsara/vpc.go +++ b/pkg/multicloud/apsara/vpc.go @@ -85,6 +85,10 @@ func (self *SVpc) IsEmulated() bool { return false } +func (self *SVpc) IsPublic() bool { + return false +} + func (self *SVpc) GetIsDefault() bool { return self.IsDefault } diff --git a/pkg/multicloud/aws/region.go b/pkg/multicloud/aws/region.go index 720c260ef..e77a917f2 100644 --- a/pkg/multicloud/aws/region.go +++ b/pkg/multicloud/aws/region.go @@ -270,7 +270,7 @@ func (self *SAwsClient) monitorRequest(regionId, apiName string, params map[stri return self.request(regionId, CLOUDWATCH_SERVICE_NAME, CLOUDWATCH_SERVICE_ID, "2010-08-01", apiName, params, retval, true) } -///////////////////////////////////////////////////////////////////////////// +// /////////////////////////////////////////////////////////////////////////// func (self *SRegion) fetchZones() error { ec2Client, err := self.getEc2Client() if err != nil { @@ -416,6 +416,10 @@ func (self *SRegion) GetIZones() ([]cloudprovider.ICloudZone, error) { return self.izones, nil } +func (self *SRegion) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) { + return nil, nil +} + func (self *SRegion) GetIVpcs() ([]cloudprovider.ICloudVpc, error) { if self.ivpcs == nil { err := self.fetchInfrastructure() diff --git a/pkg/multicloud/aws/vpc.go b/pkg/multicloud/aws/vpc.go index 2aa1f0c73..1ce0cce16 100644 --- a/pkg/multicloud/aws/vpc.go +++ b/pkg/multicloud/aws/vpc.go @@ -94,6 +94,10 @@ func (self *SVpc) IsEmulated() bool { return false } +func (self *SVpc) IsPublic() bool { + return false +} + func (self *SVpc) GetRegion() cloudprovider.ICloudRegion { return self.region } diff --git a/pkg/multicloud/azure/classic_vpc.go b/pkg/multicloud/azure/classic_vpc.go index b94f853f7..20fb7089b 100644 --- a/pkg/multicloud/azure/classic_vpc.go +++ b/pkg/multicloud/azure/classic_vpc.go @@ -76,6 +76,10 @@ func (self *SClassicVpc) GetIsDefault() bool { return false } +func (self *SClassicVpc) IsPublic() bool { + return false +} + func (self *SClassicVpc) GetCidrBlock() string { if len(self.Properties.AddressSpace.AddressPrefixes) > 0 { return self.Properties.AddressSpace.AddressPrefixes[0] diff --git a/pkg/multicloud/azure/region.go b/pkg/multicloud/azure/region.go index 4847d8a43..29951f74c 100644 --- a/pkg/multicloud/azure/region.go +++ b/pkg/multicloud/azure/region.go @@ -53,7 +53,7 @@ type SRegion struct { Longitude string } -///////////////////////////////////////////////////////////////////////////// +// /////////////////////////////////////////////////////////////////////////// func (self *SRegion) Refresh() error { // do nothing return nil @@ -104,6 +104,10 @@ func (self *SRegion) GetName() string { return fmt.Sprintf("%s %s", CLOUD_PROVIDER_AZURE_CN, self.DisplayName) } +func (self *SRegion) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) { + return nil, nil +} + func (self *SRegion) GetI18n() cloudprovider.SModelI18nTable { en := fmt.Sprintf("%s %s", CLOUD_PROVIDER_AZURE_EN, self.DisplayName) table := cloudprovider.SModelI18nTable{} diff --git a/pkg/multicloud/azure/vpc.go b/pkg/multicloud/azure/vpc.go index 216dea656..bbde76c97 100644 --- a/pkg/multicloud/azure/vpc.go +++ b/pkg/multicloud/azure/vpc.go @@ -75,6 +75,10 @@ func (self *SVpc) IsEmulated() bool { return false } +func (self *SVpc) IsPublic() bool { + return false +} + func (self *SVpc) GetIsDefault() bool { return true } diff --git a/pkg/multicloud/bingocloud/account.go b/pkg/multicloud/bingocloud/account.go index 3a37f6485..49ef04a78 100644 --- a/pkg/multicloud/bingocloud/account.go +++ b/pkg/multicloud/bingocloud/account.go @@ -1,12 +1,63 @@ package bingocloud +import ( + "crypto/aes" + "crypto/cipher" + "encoding/base64" + "fmt" + "unicode/utf8" +) + type SAccount struct { - AccessKeyId string - SecretAccessKey string - Arn string - DeptId string - DeptName string - IsEncrypted string - UserId string - UserName string + Id string `json:"Id"` + AccessKeyId string `json:"AccessKeyId"` + Arn string `json:"Arn"` + FullName string `json:"FullName"` + IsAdmin string `json:"IsAdmin"` + IsEncrypted string `json:"IsEncrypted"` + SecurityKey string `json:"SecurityKey"` + Status string `json:"Status"` + Type string `json:"Type"` + UserId string `json:"UserId"` + UserName string `json:"UserName"` +} + +func (self *SAccount) decryptKeys(masterSecretKey string) (string, string) { + if len(self.SecurityKey) == len(masterSecretKey) { + return self.AccessKeyId, self.SecurityKey + } + + secretKeyBytes, err := base64.StdEncoding.DecodeString(self.SecurityKey) + if err != nil { + return "", "" + } + var adminSecretKey = "" + if len(masterSecretKey) >= 32 { + adminSecretKey = masterSecretKey[0:32] + } else { + adminSecretKey = fmt.Sprintf("%s%032s", masterSecretKey, "")[0:32] + } + decryptVal, err := aesCrtCrypt([]byte(secretKeyBytes), []byte(adminSecretKey), make([]byte, 16)) + if err != nil { + return "", "" + } + + decryptSecret := fmt.Sprintf("%s", decryptVal) + + if !utf8.ValidString(decryptSecret) { + return self.AccessKeyId, self.SecurityKey + } + + return self.AccessKeyId, decryptSecret +} + +func aesCrtCrypt(val, key, iv []byte) ([]byte, error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + blockMode := cipher.NewCTR(block, iv) + body := make([]byte, len(val)) + blockMode.XORKeyStream(body, val) + return body, nil } diff --git a/pkg/multicloud/bingocloud/bingo.go b/pkg/multicloud/bingocloud/bingo.go index 404fbf820..a637b8053 100644 --- a/pkg/multicloud/bingocloud/bingo.go +++ b/pkg/multicloud/bingocloud/bingo.go @@ -45,6 +45,16 @@ const ( MAX_RESULT = 20 ) +var ( + ManagerActions = []string{ + "DescribeNodes", + "DescribePhysicalHosts", + "DescribeClusters", + "DescribeAvailabilityZones", + "DescribeStorages", + } +) + type BingoCloudConfig struct { cpcfg cloudprovider.ProviderConfig endpoint string @@ -63,11 +73,15 @@ func NewBingoCloudClientConfig(endpoint, accessKey, secretKey string) *BingoClou return cfg } -func (cfg *BingoCloudConfig) CloudproviderConfig(cpcfg cloudprovider.ProviderConfig) *BingoCloudConfig { +func (cfg *BingoCloudConfig) SetCloudproviderConfig(cpcfg cloudprovider.ProviderConfig) *BingoCloudConfig { cfg.cpcfg = cpcfg return cfg } +func (cfg *BingoCloudConfig) GetCloudproviderConfig() cloudprovider.ProviderConfig { + return cfg.cpcfg +} + func (cfg *BingoCloudConfig) Debug(debug bool) *BingoCloudConfig { cfg.debug = debug return cfg @@ -77,23 +91,31 @@ type SBingoCloudClient struct { *BingoCloudConfig regions []SRegion + + managerClient *SBingoCloudClient + + user string } func NewBingoCloudClient(cfg *BingoCloudConfig) (*SBingoCloudClient, error) { client := &SBingoCloudClient{BingoCloudConfig: cfg} - var err error - client.regions, err = client.GetRegions() - if err != nil { - return nil, err - } - for i := range client.regions { - client.regions[i].client = client + client.regions, _ = client.GetRegions() + if client.regions != nil { + for i := range client.regions { + client.regions[i].client = client + } } + client.user = client.getAccountUser() return client, nil } +func (self *SBingoCloudClient) SetManagerClient(client *SBingoCloudClient) { + self.regions = client.regions + self.managerClient = client +} + func (self *SBingoCloudClient) GetAccountId() string { - return self.endpoint + return self.accessKey } func (self *SBingoCloudClient) GetRegion(id string) (*SRegion, error) { @@ -289,20 +311,35 @@ func (self *SBingoCloudClient) GetSubAccounts() ([]cloudprovider.SSubAccount, er filter := map[string]string{} filter["resource-type"] = "user" - filter["key"] = "ProjectID" + filter["key"] = "X-Project-Id" result, err := self.describeTags(filter) if err != nil { return nil, err } _ = result.Unmarshal(&tags, "tagSet") - var subAccounts []cloudprovider.SSubAccount + var subAccounts = []cloudprovider.SSubAccount{{ + Id: self.getAccountUser(), + Account: self.accessKey, + Secret: self.secretKey, + Name: self.cpcfg.Name, + HealthStatus: api.CLOUD_PROVIDER_HEALTH_NORMAL, + }} + for i := range tags { + account, err := self.listAccessKeys(tags[i].ResourceId) + if err != nil { + continue + } + ak, sk := account.decryptKeys(self.secretKey) subAccount := cloudprovider.SSubAccount{ - Account: self.accessKey, - Name: tags[i].ResourceId, - DefaultProjectId: tags[i].Value, + Id: account.UserId, + Name: account.UserName, HealthStatus: api.CLOUD_PROVIDER_HEALTH_NORMAL, + Account: ak, + Secret: sk, + IsSubAccount: true, + DefaultProjectId: tags[i].Value, } subAccounts = append(subAccounts, subAccount) } @@ -310,42 +347,7 @@ func (self *SBingoCloudClient) GetSubAccounts() ([]cloudprovider.SSubAccount, er } func (self *SBingoCloudClient) GetEnrollmentAccounts() ([]cloudprovider.SEnrollmentAccount, error) { - params := map[string]string{"Marker": "", "MaxItems": "1000", "AccountName": "paas_app"} - var result struct { - IsTruncated string - Marker string `json:"marker,omitempty"` - Users struct { - Member *SAccount `json:"member,omitempty"` - } - } - var eas []cloudprovider.SEnrollmentAccount - for { - resp, err := self.invoke("ListAccounts", params) - if err != nil { - return nil, err - } - err = resp.Unmarshal(&result, "ListAccountsResult") - if err != nil { - return nil, err - } - ea := cloudprovider.SEnrollmentAccount{ - Id: result.Users.Member.UserId, - Name: result.Users.Member.UserName, - } - eas = append(eas, ea) - //for _, user := range result.Users.Member { - // ea := cloudprovider.SEnrollmentAccount{ - // Id: user.UserId, - // Name: user.UserName, - // } - // eas = append(eas, ea) - //} - if params["Marker"] == result.Marker { - break - } - params["Marker"] = result.Marker - } - return eas, nil + return nil, nil } func (self *SBingoCloudClient) GetIRegions() []cloudprovider.ICloudRegion { @@ -357,6 +359,44 @@ func (self *SBingoCloudClient) GetIRegions() []cloudprovider.ICloudRegion { return ret } +func (self *SBingoCloudClient) listAccessKeys(userName string) (*SAccount, error) { + params := map[string]string{"Marker": "", "MaxItems": "1000", "UserName": userName} + + resp, err := self.managerClient.invoke("ListAccessKeys", params) + if err != nil { + return nil, err + } + + var account *SAccount + err = resp.Unmarshal(&account, "ListAccessKeysResult", "AccessKeyMetadata", "member") + if err != nil { + return nil, err + } + + return account, nil +} + +func (self *SBingoCloudClient) getAccountUser() string { + quotas, err := self.getQuotas() + if err != nil { + return "" + } + ownerId := "" + if len(quotas) > 0 { + ownerId = quotas[0].OwnerId + } + return ownerId +} + +func (self *SBingoCloudClient) getQuotas() ([]SQuotas, error) { + resp, err := self.invoke("DescribeQuotas", nil) + if err != nil { + return nil, err + } + var ret []SQuotas + return ret, resp.Unmarshal(&ret, "quotaSet") +} + func (self *SBingoCloudClient) describeTags(filter map[string]string) (jsonutils.JSONObject, error) { params := map[string]string{"MaxResults": "10000"} i := 1 diff --git a/pkg/multicloud/bingocloud/disk.go b/pkg/multicloud/bingocloud/disk.go index 69ac7e922..69a9db0be 100644 --- a/pkg/multicloud/bingocloud/disk.go +++ b/pkg/multicloud/bingocloud/disk.go @@ -19,6 +19,7 @@ import ( "fmt" "strconv" + "yunion.io/x/jsonutils" "yunion.io/x/pkg/errors" api "yunion.io/x/cloudmux/pkg/apis/compute" @@ -60,6 +61,8 @@ type SDisk struct { StorageId string `json:"storageId"` VolumeId string `json:"volumeId"` VolumeName string `json:"volumeName"` + + ImageId string `json:"imageId"` } func (self *SDisk) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) { @@ -118,7 +121,13 @@ func (self *SDisk) GetIsAutoDelete() bool { } func (self *SDisk) GetTemplateId() string { - return "" + if self.ImageId == "" && len(self.AttachmentSet) > 0 { + instances, _, _ := self.storage.cluster.region.GetInstances(self.AttachmentSet[0].InstanceId, "", 1, "") + if instances != nil { + self.ImageId = instances[0].InstancesSet.ImageId + } + } + return self.ImageId } func (self *SDisk) GetDiskType() string { @@ -176,7 +185,12 @@ func (self *SDisk) GetExtSnapshotPolicyIds() ([]string, error) { } func (self *SDisk) Resize(ctx context.Context, newSizeMB int64) error { - return cloudprovider.ErrNotImplemented + params := map[string]string{} + params["VolumeId"] = self.VolumeId + params["Size"] = strconv.FormatInt(newSizeMB/1024, 10) + + _, err := self.storage.cluster.region.invoke("ResizeVolume", params) + return err } func (self *SDisk) Reset(ctx context.Context, snapshotId string) (string, error) { @@ -187,6 +201,14 @@ func (self *SDisk) Rebuild(ctx context.Context) error { return cloudprovider.ErrNotImplemented } +func (self *SDisk) Refresh() error { + newDisk, err := self.storage.cluster.region.GetDisk(self.GetGlobalId()) + if err != nil { + return err + } + return jsonutils.Update(self, &newDisk) +} + func (self *SDisk) GetStatus() string { switch self.Status { case "available", "in-use": @@ -203,6 +225,10 @@ func (self *SRegion) GetDisks(id string, maxResult int, nextToken string) ([]SDi params[fmt.Sprintf("Filter.%d.Name", idx)] = "volume-id" params[fmt.Sprintf("Filter.%d.Value.1", idx)] = id idx++ + } else { + params[fmt.Sprintf("Filter.%d.Name", idx)] = "owner-id" + params[fmt.Sprintf("Filter.%d.Value.1", idx)] = self.client.user + idx++ } if len(nextToken) > 0 { @@ -277,7 +303,7 @@ func (self *SRegion) GetDisk(id string) (*SDisk, error) { func (self *SStorage) CreateIDisk(conf *cloudprovider.DiskCreateConfig) (cloudprovider.ICloudDisk, error) { params := map[string]string{} params["VolumeName"] = conf.Name - params["AvailabilityZone"] = self.cluster.ClusterId + params["AvailabilityZone"] = conf.ZoneId params["Size"] = strconv.Itoa(conf.SizeGb) resp, err := self.cluster.region.invoke("CreateVolume", params) @@ -286,6 +312,7 @@ func (self *SStorage) CreateIDisk(conf *cloudprovider.DiskCreateConfig) (cloudpr } ret := &SDisk{} _ = resp.Unmarshal(&ret) + ret.storage = self return ret, nil } diff --git a/pkg/multicloud/bingocloud/eip.go b/pkg/multicloud/bingocloud/eip.go index 499feeffd..a66b3c204 100644 --- a/pkg/multicloud/bingocloud/eip.go +++ b/pkg/multicloud/bingocloud/eip.go @@ -16,7 +16,10 @@ package bingocloud import ( "fmt" + "strconv" + "strings" + "yunion.io/x/jsonutils" "yunion.io/x/pkg/errors" api "yunion.io/x/cloudmux/pkg/apis/compute" @@ -85,16 +88,33 @@ func (self *SEip) GetInternetChargeType() string { return api.EIP_CHARGE_TYPE_BY_BANDWIDTH } +func (self *SEip) Refresh() error { + newEip, err := self.region.GetIEipById(self.GetId()) + if err != nil { + return err + } + return jsonutils.Update(self, &newEip) +} + func (self *SEip) Delete() error { return cloudprovider.ErrNotImplemented } func (self *SEip) Associate(conf *cloudprovider.AssociateConfig) error { + nics, err := self.region.GetInstanceNics(conf.InstanceId) + if err != nil { + return err + } + if len(nics) == 0 { + return errors.Wrapf(cloudprovider.ErrNotFound, "region.GetInstanceNics", conf.InstanceId) + } + params := map[string]string{} params["PublicIp"] = self.PublicIp params["InstanceId"] = conf.InstanceId + params["NetworkInterfaceId"] = nics[0].NetworkInterfaceId - _, err := self.region.invoke("AssociateAddress", params) + _, err = self.region.invoke("AssociateAddress", params) return err } @@ -103,6 +123,11 @@ func (self *SEip) Dissociate() error { params["PublicIp"] = self.PublicIp _, err := self.region.invoke("DisassociateAddress", params) + //参数错误: 只有用作NAT的弹性IP才能解绑, 错误编码: 106574 + if err != nil && strings.Contains(err.Error(), "106574") { + return nil + } + return err } @@ -121,7 +146,7 @@ func (self *SEip) GetStatus() string { func (self *SRegion) GetEips(ip, instanceId, nextToken string) ([]SEip, string, error) { params := map[string]string{} if len(ip) > 0 { - params["PublicIp"] = ip + params["PublicIp.1"] = ip } if len(nextToken) > 0 { params["NextToken"] = nextToken @@ -133,6 +158,9 @@ func (self *SRegion) GetEips(ip, instanceId, nextToken string) ([]SEip, string, params[fmt.Sprintf("Filter.%d.Value.1", idx)] = instanceId idx++ } + params[fmt.Sprintf("Filter.%d.Name", idx)] = "owner-id" + params[fmt.Sprintf("Filter.%d.Value.1", idx)] = self.client.user + idx++ resp, err := self.invoke("DescribeAddresses", params) if err != nil { @@ -144,7 +172,67 @@ func (self *SRegion) GetEips(ip, instanceId, nextToken string) ([]SEip, string, }{} _ = resp.Unmarshal(&ret) - return ret.AddressesSet, ret.NextToken, nil + if len(ip) > 0 || len(instanceId) > 0 { + return ret.AddressesSet, ret.NextToken, nil + } + + var floatingRet []SEip + for _, eip := range ret.AddressesSet { + if strings.Contains(strings.ToLower(eip.AddressType), "virtualip") { + continue + } + if eip.InstanceId == "" && eip.CanAssociate { + floatingRet = append(floatingRet, eip) + continue + } + if eip.InstanceId != "" { + nics, err := self.GetInstanceNics(eip.InstanceId) + if err != nil { + return nil, "", err + } + isSecondaryIp := false + for i := range nics { + if eip.PublicIp == nics[i].PrivateIPAddress { + isSecondaryIp = true + break + } + for j := range nics[i].PrivateIPAddressesSet { + if nics[i].PrivateIPAddressesSet[j].PrivateIPAddress == eip.PublicIp && nics[i].PrivateIPAddressesSet[j].PrivateIPAddress == nics[i].PrivateIPAddressesSet[j].Association.PublicIp { + isSecondaryIp = true + break + } + } + } + if !isSecondaryIp { + floatingRet = append(floatingRet, eip) + } + } + } + + return floatingRet, ret.NextToken, nil +} + +func (self *SRegion) CreateEIP(eip *cloudprovider.SEip) (cloudprovider.ICloudEIP, error) { + params := map[string]string{} + if len(eip.NetworkExternalId) > 0 { + params["SubnetId"] = eip.NetworkExternalId + } + if eip.BandwidthMbps > 0 { + params["Bandwidth"] = strconv.Itoa(eip.BandwidthMbps) + } + if len(eip.IP) > 0 { + params["DesiredAddress"] = eip.IP + } + resp, err := self.invoke("AllocateAddress", params) + if err != nil { + return nil, errors.Wrapf(err, "AllocateAddress") + } + var ip string + err = resp.Unmarshal(&ip, "publicIp") + if err != nil { + return nil, errors.Wrapf(err, "AllocateAddress") + } + return self.GetIEipById(ip) } func (self *SRegion) GetIEips() ([]cloudprovider.ICloudEIP, error) { diff --git a/pkg/multicloud/bingocloud/image.go b/pkg/multicloud/bingocloud/image.go index 1433c66ab..e457ef5b8 100644 --- a/pkg/multicloud/bingocloud/image.go +++ b/pkg/multicloud/bingocloud/image.go @@ -18,6 +18,7 @@ import ( "context" "time" + "yunion.io/x/jsonutils" "yunion.io/x/pkg/errors" "yunion.io/x/pkg/util/imagetools" "yunion.io/x/pkg/util/rbacscope" @@ -109,6 +110,14 @@ func (self *SImage) GetImageStatus() string { return "active" } +func (self *SImage) Refresh() error { + img, err := self.cache.region.GetImageById(self.ImageId) + if err != nil { + return err + } + return jsonutils.Update(self, img) +} + func (i *SImage) getNormalizedImageInfo() *imagetools.ImageInfo { if i.imageInfo == nil { imgInfo := imagetools.NormalizeImageInfo(i.OSName, i.Architecture, i.Platform, "", "") @@ -197,6 +206,11 @@ func (self *SRegion) GetImages(id, nextToken string) ([]SImage, string, error) { if len(nextToken) > 0 { params["NextToken"] = nextToken } + //idx := 1 + //params[fmt.Sprintf("Filter.%d.Name", idx)] = "owner-id" + //params[fmt.Sprintf("Filter.%d.Value.1", idx)] = self.client.user + //idx++ + resp, err := self.invoke("DescribeImages", params) if err != nil { return nil, "", err @@ -217,6 +231,15 @@ func (self *SRegion) GetImageById(id string) (*SImage, error) { if len(imgs) == 0 { return nil, errors.Wrapf(cloudprovider.ErrNotFound, id) } + + for i := range imgs { + storage, err := self.GetIStorageById(imgs[i].StorageId) + if err != nil { + return nil, err + } + imgs[i].cache = &SStoragecache{storageId: storage.GetId(), storageName: storage.GetName(), region: self} + } + return &imgs[0], nil } @@ -250,7 +273,8 @@ func (self *SStoragecache) GetIImageById(id string) (cloudprovider.ICloudImage, return nil, err } for i := range images { - if images[i].GetGlobalId() == id && images[i].StorageId == self.storageId { + // && images[i].StorageId == self.storageId + if images[i].GetGlobalId() == id { images[i].cache = self return &images[i], nil } diff --git a/pkg/multicloud/bingocloud/instance.go b/pkg/multicloud/bingocloud/instance.go index 791d984f4..19890db7a 100644 --- a/pkg/multicloud/bingocloud/instance.go +++ b/pkg/multicloud/bingocloud/instance.go @@ -161,11 +161,28 @@ func (self *SInstance) SetSecurityGroups(secgroupIds []string) error { } func (self *SInstance) AttachDisk(ctx context.Context, diskId string) error { - return nil + var deviceNames []string + for _, device := range self.InstancesSet.BlockDeviceMapping { + deviceNames = append(deviceNames, device.DeviceName) + } + deviceName, err := nextDeviceName(deviceNames) + if err != nil { + return errors.Wrap(err, "nextDeviceName") + } + params := map[string]string{} + params["VolumeId"] = diskId + params["InstanceId"] = self.InstancesSet.InstanceId + params["Device"] = deviceName + _, err = self.node.cluster.region.invoke("AttachVolume", params) + return err } func (self *SInstance) DetachDisk(ctx context.Context, diskId string) error { - return nil + params := map[string]string{} + params["VolumeId"] = diskId + params["InstanceId"] = self.InstancesSet.InstanceId + _, err := self.node.cluster.region.invoke("DetachVolume", params) + return err } func (self *SInstance) ChangeConfig(ctx context.Context, config *cloudprovider.SManagedVMChangeConfig) error { @@ -180,6 +197,19 @@ func (self *SInstance) DeployVM(ctx context.Context, name string, username strin return self.node.cluster.region.modifyInstanceAttribute(self.InstancesSet.InstanceId, attrs) } +func (self *SInstance) LiveMigrateVM(hostid string) error { + return self.MigrateVM(hostid) +} + +func (self *SInstance) MigrateVM(hostid string) error { + params := map[string]string{} + params["InstanceId"] = self.InstancesSet.InstanceId + params["ToNodeId"] = hostid + + _, err := self.node.cluster.region.invoke("MigrateInstance", params) + return err +} + func (self *SInstance) DeleteVM(ctx context.Context) error { params := map[string]string{} params["InstanceId.1"] = self.InstancesSet.InstanceId @@ -286,6 +316,7 @@ func (self *SInstance) GetIDisks() ([]cloudprovider.ICloudDisk, error) { if err != nil { return nil, err } + disk.ImageId = self.InstancesSet.ImageId storage, ok := storageMaps[disk.StorageId] if ok { storage.cluster = self.node.cluster @@ -313,9 +344,21 @@ func (self *SInstance) GetIEIP() (cloudprovider.ICloudEIP, error) { if err != nil { return nil, err } - for i := range eips { - eips[i].region = self.node.cluster.region - return &eips[i], nil + nics, err := self.node.cluster.region.GetInstanceNics(self.InstancesSet.InstanceId) + if err != nil { + return nil, err + } + for i := range nics { + for j := range eips { + if eips[i].PublicIp != nics[i].PrivateIPAddress { + for k := range nics[i].PrivateIPAddressesSet { + if nics[i].PrivateIPAddressesSet[k].PrivateIPAddress != nics[i].PrivateIPAddressesSet[k].Association.PublicIp { + eips[j].region = self.node.cluster.region + return &eips[j], nil + } + } + } + } } return nil, nil } @@ -335,6 +378,34 @@ func (self *SInstance) Refresh() error { return cloudprovider.ErrNotFound } +func (self *SInstance) SaveImage(opts *cloudprovider.SaveImageOptions) (cloudprovider.ICloudImage, error) { + bundleId := "" + var images []struct { + ImageId string `json:"imageId"` + } + + params := map[string]string{} + params["InstanceId"] = self.InstancesSet.InstanceId + params["AsImage"] = "true" + params["StorageId"] = "storage-cloud" + resp, err := self.node.cluster.region.invoke("BundleInstance", params) + if err != nil { + return nil, err + } + resp.Unmarshal(&bundleId, "bundleInstanceTask", "bundleId") + + params = map[string]string{} + params["BundleId.1"] = bundleId + + resp, err = self.node.cluster.region.invoke("DescribeBundleTasks", params) + if err != nil { + return nil, err + } + resp.Unmarshal(&images, "bundleInstanceTasksSet") + + return self.node.cluster.region.GetImageById(images[0].ImageId) +} + func (self *SInstance) GetStatus() string { switch self.InstancesSet.InstanceState.Name { case "stopped": @@ -360,6 +431,7 @@ func (self *SInstance) GetVNCInfo(input *cloudprovider.ServerVncInput) (*cloudpr result.GetVncInfoResult.InstanceId = self.InstancesSet.InstanceId result.GetVncInfoResult.Hypervisor = self.GetHypervisor() + result.GetVncInfoResult.Protocol = "vnc" return result.GetVncInfoResult, nil } @@ -435,7 +507,7 @@ func (self *SInstance) UpdateVM(ctx context.Context, name string) error { } func (self *SInstance) CreateInstanceSnapshot(ctx context.Context, name string, desc string) (cloudprovider.ICloudInstanceSnapshot, error) { - newId, err := self.node.cluster.region.createInstanceSnapshot(self.InstancesSet.InstanceId, name, desc) + newId, err := self.node.cluster.region.createInstanceBackup(self.InstancesSet.InstanceId, name, desc) if err != nil { return nil, err } @@ -443,34 +515,34 @@ func (self *SInstance) CreateInstanceSnapshot(ctx context.Context, name string, } func (self *SInstance) GetInstanceSnapshot(id string) (cloudprovider.ICloudInstanceSnapshot, error) { - snapshots, err := self.node.cluster.region.getInstanceSnapshots(self.InstancesSet.InstanceId, id) + backups, err := self.node.cluster.region.getInstanceBackups(self.InstancesSet.InstanceId, id) if err != nil { return nil, err } - for i := range snapshots { - if snapshots[i].GetGlobalId() == id { - snapshots[i].region = self.node.cluster.region - return &snapshots[i], nil + for i := range backups { + if backups[i].GetGlobalId() == id { + backups[i].region = self.node.cluster.region + return &backups[i], nil } } return nil, cloudprovider.ErrNotFound } func (self *SInstance) GetInstanceSnapshots() ([]cloudprovider.ICloudInstanceSnapshot, error) { - snapshots, err := self.node.cluster.region.getInstanceSnapshots(self.InstancesSet.InstanceId, "") + backups, err := self.node.cluster.region.getInstanceBackups(self.InstancesSet.InstanceId, "") if err != nil { return nil, err } var ret []cloudprovider.ICloudInstanceSnapshot - for i := range snapshots { - snapshots[i].region = self.node.cluster.region - ret = append(ret, &snapshots[i]) + for i := range backups { + backups[i].region = self.node.cluster.region + ret = append(ret, &backups[i]) } return ret, nil } func (self *SInstance) ResetToInstanceSnapshot(ctx context.Context, idStr string) error { - return self.node.cluster.region.revertInstanceSnapshot(idStr) + return cloudprovider.ErrNotImplemented } func (self *SRegion) GetIVMById(id string) (cloudprovider.ICloudVM, error) { @@ -496,7 +568,7 @@ func (self *SRegion) GetInstances(id, nodeId string, maxResult int, nextToken st } idx := 1 - if len(nodeId) > 0 { + if len(nodeId) > 0 && len(id) == 0 { params[fmt.Sprintf("Filter.%d.Name", idx)] = "node-id" params[fmt.Sprintf("Filter.%d.Value.1", idx)] = nodeId idx++ @@ -506,6 +578,10 @@ func (self *SRegion) GetInstances(id, nodeId string, maxResult int, nextToken st params[fmt.Sprintf("Filter.%d.Name", idx)] = "instance-id" params[fmt.Sprintf("Filter.%d.Value.1", idx)] = id idx++ + } else { + params[fmt.Sprintf("Filter.%d.Name", idx)] = "owner-id" + params[fmt.Sprintf("Filter.%d.Value.1", idx)] = self.client.user + idx++ } resp, err := self.invoke("DescribeInstances", params) @@ -527,7 +603,7 @@ func (self *SRegion) modifyInstanceAttribute(instanceId string, attrs map[string for key, value := range attrs { params["Attribute"] = key params["Value"] = value - _, err := self.client.invoke("ModifyInstanceAttribute", params) + _, err := self.invoke("ModifyInstanceAttribute", params) if err != nil { return err } diff --git a/pkg/multicloud/bingocloud/instance_snapshot.go b/pkg/multicloud/bingocloud/instance_snapshot.go index 076485659..7a64dbc35 100644 --- a/pkg/multicloud/bingocloud/instance_snapshot.go +++ b/pkg/multicloud/bingocloud/instance_snapshot.go @@ -8,132 +8,136 @@ import ( "yunion.io/x/cloudmux/pkg/cloudprovider" ) -type SInstanceSnapshot struct { - region *SRegion - InstanceSnapshotId string - InstanceSnapshotName string - InstanceId string - DiskOnly bool - Size int64 - Status string - StatusReason string - CreateTime string +type SInstanceBackup struct { + region *SRegion + BackupId string + InstanceId string + BackupName string + DisplayName string + OwnerId string + BackupSize int + BackupStatus string + Progress string + StorageId string + BlockDeviceMapping string + Description string } -func (self SInstanceSnapshot) GetId() string { - return self.InstanceSnapshotId +func (self SInstanceBackup) GetId() string { + return self.BackupId } -func (self SInstanceSnapshot) GetName() string { - return self.InstanceSnapshotName +func (self SInstanceBackup) GetName() string { + return self.BackupName } -func (self SInstanceSnapshot) GetGlobalId() string { - return self.InstanceSnapshotId +func (self SInstanceBackup) GetGlobalId() string { + return self.BackupId } -func (self SInstanceSnapshot) GetCreatedAt() time.Time { - ct, _ := time.Parse("2006-01-02T15:04:05.000Z", self.CreateTime) - return ct +func (self SInstanceBackup) GetCreatedAt() time.Time { + return time.Now() } -func (self SInstanceSnapshot) GetStatus() string { - return self.Status -} - -func (self SInstanceSnapshot) Refresh() error { - newSnapshot, err := self.region.getInstanceSnapshots(self.InstanceId, self.InstanceSnapshotId) - if err != nil { - return err - } - if len(newSnapshot) == 1 { - return jsonutils.Update(self, &newSnapshot[0]) +func (self SInstanceBackup) GetStatus() string { + status := self.BackupStatus + switch self.BackupStatus { + case "complete": + status = "completed" } - return cloudprovider.ErrNotFound + return status } -func (self SInstanceSnapshot) IsEmulated() bool { +func (self SInstanceBackup) IsEmulated() bool { return false } -func (self SInstanceSnapshot) GetSysTags() map[string]string { +func (self SInstanceBackup) GetSysTags() map[string]string { return nil } -func (self SInstanceSnapshot) GetTags() (map[string]string, error) { +func (self SInstanceBackup) GetTags() (map[string]string, error) { return nil, nil } -func (self SInstanceSnapshot) SetTags(tags map[string]string, replace bool) error { +func (self SInstanceBackup) SetTags(tags map[string]string, replace bool) error { return nil } -func (self SInstanceSnapshot) GetProjectId() string { +func (self SInstanceBackup) GetProjectId() string { return "" } -func (self SInstanceSnapshot) GetDescription() string { - return "" +func (self SInstanceBackup) GetDescription() string { + return self.Description } -func (self SInstanceSnapshot) Delete() error { - return self.region.deleteInstanceSnapshot(self.InstanceSnapshotId) +func (self SInstanceBackup) Delete() error { + return self.region.deleteInstanceBackup(self.BackupId) } -func (self *SRegion) createInstanceSnapshot(instanceId, name string, desc string) (string, error) { +func (self SInstanceBackup) Refresh() error { + newBackups, err := self.region.getInstanceBackups(self.InstanceId, self.BackupId) + if err != nil { + return err + } + if len(newBackups) == 1 { + return jsonutils.Update(self, &newBackups[0]) + } + return cloudprovider.ErrNotFound +} + +func (self *SRegion) createInstanceBackup(instanceId, name string, desc string) (string, error) { params := map[string]string{} params["InstanceId"] = instanceId - params["InstanceSnapshotName"] = name + params["BackupName"] = name params["Description"] = desc - params["DiskOnly"] = "false" - resp, err := self.client.invoke("CreateInstanceSnapshot", params) + resp, err := self.invoke("BackupInstance", params) if err != nil { return "", err } newId := "" - err = resp.Unmarshal(&newId, "instanceSnapshotId") + err = resp.Unmarshal(&newId, "backupInstanceResult", "backup", "backupId") return newId, err } -func (self *SRegion) getInstanceSnapshots(instanceId, snapshotId string) ([]SInstanceSnapshot, error) { +func (self *SRegion) getInstanceBackups(instanceId, backupId string) ([]SInstanceBackup, error) { params := map[string]string{} if instanceId != "" { - params["InstanceId"] = instanceId - } - if snapshotId != "" { - params["InstanceSnapshotId.1"] = snapshotId + params["InstanceId.1"] = instanceId } - resp, err := self.client.invoke("DescribeInstanceSnapshots", params) + resp, err := self.invoke("DescribeInstanceBackups", params) if err != nil { return nil, err } - var ret []SInstanceSnapshot - _ = resp.Unmarshal(&ret, "instanceSnapshotSet") + var ret []SInstanceBackup + _ = resp.Unmarshal(&ret, "describeInstanceBackupsResult", "instanceBackups") - return ret, err -} + if backupId != "" && ret != nil { + for _, backup := range ret { + if backupId == backup.BackupId { + return []SInstanceBackup{backup}, nil + } + } + } -func (self *SRegion) deleteInstanceSnapshot(id string) error { - params := map[string]string{} - params["InstanceSnapshotId.1"] = id - _, err := self.client.invoke("DeleteInstanceSnapshots", params) - return err + return ret, err } -func (self *SRegion) revertInstanceSnapshot(id string) error { +func (self *SRegion) restoreInstanceBackup(backupId string) error { params := map[string]string{} - params["InstanceSnapshotId.1"] = id - _, err := self.client.invoke("RevertInstanceSnapshot", params) + params["BackupId"] = backupId + _, err := self.invoke("RestoreFromInstanceBackup", params) return err } func (self *SRegion) deleteInstanceBackup(id string) error { params := map[string]string{} params["BackupId"] = id - _, err := self.client.invoke("DeleteInstanceBackup", params) + _, err := self.invoke("DeleteInstanceBackup", params) return err } diff --git a/pkg/multicloud/bingocloud/instancenic.go b/pkg/multicloud/bingocloud/instancenic.go index 1b2d2b990..a2204c412 100644 --- a/pkg/multicloud/bingocloud/instancenic.go +++ b/pkg/multicloud/bingocloud/instancenic.go @@ -38,8 +38,16 @@ type SInstanceNic struct { PrivateDNSName string `json:"privateDnsName"` PrivateIPAddress string `json:"privateIpAddress"` PrivateIPAddressesSet []struct { - Association string `json:"association"` - Primary string `json:"primary"` + Association struct { + PublicIp string `json:"publicIp"` + PublicDnsName string `json:"publicDnsName"` + SubnetId string `json:"subnetId"` + VpcId string `json:"vpcId"` + IpOwnerId string `json:"ipOwnerId"` + AllocationId string `json:"allocationId"` + AssociationId string `json:"associationId"` + } `json:"association"` + Primary bool `json:"primary"` PrivateDNSName string `json:"privateDnsName"` PrivateIPAddress string `json:"privateIpAddress"` } `json:"privateIpAddressesSet"` diff --git a/pkg/multicloud/bingocloud/monitor.go b/pkg/multicloud/bingocloud/monitor.go index db2afac94..097d4ebca 100644 --- a/pkg/multicloud/bingocloud/monitor.go +++ b/pkg/multicloud/bingocloud/monitor.go @@ -58,7 +58,7 @@ func (self *SBingoCloudClient) DescribeMetricList(ns, metricNm, dimensionName, d params["EndTime"] = until.UTC().Format(time.RFC3339) params["Statistics.member.1"] = "Average" params["Period"] = "60" - resp, err := self.invoke("GetMetricStatistics", params) + resp, err := self.managerClient.invoke("GetMetricStatistics", params) if err != nil { return nil, errors.Wrap(err, "GetMetricStatistics err") } @@ -84,15 +84,16 @@ func (self *SBingoCloudClient) GetEcsMetrics(opts *cloudprovider.MetricListOptio var ret []cloudprovider.MetricValues for metricType, metricName := range map[cloudprovider.TMetricType]string{ cloudprovider.VM_METRIC_TYPE_CPU_USAGE: "CPUUtilization", - cloudprovider.VM_METRIC_TYPE_MEM_USAGE: "MemoryUsage", + cloudprovider.VM_METRIC_TYPE_MEM_USAGE: "MemeryUsage", cloudprovider.VM_METRIC_TYPE_NET_BPS_RX: "NetworkIn", cloudprovider.VM_METRIC_TYPE_NET_BPS_TX: "NetworkOut", cloudprovider.VM_METRIC_TYPE_DISK_IO_READ_BPS: "DiskReadBytes", cloudprovider.VM_METRIC_TYPE_DISK_IO_WRITE_BPS: "DiskWriteBytes", cloudprovider.VM_METRIC_TYPE_DISK_IO_READ_IOPS: "DiskReadOps", cloudprovider.VM_METRIC_TYPE_DISK_IO_WRITE_IOPS: "DiskWriteOps", + cloudprovider.VM_METRIC_TYPE_DISK_USAGE: "DiskUsage", } { - data, err := self.DescribeMetricList("AWS/EC2", metricName, "InstanceId", opts.ResourceId, opts.StartTime, opts.EndTime) + data, err := self.managerClient.DescribeMetricList("AWS/EC2", metricName, "InstanceId", opts.ResourceId, opts.StartTime, opts.EndTime) if err != nil { log.Errorf("DescribeMetricList error: %v", err) continue @@ -123,7 +124,7 @@ func (self *SBingoCloudClient) GetHostMetrics(opts *cloudprovider.MetricListOpti cloudprovider.HOST_METRIC_TYPE_DISK_IO_READ_IOPS: "DiskReadOps", cloudprovider.HOST_METRIC_TYPE_DISK_IO_WRITE_IOPS: "DiskWriteOps", } { - data, err := self.DescribeMetricList("AWS/HOST", metricName, "HostId", opts.ResourceId, opts.StartTime, opts.EndTime) + data, err := self.managerClient.DescribeMetricList("AWS/HOST", metricName, "HostId", opts.ResourceId, opts.StartTime, opts.EndTime) if err != nil { log.Errorf("DescribeMetricList error: %v", err) continue diff --git a/pkg/multicloud/bingocloud/provider/provider.go b/pkg/multicloud/bingocloud/provider/provider.go index daa3fb7ae..4292f4fd8 100644 --- a/pkg/multicloud/bingocloud/provider/provider.go +++ b/pkg/multicloud/bingocloud/provider/provider.go @@ -78,11 +78,25 @@ func (self *SBingoCloudProviderFactory) GetProvider(cfg cloudprovider.ProviderCo client, err := bingocloud.NewBingoCloudClient( bingocloud.NewBingoCloudClientConfig( cfg.URL, cfg.Account, cfg.Secret, - ).CloudproviderConfig(cfg), + ).SetCloudproviderConfig(cfg), ) if err != nil { return nil, err } + client.SetManagerClient(client) + + if cfg.ManagerProviderConfig != nil { + managerClient, err := bingocloud.NewBingoCloudClient( + bingocloud.NewBingoCloudClientConfig( + cfg.ManagerProviderConfig.URL, cfg.ManagerProviderConfig.Account, cfg.ManagerProviderConfig.Secret, + ).SetCloudproviderConfig(*cfg.ManagerProviderConfig), + ) + if err != nil { + return nil, err + } + client.SetManagerClient(managerClient) + } + return &SBingoCloudProvider{ SBaseProvider: cloudprovider.NewBaseProvider(self), client: client, @@ -107,6 +121,14 @@ type SBingoCloudProvider struct { client *bingocloud.SBingoCloudClient } +func (self *SBingoCloudProvider) GetProviderConfig() cloudprovider.ProviderConfig { + return self.client.GetCloudproviderConfig() +} + +func (self *SBingoCloudProvider) SetProviderConfig(cfg cloudprovider.ProviderConfig) { + self.client.SetCloudproviderConfig(cfg) +} + func (self *SBingoCloudProvider) GetSysInfo() (jsonutils.JSONObject, error) { return jsonutils.NewDict(), nil } diff --git a/pkg/multicloud/bingocloud/quotas.go b/pkg/multicloud/bingocloud/quotas.go index cb2319ea6..03fcece01 100644 --- a/pkg/multicloud/bingocloud/quotas.go +++ b/pkg/multicloud/bingocloud/quotas.go @@ -8,12 +8,3 @@ type SQuotas struct { HardLimit int InUse int } - -func (self *SRegion) GetQuotas() ([]SQuotas, error) { - resp, err := self.invoke("DescribeQuotas", nil) - if err != nil { - return nil, err - } - var ret []SQuotas - return ret, resp.Unmarshal(&ret, "quotaSet") -} diff --git a/pkg/multicloud/bingocloud/region.go b/pkg/multicloud/bingocloud/region.go index 5f0a05a3d..14ffa32b0 100644 --- a/pkg/multicloud/bingocloud/region.go +++ b/pkg/multicloud/bingocloud/region.go @@ -19,6 +19,7 @@ import ( "yunion.io/x/jsonutils" "yunion.io/x/pkg/errors" + "yunion.io/x/pkg/utils" api "yunion.io/x/cloudmux/pkg/apis/compute" "yunion.io/x/cloudmux/pkg/cloudprovider" @@ -79,23 +80,14 @@ func (self *SRegion) GetCloudEnv() string { return "" } -func (self *SRegion) getAccountUser() string { - quotas, err := self.GetQuotas() - if err != nil { - return "" - } - ownerId := "" - if len(quotas) > 0 { - ownerId = quotas[0].OwnerId - } - return ownerId -} - func (self *SRegion) GetGeographicInfo() cloudprovider.SGeographicInfo { return cloudprovider.SGeographicInfo{} } func (self *SRegion) invoke(action string, params map[string]string) (jsonutils.JSONObject, error) { + if utils.IsInStringArray(action, ManagerActions) { + return self.client.managerClient.invoke(action, params) + } return self.client.invoke(action, params) } @@ -108,6 +100,10 @@ func (self *SBingoCloudClient) GetRegions() ([]SRegion, error) { return ret, resp.Unmarshal(&ret, "regionInfo") } +func (self *SRegion) GetIDiskById(id string) (cloudprovider.ICloudDisk, error) { + return self.GetDisk(id) +} + func (self *SRegion) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) { storages, err := self.getStorages() if err != nil { @@ -161,6 +157,28 @@ func (self *SRegion) GetIStoragecacheById(id string) (cloudprovider.ICloudStorag return nil, errors.Wrapf(cloudprovider.ErrNotFound, id) } +func (self *SRegion) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) { + part, nextToken, err := self.GetSecurityGroups("", "", "") + if err != nil { + return nil, err + } + var groups []SSecurityGroup + groups = append(groups, part...) + for len(nextToken) > 0 { + part, nextToken, err = self.GetSecurityGroups("", "", nextToken) + if err != nil { + return nil, err + } + groups = append(groups, part...) + } + var ret []cloudprovider.ICloudSecurityGroup + for i := range groups { + groups[i].region = self + ret = append(ret, &groups[i]) + } + return ret, nil +} + func (self *SRegion) GetIHosts() ([]cloudprovider.ICloudHost, error) { zones, err := self.GetIZones() if err != nil { @@ -222,3 +240,12 @@ func (self *SRegion) GetISnapshotById(id string) (cloudprovider.ICloudSnapshot, } return nil, cloudprovider.ErrNotFound } + +func (self *SRegion) CreateIVpc(opts *cloudprovider.VpcCreateOptions) (cloudprovider.ICloudVpc, error) { + vpc, err := self.CreateVpc(opts) + if err != nil { + return nil, err + } + vpc.region = self + return vpc, nil +} diff --git a/pkg/multicloud/bingocloud/securitygroup.go b/pkg/multicloud/bingocloud/securitygroup.go index 608e5f488..60e0c1b54 100644 --- a/pkg/multicloud/bingocloud/securitygroup.go +++ b/pkg/multicloud/bingocloud/securitygroup.go @@ -16,6 +16,7 @@ package bingocloud import ( "encoding/json" + "fmt" "strings" "yunion.io/x/log" @@ -200,20 +201,26 @@ func (self *SRegion) addSecurityGroupRules(secGrpId string, rule cloudprovider.S func (self *SRegion) GetSecurityGroups(id, name, nextToken string) ([]SSecurityGroup, string, error) { params := map[string]string{} - params["Filter.1.Name"] = "owner-id" - params["Filter.1.Value.1"] = self.getAccountUser() if len(id) > 0 { params["GroupId.1"] = id } - if len(name) > 0 { - params["Filter.2.Name"] = "group-name" - params["Filter.2.Value.1"] = name - } + if len(nextToken) > 0 { params["NextToken"] = nextToken } + idx := 1 + if len(name) > 0 { + params[fmt.Sprintf("Filter.%d.Name", idx)] = "group-name" + params[fmt.Sprintf("Filter.%d.Value.1", idx)] = name + idx++ + } + + params[fmt.Sprintf("Filter.%d.Name", idx)] = "owner-id" + params[fmt.Sprintf("Filter.%d.Value.1", idx)] = self.client.user + idx++ + resp, err := self.invoke("DescribeSecurityGroups", params) if err != nil { return nil, "", err @@ -271,6 +278,10 @@ func (self *SRegion) CreateISecurityGroup(conf *cloudprovider.SecurityGroupCreat params := map[string]string{} if len(conf.Name) > 0 { params["GroupName"] = conf.Name + existSecgroups, _, _ := self.GetSecurityGroups("", conf.Name, "") + if len(existSecgroups) > 0 { + return &existSecgroups[0], nil + } } resp, err := self.invoke("CreateSecurityGroup", params) if err != nil { @@ -285,24 +296,6 @@ func (self *SRegion) CreateISecurityGroup(conf *cloudprovider.SecurityGroupCreat } if ret.Return { - //rule := cloudprovider.SecurityRule{ - // ExternalId: ret.GroupId, - // SecurityRule: secrules.SecurityRule{ - // Action: secrules.SecurityRuleAllow, - // Protocol: secrules.PROTO_ANY, - // Direction: secrules.DIR_IN, - // Priority: 1, - // Ports: []int{}, - // PortStart: 1, - // PortEnd: 65535, - // }, - //} - //rule.ParseCIDR("0.0.0.0/0") - //err = self.addSecurityGroupRules(ret.GroupId, rule) - //if err != nil { - // _ = self.deleteSecurityGroup(ret.GroupId) - // return nil, err - //} return self.GetISecurityGroupById(ret.GroupId) } diff --git a/pkg/multicloud/bingocloud/snapshot.go b/pkg/multicloud/bingocloud/snapshot.go index d515aaa84..c485b997a 100644 --- a/pkg/multicloud/bingocloud/snapshot.go +++ b/pkg/multicloud/bingocloud/snapshot.go @@ -54,7 +54,8 @@ func (self SSnapshot) Refresh() error { return err } if len(newSnapshot) == 1 { - return jsonutils.Update(self, &newSnapshot[0]) + newSnapshot[0].region = self.region + return jsonutils.Update(&self, newSnapshot[0]) } return cloudprovider.ErrNotFound } @@ -93,9 +94,6 @@ func (self SSnapshot) GetDiskType() string { } func (self SSnapshot) Delete() error { - if self.BackupId != "" { - return self.region.deleteInstanceBackup(self.BackupId) - } return self.region.deleteSnapshot(self.SnapshotId) } @@ -105,7 +103,7 @@ func (self *SRegion) createSnapshot(volumeId, name string, desc string) (string, params["SnapshotName"] = name params["Description"] = desc - resp, err := self.client.invoke("CreateSnapshot", params) + resp, err := self.invoke("CreateSnapshot", params) if err != nil { return "", err } @@ -124,7 +122,7 @@ func (self *SRegion) getSnapshots(id, name string) ([]SSnapshot, error) { params["Filter.1.Name"] = name } - resp, err := self.client.invoke("DescribeSnapshots", params) + resp, err := self.invoke("DescribeSnapshots", params) if err != nil { return nil, err } @@ -138,6 +136,6 @@ func (self *SRegion) getSnapshots(id, name string) ([]SSnapshot, error) { func (self *SRegion) deleteSnapshot(id string) error { params := map[string]string{} params["SnapshotId"] = id - _, err := self.client.invoke("DeleteSnapshot", params) + _, err := self.invoke("DeleteSnapshot", params) return err } diff --git a/pkg/multicloud/bingocloud/vpc.go b/pkg/multicloud/bingocloud/vpc.go index 6f33035e8..ff9b2ffa9 100644 --- a/pkg/multicloud/bingocloud/vpc.go +++ b/pkg/multicloud/bingocloud/vpc.go @@ -15,6 +15,9 @@ package bingocloud import ( + "fmt" + + "yunion.io/x/jsonutils" "yunion.io/x/pkg/errors" api "yunion.io/x/cloudmux/pkg/apis/compute" @@ -60,14 +63,33 @@ func (self *SVpc) GetName() string { return self.VpcName } +func (self *SVpc) Refresh() error { + newVpc, err := self.region.GetIVpcById(self.VpcId) + if err != nil { + return err + } + if newVpc != nil { + return jsonutils.Update(self, &newVpc) + } + return cloudprovider.ErrNotFound +} + func (self *SVpc) Delete() error { - return cloudprovider.ErrNotImplemented + params := make(map[string]string) + params["VpcId"] = self.VpcId + + _, err := self.region.invoke("DeleteVpc", params) + return err } func (self *SVpc) GetCidrBlock() string { return self.CidrBlock } +func (self *SVpc) IsPublic() bool { + return self.Shared == "true" +} + func (self *SVpc) GetIRouteTableById(id string) (cloudprovider.ICloudRouteTable, error) { return nil, cloudprovider.ErrNotImplemented } @@ -115,19 +137,37 @@ func (self *SVpc) GetStatus() string { } } +func (self *SRegion) GetIVpcById(id string) (cloudprovider.ICloudVpc, error) { + vpcs, err := self.GetIVpcs() + if err != nil { + return nil, err + } + for i := range vpcs { + if vpcs[i].GetGlobalId() == id { + return vpcs[i], nil + } + } + return nil, cloudprovider.ErrNotFound +} + func (self *SRegion) GetVpcs(id string) ([]SVpc, error) { params := map[string]string{} if len(id) > 0 { params["VpcId"] = id } + idx := 1 + params[fmt.Sprintf("Filter.%d.Name", idx)] = "owner-id" + params[fmt.Sprintf("Filter.%d.Value.1", idx)] = self.client.user + idx++ resp, err := self.invoke("DescribeVpcs", params) if err != nil { return nil, err } var vpcs []SVpc + resp.Unmarshal(&vpcs, "vpcSet") - return vpcs, resp.Unmarshal(&vpcs, "vpcSet") + return vpcs, nil } func (self *SRegion) GetIVpcs() ([]cloudprovider.ICloudVpc, error) { @@ -142,3 +182,25 @@ func (self *SRegion) GetIVpcs() ([]cloudprovider.ICloudVpc, error) { } return ret, nil } + +func (self *SRegion) CreateVpc(opts *cloudprovider.VpcCreateOptions) (*SVpc, error) { + params := make(map[string]string) + if len(opts.CIDR) > 0 { + params["CidrBlock"] = opts.CIDR + } + if len(opts.NAME) > 0 { + params["VpcName"] = opts.NAME + } + if len(opts.Desc) > 0 { + params["Description"] = opts.Desc + } + + resp, err := self.invoke("CreateVpc", params) + if err != nil { + return nil, err + } + + var vpc *SVpc + err = resp.Unmarshal(&vpc, "vpc") + return vpc, err +} diff --git a/pkg/multicloud/ctyun/region.go b/pkg/multicloud/ctyun/region.go index 0a29e8438..9a2cc91b0 100644 --- a/pkg/multicloud/ctyun/region.go +++ b/pkg/multicloud/ctyun/region.go @@ -408,6 +408,10 @@ func (self *SRegion) GetIStorages() ([]cloudprovider.ICloudStorage, error) { return iStores, nil } +func (self *SRegion) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) { + return nil, nil +} + func (self *SRegion) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) { izones, err := self.GetIZones() if err != nil { diff --git a/pkg/multicloud/ctyun/vpc.go b/pkg/multicloud/ctyun/vpc.go index e99ad9558..c2e6f7ba9 100644 --- a/pkg/multicloud/ctyun/vpc.go +++ b/pkg/multicloud/ctyun/vpc.go @@ -80,6 +80,10 @@ func (self *SVpc) IsEmulated() bool { return false } +func (self *SVpc) IsPublic() bool { + return false +} + func (self *SVpc) GetRegion() cloudprovider.ICloudRegion { return self.region } diff --git a/pkg/multicloud/ecloud/region.go b/pkg/multicloud/ecloud/region.go index 16c518767..3e68cda55 100644 --- a/pkg/multicloud/ecloud/region.go +++ b/pkg/multicloud/ecloud/region.go @@ -159,6 +159,10 @@ func (r *SRegion) fetchVpcs() error { return nil } +func (self *SRegion) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) { + return nil, nil +} + func (r *SRegion) getVpcs() ([]SVpc, error) { request := NewConsoleRequest(r.ID, "/api/v2/netcenter/vpc", nil, nil) vpcs := make([]SVpc, 0) diff --git a/pkg/multicloud/ecloud/vpc.go b/pkg/multicloud/ecloud/vpc.go index 1250eb1a7..3547ca355 100644 --- a/pkg/multicloud/ecloud/vpc.go +++ b/pkg/multicloud/ecloud/vpc.go @@ -83,6 +83,10 @@ func (v *SVpc) IsEmulated() bool { return false } +func (self *SVpc) IsPublic() bool { + return false +} + func (v *SVpc) GetRegion() cloudprovider.ICloudRegion { return v.region } diff --git a/pkg/multicloud/esxi/manager.go b/pkg/multicloud/esxi/manager.go index c407f24e3..8bf62581b 100644 --- a/pkg/multicloud/esxi/manager.go +++ b/pkg/multicloud/esxi/manager.go @@ -323,6 +323,10 @@ func (cli *SESXiClient) GetVersion() string { return cli.client.ServiceContent.About.Version } +func (self *SESXiClient) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) { + return nil, nil +} + func (cli *SESXiClient) About() jsonutils.JSONObject { about := jsonutils.Marshal(&cli.client.ServiceContent.About) aboutDict := about.(*jsonutils.JSONDict) diff --git a/pkg/multicloud/google/region.go b/pkg/multicloud/google/region.go index 1a78484fe..377e59d66 100644 --- a/pkg/multicloud/google/region.go +++ b/pkg/multicloud/google/region.go @@ -87,6 +87,10 @@ func (region *SRegion) GetProvider() string { return CLOUD_PROVIDER_GOOGLE } +func (self *SRegion) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) { + return nil, nil +} + func (region *SRegion) GetStatus() string { if region.Status == "UP" || utils.IsInStringArray(region.Name, MultiRegions) || utils.IsInStringArray(region.Name, DualRegions) { return api.CLOUD_REGION_STATUS_INSERVER diff --git a/pkg/multicloud/google/vpc.go b/pkg/multicloud/google/vpc.go index c5381a66d..d84460a38 100644 --- a/pkg/multicloud/google/vpc.go +++ b/pkg/multicloud/google/vpc.go @@ -85,6 +85,10 @@ func (vpc *SVpc) IsEmulated() bool { return false } +func (self *SVpc) IsPublic() bool { + return false +} + func (vpc *SVpc) GetIsDefault() bool { return false } diff --git a/pkg/multicloud/hcso/region.go b/pkg/multicloud/hcso/region.go index 083c717b8..b2130f91e 100644 --- a/pkg/multicloud/hcso/region.go +++ b/pkg/multicloud/hcso/region.go @@ -188,6 +188,10 @@ func (self *SRegion) GetGeographicInfo() cloudprovider.SGeographicInfo { return cloudprovider.SGeographicInfo{} } +func (self *SRegion) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) { + return nil, nil +} + func (self *SRegion) GetILoadBalancers() ([]cloudprovider.ICloudLoadbalancer, error) { elbs, err := self.GetLoadBalancers() if err != nil { diff --git a/pkg/multicloud/hcso/vpc.go b/pkg/multicloud/hcso/vpc.go index 4ec7a158c..655199c30 100644 --- a/pkg/multicloud/hcso/vpc.go +++ b/pkg/multicloud/hcso/vpc.go @@ -132,6 +132,10 @@ func (self *SVpc) IsEmulated() bool { return false } +func (self *SVpc) IsPublic() bool { + return false +} + func (self *SVpc) GetRegion() cloudprovider.ICloudRegion { return self.region } diff --git a/pkg/multicloud/huawei/region.go b/pkg/multicloud/huawei/region.go index 9fa33e126..b45da6afe 100644 --- a/pkg/multicloud/huawei/region.go +++ b/pkg/multicloud/huawei/region.go @@ -57,6 +57,10 @@ type SRegion struct { storageCache *SStoragecache } +func (self *SRegion) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) { + return nil, nil +} + func (self *SRegion) GetClient() *SHuaweiClient { return self.client } diff --git a/pkg/multicloud/huawei/vpc.go b/pkg/multicloud/huawei/vpc.go index ffc43f336..585b7d9eb 100644 --- a/pkg/multicloud/huawei/vpc.go +++ b/pkg/multicloud/huawei/vpc.go @@ -130,6 +130,10 @@ func (self *SVpc) IsEmulated() bool { return false } +func (self *SVpc) IsPublic() bool { + return false +} + func (self *SVpc) GetRegion() cloudprovider.ICloudRegion { return self.region } diff --git a/pkg/multicloud/jdcloud/region.go b/pkg/multicloud/jdcloud/region.go index 9309f2dde..7e2fd2510 100644 --- a/pkg/multicloud/jdcloud/region.go +++ b/pkg/multicloud/jdcloud/region.go @@ -161,6 +161,10 @@ func (r *SRegion) GetIEips() ([]cloudprovider.ICloudEIP, error) { return nil, nil } +func (self *SRegion) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) { + return nil, nil +} + func (r *SRegion) GetIVpcById(id string) (cloudprovider.ICloudVpc, error) { vpc, err := r.GetVpcById(id) if err != nil { diff --git a/pkg/multicloud/jdcloud/vpc.go b/pkg/multicloud/jdcloud/vpc.go index 8e513a41a..06b57af61 100644 --- a/pkg/multicloud/jdcloud/vpc.go +++ b/pkg/multicloud/jdcloud/vpc.go @@ -63,6 +63,10 @@ func (v *SVpc) IsEmulated() bool { return false } +func (self *SVpc) IsPublic() bool { + return false +} + func (v *SVpc) GetRegion() cloudprovider.ICloudRegion { return v.region } diff --git a/pkg/multicloud/nutanix/region.go b/pkg/multicloud/nutanix/region.go index 65cb9f5b9..acb49b419 100644 --- a/pkg/multicloud/nutanix/region.go +++ b/pkg/multicloud/nutanix/region.go @@ -110,6 +110,10 @@ func (self *SRegion) GetIVpcById(id string) (cloudprovider.ICloudVpc, error) { return vpc, nil } +func (self *SRegion) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) { + return nil, nil +} + func (self *SRegion) GetIVpcs() ([]cloudprovider.ICloudVpc, error) { vpcs, err := self.GetVpcs() if err != nil { diff --git a/pkg/multicloud/nutanix/vpc.go b/pkg/multicloud/nutanix/vpc.go index 2e26fe0ee..9999e1ee1 100644 --- a/pkg/multicloud/nutanix/vpc.go +++ b/pkg/multicloud/nutanix/vpc.go @@ -62,6 +62,10 @@ func (self *SVpc) GetName() string { return self.Name } +func (self *SVpc) IsPublic() bool { + return false +} + func (self *SVpc) GetId() string { return self.UUID } diff --git a/pkg/multicloud/objectstore/objectstore.go b/pkg/multicloud/objectstore/objectstore.go index 08f54c15f..9c99616d2 100644 --- a/pkg/multicloud/objectstore/objectstore.go +++ b/pkg/multicloud/objectstore/objectstore.go @@ -162,6 +162,10 @@ func (cli *SObjectStoreClient) GetIRegion() cloudprovider.ICloudRegion { return cli.GetVirtualObject().(cloudprovider.ICloudRegion) } +func (self *SObjectStoreClient) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) { + return nil, nil +} + func (cli *SObjectStoreClient) GetIBucketProvider() IBucketProvider { return cli.GetVirtualObject().(IBucketProvider) } diff --git a/pkg/multicloud/openstack/region.go b/pkg/multicloud/openstack/region.go index 119678971..f8b7a6b57 100644 --- a/pkg/multicloud/openstack/region.go +++ b/pkg/multicloud/openstack/region.go @@ -165,6 +165,10 @@ func (region *SRegion) GetIStorages() ([]cloudprovider.ICloudStorage, error) { return iStorages, nil } +func (self *SRegion) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) { + return nil, nil +} + func (region *SRegion) getStoragecache() *SStoragecache { if region.storageCache == nil { region.storageCache = &SStoragecache{region: region} diff --git a/pkg/multicloud/openstack/vpc.go b/pkg/multicloud/openstack/vpc.go index 6ad9be277..c06a19d9e 100644 --- a/pkg/multicloud/openstack/vpc.go +++ b/pkg/multicloud/openstack/vpc.go @@ -87,6 +87,10 @@ func (vpc *SVpc) IsEmulated() bool { return false } +func (self *SVpc) IsPublic() bool { + return false +} + func (vpc *SVpc) GetIsDefault() bool { return vpc.IsDefault } diff --git a/pkg/multicloud/proxmox/region.go b/pkg/multicloud/proxmox/region.go index 2d9be0df7..d4d565012 100644 --- a/pkg/multicloud/proxmox/region.go +++ b/pkg/multicloud/proxmox/region.go @@ -77,6 +77,10 @@ func (self *SRegion) Refresh() error { return nil } +func (self *SRegion) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) { + return nil, nil +} + func (self *SRegion) GetISecurityGroupById(secgroupId string) (cloudprovider.ICloudSecurityGroup, error) { return nil, cloudprovider.ErrNotSupported } diff --git a/pkg/multicloud/proxmox/vpc.go b/pkg/multicloud/proxmox/vpc.go index 380ddd2e3..f96b1c934 100644 --- a/pkg/multicloud/proxmox/vpc.go +++ b/pkg/multicloud/proxmox/vpc.go @@ -47,6 +47,10 @@ func (self *SVpc) IsEmulated() bool { return true } +func (self *SVpc) IsPublic() bool { + return false +} + func (self *SVpc) GetCidrBlock() string { return "0.0.0.0/0" } diff --git a/pkg/multicloud/qcloud/region.go b/pkg/multicloud/qcloud/region.go index 7c6846c17..507cacb97 100644 --- a/pkg/multicloud/qcloud/region.go +++ b/pkg/multicloud/qcloud/region.go @@ -150,6 +150,10 @@ func (self *SRegion) GetIEipById(eipId string) (cloudprovider.ICloudEIP, error) return &eips[0], nil } +func (self *SRegion) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) { + return nil, nil +} + func (self *SRegion) GetIEips() ([]cloudprovider.ICloudEIP, error) { eips, total, err := self.GetEips("", "", 0, 50) if err != nil { diff --git a/pkg/multicloud/qcloud/vpc.go b/pkg/multicloud/qcloud/vpc.go index 97ad2fa44..7544b5e97 100644 --- a/pkg/multicloud/qcloud/vpc.go +++ b/pkg/multicloud/qcloud/vpc.go @@ -65,6 +65,10 @@ func (self *SVpc) IsEmulated() bool { return false } +func (self *SVpc) IsPublic() bool { + return false +} + func (self *SVpc) GetIsDefault() bool { return self.IsDefault } diff --git a/pkg/multicloud/remotefile/region.go b/pkg/multicloud/remotefile/region.go index 29fc2b083..dea53ef0a 100644 --- a/pkg/multicloud/remotefile/region.go +++ b/pkg/multicloud/remotefile/region.go @@ -118,6 +118,10 @@ func (self *SRegion) GetIDiskById(id string) (cloudprovider.ICloudDisk, error) { return nil, cloudprovider.ErrNotFound } +func (self *SRegion) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) { + return nil, nil +} + func (self *SRegion) GetIVpcs() ([]cloudprovider.ICloudVpc, error) { vpcs, err := self.client.GetVpcs() if err != nil { diff --git a/pkg/multicloud/remotefile/vpc.go b/pkg/multicloud/remotefile/vpc.go index 03e93603d..d5d1294a0 100644 --- a/pkg/multicloud/remotefile/vpc.go +++ b/pkg/multicloud/remotefile/vpc.go @@ -40,6 +40,10 @@ func (self *SVpc) GetCidrBlock() string { return self.CidrBlock } +func (self *SVpc) IsPublic() bool { + return false +} + func (self *SVpc) GetIRouteTableById(id string) (cloudprovider.ICloudRouteTable, error) { return nil, cloudprovider.ErrNotSupported } diff --git a/pkg/multicloud/ucloud/region.go b/pkg/multicloud/ucloud/region.go index 56b50b16f..0a635bfdd 100644 --- a/pkg/multicloud/ucloud/region.go +++ b/pkg/multicloud/ucloud/region.go @@ -143,6 +143,10 @@ func (self *SRegion) GetIEips() ([]cloudprovider.ICloudEIP, error) { return ieips, nil } +func (self *SRegion) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) { + return nil, nil +} + func (self *SRegion) GetIVpcById(id string) (cloudprovider.ICloudVpc, error) { ivpcs, err := self.GetIVpcs() if err != nil { diff --git a/pkg/multicloud/ucloud/vpc.go b/pkg/multicloud/ucloud/vpc.go index fdba13a52..5c8fec956 100644 --- a/pkg/multicloud/ucloud/vpc.go +++ b/pkg/multicloud/ucloud/vpc.go @@ -71,6 +71,10 @@ func (self *SVPC) GetGlobalId() string { return self.GetId() } +func (self *SVPC) IsPublic() bool { + return false +} + func (self *SVPC) GetStatus() string { return api.VPC_STATUS_AVAILABLE } diff --git a/pkg/multicloud/zstack/region.go b/pkg/multicloud/zstack/region.go index dcdb0201c..1edfbeb59 100644 --- a/pkg/multicloud/zstack/region.go +++ b/pkg/multicloud/zstack/region.go @@ -120,6 +120,10 @@ func (region *SRegion) GetIStorageById(id string) (cloudprovider.ICloudStorage, return nil, cloudprovider.ErrNotFound } +func (self *SRegion) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) { + return nil, nil +} + func (region *SRegion) GetIHosts() ([]cloudprovider.ICloudHost, error) { hosts, err := region.GetHosts("", "") if err != nil { diff --git a/pkg/multicloud/zstack/vpc.go b/pkg/multicloud/zstack/vpc.go index adf217820..6474b5390 100644 --- a/pkg/multicloud/zstack/vpc.go +++ b/pkg/multicloud/zstack/vpc.go @@ -47,6 +47,10 @@ func (vpc *SVpc) IsEmulated() bool { return true } +func (self *SVpc) IsPublic() bool { + return false +} + func (vpc *SVpc) GetIsDefault() bool { return true }