diff --git a/go.mod b/go.mod index 47651a7c23..14187d1543 100644 --- a/go.mod +++ b/go.mod @@ -89,7 +89,7 @@ require ( k8s.io/cluster-bootstrap v0.19.3 k8s.io/cri-api v0.22.17 moul.io/http2curl/v2 v2.3.0 - yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20240407070842-c86e783a71ae + yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20240409024937-1c58cb7de60a yunion.io/x/executor v0.0.0-20230705125604-c5ac3141db32 yunion.io/x/jsonutils v1.0.1-0.20240203102553-4096f103b401 yunion.io/x/log v1.0.1-0.20240305175729-7cf2d6cd5a91 diff --git a/go.sum b/go.sum index d2fbb26fdf..7671a4e0de 100644 --- a/go.sum +++ b/go.sum @@ -1210,8 +1210,8 @@ sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= -yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20240407070842-c86e783a71ae h1:R/PRTt4DaAHTSQh1K6+p131HKt6SRzwLiw5u8TgIB/w= -yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20240407070842-c86e783a71ae/go.mod h1:dsUESXIbXJ+/ywbNClhldOrbPOiBi2udrgOnB/ffoWk= +yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20240409024937-1c58cb7de60a h1:/2cG8vQUToTwOOHD3fB4rYgh6hCuxAd4Q7VGArxPpsg= +yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20240409024937-1c58cb7de60a/go.mod h1:dsUESXIbXJ+/ywbNClhldOrbPOiBi2udrgOnB/ffoWk= yunion.io/x/executor v0.0.0-20230705125604-c5ac3141db32 h1:v7POYkQwo1XzOxBoIoRVr/k0V9Y5JyjpshlIFa9raug= yunion.io/x/executor v0.0.0-20230705125604-c5ac3141db32/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws= yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051/go.mod h1:4N0/RVzsYL3kH3WE/H1BjUQdFiWu50JGCFQuuy+Z634= diff --git a/vendor/modules.txt b/vendor/modules.txt index 6aa64a8bf1..fae1d6c49c 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1476,7 +1476,7 @@ sigs.k8s.io/structured-merge-diff/v4/value # sigs.k8s.io/yaml v1.2.0 ## explicit; go 1.12 sigs.k8s.io/yaml -# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20240407070842-c86e783a71ae +# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20240409024937-1c58cb7de60a ## explicit; go 1.18 yunion.io/x/cloudmux/pkg/apis yunion.io/x/cloudmux/pkg/apis/billing diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/securitygroup.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/securitygroup.go index 127b103485..f52cce0f5c 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/securitygroup.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/securitygroup.go @@ -102,14 +102,18 @@ func (self *SRegion) CreateSecurityGroupRule(secGrpId string, opts *cloudprovide if opts.Protocol != secrules.PROTO_ANY { params["IpPermissions.1.IpProtocol"] = strings.ToLower(opts.Protocol) } - if len(opts.CIDR) > 0 { - if _, err := netutils.NewIPV6Prefix(opts.CIDR); err == nil { - params["IpPermissions.1.Ipv6Ranges.1.CidrIpv6"] = opts.CIDR - params["IpPermissions.1.Ipv6Ranges.1.Description"] = opts.Desc - } else { - params["IpPermissions.1.IpRanges.1.CidrIp"] = opts.CIDR - params["IpPermissions.1.IpRanges.1.Description"] = opts.Desc + if len(opts.CIDR) == 0 { + opts.CIDR = "0.0.0.0/0" + } + if _, err := netutils.NewIPV6Prefix(opts.CIDR); err == nil { + params["IpPermissions.1.Ipv6Ranges.1.CidrIpv6"] = opts.CIDR + params["IpPermissions.1.Ipv6Ranges.1.Description"] = opts.Desc + } else { + if !strings.Contains(opts.CIDR, "/") { + opts.CIDR = opts.CIDR + "/32" } + params["IpPermissions.1.IpRanges.1.CidrIp"] = opts.CIDR + params["IpPermissions.1.IpRanges.1.Description"] = opts.Desc } start, end := 0, 0 if len(opts.Ports) > 0 { @@ -160,7 +164,7 @@ func (self *SRegion) CreateSecurityGroupRule(secGrpId string, opts *cloudprovide for i := range ret.SecurityGroupRuleSet { return &ret.SecurityGroupRuleSet[i], nil } - return nil, errors.Wrapf(cloudprovider.ErrNotFound, "after create") + return nil, errors.Wrapf(cloudprovider.ErrNotFound, "after create %s", jsonutils.Marshal(opts)) } func (self *SRegion) DeleteSecurityGroupRule(secGrpId string, direction, ruleId string) error { diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/disks.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/disks.go new file mode 100644 index 0000000000..4ea3f1f3f5 --- /dev/null +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/disks.go @@ -0,0 +1,243 @@ +// 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 ksyun + +import ( + "context" + "fmt" + + api "yunion.io/x/cloudmux/pkg/apis/compute" + "yunion.io/x/cloudmux/pkg/cloudprovider" + "yunion.io/x/cloudmux/pkg/multicloud" + "yunion.io/x/pkg/errors" +) + +type Attachment struct { + InstanceID string `json:"InstanceId"` + MountPoint string `json:"MountPoint"` + DeleteWithInstance bool `json:"DeleteWithInstance"` +} + +type HistoryAttachment struct { + InstanceID string `json:"InstanceId"` + AttachTime string `json:"AttachTime"` + DetachTime string `json:"DetachTime"` + MountPoint string `json:"MountPoint"` +} + +type SDisk struct { + storage *SStorage + multicloud.SDisk + SKsTag + + VolumeID string `json:"VolumeId"` + VolumeName string `json:"VolumeName"` + VolumeDesc string `json:"VolumeDesc,omitempty"` + Size int `json:"Size"` + VolumeStatus string `json:"VolumeStatus"` + VolumeType string `json:"VolumeType"` + VolumeCategory string `json:"VolumeCategory"` + InstanceID string `json:"InstanceId"` + AvailabilityZone string `json:"AvailabilityZone"` + ChargeType string `json:"ChargeType"` + InstanceTradeType int `json:"InstanceTradeType"` + CreateTime string `json:"CreateTime"` + Attachment []Attachment `json:"Attachment"` + ProjectID int `json:"ProjectId"` + ExpireTime string `json:"ExpireTime,omitempty"` + HistoryAttachment []HistoryAttachment `json:"HistoryAttachment,omitempty"` + DeleteWithInstance bool `json:"DeleteWithInstance"` +} + +func (region *SRegion) GetDisks(diskIds []string, storageType, zoneId string) ([]SDisk, error) { + disks := []SDisk{} + params := map[string]string{ + "MaxResults": "1000", + } + for i, v := range diskIds { + params[fmt.Sprintf("VolumeId.%d", i+1)] = v + } + if len(storageType) > 0 { + params["VolumeType"] = storageType + } + for { + resp, err := region.ebsRequest("DescribeVolumes", params) + if err != nil { + return nil, errors.Wrap(err, "list instance") + } + part := struct { + RequestID string `json:"RequestId"` + Volumes []SDisk `json:"Volumes"` + TotalCount int `json:"TotalCount"` + Marker int `json:"Marker"` + }{} + err = resp.Unmarshal(&part) + if err != nil { + return nil, errors.Wrap(err, "unmarshal instances") + } + disks = append(disks, part.Volumes...) + if len(disks) >= part.TotalCount { + break + } + params["Marker"] = fmt.Sprintf("%d", part.Marker) + } + if len(zoneId) > 0 { + res := []SDisk{} + for _, disk := range disks { + if disk.AvailabilityZone == zoneId { + res = append(res, disk) + } + } + return res, nil + } + return disks, nil + +} + +func (region *SRegion) GetDiskByInstanceId(instanceId string) ([]SDisk, error) { + disks := []SDisk{} + params := map[string]string{ + "MaxResults": "1000", + } + params["InstanceId"] = instanceId + resp, err := region.ebsRequest("DescribeInstanceVolumes", params) + if err != nil { + return nil, errors.Wrap(err, "DescribeInstanceVolumes") + } + return disks, resp.Unmarshal(&disks, "Attachments") +} + +func (disk *SDisk) GetIStorage() (cloudprovider.ICloudStorage, error) { + if disk.storage == nil { + return nil, fmt.Errorf("disk %s(%s) missing storage", disk.VolumeName, disk.VolumeID) + } + return disk.storage, nil +} + +func (disk *SDisk) GetIStorageId() string { + if disk.storage == nil { + return "" + } + return disk.storage.GetGlobalId() +} + +func (disk *SDisk) GetDiskFormat() string { + return "" +} + +func (disk *SDisk) GetId() string { + return disk.VolumeID +} + +func (disk *SDisk) GetGlobalId() string { + return disk.VolumeID +} + +func (disk *SDisk) GetName() string { + return disk.VolumeName +} + +func (disk *SDisk) GetStatus() string { + // creating、available、attaching、inuse、detaching、extending、deleting、error + switch disk.VolumeStatus { + case "available", "inuse", "in-use": + return api.DISK_READY + case "detaching": + return api.DISK_DETACHING + case "error": + return api.DISK_UNKNOWN + default: + return disk.VolumeStatus + } +} + +func (disk *SDisk) GetDiskSizeMB() int { + return disk.Size * 1024 +} + +func (disk *SDisk) GetIsAutoDelete() bool { + return disk.DeleteWithInstance +} + +func (disk *SDisk) GetTemplateId() string { + return "" +} + +func (disk *SDisk) GetDiskType() string { + if disk.VolumeCategory == "system" { + return api.DISK_TYPE_SYS + } + return api.DISK_TYPE_DATA +} + +func (disk *SDisk) GetFsFormat() string { + return "" +} + +func (disk *SDisk) GetIsNonPersistent() bool { + return false +} + +func (disk *SDisk) GetIops() int { + return 0 +} + +func (disk *SDisk) GetDriver() string { + return "" +} + +func (disk *SDisk) GetCacheMode() string { + return "" +} + +func (disk *SDisk) GetMountpoint() string { + return "" +} + +func (disk *SDisk) GetAccessPath() string { + return "" +} + +func (disk *SDisk) Delete(ctx context.Context) error { + return cloudprovider.ErrNotSupported +} + +func (disk *SDisk) CreateISnapshot(ctx context.Context, name string, desc string) (cloudprovider.ICloudSnapshot, error) { + return nil, cloudprovider.ErrNotSupported +} + +func (disk *SDisk) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) { + return nil, cloudprovider.ErrNotSupported +} + +func (disk *SDisk) GetExtSnapshotPolicyIds() ([]string, error) { + return nil, cloudprovider.ErrNotSupported +} + +func (disk *SDisk) Resize(ctx context.Context, newSizeMB int64) error { + return cloudprovider.ErrNotSupported +} + +func (disk *SDisk) Reset(ctx context.Context, snapshotId string) (string, error) { + return "", cloudprovider.ErrNotSupported +} + +func (disk *SDisk) Rebuild(ctx context.Context) error { + return cloudprovider.ErrNotSupported +} + +func (disk *SDisk) SetStorage(storage SStorage) { + disk.storage = &storage +} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/eip.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/eip.go new file mode 100644 index 0000000000..2d8b2c921e --- /dev/null +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/eip.go @@ -0,0 +1,229 @@ +// 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 ksyun + +import ( + "fmt" + "time" + + "yunion.io/x/jsonutils" + "yunion.io/x/pkg/errors" + + billing_api "yunion.io/x/cloudmux/pkg/apis/billing" + api "yunion.io/x/cloudmux/pkg/apis/compute" + "yunion.io/x/cloudmux/pkg/cloudprovider" + "yunion.io/x/cloudmux/pkg/multicloud" +) + +type SEipResp struct { + RequestID string `json:"RequestId"` + NextToken string `json:"NextToken"` + AddressesSet []SEip `json:"AddressesSet"` + TotalCount int `json:"TotalCount"` +} + +type SEip struct { + multicloud.SEipBase + region *SRegion + SKsTag + + PublicIP string `json:"PublicIp"` + AllocationID string `json:"AllocationId"` + State string `json:"State"` + IPState string `json:"IpState"` + LineID string `json:"LineId"` + BandWidth int `json:"BandWidth"` + InstanceType string `json:"InstanceType"` + InstanceID string `json:"InstanceId"` + ChargeType string `json:"ChargeType"` + IPVersion string `json:"IpVersion"` + ProjectID string `json:"ProjectId"` + CreateTime string `json:"CreateTime"` + Mode string `json:"Mode"` + NetworkInterfaceID string `json:"NetworkInterfaceId,omitempty"` + NetworkInterfaceType string `json:"NetworkInterfaceType,omitempty"` + PrivateIPAddress string `json:"PrivateIpAddress,omitempty"` + InternetGatewayID string `json:"InternetGatewayId,omitempty"` + HostType string `json:"HostType,omitempty"` +} + +func (region *SRegion) GetEips(eipIds []string) ([]SEip, error) { + params := map[string]string{ + "MaxResults": "1000", + } + for i, eipId := range eipIds { + params[fmt.Sprintf("AllocationId.%d", i+1)] = eipId + } + res := []SEip{} + for { + resp, err := region.eipRequest("DescribeAddresses", params) + if err != nil { + return nil, errors.Wrap(err, "get eips") + } + part := SEipResp{} + err = resp.Unmarshal(&part) + if err != nil { + return nil, errors.Wrap(err, "unmarshal eip") + } + res = append(res, part.AddressesSet...) + if len(part.NextToken) == 0 { + break + } + params["NextToken"] = part.NextToken + } + return res, nil +} + +func (region *SRegion) GetEip(eipId string) (*SEip, error) { + eips, err := region.GetEips([]string{eipId}) + if err != nil { + return nil, errors.Wrap(err, "GetEips") + } + for _, eip := range eips { + if eip.GetId() == eipId { + return &eip, nil + } + } + return nil, errors.Wrapf(errors.ErrNotFound, "eip id:%s", eipId) +} + +func (eip *SEip) GetId() string { + return eip.AllocationID +} + +func (eip *SEip) GetName() string { + return eip.AllocationID +} + +func (eip *SEip) GetGlobalId() string { + return eip.AllocationID +} + +func (eip *SEip) GetStatus() string { + switch eip.State { + case "associate": + return api.EIP_STATUS_READY + case "disassociate": + return api.EIP_STATUS_READY + default: + return api.EIP_STATUS_UNKNOWN + } +} + +func (eip *SEip) Refresh() error { + extEip, err := eip.region.GetEip(eip.AllocationID) + if err != nil { + return errors.Wrap(err, "region.GetEip") + } + return jsonutils.Update(eip, &extEip) +} + +func (eip *SEip) GetIpAddr() string { + return eip.PublicIP +} + +func (eip *SEip) GetMode() string { + return api.EIP_MODE_STANDALONE_EIP +} + +func (eip *SEip) GetAssociationType() string { + switch eip.InstanceType { + case "Ipfwd": + return api.EIP_ASSOCIATE_TYPE_SERVER + case "Slb": + return api.EIP_ASSOCIATE_TYPE_LOADBALANCER + default: + return eip.InstanceType + } +} + +func (eip *SEip) GetAssociationExternalId() string { + return eip.InstanceID +} + +func (eip *SEip) GetBandwidth() int { + return int(eip.BandWidth) // Mb +} + +func (eip *SEip) GetINetworkId() string { + return "" +} + +func (eip *SEip) GetInternetChargeType() string { + return "" +} + +func (eip *SEip) GetBillingType() string { + if eip.ChargeType == "Monthly" { + return billing_api.BILLING_TYPE_PREPAID + } + return billing_api.BILLING_TYPE_POSTPAID +} + +func (eip *SEip) GetCreatedAt() time.Time { + createdAt, _ := time.Parse("2006-01-02 15:04:05", eip.CreateTime) + return createdAt +} + +func (eip *SEip) GetExpiredAt() time.Time { + return time.Time{} +} + +func (eip *SEip) Delete() error { + return cloudprovider.ErrNotImplemented +} + +func (eip *SEip) Associate(conf *cloudprovider.AssociateConfig) error { + return cloudprovider.ErrNotImplemented +} + +func (eip *SEip) Dissociate() error { + return cloudprovider.ErrNotImplemented +} + +func (eip *SEip) ChangeBandwidth(bw int) error { + return cloudprovider.ErrNotImplemented +} + +func (region *SRegion) GetInstancePortId(instanceId string) (string, error) { + return "", cloudprovider.ErrNotImplemented +} +func (region *SRegion) AllocateEIP(opts *cloudprovider.SEip) (*SEip, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (region *SRegion) DeallocateEIP(eipId string) error { + return cloudprovider.ErrNotImplemented +} + +func (region *SRegion) AssociateEip(eipId string, instanceId string) error { + return cloudprovider.ErrNotImplemented +} + +func (region *SRegion) AssociateEipWithPortId(eipId string, portId string) error { + return cloudprovider.ErrNotImplemented +} + +func (region *SRegion) DissociateEip(eipId string) error { + return region.AssociateEipWithPortId(eipId, "") +} + +func (region *SRegion) UpdateEipBandwidth(bandwidthId string, bw int) error { + return cloudprovider.ErrNotImplemented +} + +func (eip *SEip) GetProjectId() string { + return "" +} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/group.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/group.go index 5c27d00ffb..21449978ed 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/group.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/group.go @@ -33,71 +33,71 @@ type SGroup struct { PolicyCount int } -func (self *SGroup) GetName() string { - return self.GroupName +func (group *SGroup) GetName() string { + return group.GroupName } -func (self *SGroup) GetGlobalId() string { - return self.GroupName +func (group *SGroup) GetGlobalId() string { + return group.GroupName } -func (self *SGroup) GetDescription() string { - return self.Description +func (group *SGroup) GetDescription() string { + return group.Description } -func (self *SGroup) GetICloudusers() ([]cloudprovider.IClouduser, error) { +func (group *SGroup) GetICloudusers() ([]cloudprovider.IClouduser, error) { return nil, cloudprovider.ErrNotSupported } -func (self *SGroup) GetICloudpolicies() ([]cloudprovider.ICloudpolicy, error) { - policies, err := self.client.ListGroupPolicies(self.GroupName) +func (group *SGroup) GetICloudpolicies() ([]cloudprovider.ICloudpolicy, error) { + policies, err := group.client.ListGroupPolicies(group.GroupName) if err != nil { return nil, err } ret := []cloudprovider.ICloudpolicy{} for i := range policies { - policies[i].client = self.client + policies[i].client = group.client ret = append(ret, &policies[i]) } return ret, nil } -func (self *SGroup) AddUser(name string) error { - return self.client.AddUserToGroup(name, self.GroupName) +func (group *SGroup) AddUser(name string) error { + return group.client.AddUserToGroup(name, group.GroupName) } -func (self *SGroup) RemoveUser(name string) error { - return self.client.RemoveUserFromGroup(name, self.GroupName) +func (group *SGroup) RemoveUser(name string) error { + return group.client.RemoveUserFromGroup(name, group.GroupName) } -func (self *SGroup) AttachPolicy(policyName string, policyType api.TPolicyType) error { - return self.client.AttachGroupPolicy(self.GroupName, policyName) +func (group *SGroup) AttachPolicy(policyName string, policyType api.TPolicyType) error { + return group.client.AttachGroupPolicy(group.GroupName, policyName) } -func (self *SGroup) DetachPolicy(policyName string, policyType api.TPolicyType) error { - return self.client.DetachGroupPolicy(self.GroupName, policyName) +func (group *SGroup) DetachPolicy(policyName string, policyType api.TPolicyType) error { + return group.client.DetachGroupPolicy(group.GroupName, policyName) } -func (self *SGroup) Delete() error { - return self.client.DeleteGroup(self.GroupName) +func (group *SGroup) Delete() error { + return group.client.DeleteGroup(group.GroupName) } -func (self *SKsyunClient) CreateICloudgroup(name string, desc string) (cloudprovider.ICloudgroup, error) { - group, err := self.CreateGroup(name, desc) +func (client *SKsyunClient) CreateICloudgroup(name string, desc string) (cloudprovider.ICloudgroup, error) { + group, err := client.CreateGroup(name, desc) if err != nil { return nil, err } return group, nil } -func (self *SKsyunClient) GetICloudgroups() ([]cloudprovider.ICloudgroup, error) { - groups, err := self.ListGroups() +func (client *SKsyunClient) GetICloudgroups() ([]cloudprovider.ICloudgroup, error) { + groups, err := client.ListGroups() if err != nil { return nil, err } ret := []cloudprovider.ICloudgroup{} for i := range groups { - groups[i].client = self + groups[i].client = client ret = append(ret, &groups[i]) } return ret, nil diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/host.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/host.go new file mode 100644 index 0000000000..1279bf16db --- /dev/null +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/host.go @@ -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 ksyun + +import ( + api "yunion.io/x/cloudmux/pkg/apis/compute" + "yunion.io/x/cloudmux/pkg/cloudprovider" + "yunion.io/x/cloudmux/pkg/multicloud" + "yunion.io/x/pkg/errors" + + "yunion.io/x/jsonutils" +) + +type SHost struct { + multicloud.SHostBase + zone *SZone +} + +func (host *SHost) GetIVMs() ([]cloudprovider.ICloudVM, error) { + instances, err := host.zone.region.GetInstances(host.zone.GetName(), []string{}) + if err != nil { + return nil, err + } + ivms := make([]cloudprovider.ICloudVM, len(instances)) + for i := 0; i < len(instances); i += 1 { + instances[i].host = host + ivms[i] = &instances[i] + } + return ivms, nil +} + +func (host *SHost) GetIVMById(vmId string) (cloudprovider.ICloudVM, error) { + ins, err := host.zone.region.GetInstance(vmId) + if err != nil { + return nil, errors.Wrap(err, "GetInstance") + } + ins.host = host + return ins, nil +} + +func (host *SHost) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudprovider.ICloudVM, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (host *SHost) GetAccessIp() string { + return "" +} + +func (host *SHost) IsEmulated() bool { + return true +} + +func (host *SHost) GetAccessMac() string { + return "" +} + +func (host *SHost) GetName() string { + return host.zone.AvailabilityZone +} + +func (host *SHost) GetNodeCount() int8 { + return 0 +} + +func (host *SHost) GetSN() string { + return "" +} + +func (host *SHost) GetStatus() string { + return api.HOST_STATUS_RUNNING +} + +func (host *SHost) GetCpuCount() int { + return 0 +} + +func (host *SHost) GetCpuDesc() string { + return "" +} + +func (host *SHost) GetCpuMhz() int { + return 0 +} + +func (host *SHost) GetMemSizeMB() int { + return 0 +} + +func (host *SHost) GetStorageSizeMB() int64 { + return 0 +} + +func (host *SHost) GetStorageClass() string { + return "" +} + +func (host *SHost) GetStorageType() string { + return "" +} + +func (host *SHost) GetEnabled() bool { + return false +} + +func (host *SHost) GetIsMaintenance() bool { + return false +} + +func (host *SHost) GetGlobalId() string { + return host.zone.GetId() +} + +func (host *SHost) GetId() string { + return host.zone.GetId() +} + +func (host *SHost) GetHostStatus() string { + return api.HOST_STATUS_READY +} + +func (host *SHost) GetHostType() string { + return api.HOST_TYPE_KSYUN +} + +func (host *SHost) GetIHostNics() ([]cloudprovider.ICloudHostNetInterface, error) { + return nil, errors.ErrNotImplemented +} + +func (host *SHost) GetIStorageById(storageId string) (cloudprovider.ICloudStorage, error) { + return host.zone.GetIStorageById(storageId) +} + +func (host *SHost) GetIStorages() ([]cloudprovider.ICloudStorage, error) { + return host.zone.GetIStorages() +} + +func (host *SHost) GetSysInfo() jsonutils.JSONObject { + info := jsonutils.NewDict() + info.Add(jsonutils.NewString(CLOUD_PROVIDER_KSYUN_CN), "manufacture") + return info +} + +func (host *SHost) GetVersion() string { + return "" +} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/instancenic.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/instancenic.go new file mode 100644 index 0000000000..7fa04fddfa --- /dev/null +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/instancenic.go @@ -0,0 +1,68 @@ +// 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 ksyun + +import ( + "yunion.io/x/pkg/util/netutils" + + "yunion.io/x/cloudmux/pkg/cloudprovider" +) + +type SInstanceNic struct { + Instance *SInstance + Id string + IpAddr string + MacAddr string + + Classic bool + + cloudprovider.DummyICloudNic +} + +func (nic *SInstanceNic) GetId() string { + return nic.Id +} + +func (nic *SInstanceNic) GetIP() string { + return nic.IpAddr +} + +func (nic *SInstanceNic) GetMAC() string { + if len(nic.MacAddr) > 0 { + return nic.MacAddr + } + ip, _ := netutils.NewIPV4Addr(nic.GetIP()) + return ip.ToMac("00:16:") +} + +func (nic *SInstanceNic) InClassicNetwork() bool { + return nic.Classic +} + +func (nic *SInstanceNic) GetDriver() string { + return "virtio" +} + +func (nic *SInstanceNic) GetINetworkId() string { + return nic.Instance.SubnetID +} + +func (nic *SInstanceNic) AssignAddress(ipAddrs []string) error { + return cloudprovider.ErrNotImplemented +} + +func (nic *SInstanceNic) UnassignAddress(ipAddrs []string) error { + return cloudprovider.ErrNotImplemented +} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/instances.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/instances.go new file mode 100644 index 0000000000..4d46a40e84 --- /dev/null +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/instances.go @@ -0,0 +1,423 @@ +// 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 ksyun + +import ( + "context" + "fmt" + "time" + + billing_api "yunion.io/x/cloudmux/pkg/apis/billing" + api "yunion.io/x/cloudmux/pkg/apis/compute" + "yunion.io/x/cloudmux/pkg/cloudprovider" + "yunion.io/x/cloudmux/pkg/multicloud" + "yunion.io/x/jsonutils" + "yunion.io/x/pkg/errors" + "yunion.io/x/pkg/util/imagetools" + "yunion.io/x/pkg/utils" +) + +type SInstanceResp struct { + Marker int `json:"Marker"` + InstanceCount int `json:"InstanceCount"` + RequestID string `json:"RequestId"` + InstancesSet []SInstance `json:"InstancesSet"` +} + +type InstanceConfigure struct { + Vcpu int `json:"VCPU"` + Gpu int `json:"GPU"` + MemoryGb int `json:"MemoryGb"` + DataDiskGb int `json:"DataDiskGb"` + RootDiskGb int `json:"RootDiskGb"` + DataDiskType string `json:"DataDiskType"` + Vgpu string `json:"VGPU"` +} + +type InstanceState struct { + Name string `json:"Name"` + OnMigrate bool `json:"OnMigrate"` + CostTime string `json:"CostTime"` + TimeStamp string `json:"TimeStamp"` +} + +type Monitoring struct { + State string `json:"State"` +} + +type GroupSet struct { + GroupID string `json:"GroupId"` +} + +type InstanceSecurityGroupSet struct { + SecurityGroupID string `json:"SecurityGroupId"` +} + +type NetworkInterfaceSet struct { + AllocationId string `json:"AllocationId"` + NetworkInterfaceID string `json:"NetworkInterfaceId"` + NetworkInterfaceType string `json:"NetworkInterfaceType"` + VpcID string `json:"VpcId"` + SubnetID string `json:"SubnetId"` + MacAddress string `json:"MacAddress"` + PrivateIPAddress string `json:"PrivateIpAddress"` + GroupSet []GroupSet `json:"GroupSet"` + SecurityGroupSet []InstanceSecurityGroupSet `json:"SecurityGroupSet"` + NetworkInterfaceName string `json:"NetworkInterfaceName"` +} + +type SystemDisk struct { + DiskType string `json:"DiskType"` + DiskSize int `json:"DiskSize"` +} + +type DataDisks struct { + DiskID string `json:"DiskId"` + DiskType string `json:"DiskType"` + DiskSize int `json:"DiskSize"` + DeleteWithInstance bool `json:"DeleteWithInstance"` + Encrypted bool `json:"Encrypted"` +} + +type SInstance struct { + multicloud.SInstanceBase + SKsTag + host *SHost + + InstanceID string `json:"InstanceId"` + ProjectID string `json:"ProjectId"` + ShutdownNoCharge bool `json:"ShutdownNoCharge"` + IsDistributeIpv6 bool `json:"IsDistributeIpv6"` + InstanceName string `json:"InstanceName"` + InstanceType string `json:"InstanceType"` + InstanceConfigure InstanceConfigure `json:"InstanceConfigure"` + ImageID string `json:"ImageId"` + SubnetID string `json:"SubnetId"` + PrivateIPAddress string `json:"PrivateIpAddress"` + InstanceState InstanceState `json:"InstanceState"` + Monitoring Monitoring `json:"Monitoring"` + NetworkInterfaceSet []NetworkInterfaceSet `json:"NetworkInterfaceSet"` + SriovNetSupport string `json:"SriovNetSupport"` + IsShowSriovNetSupport bool `json:"IsShowSriovNetSupport"` + CreationDate time.Time `json:"CreationDate"` + AvailabilityZone string `json:"AvailabilityZone"` + AvailabilityZoneName string `json:"AvailabilityZoneName"` + DedicatedUUID string `json:"DedicatedUuid"` + ProductType int `json:"ProductType"` + ProductWhat int `json:"ProductWhat"` + LiveUpgradeSupport bool `json:"LiveUpgradeSupport"` + ChargeType string `json:"ChargeType"` + SystemDisk SystemDisk `json:"SystemDisk"` + HostName string `json:"HostName"` + UserData string `json:"UserData"` + Migration int `json:"Migration"` + DataDisks []DataDisks `json:"DataDisks"` + VncSupport bool `json:"VncSupport"` + Platform string `json:"Platform"` +} + +func (region *SRegion) GetInstances(zoneName string, instanceIds []string) ([]SInstance, error) { + instances := []SInstance{} + params := map[string]string{ + "MaxResults": "1000", + "Marker": "0", + } + if len(zoneName) > 0 { + params["Filter.1.Name"] = "availability-zone-name" + params["Filter.1.Value.1"] = zoneName + } + for i, v := range instanceIds { + params[fmt.Sprintf("%d", i+1)] = v + } + for { + resp, err := region.ecsRequest("DescribeInstances", params) + if err != nil { + return nil, errors.Wrap(err, "list instance") + } + part := SInstanceResp{} + err = resp.Unmarshal(&part) + if err != nil { + return nil, errors.Wrap(err, "unmarshal instances") + } + instances = append(instances, part.InstancesSet...) + if len(instances) >= part.InstanceCount { + break + } + params["Marker"] = fmt.Sprintf("%d", part.Marker) + } + + return instances, nil +} + +func (region *SRegion) GetInstance(instanceId string) (*SInstance, error) { + instances, err := region.GetInstances("", []string{instanceId}) + if err != nil { + return nil, errors.Wrap(err, "GetInstances") + } + for _, instance := range instances { + if instance.GetGlobalId() == instanceId { + return &instance, nil + } + } + return nil, errors.Wrapf(err, "instance id:%s", instanceId) +} + +func (ins *SInstance) Refresh() error { + extIns, err := ins.host.zone.region.GetInstance(ins.GetGlobalId()) + if err != nil { + return errors.Wrap(err, "GetInstance") + } + return jsonutils.Update(ins, extIns) +} + +func (ins *SInstance) AssignSecurityGroup(secgroupId string) error { + return cloudprovider.ErrNotImplemented +} + +func (ins *SInstance) AttachDisk(ctx context.Context, diskId string) error { + return cloudprovider.ErrNotImplemented +} + +func (ins *SInstance) ChangeConfig(ctx context.Context, config *cloudprovider.SManagedVMChangeConfig) error { + return cloudprovider.ErrNotImplemented +} + +func (ins *SInstance) DeleteVM(ctx context.Context) error { + return cloudprovider.ErrNotImplemented +} + +func (ins *SInstance) DetachDisk(ctx context.Context, diskId string) error { + return cloudprovider.ErrNotImplemented +} + +func (ins *SInstance) GetBios() cloudprovider.TBiosType { + return "" +} + +func (ins *SInstance) GetBootOrder() string { + return "" +} + +func (ins *SInstance) GetError() error { + return nil +} + +func (ins *SInstance) GetFullOsName() string { + return "" +} + +func (ins *SInstance) GetGlobalId() string { + return ins.InstanceID +} + +func (ins *SInstance) GetId() string { + return ins.InstanceID +} + +func (ins *SInstance) GetInstanceType() string { + return ins.InstanceType +} + +func (ins *SInstance) GetMachine() string { + return "pc" +} + +func (ins *SInstance) GetHostname() string { + return ins.HostName +} + +func (ins *SInstance) GetName() string { + return ins.InstanceName +} + +func (ins *SInstance) GetOsArch() string { + return "" +} + +func (ins *SInstance) GetOsDist() string { + return "" +} + +func (ins *SInstance) GetOsLang() string { + return "" +} + +func (ins *SInstance) GetOsType() cloudprovider.TOsType { + imageInfo := imagetools.NormalizeImageInfo("", "", "", ins.Platform, "") + return cloudprovider.TOsType(imageInfo.OsType) +} + +func (ins *SInstance) GetOsVersion() string { + return "" +} + +func (ins *SInstance) GetProjectId() string { + return ins.ProjectID +} + +func (ins *SInstance) GetSecurityGroupIds() ([]string, error) { + ids := []string{} + for _, netSet := range ins.NetworkInterfaceSet { + for _, secgroupSet := range netSet.SecurityGroupSet { + ids = append(ids, secgroupSet.SecurityGroupID) + } + } + return ids, nil +} + +func (ins *SInstance) GetStatus() string { + switch ins.InstanceState.Name { + case "active": + return api.VM_RUNNING + } + return ins.InstanceState.Name +} + +func (ins *SInstance) GetHypervisor() string { + return api.HYPERVISOR_KSYUN +} + +func (ins *SInstance) GetIDisks() ([]cloudprovider.ICloudDisk, error) { + disks, err := ins.host.zone.region.GetDiskByInstanceId(ins.GetId()) + if err != nil { + return nil, errors.Wrap(err, "getDisks") + } + res := []cloudprovider.ICloudDisk{} + for i := 0; i < len(disks); i++ { + res = append(res, &disks[i]) + } + return res, nil +} + +func (ins *SInstance) GetIEIP() (cloudprovider.ICloudEIP, error) { + eipIds := []string{} + for _, set := range ins.NetworkInterfaceSet { + eipIds = append(eipIds, set.AllocationId) + } + if len(eipIds) == 0 { + return nil, cloudprovider.ErrNotFound + } + eips, err := ins.host.zone.region.GetEips(eipIds) + if err != nil { + return nil, errors.Wrap(err, "get eips") + } + if len(eips) == 0 { + return nil, errors.ErrNotFound + } + for _, eip := range eips { + if utils.IsInStringArray(eip.GetId(), eipIds) { + eip.region = ins.host.zone.region + return &eip, nil + } + } + return nil, errors.Wrapf(err, "instanceId id:%s", ins.GetGlobalId()) +} + +func (ins *SInstance) GetINics() ([]cloudprovider.ICloudNic, error) { + nics := []cloudprovider.ICloudNic{} + for i := 0; i < len(ins.NetworkInterfaceSet); i++ { + nic := SInstanceNic{ + Instance: ins, + Id: ins.NetworkInterfaceSet[i].SubnetID, + IpAddr: ins.NetworkInterfaceSet[i].PrivateIPAddress, + MacAddr: ins.NetworkInterfaceSet[i].MacAddress, + } + nics = append(nics, &nic) + } + return nics, nil +} + +func (ins *SInstance) GetVNCInfo(input *cloudprovider.ServerVncInput) (*cloudprovider.ServerVncOutput, error) { + // TODO + resp, err := ins.host.zone.region.ecsRequest("GetVNCAddress", map[string]string{"InstanceId": ins.InstanceID}) + if err != nil { + return nil, errors.Wrap(err, "GetVNCAddress") + } + temp := struct { + VNCAddress struct { + Port string `json:"Port"` + Host string `json:"Host"` + } + Cookies []struct { + CookieKey string `json:"CookieKey"` + CookieValue string `json:"CookieValue"` + } `json:"Cookies"` + Domain string `json:"Domain"` + }{} + err = resp.Unmarshal(&temp) + if err != nil { + return nil, errors.Wrap(err, "unmarshal vnc info") + } + return nil, errors.ErrNotImplemented +} + +func (ins *SInstance) GetVcpuCount() int { + return ins.InstanceConfigure.Vcpu +} + +func (ins *SInstance) GetVmemSizeMB() int { + return ins.InstanceConfigure.MemoryGb * 1024 +} + +func (ins *SInstance) GetVdi() string { + return "" +} + +func (ins *SInstance) GetVga() string { + return "" +} + +func (ins *SInstance) RebuildRoot(ctx context.Context, config *cloudprovider.SManagedVMRebuildRootConfig) (string, error) { + return "", errors.ErrNotImplemented +} + +func (ins *SInstance) SetSecurityGroups(secgroupIds []string) error { + return errors.ErrNotImplemented +} + +func (ins *SInstance) StartVM(ctx context.Context) error { + return cloudprovider.ErrNotImplemented +} + +func (ins *SInstance) StopVM(ctx context.Context, opts *cloudprovider.ServerStopOptions) error { + return cloudprovider.ErrNotImplemented +} + +func (ins *SInstance) UpdateUserData(userData string) error { + return cloudprovider.ErrNotImplemented +} + +func (ins *SInstance) UpdateVM(ctx context.Context, input cloudprovider.SInstanceUpdateOptions) error { + return cloudprovider.ErrNotImplemented +} + +func (ins *SInstance) GetIHost() cloudprovider.ICloudHost { + return ins.host +} + +func (ins *SInstance) DeployVM(ctx context.Context, opts *cloudprovider.SInstanceDeployOptions) error { + return cloudprovider.ErrNotImplemented +} + +func (ins *SInstance) GetBillingType() string { + if ins.ChargeType == "Monthly" { + return billing_api.BILLING_TYPE_PREPAID + } + return billing_api.BILLING_TYPE_POSTPAID +} + +func (ins *SInstance) GetCreatedAt() time.Time { + return ins.CreationDate +} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/ksyun.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/ksyun.go index 3a42259f62..8d51aa36de 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/ksyun.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/ksyun.go @@ -71,14 +71,14 @@ func NewKsyunClientConfig(accessKeyId, accessKeySecret string) *KsyunClientConfi return cfg } -func (self *KsyunClientConfig) Debug(debug bool) *KsyunClientConfig { - self.debug = debug - return self +func (cli *KsyunClientConfig) Debug(debug bool) *KsyunClientConfig { + cli.debug = debug + return cli } -func (self *KsyunClientConfig) CloudproviderConfig(cpcfg cloudprovider.ProviderConfig) *KsyunClientConfig { - self.cpcfg = cpcfg - return self +func (cli *KsyunClientConfig) CloudproviderConfig(cpcfg cloudprovider.ProviderConfig) *KsyunClientConfig { + cli.cpcfg = cpcfg + return cli } func NewKsyunClient(cfg *KsyunClientConfig) (*SKsyunClient, error) { @@ -92,8 +92,8 @@ func NewKsyunClient(cfg *KsyunClientConfig) (*SKsyunClient, error) { return client, err } -func (self *SKsyunClient) GetRegions() ([]SRegion, error) { - resp, err := self.ec2Request("", "DescribeRegions", nil) +func (cli *SKsyunClient) GetRegions() ([]SRegion, error) { + resp, err := cli.ec2Request("", "DescribeRegions", nil) if err != nil { return nil, err } @@ -105,22 +105,22 @@ func (self *SKsyunClient) GetRegions() ([]SRegion, error) { return nil, err } for i := range ret.RegionSet { - ret.RegionSet[i].client = self + ret.RegionSet[i].client = cli } return ret.RegionSet, nil } -func (self *SKsyunClient) GetRegion(id string) (*SRegion, error) { - for i := range self.regions { - if self.regions[i].Region == id { - self.regions[i].client = self - return &self.regions[i], nil +func (cli *SKsyunClient) GetRegion(id string) (*SRegion, error) { + for i := range cli.regions { + if cli.regions[i].GetGlobalId() == id || cli.regions[i].GetId() == id { + cli.regions[i].client = cli + return &cli.regions[i], nil } } return nil, cloudprovider.ErrNotFound } -func (self *SKsyunClient) getUrl(service, regionId string) (string, error) { +func (cli *SKsyunClient) getUrl(service, regionId string) (string, error) { if len(regionId) == 0 { regionId = KSYUN_DEFAULT_REGION } @@ -129,6 +129,12 @@ func (self *SKsyunClient) getUrl(service, regionId string) (string, error) { return fmt.Sprintf("http://%s.api.ksyun.com", service), nil case "kec": return fmt.Sprintf("https://kec.%s.api.ksyun.com", regionId), nil + case "vpc": + return "http://vpc.api.ksyun.com", nil + case "ebs": + return "http://ebs.api.ksyun.com", nil + case "eip": + return "http://eip.api.ksyun.com", nil } return "", errors.Wrapf(cloudprovider.ErrNotSupported, "service %s", service) } @@ -173,19 +179,19 @@ type sKsyunError struct { } `json:"Error"` } -func (self *sKsyunError) Error() string { - return jsonutils.Marshal(self).String() +func (cli *sKsyunError) Error() string { + return jsonutils.Marshal(cli).String() } -func (self *sKsyunError) ParseErrorFromJsonResponse(statusCode int, status string, body jsonutils.JSONObject) error { +func (cli *sKsyunError) ParseErrorFromJsonResponse(statusCode int, status string, body jsonutils.JSONObject) error { if body != nil { - body.Unmarshal(self) + body.Unmarshal(cli) } - self.StatusCode = statusCode - return self + cli.StatusCode = statusCode + return cli } -func (self *SKsyunClient) sign(req *http.Request) (string, error) { +func (cli *SKsyunClient) sign(req *http.Request) (string, error) { query, err := url.ParseQuery(req.URL.RawQuery) if err != nil { return "", err @@ -206,15 +212,15 @@ func (self *SKsyunClient) sign(req *http.Request) (string, error) { } buf.Truncate(buf.Len() - 1) - hashed := hmac.New(sha256.New, []byte(self.accessKeySecret)) - hashed.Write([]byte(buf.String())) + hashed := hmac.New(sha256.New, []byte(cli.accessKeySecret)) + hashed.Write(buf.Bytes()) return hex.EncodeToString(hashed.Sum(nil)), nil } -func (self *SKsyunClient) Do(req *http.Request) (*http.Response, error) { - client := self.getDefaultClient() +func (cli *SKsyunClient) Do(req *http.Request) (*http.Response, error) { + client := cli.getDefaultClient() - signature, err := self.sign(req) + signature, err := cli.sign(req) if err != nil { return nil, errors.Wrapf(err, "sign") } @@ -230,25 +236,28 @@ func (self *SKsyunClient) Do(req *http.Request) (*http.Response, error) { return client.Do(req) } -func (self *SKsyunClient) ec2Request(regionId, apiName string, params map[string]string) (jsonutils.JSONObject, error) { - return self.request("kec", regionId, apiName, "2016-03-04", params) +func (cli *SKsyunClient) ec2Request(regionId, apiName string, params map[string]string) (jsonutils.JSONObject, error) { + return cli.request("kec", regionId, apiName, "2016-03-04", params) } -func (self *SKsyunClient) iamRequest(regionId, apiName string, params map[string]string) (jsonutils.JSONObject, error) { - return self.request("iam", regionId, apiName, "2015-11-01", params) +func (cli *SKsyunClient) iamRequest(regionId, apiName string, params map[string]string) (jsonutils.JSONObject, error) { + return cli.request("iam", regionId, apiName, "2015-11-01", params) } -func (self *SKsyunClient) request(service, regionId, apiName, apiVersion string, params map[string]string) (jsonutils.JSONObject, error) { - uri, err := self.getUrl(service, regionId) +func (cli *SKsyunClient) request(service, regionId, apiName, apiVersion string, params map[string]string) (jsonutils.JSONObject, error) { + uri, err := cli.getUrl(service, regionId) if err != nil { return nil, errors.Wrapf(err, "getUrl") } if params == nil { params = map[string]string{} } + if len(regionId) > 0 { + params["Region"] = regionId + } params["Action"] = apiName params["Version"] = apiVersion - params["Accesskey"] = self.accessKeyId + params["Accesskey"] = cli.accessKeyId params["SignatureMethod"] = "HMAC-SHA256" params["Service"] = service params["Format"] = "json" @@ -259,10 +268,14 @@ func (self *SKsyunClient) request(service, regionId, apiName, apiVersion string, values.Set(k, v) } uri = fmt.Sprintf("%s?%s", uri, values.Encode()) - req := httputils.NewJsonRequest(httputils.GET, uri, nil) + method := httputils.GET + if !strings.HasPrefix(apiName, "Describe") { + method = httputils.POST + } + req := httputils.NewJsonRequest(method, uri, nil) ksErr := &sKsyunError{} - client := httputils.NewJsonClient(self) - _, resp, err := client.Send(self.ctx, req, ksErr, self.debug) + client := httputils.NewJsonClient(cli) + _, resp, err := client.Send(cli.ctx, req, ksErr, cli.debug) if err != nil { return nil, err } @@ -276,21 +289,21 @@ func (self *SKsyunClient) request(service, regionId, apiName, apiVersion string, return resp, nil } -func (self *SKsyunClient) GetSubAccounts() ([]cloudprovider.SSubAccount, error) { +func (cli *SKsyunClient) GetSubAccounts() ([]cloudprovider.SSubAccount, error) { subAccount := cloudprovider.SSubAccount{} - subAccount.Id = self.GetAccountId() - subAccount.Name = self.cpcfg.Name - subAccount.Account = self.accessKeyId + subAccount.Id = cli.GetAccountId() + subAccount.Name = cli.cpcfg.Name + subAccount.Account = cli.accessKeyId subAccount.HealthStatus = api.CLOUD_PROVIDER_HEALTH_NORMAL return []cloudprovider.SSubAccount{subAccount}, nil } -func (self *SKsyunClient) GetAccountId() string { - if len(self.customerId) > 0 { - return self.customerId +func (cli *SKsyunClient) GetAccountId() string { + if len(cli.customerId) > 0 { + return cli.customerId } - self.QueryCashWalletAction() - return self.customerId + cli.QueryCashWalletAction() + return cli.customerId } type CashWalletDetail struct { @@ -301,8 +314,8 @@ type CashWalletDetail struct { Currency string } -func (self *SKsyunClient) QueryCashWalletAction() (*CashWalletDetail, error) { - resp, err := self.request("kingpay", "", "QueryCashWalletAction", "V1", nil) +func (cli *SKsyunClient) QueryCashWalletAction() (*CashWalletDetail, error) { + resp, err := cli.request("kingpay", "", "QueryCashWalletAction", "V1", nil) if err != nil { return nil, err } @@ -311,11 +324,11 @@ func (self *SKsyunClient) QueryCashWalletAction() (*CashWalletDetail, error) { if err != nil { return nil, errors.Wrapf(err, "resp.Unmarshal") } - self.customerId = ret.CustomerId + cli.customerId = ret.CustomerId return ret, nil } -func (self *SKsyunClient) GetCapabilities() []string { +func (cli *SKsyunClient) GetCapabilities() []string { caps := []string{ cloudprovider.CLOUD_CAPABILITY_COMPUTE + cloudprovider.READ_ONLY_SUFFIX, cloudprovider.CLOUD_CAPABILITY_CLOUDID, diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/network.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/network.go new file mode 100644 index 0000000000..96ec7fa19e --- /dev/null +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/network.go @@ -0,0 +1,195 @@ +// 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 ksyun + +import ( + "fmt" + + api "yunion.io/x/cloudmux/pkg/apis/compute" + "yunion.io/x/cloudmux/pkg/cloudprovider" + "yunion.io/x/cloudmux/pkg/multicloud" + "yunion.io/x/jsonutils" + "yunion.io/x/pkg/errors" + "yunion.io/x/pkg/util/netutils" + "yunion.io/x/pkg/util/rbacscope" +) + +type SNetworkResp struct { + SubnetSet []SNetwork `json:"SubnetSet"` + RequestID string `json:"RequestId"` + NextToken string `json:"NextToken"` +} + +type SNetwork struct { + multicloud.SNetworkBase + SKsTag + wire *SWire + + RouteTableID string `json:"RouteTableId"` + NetworkACLID string `json:"NetworkAclId"` + NatID string `json:"NatId"` + CreateTime string `json:"CreateTime"` + DhcpIPTo string `json:"DhcpIpTo"` + DNS1 string `json:"Dns1"` + CidrBlock string `json:"CidrBlock"` + DNS2 string `json:"Dns2"` + ProvidedIpv6CidrBlock bool `json:"ProvidedIpv6CidrBlock"` + SubnetID string `json:"SubnetId"` + SubnetType string `json:"SubnetType"` + SubnetName string `json:"SubnetName"` + VpcID string `json:"VpcId"` + GatewayIP string `json:"GatewayIp"` + AvailabilityZoneName string `json:"AvailabilityZoneName"` + DhcpIPFrom string `json:"DhcpIpFrom"` + AvailableIPNumber int `json:"AvailableIpNumber"` + SecondaryCidrID string `json:"SecondaryCidrId"` +} + +func (region *SRegion) GetNetworks(vpcIds, networkIds []string, zoneName string) ([]SNetwork, error) { + networks := []SNetwork{} + param := map[string]string{} + searchIndex := 1 + if len(vpcIds) > 0 { + param[fmt.Sprintf("Filter.%d.Name", searchIndex)] = "vpc-id" + for i, vpcId := range vpcIds { + param[fmt.Sprintf("Filter.%d.Value.%d", searchIndex, i+1)] = vpcId + } + searchIndex++ + } + + if len(zoneName) > 0 { + param[fmt.Sprintf("Filter.%d.Name", searchIndex)] = "availability-zone-name" + param[fmt.Sprintf("Filter.%d.Value.%d", searchIndex, 1)] = zoneName + searchIndex++ + } + + for i, networkId := range networkIds { + param[fmt.Sprintf("SubnetId.%d", i+1)] = networkId + } + for { + resp, err := region.vpcRequest("DescribeSubnets", param) + if err != nil { + return nil, errors.Wrap(err, "list networks") + } + res := SNetworkResp{} + err = resp.Unmarshal(&res) + if err != nil { + return nil, errors.Wrap(err, "unmarshal instances") + } + networks = append(networks, res.SubnetSet...) + if len(res.NextToken) == 0 { + break + } + param["NextToken"] = res.NextToken + } + + return networks, nil +} + +func (region *SRegion) GetNetwork(networkId string) (*SNetwork, error) { + extNetworks, err := region.GetNetworks(nil, []string{networkId}, "") + if err != nil { + return nil, errors.Wrap(err, "GetNetworks") + } + for _, extNetwork := range extNetworks { + if extNetwork.GetGlobalId() == networkId { + return &extNetwork, nil + } + } + return nil, errors.Wrapf(errors.ErrNotFound, "network id:%s", networkId) +} + +func (net *SNetwork) GetId() string { + return net.SubnetID +} + +func (net *SNetwork) GetName() string { + if len(net.SubnetName) == 0 { + return net.SubnetID + } + + return net.SubnetName +} + +func (net *SNetwork) GetGlobalId() string { + return net.SubnetID +} + +func (net *SNetwork) GetStatus() string { + return api.NETWORK_STATUS_AVAILABLE +} + +func (net *SNetwork) Refresh() error { + extNet, err := net.wire.zone.region.GetNetwork(net.GetGlobalId()) + if err != nil { + return errors.Wrap(err, "GetNetwork") + } + return jsonutils.Update(net, extNet) +} + +func (net *SNetwork) GetIWire() cloudprovider.ICloudWire { + return net.wire +} + +func (net *SNetwork) GetIpStart() string { + pref, _ := netutils.NewIPV4Prefix(net.CidrBlock) + startIp := pref.Address.NetAddr(pref.MaskLen) // 0 + startIp = startIp.StepUp() // 1 + return startIp.String() +} + +func (net *SNetwork) GetIpEnd() string { + pref, _ := netutils.NewIPV4Prefix(net.CidrBlock) + endIp := pref.Address.BroadcastAddr(pref.MaskLen) // 255 + endIp = endIp.StepDown() // 254 + return endIp.String() +} + +func (net *SNetwork) GetIpMask() int8 { + pref, _ := netutils.NewIPV4Prefix(net.CidrBlock) + return pref.MaskLen +} + +func (net *SNetwork) GetGateway() string { + return net.GatewayIP +} + +func (net *SNetwork) GetServerType() string { + return api.NETWORK_TYPE_GUEST +} + +func (net *SNetwork) GetIsPublic() bool { + return true +} + +func (net *SNetwork) GetPublicScope() rbacscope.TRbacScope { + return rbacscope.ScopeDomain +} + +func (net *SNetwork) Delete() error { + return cloudprovider.ErrNotImplemented +} + +func (net *SNetwork) GetAllocTimeoutSeconds() int { + return 120 // 2 minutes +} + +func (net *SNetwork) GetProjectId() string { + return "" +} + +func (net *SNetwork) GetDescription() string { + return "" +} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/policy.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/policy.go index 54cba9dde7..ceb46ae5fe 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/policy.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/policy.go @@ -88,14 +88,14 @@ func (policy *SPolicy) GetDocument() (*jsonutils.JSONDict, error) { return obj.(*jsonutils.JSONDict), nil } -func (self *SKsyunClient) GetICloudpolicies() ([]cloudprovider.ICloudpolicy, error) { - policies, err := self.ListPolicies("") +func (client *SKsyunClient) GetICloudpolicies() ([]cloudprovider.ICloudpolicy, error) { + policies, err := client.ListPolicies("") if err != nil { return nil, err } ret := []cloudprovider.ICloudpolicy{} for i := range policies { - policies[i].client = self + policies[i].client = client ret = append(ret, &policies[i]) } return ret, nil diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/region.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/region.go index 7dd725aaa2..46f300076f 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/region.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/region.go @@ -20,6 +20,8 @@ import ( api "yunion.io/x/cloudmux/pkg/apis/compute" "yunion.io/x/cloudmux/pkg/cloudprovider" "yunion.io/x/cloudmux/pkg/multicloud" + "yunion.io/x/jsonutils" + "yunion.io/x/pkg/errors" ) type SRegion struct { @@ -32,55 +34,55 @@ type SRegion struct { RegionName string } -func (self *SRegion) GetId() string { - return self.Region +func (region *SRegion) GetId() string { + return region.Region } -func (self *SRegion) GetGlobalId() string { - return fmt.Sprintf("%s/%s", api.CLOUD_PROVIDER_KSYUN, self.Region) +func (region *SRegion) GetGlobalId() string { + return fmt.Sprintf("%s/%s", api.CLOUD_PROVIDER_KSYUN, region.Region) } -func (self *SRegion) GetProvider() string { +func (region *SRegion) GetProvider() string { return api.CLOUD_PROVIDER_KSYUN } -func (self *SRegion) GetCloudEnv() string { +func (region *SRegion) GetCloudEnv() string { return api.CLOUD_PROVIDER_KSYUN } -func (self *SRegion) GetGeographicInfo() cloudprovider.SGeographicInfo { +func (region *SRegion) GetGeographicInfo() cloudprovider.SGeographicInfo { geo, ok := map[string]cloudprovider.SGeographicInfo{ "cn-northwest-1": api.RegionQingYang, "ap-singapore-1": api.RegionSingapore, "cn-beijing-6": api.RegionBeijing, "cn-guangzhou-1": api.RegionGuangzhou, "cn-shanghai-2": api.RegionShanghai, - }[self.Region] + }[region.Region] if ok { return geo } return cloudprovider.SGeographicInfo{} } -func (self *SRegion) GetName() string { - return self.RegionName +func (region *SRegion) GetName() string { + return region.RegionName } -func (self *SRegion) GetI18n() cloudprovider.SModelI18nTable { +func (region *SRegion) GetI18n() cloudprovider.SModelI18nTable { table := cloudprovider.SModelI18nTable{} - table["name"] = cloudprovider.NewSModelI18nEntry(self.GetName()).CN(self.GetName()).EN(self.Region) + table["name"] = cloudprovider.NewSModelI18nEntry(region.GetName()).CN(region.GetName()).EN(region.Region) return table } -func (self *SRegion) GetStatus() string { +func (region *SRegion) GetStatus() string { return api.CLOUD_REGION_STATUS_INSERVER } -func (self *SRegion) GetClient() *SKsyunClient { - return self.client +func (region *SRegion) GetClient() *SKsyunClient { + return region.client } -func (self *SRegion) CreateEIP(opts *cloudprovider.SEip) (cloudprovider.ICloudEIP, error) { +func (region *SRegion) CreateEIP(opts *cloudprovider.SEip) (cloudprovider.ICloudEIP, error) { return nil, cloudprovider.ErrNotImplemented } @@ -88,38 +90,166 @@ func (region *SRegion) CreateISecurityGroup(conf *cloudprovider.SecurityGroupCre return nil, cloudprovider.ErrNotImplemented } -func (region *SRegion) GetISecurityGroupById(secgroupId string) (cloudprovider.ICloudSecurityGroup, error) { +func (region *SRegion) CreateIVpc(opts *cloudprovider.VpcCreateOptions) (cloudprovider.ICloudVpc, error) { return nil, cloudprovider.ErrNotImplemented } -func (self *SRegion) CreateIVpc(opts *cloudprovider.VpcCreateOptions) (cloudprovider.ICloudVpc, error) { - return nil, cloudprovider.ErrNotImplemented +func (region *SRegion) GetIVpcs() ([]cloudprovider.ICloudVpc, error) { + vpcs, err := region.GetVpcs([]string{}) + if err != nil { + return nil, errors.Wrap(err, "GetVpcs") + } + res := []cloudprovider.ICloudVpc{} + for i := 0; i < len(vpcs); i++ { + vpcs[i].region = region + res = append(res, &vpcs[i]) + } + return res, nil } -func (self *SRegion) GetIVpcs() ([]cloudprovider.ICloudVpc, error) { - return nil, cloudprovider.ErrNotImplemented -} - -func (self *SRegion) GetIVpcById(id string) (cloudprovider.ICloudVpc, error) { - return nil, cloudprovider.ErrNotImplemented +func (region *SRegion) GetIVpcById(id string) (cloudprovider.ICloudVpc, error) { + vpc, err := region.GetVpc(id) + if err != nil { + return nil, errors.Wrap(err, "region.GetVpc") + } + vpc.region = region + return vpc, nil } func (region *SRegion) GetCapabilities() []string { return region.client.GetCapabilities() } -func (self *SRegion) GetIEipById(eipId string) (cloudprovider.ICloudEIP, error) { - return nil, cloudprovider.ErrNotImplemented +func (region *SRegion) GetISecurityGroupById(secgroupId string) (cloudprovider.ICloudSecurityGroup, error) { + group, err := region.GetSecurityGroup(secgroupId) + if err != nil { + return nil, errors.Wrap(err, "region.GetSecurityGroup") + } + group.region = region + return group, nil } -func (self *SRegion) GetIEips() ([]cloudprovider.ICloudEIP, error) { - return nil, cloudprovider.ErrNotImplemented +func (region *SRegion) GetIEipById(eipId string) (cloudprovider.ICloudEIP, error) { + eip, err := region.GetEip(eipId) + if err != nil { + return nil, errors.Wrap(err, "GetEipById") + } + eip.region = region + return eip, nil } -func (self *SRegion) GetIZones() ([]cloudprovider.ICloudZone, error) { - return nil, cloudprovider.ErrNotImplemented +func (region *SRegion) GetIHosts() ([]cloudprovider.ICloudHost, error) { + zones, err := region.GetIZones() + if err != nil { + return nil, errors.Wrap(err, "GetIZones") + } + hosts := []cloudprovider.ICloudHost{} + for _, zone := range zones { + zoneHosts, err := zone.GetIHosts() + if err != nil { + return nil, errors.Wrap(err, "zone.GetIHosts") + } + hosts = append(hosts, zoneHosts...) + } + return hosts, nil } -func (self *SRegion) GetIZoneById(id string) (cloudprovider.ICloudZone, error) { - return nil, cloudprovider.ErrNotImplemented +func (region *SRegion) GetIHostById(id string) (cloudprovider.ICloudHost, error) { + hosts, err := region.GetIHosts() + if err != nil { + return nil, err + } + for _, host := range hosts { + if host.GetId() == id { + return host, nil + } + } + return nil, errors.ErrNotFound +} + +func (region *SRegion) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) { + zones, err := region.GetIZones() + if err != nil { + return nil, errors.Wrap(err, "region.GetIZones") + } + for _, zone := range zones { + storage, err := zone.GetIStorageById(id) + if err == nil { + return storage, nil + } else if errors.Cause(err) != cloudprovider.ErrNotFound { + return nil, errors.Wrap(err, "GetIStorageById") + } + } + return nil, errors.ErrNotFound +} + +func (region *SRegion) GetIEips() ([]cloudprovider.ICloudEIP, error) { + eips, err := region.GetEips([]string{}) + if err != nil { + return nil, errors.Wrap(err, "GetEips") + } + res := []cloudprovider.ICloudEIP{} + for i := 0; i < len(eips); i++ { + eips[i].region = region + res = append(res, &eips[i]) + } + return res, nil +} + +func (region *SRegion) GetIZones() ([]cloudprovider.ICloudZone, error) { + zones, err := region.GetZones() + if err != nil { + return nil, errors.Wrap(err, "GetZones") + } + res := []cloudprovider.ICloudZone{} + for i := 0; i < len(zones); i++ { + zones[i].region = region + res = append(res, &zones[i]) + } + return res, nil +} + +func (region *SRegion) GetIZoneById(id string) (cloudprovider.ICloudZone, error) { + izones, err := region.GetIZones() + if err != nil { + return nil, errors.Wrap(err, "GetIZones") + } + for _, izone := range izones { + if izone.GetGlobalId() == id { + return izone, nil + } + } + return nil, errors.Wrapf(cloudprovider.ErrNotFound, "zone id:%s", id) +} + +func (region *SRegion) GetIStorages() ([]cloudprovider.ICloudStorage, error) { + iStores := make([]cloudprovider.ICloudStorage, 0) + izones, err := region.GetIZones() + if err != nil { + return nil, err + } + for _, izone := range izones { + iZoneStores, err := izone.GetIStorages() + if err != nil { + return nil, err + } + iStores = append(iStores, iZoneStores...) + } + return iStores, nil +} + +func (region *SRegion) ecsRequest(action string, params map[string]string) (jsonutils.JSONObject, error) { + return region.client.request("kec", region.Region, action, "2016-03-04", params) +} + +func (region *SRegion) eipRequest(action string, params map[string]string) (jsonutils.JSONObject, error) { + return region.client.request("eip", region.Region, action, "2016-03-04", params) +} + +func (region *SRegion) ebsRequest(action string, params map[string]string) (jsonutils.JSONObject, error) { + return region.client.request("ebs", region.Region, action, "2016-03-04", params) +} + +func (region *SRegion) vpcRequest(action string, params map[string]string) (jsonutils.JSONObject, error) { + return region.client.request("vpc", region.Region, action, "2016-03-04", params) } diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/secgroup_rules.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/secgroup_rules.go new file mode 100644 index 0000000000..1788802aae --- /dev/null +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/secgroup_rules.go @@ -0,0 +1,90 @@ +// 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 ksyun + +import ( + "fmt" + + "yunion.io/x/cloudmux/pkg/cloudprovider" + "yunion.io/x/pkg/errors" + "yunion.io/x/pkg/util/secrules" +) + +type SPermission struct { + region *SRegion + + Policy string `json:"Policy"` + PortRangeTo int `json:"PortRangeTo"` + Description string `json:"Description"` + IcmpCode int `json:"IcmpCode"` + IcmpType int `json:"IcmpType"` + Priority int `json:"Priority"` + CreateTime string `json:"CreateTime"` + CidrBlock string `json:"CidrBlock"` + Direction string `json:"Direction"` + PortRangeFrom int `json:"PortRangeFrom"` + SecurityGroupEntryID string `json:"SecurityGroupEntryId"` + RuleTag string `json:"RuleTag"` + Protocol string `json:"Protocol"` +} + +func (rule *SPermission) GetGlobalId() string { + return rule.SecurityGroupEntryID +} + +func (rule *SPermission) GetDirection() secrules.TSecurityRuleDirection { + return secrules.TSecurityRuleDirection(rule.Direction) +} + +func (rule *SPermission) GetPriority() int { + return rule.Priority +} + +func (rule *SPermission) GetAction() secrules.TSecurityRuleAction { + if rule.Policy == "Drop" { + return secrules.SecurityRuleDeny + } + return secrules.SecurityRuleAllow +} + +func (rule *SPermission) GetProtocol() string { + return rule.Protocol +} + +func (rule *SPermission) GetPorts() string { + if rule.PortRangeFrom > 0 && rule.PortRangeTo > 0 { + if rule.PortRangeFrom == rule.PortRangeTo { + return fmt.Sprintf("%d", rule.PortRangeFrom) + } + return fmt.Sprintf("%d-%d", rule.PortRangeFrom, rule.PortRangeTo) + } + return "" +} + +func (rule *SPermission) GetDescription() string { + return rule.Description +} + +func (rule *SPermission) GetCIDRs() []string { + return []string{rule.CidrBlock} +} + +func (rule *SPermission) Update(opts *cloudprovider.SecurityGroupRuleUpdateOptions) error { + return errors.ErrNotImplemented +} + +func (rule *SPermission) Delete() error { + return errors.ErrNotImplemented +} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/securitygroup.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/securitygroup.go new file mode 100644 index 0000000000..cb61614e3d --- /dev/null +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/securitygroup.go @@ -0,0 +1,209 @@ +// 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 ksyun + +import ( + "fmt" + + "yunion.io/x/jsonutils" + "yunion.io/x/pkg/errors" + + api "yunion.io/x/cloudmux/pkg/apis/compute" + "yunion.io/x/cloudmux/pkg/cloudprovider" + "yunion.io/x/cloudmux/pkg/multicloud" +) + +type SecurityGroupPermissionNicType string + +const ( + IntranetNicType SecurityGroupPermissionNicType = "intranet" + InternetNicType SecurityGroupPermissionNicType = "internet" +) + +type SSecurityGroup struct { + multicloud.SSecurityGroup + SKsTag + region *SRegion + + CreateTime string `json:"CreateTime"` + ProductTag string `json:"ProductTag"` + SecurityGroupEntrySet []SPermission `json:"SecurityGroupEntrySet"` + SecurityGroupID string `json:"SecurityGroupId"` + SecurityGroupName string `json:"SecurityGroupName"` + SecurityGroupType string `json:"SecurityGroupType"` + UserTag string `json:"UserTag"` + VpcID string `json:"VpcId"` +} + +type SecurityGroupEntrySet struct { + CidrBlock string `json:"CidrBlock"` + CreateTime string `json:"CreateTime"` + Direction string `json:"Direction"` + IcmpCode int `json:"IcmpCode,omitempty"` + IcmpType int `json:"IcmpType,omitempty"` + Policy string `json:"Policy"` + Priority int `json:"Priority"` + ProductTag string `json:"ProductTag"` + Protocol string `json:"Protocol"` + RuleTag string `json:"RuleTag,omitempty"` + SecurityGroupEntryID string `json:"SecurityGroupEntryId"` + UserTag string `json:"UserTag"` + PortRangeFrom int `json:"PortRangeFrom,omitempty"` + PortRangeTo int `json:"PortRangeTo,omitempty"` +} + +func (secgroup *SSecurityGroup) GetVpcId() string { + return secgroup.VpcID +} + +func (secgroup *SSecurityGroup) GetId() string { + return secgroup.SecurityGroupID +} + +func (secgroup *SSecurityGroup) GetGlobalId() string { + return secgroup.SecurityGroupID +} + +func (secgroup *SSecurityGroup) GetRules() ([]cloudprovider.ISecurityGroupRule, error) { + ret := make([]cloudprovider.ISecurityGroupRule, 0) + for i := range secgroup.SecurityGroupEntrySet { + secgroup.SecurityGroupEntrySet[i].region = secgroup.region + ret = append(ret, &secgroup.SecurityGroupEntrySet[i]) + } + return ret, nil +} + +func (secgroup *SSecurityGroup) GetName() string { + if len(secgroup.SecurityGroupName) > 0 { + return secgroup.SecurityGroupName + } + return secgroup.SecurityGroupID +} + +func (secgroup *SSecurityGroup) GetStatus() string { + return api.SECGROUP_STATUS_READY +} + +func (secgroup *SSecurityGroup) Refresh() error { + group, err := secgroup.region.GetSecurityGroup(secgroup.SecurityGroupID) + if err != nil { + return err + } + return jsonutils.Update(secgroup, group) +} + +func (secgroup *SSecurityGroup) GetReferences() ([]cloudprovider.SecurityGroupReference, error) { + references, err := secgroup.region.DescribeSecurityGroupReferences(secgroup.SecurityGroupID) + if err != nil { + return nil, errors.Wrapf(err, "DescribeSecurityGroupReferences") + } + ret := []cloudprovider.SecurityGroupReference{} + for _, reference := range references { + if reference.SecurityGroupId == secgroup.SecurityGroupID { + for _, sec := range reference.ReferencingSecurityGroups.ReferencingSecurityGroup { + ret = append(ret, cloudprovider.SecurityGroupReference{ + Id: sec.SecurityGroupId, + }) + } + } + } + return ret, nil +} + +type ReferencingSecurityGroup struct { + AliUid string + SecurityGroupId string +} + +type ReferencingSecurityGroups struct { + ReferencingSecurityGroup []ReferencingSecurityGroup +} + +type SecurityGroupReferences struct { + SecurityGroupId string + ReferencingSecurityGroups ReferencingSecurityGroups +} + +func (region *SRegion) DescribeSecurityGroupReferences(id string) ([]SecurityGroupReferences, error) { + return nil, errors.ErrNotImplemented +} + +func (region *SRegion) GetSecurityGroups(vpcId string, securityGroupIds []string) ([]SSecurityGroup, error) { + ret := []SSecurityGroup{} + params := map[string]string{ + "MaxResults": "1000", + } + if len(vpcId) > 0 { + params["Filter.1.Name"] = "vpc-id" + params["Filter.1.Value.1"] = vpcId + } + for i, secgroupId := range securityGroupIds { + params[fmt.Sprintf("SecurityGroupId.%d", i+1)] = secgroupId + } + + for { + secgroupResp := struct { + RequestID string `json:"RequestId"` + SecurityGroupSet []SSecurityGroup `json:"SecurityGroupSet"` + NextToken string `json:"NextToken"` + }{} + resp, err := region.vpcRequest("DescribeSecurityGroups", params) + if err != nil { + return nil, errors.Wrap(err, "DescribeSecurityGroups") + } + err = resp.Unmarshal(&secgroupResp) + if err != nil { + return nil, errors.Wrap(err, "unmarshal secgroups") + } + ret = append(ret, secgroupResp.SecurityGroupSet...) + if len(secgroupResp.NextToken) == 0 { + break + } + params["NextToken"] = secgroupResp.NextToken + } + + return ret, nil +} + +func (region *SRegion) GetSecurityGroup(id string) (*SSecurityGroup, error) { + groups, err := region.GetSecurityGroups("", []string{id}) + if err != nil { + return nil, err + } + for _, group := range groups { + return &group, nil + } + return nil, errors.Wrapf(cloudprovider.ErrNotFound, "security_group id:%s", id) +} + +func (region *SRegion) CreateSecurityGroup(opts *cloudprovider.SecurityGroupCreateInput) (string, error) { + return "", errors.ErrNotImplemented +} + +func (region *SRegion) SetSecurityGroups(secgroupIds []string, instanceId string) error { + return errors.ErrNotImplemented +} + +func (region *SRegion) DeleteSecurityGroup(secGrpId string) error { + return errors.ErrNotImplemented +} + +func (region *SSecurityGroup) GetProjectId() string { + return "" +} + +func (sg *SSecurityGroup) Delete() error { + return errors.ErrNotImplemented +} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/storages.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/storages.go new file mode 100644 index 0000000000..c61e9669d7 --- /dev/null +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/storages.go @@ -0,0 +1,135 @@ +// 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 ksyun + +import ( + "fmt" + "strings" + + api "yunion.io/x/cloudmux/pkg/apis/compute" + "yunion.io/x/cloudmux/pkg/cloudprovider" + "yunion.io/x/cloudmux/pkg/multicloud" + "yunion.io/x/pkg/errors" + + "yunion.io/x/jsonutils" +) + +type SStorage struct { + multicloud.SStorageBase + + zone *SZone + StorageType string +} + +var ksDiskTypes = []string{"ESSD_PL1", "ESSD_PL2", "ESSD_PL3", "SSD3.0", "EHDD"} + +func (storage *SStorage) GetId() string { + return fmt.Sprintf("%s-%s-%s", storage.zone.region.client.cpcfg.Id, storage.zone.GetId(), storage.StorageType) +} + +func (storage *SStorage) GetName() string { + return fmt.Sprintf("%s-%s-%s", storage.zone.region.client.cpcfg.Name, storage.zone.GetId(), storage.StorageType) +} + +func (storage *SStorage) GetGlobalId() string { + return fmt.Sprintf("%s-%s-%s", storage.zone.region.client.cpcfg.Id, storage.zone.GetGlobalId(), storage.StorageType) +} + +func (storage *SStorage) IsEmulated() bool { + return true +} + +func (storage *SStorage) GetIZone() cloudprovider.ICloudZone { + return storage.zone +} + +func (storage *SStorage) GetIDisks() ([]cloudprovider.ICloudDisk, error) { + disks, err := storage.zone.region.GetDisks(nil, storage.StorageType, storage.zone.GetId()) + if err != nil { + return nil, errors.Wrap(err, "region.GetDisks") + } + ret := []cloudprovider.ICloudDisk{} + for i := range disks { + disks[i].storage = storage + ret = append(ret, &disks[i]) + } + return ret, nil +} + +func (storage *SStorage) GetStorageType() string { + return storage.StorageType +} + +func (storage *SStorage) GetMediumType() string { + if strings.Contains(storage.StorageType, "SSD") { + return api.DISK_TYPE_SSD + } else { + return api.DISK_TYPE_ROTATE + } +} + +func (storage *SStorage) GetCapacityMB() int64 { + return 0 +} + +func (storage *SStorage) GetCapacityUsedMB() int64 { + return 0 +} + +func (storage *SStorage) GetStorageConf() jsonutils.JSONObject { + return jsonutils.NewDict() +} + +func (storage *SStorage) GetEnabled() bool { + return true +} + +func (storage *SStorage) CreateIDisk(conf *cloudprovider.DiskCreateConfig) (cloudprovider.ICloudDisk, error) { + return nil, cloudprovider.ErrNotSupported +} + +func (storage *SStorage) GetIDiskById(id string) (cloudprovider.ICloudDisk, error) { + disks, err := storage.zone.region.GetDisks([]string{id}, "", storage.zone.GetId()) + if err != nil { + return nil, err + } + for _, disk := range disks { + if disk.GetId() == id { + disk.storage = storage + return &disk, nil + } + } + return nil, errors.Wrapf(cloudprovider.ErrNotFound, "disk id:%s", id) +} + +func (storage *SStorage) GetMountPoint() string { + return "" +} + +func (storage *SStorage) IsSysDiskStore() bool { + return true +} + +func (storage *SStorage) DisableSync() bool { + return false +} + +func (storage *SStorage) GetIStoragecache() cloudprovider.ICloudStoragecache { + return nil +} + +func (storage *SStorage) GetStatus() string { + return api.STORAGE_ONLINE +} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/tag_base.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/tag_base.go new file mode 100644 index 0000000000..0925574fc0 --- /dev/null +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/tag_base.go @@ -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 ksyun + +type SKsTag struct{} + +func (tag SKsTag) GetName() string { + return "" +} + +func (tag SKsTag) GetDescription() string { + return "" +} + +func (tag *SKsTag) GetTags() (map[string]string, error) { + return nil, nil +} + +func (tag *SKsTag) GetSysTags() map[string]string { + return nil +} + +func (tag *SKsTag) SetTags(tags map[string]string, replace bool) error { + return nil +} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/user.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/user.go index 7d702ba5bb..232aaa8b51 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/user.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/user.go @@ -102,13 +102,13 @@ func (user *SUser) ResetPassword(password string) error { return user.client.UpdateLoginProfile(user.UserName, password) } -func (self *SKsyunClient) UpdateLoginProfile(name, password string) error { +func (client *SKsyunClient) UpdateLoginProfile(name, password string) error { params := map[string]string{ "UserName": name, "Password": password, "ViewAllProject": "true", } - _, err := self.iamRequest("", "UpdateLoginProfile", params) + _, err := client.iamRequest("", "UpdateLoginProfile", params) return err } @@ -118,11 +118,11 @@ type LoginProfile struct { LastLoginDate time.Time } -func (self *SKsyunClient) GetLoginProfile(name string) (*LoginProfile, error) { +func (client *SKsyunClient) GetLoginProfile(name string) (*LoginProfile, error) { params := map[string]string{ "UserName": name, } - resp, err := self.iamRequest("", "GetLoginProfile", params) + resp, err := client.iamRequest("", "GetLoginProfile", params) if err != nil { return nil, err } @@ -171,11 +171,11 @@ func (client *SKsyunClient) GetUsers() ([]SUser, error) { return ret, nil } -func (self *SKsyunClient) DeleteUser(name string) error { +func (client *SKsyunClient) DeleteUser(name string) error { params := map[string]string{ "UserName": name, } - _, err := self.iamRequest("", "DeleteUser", params) + _, err := client.iamRequest("", "DeleteUser", params) return err } @@ -200,7 +200,7 @@ func (client *SKsyunClient) CreateIClouduser(opts *cloudprovider.SClouduserCreat return user, nil } -func (self *SKsyunClient) CreateUser(opts *cloudprovider.SClouduserCreateConfig) (*SUser, error) { +func (client *SKsyunClient) CreateUser(opts *cloudprovider.SClouduserCreateConfig) (*SUser, error) { params := map[string]string{ "UserName": opts.Name, "Remark": opts.Desc, @@ -208,11 +208,11 @@ func (self *SKsyunClient) CreateUser(opts *cloudprovider.SClouduserCreateConfig) "Phone": opts.MobilePhone, "Password": opts.Password, } - resp, err := self.iamRequest("", "CreateUser", params) + resp, err := client.iamRequest("", "CreateUser", params) if err != nil { return nil, err } - ret := &SUser{client: self} + ret := &SUser{client: client} err = resp.Unmarshal(ret, "User") if err != nil { return nil, err diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/vpc.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/vpc.go new file mode 100644 index 0000000000..3934e2f996 --- /dev/null +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/vpc.go @@ -0,0 +1,210 @@ +// 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 ksyun + +import ( + "fmt" + + api "yunion.io/x/cloudmux/pkg/apis/compute" + "yunion.io/x/cloudmux/pkg/cloudprovider" + "yunion.io/x/cloudmux/pkg/multicloud" + "yunion.io/x/jsonutils" + + "yunion.io/x/pkg/errors" +) + +type SVpc struct { + multicloud.SVpc + SKsTag + + region *SRegion + + IsDefault bool `json:"IsDefault"` + VpcID string `json:"VpcId"` + CreateTime string `json:"CreateTime"` + CidrBlock string `json:"CidrBlock"` + VpcName string `json:"VpcName"` + ProvidedIpv6CidrBlock bool `json:"ProvidedIpv6CidrBlock"` +} + +func (region *SRegion) GetVpcs(ids []string) ([]SVpc, error) { + param := map[string]string{ + "MaxResults": "1000", + } + for i, vpcId := range ids { + param[fmt.Sprintf("VpcId.%d", i+1)] = vpcId + } + vpcs := []SVpc{} + for { + resp, err := region.vpcRequest("DescribeVpcs", param) + if err != nil { + return nil, errors.Wrap(err, "list instance") + } + part := []SVpc{} + err = resp.Unmarshal(&part, "VpcSet") + if err != nil { + return nil, errors.Wrap(err, "unmarshal instances") + } + vpcs = append(vpcs, part...) + nextToken, err := resp.GetString("NextToken") + if err != nil { + break + } + param["NextToken"] = nextToken + } + return vpcs, nil +} + +func (region *SRegion) GetVpc(id string) (*SVpc, error) { + vpcs, err := region.GetVpcs([]string{id}) + if err != nil { + return nil, errors.Wrap(err, "GetVpcs") + } + for _, vpc := range vpcs { + if vpc.GetGlobalId() == id { + return &vpc, nil + } + } + return nil, errors.Wrapf(err, "vpc id:%s", id) +} + +func (vpc *SVpc) GetId() string { + return vpc.VpcID +} + +func (vpc *SVpc) GetName() string { + if len(vpc.VpcName) > 0 { + return vpc.VpcName + } + return vpc.VpcID +} + +func (vpc *SVpc) GetGlobalId() string { + return vpc.VpcID +} + +func (vpc *SVpc) GetStatus() string { + return api.VPC_STATUS_AVAILABLE +} + +func (vpc *SVpc) Refresh() error { + extVpc, err := vpc.region.GetVpc(vpc.GetGlobalId()) + if err != nil { + return errors.Wrap(err, "GetVpc") + } + return jsonutils.Update(vpc, extVpc) +} + +func (vpc *SVpc) GetRegion() cloudprovider.ICloudRegion { + return vpc.region +} + +func (vpc *SVpc) GetIsDefault() bool { + return vpc.IsDefault +} + +func (vpc *SVpc) GetCidrBlock() string { + return vpc.CidrBlock +} + +func (vpc *SVpc) GetIWires() ([]cloudprovider.ICloudWire, error) { + zones, err := vpc.region.GetZones() + if err != nil { + return nil, errors.Wrap(err, "GetZones") + } + for i := range zones { + zones[i].region = vpc.region + } + wires := []cloudprovider.ICloudWire{} + for i := 0; i < len(zones); i++ { + wire := SWire{ + vpc: vpc, + zone: &zones[i], + } + wires = append(wires, &wire) + } + return wires, nil +} + +func (vpc *SVpc) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) { + secgroups, err := vpc.region.GetSecurityGroups(vpc.VpcID, nil) + if err != nil { + return nil, errors.Wrap(err, "GetSecurityGroups") + } + isecgroups := []cloudprovider.ICloudSecurityGroup{} + for i := range secgroups { + secgroups[i].region = vpc.region + isecgroups = append(isecgroups, &secgroups[i]) + } + return isecgroups, nil +} + +func (vpc *SVpc) GetIRouteTables() ([]cloudprovider.ICloudRouteTable, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (vpc *SVpc) GetIRouteTableById(routeTableId string) (cloudprovider.ICloudRouteTable, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (vpc *SVpc) Delete() error { + return cloudprovider.ErrNotImplemented +} + +func (vpc *SVpc) GetIWireById(wireId string) (cloudprovider.ICloudWire, error) { + wires, err := vpc.GetIWires() + if err != nil { + return nil, errors.Wrap(err, "vpc.GetIWires") + } + for _, wire := range wires { + if wire.GetGlobalId() == wireId { + return wire, nil + } + } + return nil, errors.Wrapf(errors.ErrNotFound, "wire id:%s", wireId) +} + +func (vpc *SVpc) GetINatGateways() ([]cloudprovider.ICloudNatGateway, error) { + return nil, cloudprovider.ErrNotImplemented + +} + +func (vpc *SVpc) GetICloudVpcPeeringConnections() ([]cloudprovider.ICloudVpcPeeringConnection, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (vpc *SVpc) GetICloudAccepterVpcPeeringConnections() ([]cloudprovider.ICloudVpcPeeringConnection, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (vpc *SVpc) GetICloudVpcPeeringConnectionById(id string) (cloudprovider.ICloudVpcPeeringConnection, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (vpc *SVpc) CreateICloudVpcPeeringConnection(opts *cloudprovider.VpcPeeringConnectionCreateOptions) (cloudprovider.ICloudVpcPeeringConnection, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (vpc *SVpc) AcceptICloudVpcPeeringConnection(id string) error { + return cloudprovider.ErrNotImplemented +} + +func (vpc *SVpc) GetAuthorityOwnerId() string { + return "" +} + +func (vpc *SRegion) DeleteVpc(vpcId string) error { + return cloudprovider.ErrNotImplemented +} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/wire.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/wire.go new file mode 100644 index 0000000000..916f9a8fd8 --- /dev/null +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/wire.go @@ -0,0 +1,99 @@ +// 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 ksyun + +import ( + "fmt" + + api "yunion.io/x/cloudmux/pkg/apis/compute" + "yunion.io/x/cloudmux/pkg/cloudprovider" + "yunion.io/x/cloudmux/pkg/multicloud" + + "yunion.io/x/pkg/errors" +) + +type SWire struct { + multicloud.SResourceBase + SKsTag + zone *SZone + vpc *SVpc +} + +func (wire *SWire) GetId() string { + return fmt.Sprintf("%s-%s", wire.vpc.GetId(), wire.zone.GetId()) +} + +func (wire *SWire) GetName() string { + return wire.GetId() +} + +func (wire *SWire) IsEmulated() bool { + return true +} + +func (wire *SWire) GetStatus() string { + return api.WIRE_STATUS_AVAILABLE +} + +func (wire *SWire) Refresh() error { + return nil +} + +func (wire *SWire) GetGlobalId() string { + return fmt.Sprintf("%s-%s", wire.vpc.GetGlobalId(), wire.zone.GetId()) +} + +func (wire *SWire) GetIVpc() cloudprovider.ICloudVpc { + return wire.vpc +} + +func (wire *SWire) GetIZone() cloudprovider.ICloudZone { + return wire.zone +} + +func (wire *SWire) GetINetworks() ([]cloudprovider.ICloudNetwork, error) { + networks, err := wire.vpc.region.GetNetworks([]string{wire.vpc.VpcID}, []string{}, wire.zone.GetName()) + if err != nil { + return nil, errors.Wrap(err, "GetNetworks") + } + inetworks := []cloudprovider.ICloudNetwork{} + for i := 0; i < len(networks); i++ { + if networks[i].AvailabilityZoneName == wire.zone.GetName() { + inetworks = append(inetworks, &networks[i]) + } + } + return inetworks, nil +} + +func (wire *SWire) GetBandwidth() int { + return 10000 +} + +func (wire *SWire) CreateINetwork(opts *cloudprovider.SNetworkCreateOptions) (cloudprovider.ICloudNetwork, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (wire *SWire) GetINetworkById(netid string) (cloudprovider.ICloudNetwork, error) { + network, err := wire.vpc.region.GetNetwork(netid) + if err != nil { + return nil, errors.Wrap(err, "GetNetwork") + } + network.wire = wire + return network, nil +} + +func (wire *SWire) GetDescription() string { + return "" +} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/zone.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/zone.go new file mode 100644 index 0000000000..86f109972f --- /dev/null +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/zone.go @@ -0,0 +1,173 @@ +// 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 ksyun + +import ( + "fmt" + + api "yunion.io/x/cloudmux/pkg/apis/compute" + "yunion.io/x/cloudmux/pkg/cloudprovider" + "yunion.io/x/cloudmux/pkg/multicloud" + + "yunion.io/x/pkg/errors" + "yunion.io/x/pkg/utils" +) + +type SZone struct { + multicloud.SResourceBase + region *SRegion + host *SHost + SKsTag + + AvailabilityZone string +} + +func (region *SRegion) GetZones() ([]SZone, error) { + params := map[string]string{} + if len(region.Region) > 0 { + params = map[string]string{"Region": region.Region} + } + resp, err := region.ecsRequest("DescribeAvailabilityZones", params) + if err != nil { + return nil, errors.Wrap(err, "request zone") + } + zones := []SZone{} + err = resp.Unmarshal(&zones, "AvailabilityZoneSet") + if err != nil { + return nil, errors.Wrap(err, "unmarshal zones") + } + return zones, nil +} + +func (zone *SZone) GetId() string { + return zone.AvailabilityZone +} + +func (zone *SZone) GetName() string { + return zone.AvailabilityZone +} + +func (zone *SZone) GetI18n() cloudprovider.SModelI18nTable { + return nil +} + +func (zone *SZone) GetGlobalId() string { + return fmt.Sprintf("%s/%s/%s", api.CLOUD_PROVIDER_KSYUN, zone.region.GetId(), zone.AvailabilityZone) +} + +func (zone *SZone) GetStatus() string { + return api.ZONE_ENABLE +} + +func (zone *SZone) Refresh() error { + return nil +} + +func (zone *SZone) GetIRegion() cloudprovider.ICloudRegion { + return zone.region +} + +func (zone *SZone) GetIHostById(id string) (cloudprovider.ICloudHost, error) { + host := zone.getHost() + if host.GetGlobalId() == id { + return host, nil + } + return nil, cloudprovider.ErrNotFound +} + +func (zone *SZone) getHost() *SHost { + if zone.host == nil { + zone.host = &SHost{zone: zone} + } + return zone.host +} + +func (zone *SZone) GetIStorages() ([]cloudprovider.ICloudStorage, error) { + storages, err := zone.GetStorages() + if err != nil { + return nil, errors.Wrap(err, "GetStorages") + } + istorages := []cloudprovider.ICloudStorage{} + for _, storage := range storages { + storage.zone = zone + istorages = append(istorages, &storage) + } + return istorages, nil +} + +func (zone *SZone) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) { + istorages, err := zone.GetIStorages() + if err != nil { + return nil, errors.Wrap(err, "GetIStorages") + } + for _, istorage := range istorages { + if istorage.GetGlobalId() == id { + return istorage, nil + } + } + return nil, errors.Wrapf(errors.ErrNotFound, "storage id:%s", id) +} + +func (zone *SZone) GetIWires() ([]cloudprovider.ICloudWire, error) { + vpcs, err := zone.region.GetVpcs([]string{}) + if err != nil { + return nil, errors.Wrap(err, "GetVpcs") + } + for i := range vpcs { + vpcs[i].region = zone.region + } + iwires := []cloudprovider.ICloudWire{} + for _, vpc := range vpcs { + iwires = append(iwires, &SWire{ + vpc: &vpc, + zone: zone, + }) + } + return iwires, nil +} + +func (zone *SZone) GetIHosts() ([]cloudprovider.ICloudHost, error) { + return []cloudprovider.ICloudHost{zone.getHost()}, nil +} + +func (zone *SZone) GetDescription() string { + return "" +} + +func (zone *SZone) GetStorages() ([]SStorage, error) { + zoneDiskType := []string{} + for i := range ksDiskTypes { + params := map[string]string{ + "VolumeType": ksDiskTypes[i], + } + resp, err := zone.region.ebsRequest("DescribeAvailabilityZones", params) + if err != nil { + return nil, errors.Wrapf(err, "%s:ValidateAttachInstance", ksDiskTypes[i]) + } + zoneList := []string{} + err = resp.Unmarshal(&zoneList, "AvailabilityZones") + if err != nil { + return nil, errors.Wrap(err, "unmarshal zoneList") + } + if utils.IsInStringArray(zone.GetName(), zoneList) { + zoneDiskType = append(zoneDiskType, ksDiskTypes[i]) + } + } + storages := []SStorage{} + for i := range zoneDiskType { + storages = append(storages, SStorage{zone: zone, StorageType: zoneDiskType[i]}) + } + return storages, nil +}