update vendor:ksyun ecs (#19904)

Co-authored-by: 马鸿飞 <mahongfei@yunion.cn>
This commit is contained in:
gouqi11
2024-04-09 11:51:48 +08:00
committed by GitHub
co-authored by 马鸿飞
parent 6b201dcc26
commit 7e864dcb56
22 changed files with 2547 additions and 132 deletions
+1 -1
View File
@@ -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
+2 -2
View File
@@ -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=
+1 -1
View File
@@ -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
+12 -8
View File
@@ -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 {
+243
View File
@@ -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
}
+229
View File
@@ -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 ""
}
+25 -25
View File
@@ -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
+157
View File
@@ -0,0 +1,157 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package 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 ""
}
+68
View File
@@ -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
}
+423
View File
@@ -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
}
+63 -50
View File
@@ -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,
+195
View File
@@ -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 ""
}
+3 -3
View File
@@ -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
+163 -33
View File
@@ -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)
}
+90
View File
@@ -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
}
+209
View File
@@ -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
}
+135
View File
@@ -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
}
+37
View File
@@ -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
}
+9 -9
View File
@@ -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
+210
View File
@@ -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
}
+99
View File
@@ -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 ""
}
+173
View File
@@ -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
}