diff --git a/cmd/climc/shell/compute/cloudaccounts.go b/cmd/climc/shell/compute/cloudaccounts.go index 9d5c577c4e..76550815b5 100644 --- a/cmd/climc/shell/compute/cloudaccounts.go +++ b/cmd/climc/shell/compute/cloudaccounts.go @@ -55,6 +55,7 @@ func init() { cmd.CreateWithKeyword("create-incloudsphere", &options.SInCloudSphereAccountCreateOptions{}) cmd.CreateWithKeyword("create-proxmox", &options.SProxmoxAccountCreateOptions{}) cmd.CreateWithKeyword("create-remotefile", &options.SRemoteFileAccountCreateOptions{}) + cmd.CreateWithKeyword("create-ksyun", &options.SKsyunCloudAccountCreateOptions{}) cmd.UpdateWithKeyword("update-vmware", &options.SVMwareCloudAccountUpdateOptions{}) cmd.UpdateWithKeyword("update-aliyun", &options.SAliyunCloudAccountUpdateOptions{}) @@ -76,6 +77,7 @@ func init() { cmd.UpdateWithKeyword("update-bingocloud", &options.SBingoCloudAccountUpdateOptions{}) cmd.UpdateWithKeyword("update-incloudsphere", &options.SInCloudSphereAccountUpdateOptions{}) cmd.UpdateWithKeyword("update-proxmox", &options.SProxmoxAccountUpdateOptions{}) + cmd.UpdateWithKeyword("update-ksyun", &options.SKsyunCloudAccountUpdateOptions{}) cmd.Perform("update-credential", &options.CloudaccountUpdateCredentialOptions{}) @@ -100,6 +102,7 @@ func init() { cmd.PerformWithKeyword("update-credential-bingocloud", "update-credential", &options.SBingoCloudAccountUpdateCredentialOptions{}) cmd.PerformWithKeyword("update-credential-incloudsphere", "update-credential", &options.SInCloudSphereAccountUpdateCredentialOptions{}) cmd.PerformWithKeyword("update-credential-proxmox", "update-credential", &options.SProxmoxAccountUpdateCredentialOptions{}) + cmd.PerformWithKeyword("update-credential-ksyun", "update-credential", &options.SKsyunCloudAccountUpdateCredentialOptions{}) cmd.PerformWithKeyword("test-connectivity-google", "test-connectivity", &options.SGoogleCloudAccountUpdateCredentialOptions{}) cmd.PerformWithKeyword("test-connectivity-vmware", "test-connectivity", &options.SVMwareCloudAccountUpdateCredentialOptions{}) diff --git a/cmd/climc/shell/misc/feature.go b/cmd/climc/shell/misc/feature.go index 5325171ed8..e15dd1bf26 100644 --- a/cmd/climc/shell/misc/feature.go +++ b/cmd/climc/shell/misc/feature.go @@ -62,6 +62,7 @@ func init() { "k8s", "monitor", "bingocloud", + "ksyun", } const ( diff --git a/go.mod b/go.mod index 1e96d4c0ed..c96af29af6 100644 --- a/go.mod +++ b/go.mod @@ -83,7 +83,7 @@ require ( k8s.io/client-go v0.19.3 k8s.io/cluster-bootstrap v0.19.3 moul.io/http2curl/v2 v2.3.0 - yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230804055523-9c707c67e05f + yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230807074306-1afe20f5d67a yunion.io/x/executor v0.0.0-20230705125604-c5ac3141db32 yunion.io/x/jsonutils v1.0.1-0.20230613121553-0f3b41e2ef19 yunion.io/x/log v1.0.1-0.20230411060016-feb3f46ab361 diff --git a/go.sum b/go.sum index edeafbd526..1fef4dfc56 100644 --- a/go.sum +++ b/go.sum @@ -1174,8 +1174,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.20230804055523-9c707c67e05f h1:jcMLnQkFGZemhnWbGCpr7ckb7yaIBbS1w2/vbLjf/tY= -yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230804055523-9c707c67e05f/go.mod h1:2sgCN7nRPQL3woLfdgqLDd92vwAHqtlz3KKiHxC5BAw= +yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230807074306-1afe20f5d67a h1:AwlwxsGXNxk80dri0FBlDb5oWSOnq5lXHeke6icd0pA= +yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230807074306-1afe20f5d67a/go.mod h1:2sgCN7nRPQL3woLfdgqLDd92vwAHqtlz3KKiHxC5BAw= 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/pkg/apis/compute/cloudaccount_const.go b/pkg/apis/compute/cloudaccount_const.go index 56502e2f06..e4843469cd 100644 --- a/pkg/apis/compute/cloudaccount_const.go +++ b/pkg/apis/compute/cloudaccount_const.go @@ -65,6 +65,7 @@ const ( CLOUD_PROVIDER_PROXMOX = compute.CLOUD_PROVIDER_PROXMOX CLOUD_PROVIDER_REMOTEFILE = compute.CLOUD_PROVIDER_REMOTEFILE CLOUD_PROVIDER_H3C = compute.CLOUD_PROVIDER_H3C + CLOUD_PROVIDER_KSYUN = compute.CLOUD_PROVIDER_KSYUN CLOUD_PROVIDER_GENERICS3 = compute.CLOUD_PROVIDER_GENERICS3 CLOUD_PROVIDER_CEPH = compute.CLOUD_PROVIDER_CEPH @@ -142,6 +143,7 @@ var ( CLOUD_PROVIDER_PROXMOX, CLOUD_PROVIDER_REMOTEFILE, CLOUD_PROVIDER_H3C, + CLOUD_PROVIDER_KSYUN, } CLOUD_PROVIDER_HOST_TYPE_MAP = map[string][]string{ @@ -222,6 +224,9 @@ var ( CLOUD_PROVIDER_H3C: { HOST_TYPE_H3C, }, + CLOUD_PROVIDER_KSYUN: { + HOST_TYPE_KSYUN, + }, } ) diff --git a/pkg/apis/compute/guest_const.go b/pkg/apis/compute/guest_const.go index 11e0384281..0b71df7d6a 100644 --- a/pkg/apis/compute/guest_const.go +++ b/pkg/apis/compute/guest_const.go @@ -197,6 +197,7 @@ const ( HYPERVISOR_PROXMOX = compute.HYPERVISOR_PROXMOX HYPERVISOR_REMOTEFILE = compute.HYPERVISOR_REMOTEFILE HYPERVISOR_H3C = compute.HYPERVISOR_H3C + HYPERVISOR_KSYUN = compute.HYPERVISOR_KSYUN // HYPERVISOR_DEFAULT = HYPERVISOR_KVM HYPERVISOR_DEFAULT = HYPERVISOR_KVM @@ -270,6 +271,7 @@ var HYPERVISORS = []string{ HYPERVISOR_PROXMOX, HYPERVISOR_REMOTEFILE, HYPERVISOR_H3C, + HYPERVISOR_KSYUN, } var ONECLOUD_HYPERVISORS = []string{ @@ -289,6 +291,7 @@ var PUBLIC_CLOUD_HYPERVISORS = []string{ HYPERVISOR_CTYUN, HYPERVISOR_ECLOUD, HYPERVISOR_JDCLOUD, + HYPERVISOR_KSYUN, } var PRIVATE_CLOUD_HYPERVISORS = []string{ @@ -337,6 +340,7 @@ var HYPERVISOR_HOSTTYPE = map[string]string{ HYPERVISOR_PROXMOX: HOST_TYPE_PROXMOX, HYPERVISOR_REMOTEFILE: HOST_TYPE_REMOTEFILE, HYPERVISOR_H3C: HOST_TYPE_H3C, + HYPERVISOR_KSYUN: HOST_TYPE_KSYUN, } var HOSTTYPE_HYPERVISOR = map[string]string{ @@ -367,6 +371,7 @@ var HOSTTYPE_HYPERVISOR = map[string]string{ HOST_TYPE_PROXMOX: HYPERVISOR_PROXMOX, HOST_TYPE_REMOTEFILE: HYPERVISOR_REMOTEFILE, HOST_TYPE_H3C: HYPERVISOR_H3C, + HOST_TYPE_KSYUN: HYPERVISOR_KSYUN, } const ( diff --git a/pkg/apis/compute/host_const.go b/pkg/apis/compute/host_const.go index 8c46d23d4c..2867674999 100644 --- a/pkg/apis/compute/host_const.go +++ b/pkg/apis/compute/host_const.go @@ -14,7 +14,9 @@ package compute -import "yunion.io/x/cloudmux/pkg/apis/compute" +import ( + "yunion.io/x/cloudmux/pkg/apis/compute" +) const ( HOST_TYPE_BAREMETAL = "baremetal" @@ -48,6 +50,7 @@ const ( HOST_TYPE_PROXMOX = compute.HOST_TYPE_PROXMOX HOST_TYPE_REMOTEFILE = compute.HOST_TYPE_REMOTEFILE HOST_TYPE_H3C = compute.HOST_TYPE_H3C + HOST_TYPE_KSYUN = compute.HOST_TYPE_KSYUN HOST_TYPE_DEFAULT = HOST_TYPE_HYPERVISOR @@ -138,6 +141,7 @@ var HOST_TYPES = []string{ HOST_TYPE_PROXMOX, HOST_TYPE_REMOTEFILE, HOST_TYPE_H3C, + HOST_TYPE_KSYUN, } var ALL_NIC_TYPES = []compute.TNicType{NIC_TYPE_IPMI, NIC_TYPE_ADMIN, NIC_TYPE_NORMAL} diff --git a/pkg/compute/guestdrivers/ksyun.go b/pkg/compute/guestdrivers/ksyun.go new file mode 100644 index 0000000000..4fa1753d69 --- /dev/null +++ b/pkg/compute/guestdrivers/ksyun.go @@ -0,0 +1,104 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package guestdrivers + +import ( + "yunion.io/x/cloudmux/pkg/cloudprovider" + "yunion.io/x/pkg/util/billing" + "yunion.io/x/pkg/util/rbacscope" + + api "yunion.io/x/onecloud/pkg/apis/compute" + "yunion.io/x/onecloud/pkg/cloudcommon/db/quotas" + "yunion.io/x/onecloud/pkg/compute/models" + "yunion.io/x/onecloud/pkg/mcclient" +) + +type SKsyunGuestDriver struct { + SManagedVirtualizedGuestDriver +} + +func init() { + driver := SKsyunGuestDriver{} + models.RegisterGuestDriver(&driver) +} + +func (self *SKsyunGuestDriver) DoScheduleSKUFilter() bool { return false } + +func (self *SKsyunGuestDriver) GetHypervisor() string { + return api.HYPERVISOR_KSYUN +} + +func (self *SKsyunGuestDriver) GetProvider() string { + return api.CLOUD_PROVIDER_KSYUN +} + +func (self *SKsyunGuestDriver) GetDefaultSysDiskBackend() string { + return "" +} + +func (self *SKsyunGuestDriver) GetMinimalSysDiskSizeGb() int { + return 20 +} + +func (self *SKsyunGuestDriver) GetComputeQuotaKeys(scope rbacscope.TRbacScope, ownerId mcclient.IIdentityProvider, brand string) models.SComputeResourceKeys { + keys := models.SComputeResourceKeys{} + keys.SBaseProjectQuotaKeys = quotas.OwnerIdProjectQuotaKeys(scope, ownerId) + keys.CloudEnv = api.CLOUD_ENV_PUBLIC_CLOUD + keys.Provider = api.CLOUD_PROVIDER_KSYUN + keys.Brand = api.CLOUD_PROVIDER_KSYUN + keys.Hypervisor = api.HYPERVISOR_KSYUN + return keys +} + +func (self *SKsyunGuestDriver) GetInstanceCapability() cloudprovider.SInstanceCapability { + return cloudprovider.SInstanceCapability{ + Hypervisor: self.GetHypervisor(), + Provider: self.GetProvider(), + DefaultAccount: cloudprovider.SDefaultAccount{ + Linux: cloudprovider.SOsDefaultAccount{ + DefaultAccount: api.VM_DEFAULT_LINUX_LOGIN_USER, + Changeable: false, + }, + Windows: cloudprovider.SOsDefaultAccount{ + DefaultAccount: api.VM_DEFAULT_WINDOWS_LOGIN_USER, + Changeable: false, + }, + }, + } +} + +func (self *SKsyunGuestDriver) GetGuestInitialStateAfterCreate() string { + return api.VM_READY +} + +func (self *SKsyunGuestDriver) GetGuestInitialStateAfterRebuild() string { + return api.VM_READY +} + +func (self *SKsyunGuestDriver) AllowReconfigGuest() bool { + return true +} + +func (self *SKsyunGuestDriver) IsSupportedBillingCycle(bc billing.SBillingCycle) bool { + return false +} + +func (self *SKsyunGuestDriver) IsSupportPublicipToEip() bool { + return false +} + +func (self *SKsyunGuestDriver) IsSupportSetAutoRenew() bool { + return false +} diff --git a/pkg/compute/hostdrivers/ksyun.go b/pkg/compute/hostdrivers/ksyun.go new file mode 100644 index 0000000000..49594c4dff --- /dev/null +++ b/pkg/compute/hostdrivers/ksyun.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 hostdrivers + +import ( + api "yunion.io/x/onecloud/pkg/apis/compute" + "yunion.io/x/onecloud/pkg/compute/models" +) + +type SKsyunHostDriver struct { + SManagedVirtualizationHostDriver +} + +func init() { + driver := SKsyunHostDriver{} + models.RegisterHostDriver(&driver) +} + +func (self *SKsyunHostDriver) GetHostType() string { + return api.HOST_TYPE_KSYUN +} + +func (self *SKsyunHostDriver) GetHypervisor() string { + return api.HYPERVISOR_KSYUN +} diff --git a/pkg/compute/regiondrivers/ksyun.go b/pkg/compute/regiondrivers/ksyun.go new file mode 100644 index 0000000000..1dd69bf1b7 --- /dev/null +++ b/pkg/compute/regiondrivers/ksyun.go @@ -0,0 +1,52 @@ +// 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 regiondrivers + +import ( + "context" + + api "yunion.io/x/onecloud/pkg/apis/compute" + "yunion.io/x/onecloud/pkg/compute/models" + "yunion.io/x/onecloud/pkg/mcclient" +) + +type SKsyunRegionDriver struct { + SManagedVirtualizationRegionDriver +} + +func init() { + driver := SKsyunRegionDriver{} + models.RegisterRegionDriver(&driver) +} + +func (self *SKsyunRegionDriver) GetProvider() string { + return api.CLOUD_PROVIDER_KSYUN +} + +func (self *SKsyunRegionDriver) IsAllowSecurityGroupNameRepeat() bool { + return true +} + +func (self *SKsyunRegionDriver) GenerateSecurityGroupName(name string) string { + return name +} + +func (self *SKsyunRegionDriver) IsSecurityGroupBelongVpc() bool { + return true +} + +func (self *SKsyunRegionDriver) ValidateCreateSnapshotData(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, storage *models.SStorage, input *api.SnapshotCreateInput) error { + return nil +} diff --git a/pkg/mcclient/options/base.go b/pkg/mcclient/options/base.go index 6d1ad5ca3a..b63651b114 100644 --- a/pkg/mcclient/options/base.go +++ b/pkg/mcclient/options/base.go @@ -245,7 +245,7 @@ type BaseListOptions struct { Manager []string `help:"List objects belonging to the cloud provider" json:"manager,omitempty"` Account string `help:"List objects belonging to the cloud account" json:"account,omitempty"` - Provider []string `help:"List objects from the provider" choices:"OneCloud|VMware|Aliyun|Apsara|Qcloud|Azure|Aws|Huawei|OpenStack|Ucloud|ZStack|Google|Ctyun|Cloudpods|Nutanix|BingoCloud|IncloudSphere|JDcloud|Proxmox|Ceph|Ecloud|HCSO|HCS|HCSOP|H3C|S3|RemoteFile" json:"provider,omitempty"` + Provider []string `help:"List objects from the provider" choices:"OneCloud|VMware|Aliyun|Apsara|Qcloud|Azure|Aws|Huawei|OpenStack|Ucloud|ZStack|Google|Ctyun|Cloudpods|Nutanix|BingoCloud|IncloudSphere|JDcloud|Proxmox|Ceph|Ecloud|HCSO|HCS|HCSOP|H3C|S3|RemoteFile|Ksyun" json:"provider,omitempty"` Brand []string `help:"List objects belonging to a special brand"` CloudEnv string `help:"Cloud environment" choices:"public|private|onpremise|private_or_onpremise" json:"cloud_env,omitempty"` PublicCloud *bool `help:"List objects belonging to public cloud" json:"public_cloud"` diff --git a/pkg/mcclient/options/cloudaccounts.go b/pkg/mcclient/options/cloudaccounts.go index b2fc9858e4..1afca60bd8 100644 --- a/pkg/mcclient/options/cloudaccounts.go +++ b/pkg/mcclient/options/cloudaccounts.go @@ -1278,3 +1278,33 @@ func (opts *SRemoteFileAccountCreateOptions) Params() (jsonutils.JSONObject, err params.(*jsonutils.JSONDict).Add(jsonutils.NewString(api.CLOUD_PROVIDER_REMOTEFILE), "provider") return params, nil } + +type SKsyunCloudAccountCreateOptions struct { + SCloudAccountCreateBaseOptions + SAccessKeyCredential +} + +func (opts *SKsyunCloudAccountCreateOptions) Params() (jsonutils.JSONObject, error) { + params := jsonutils.Marshal(opts) + params.(*jsonutils.JSONDict).Add(jsonutils.NewString("Ksyun"), "provider") + return params, nil +} + +type SKsyunCloudAccountUpdateOptions struct { + SCloudAccountUpdateBaseOptions +} + +func (opts *SKsyunCloudAccountUpdateOptions) Params() (jsonutils.JSONObject, error) { + params := jsonutils.Marshal(opts).(*jsonutils.JSONDict) + + return params, nil +} + +type SKsyunCloudAccountUpdateCredentialOptions struct { + SCloudAccountIdOptions + SAccessKeyCredential +} + +func (opts *SKsyunCloudAccountUpdateCredentialOptions) Params() (jsonutils.JSONObject, error) { + return jsonutils.Marshal(opts), nil +} diff --git a/pkg/mcclient/options/compute/servers.go b/pkg/mcclient/options/compute/servers.go index c8a8869ba6..8dc6795de3 100644 --- a/pkg/mcclient/options/compute/servers.go +++ b/pkg/mcclient/options/compute/servers.go @@ -44,7 +44,7 @@ type ServerListOptions struct { Gpu *bool `help:"Show gpu servers"` Secgroup string `help:"Secgroup ID or Name"` AdminSecgroup string `help:"AdminSecgroup ID or Name"` - Hypervisor string `help:"Show server of hypervisor" choices:"kvm|esxi|container|baremetal|aliyun|azure|aws|huawei|ucloud|zstack|openstack|google|ctyun|incloudsphere|nutanix|bingocloud|cloudpods|ecloud|jdcloud|remotefile|h3c|hcs|hcso|hcsop|proxmox"` + Hypervisor string `help:"Show server of hypervisor" choices:"kvm|esxi|container|baremetal|aliyun|azure|aws|huawei|ucloud|zstack|openstack|google|ctyun|incloudsphere|nutanix|bingocloud|cloudpods|ecloud|jdcloud|remotefile|h3c|hcs|hcso|hcsop|proxmox|ksyun"` Region string `help:"Show servers in cloudregion"` WithEip *bool `help:"Show Servers with EIP"` WithoutEip *bool `help:"Show Servers without EIP"` diff --git a/vendor/modules.txt b/vendor/modules.txt index eee5eba237..a5e7ee103d 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1438,7 +1438,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.20230804055523-9c707c67e05f +# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230807074306-1afe20f5d67a ## explicit; go 1.18 yunion.io/x/cloudmux/pkg/apis yunion.io/x/cloudmux/pkg/apis/billing @@ -1490,6 +1490,8 @@ yunion.io/x/cloudmux/pkg/multicloud/huawei/obs yunion.io/x/cloudmux/pkg/multicloud/huawei/provider yunion.io/x/cloudmux/pkg/multicloud/jdcloud yunion.io/x/cloudmux/pkg/multicloud/jdcloud/provider +yunion.io/x/cloudmux/pkg/multicloud/ksyun +yunion.io/x/cloudmux/pkg/multicloud/ksyun/provider yunion.io/x/cloudmux/pkg/multicloud/loader yunion.io/x/cloudmux/pkg/multicloud/nutanix yunion.io/x/cloudmux/pkg/multicloud/nutanix/provider diff --git a/vendor/yunion.io/x/cloudmux/pkg/apis/compute/cloudaccount_const.go b/vendor/yunion.io/x/cloudmux/pkg/apis/compute/cloudaccount_const.go index bf368c4df1..a9b977c4f6 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/apis/compute/cloudaccount_const.go +++ b/vendor/yunion.io/x/cloudmux/pkg/apis/compute/cloudaccount_const.go @@ -40,6 +40,7 @@ const ( CLOUD_PROVIDER_PROXMOX = "Proxmox" CLOUD_PROVIDER_REMOTEFILE = "RemoteFile" CLOUD_PROVIDER_H3C = "H3C" + CLOUD_PROVIDER_KSYUN = "Ksyun" CLOUD_PROVIDER_GENERICS3 = "S3" CLOUD_PROVIDER_CEPH = "Ceph" diff --git a/vendor/yunion.io/x/cloudmux/pkg/apis/compute/cloudregions_const.go b/vendor/yunion.io/x/cloudmux/pkg/apis/compute/cloudregions_const.go index e1a00e0c2e..dbf116c9c2 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/apis/compute/cloudregions_const.go +++ b/vendor/yunion.io/x/cloudmux/pkg/apis/compute/cloudregions_const.go @@ -25,6 +25,7 @@ const ( CITY_HU_HE_HAO_TE = "Huhehaote" //呼和浩特 CITY_HANG_ZHOU = "Hangzhou" //杭州 CITY_SHANG_HAI = "Shanghai" //上海 + CITY_QING_YANG = "Qingyang" //庆阳 CITY_SHEN_ZHEN = "Shenzhen" //深圳 CITY_HONG_KONG = "Hongkong" //香港 CITY_NING_XIA = "Ningxia" //宁夏 diff --git a/vendor/yunion.io/x/cloudmux/pkg/apis/compute/guest_const.go b/vendor/yunion.io/x/cloudmux/pkg/apis/compute/guest_const.go index c33c5948c3..11e2b29f1c 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/apis/compute/guest_const.go +++ b/vendor/yunion.io/x/cloudmux/pkg/apis/compute/guest_const.go @@ -73,6 +73,7 @@ const ( HYPERVISOR_PROXMOX = "proxmox" HYPERVISOR_REMOTEFILE = "remotefile" HYPERVISOR_H3C = "h3c" + HYPERVISOR_KSYUN = "ksyun" ) const ( diff --git a/vendor/yunion.io/x/cloudmux/pkg/apis/compute/host_const.go b/vendor/yunion.io/x/cloudmux/pkg/apis/compute/host_const.go index ad01cda960..a6f3f6bde8 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/apis/compute/host_const.go +++ b/vendor/yunion.io/x/cloudmux/pkg/apis/compute/host_const.go @@ -42,6 +42,7 @@ const ( HOST_TYPE_PROXMOX = "proxmox" HOST_TYPE_REMOTEFILE = "remotefile" HOST_TYPE_H3C = "h3c" + HOST_TYPE_KSYUN = "ksyun" // # possible status HOST_ONLINE = "online" diff --git a/vendor/yunion.io/x/cloudmux/pkg/apis/compute/regiondata.go b/vendor/yunion.io/x/cloudmux/pkg/apis/compute/regiondata.go index 88c49bd480..eabb0c3fb4 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/apis/compute/regiondata.go +++ b/vendor/yunion.io/x/cloudmux/pkg/apis/compute/regiondata.go @@ -38,6 +38,12 @@ var ( City: CITY_SHANG_HAI, CountryCode: COUNTRY_CODE_CN, } + RegionQingYang = cloudprovider.SGeographicInfo{ + Latitude: 35.73, + Longitude: 107.61, + City: CITY_QING_YANG, + CountryCode: COUNTRY_CODE_CN, + } RegionGuangzhou = cloudprovider.SGeographicInfo{ Latitude: 23.12911, Longitude: 113.264385, diff --git a/vendor/yunion.io/x/cloudmux/pkg/apis/const.go b/vendor/yunion.io/x/cloudmux/pkg/apis/const.go index da02f1632e..3d9595404d 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/apis/const.go +++ b/vendor/yunion.io/x/cloudmux/pkg/apis/const.go @@ -19,6 +19,7 @@ const ( STATUS_DELETE_FAILED = "delete_failed" STATUS_CREATING = "creating" STATUS_CREATE_FAILED = "create_failed" + STATUS_AVAILABLE = "available" USER_TAG_PREFIX = "user:" diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/ksyun.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/ksyun.go new file mode 100644 index 0000000000..ac58b8bfb6 --- /dev/null +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/ksyun.go @@ -0,0 +1,305 @@ +// 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 ( + "bytes" + "context" + "crypto/hmac" + "crypto/sha256" + "crypto/tls" + "encoding/hex" + "fmt" + "net/http" + "net/url" + "sort" + "strings" + "sync" + "time" + + "yunion.io/x/jsonutils" + "yunion.io/x/pkg/errors" + "yunion.io/x/pkg/gotypes" + "yunion.io/x/pkg/util/httputils" + + api "yunion.io/x/cloudmux/pkg/apis/compute" + "yunion.io/x/cloudmux/pkg/cloudprovider" +) + +const ( + CLOUD_PROVIDER_KSYUN_CN = "金山云" + KSYUN_DEFAULT_REGION = "cn-beijing-6" +) + +type KsyunClientConfig struct { + cpcfg cloudprovider.ProviderConfig + accessKeyId string + accessKeySecret string + + debug bool +} + +type SKsyunClient struct { + *KsyunClientConfig + + client *http.Client + lock sync.Mutex + ctx context.Context + + customerId string + + regions []SRegion +} + +func NewKsyunClientConfig(accessKeyId, accessKeySecret string) *KsyunClientConfig { + cfg := &KsyunClientConfig{ + accessKeyId: accessKeyId, + accessKeySecret: accessKeySecret, + } + return cfg +} + +func (self *KsyunClientConfig) Debug(debug bool) *KsyunClientConfig { + self.debug = debug + return self +} + +func (self *KsyunClientConfig) CloudproviderConfig(cpcfg cloudprovider.ProviderConfig) *KsyunClientConfig { + self.cpcfg = cpcfg + return self +} + +func NewKsyunClient(cfg *KsyunClientConfig) (*SKsyunClient, error) { + client := &SKsyunClient{ + KsyunClientConfig: cfg, + ctx: context.Background(), + } + client.ctx = context.WithValue(client.ctx, "time", time.Now()) + var err error + client.regions, err = client.GetRegions() + return client, err +} + +func (self *SKsyunClient) GetRegions() ([]SRegion, error) { + resp, err := self.ec2Request("", "DescribeRegions", nil) + if err != nil { + return nil, err + } + ret := struct { + RegionSet []SRegion + }{} + err = resp.Unmarshal(&ret) + if err != nil { + return nil, err + } + for i := range ret.RegionSet { + ret.RegionSet[i].client = self + } + 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 + } + } + return nil, cloudprovider.ErrNotFound +} + +func (self *SKsyunClient) getUrl(service, regionId string) string { + if len(regionId) == 0 { + regionId = KSYUN_DEFAULT_REGION + } + switch service { + case "kingpay": + return "http://kingpay.api.ksyun.com" + case "kec": + return fmt.Sprintf("https://kec.%s.api.ksyun.com", regionId) + } + return "" +} + +func (cli *SKsyunClient) getDefaultClient() *http.Client { + cli.lock.Lock() + defer cli.lock.Unlock() + if !gotypes.IsNil(cli.client) { + return cli.client + } + cli.client = httputils.GetAdaptiveTimeoutClient() + httputils.SetClientProxyFunc(cli.client, cli.cpcfg.ProxyFunc) + ts, _ := cli.client.Transport.(*http.Transport) + ts.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} + cli.client.Transport = cloudprovider.GetCheckTransport(ts, func(req *http.Request) (func(resp *http.Response), error) { + params, err := url.ParseQuery(req.URL.RawQuery) + if err != nil { + return nil, errors.Wrapf(err, "ParseQuery(%s)", req.URL.RawQuery) + } + action := params.Get("Action") + + for _, prefix := range []string{"Get", "List", "Describe", "Query"} { + if strings.HasPrefix(action, prefix) { + return nil, nil + } + } + if cli.cpcfg.ReadOnly { + return nil, errors.Wrapf(cloudprovider.ErrAccountReadOnly, "%s %s", req.Method, req.URL.Path) + } + return nil, nil + }) + return cli.client +} + +type sKsyunError struct { + StatusCode int `json:"StatusCode"` + RequestId string `json:"RequestId"` + ErrorMsg struct { + Code string `json:"Code"` + Message string `json:"Message"` + Type string `json:"Type"` + } `json:"Error"` +} + +func (self *sKsyunError) Error() string { + return jsonutils.Marshal(self).String() +} + +func (self *sKsyunError) ParseErrorFromJsonResponse(statusCode int, status string, body jsonutils.JSONObject) error { + if body != nil { + body.Unmarshal(self) + } + self.StatusCode = statusCode + return self +} + +func (self *SKsyunClient) sign(req *http.Request) (string, error) { + query, err := url.ParseQuery(req.URL.RawQuery) + if err != nil { + return "", err + } + keys := []string{} + for k := range query { + keys = append(keys, k) + } + sort.Strings(keys) + var buf bytes.Buffer + + for i := range keys { + k := keys[i] + buf.WriteString(strings.Replace(url.QueryEscape(k), "+", "%20", -1)) + buf.WriteString("=") + buf.WriteString(strings.Replace(url.QueryEscape(query.Get(k)), "+", "%20", -1)) + buf.WriteString("&") + } + buf.Truncate(buf.Len() - 1) + + hashed := hmac.New(sha256.New, []byte(self.accessKeySecret)) + hashed.Write([]byte(buf.String())) + return hex.EncodeToString(hashed.Sum(nil)), nil +} + +func (self *SKsyunClient) Do(req *http.Request) (*http.Response, error) { + client := self.getDefaultClient() + + signature, err := self.sign(req) + if err != nil { + return nil, errors.Wrapf(err, "sign") + } + + query, err := url.ParseQuery(req.URL.RawQuery) + if err != nil { + return nil, err + } + + query.Set("Signature", signature) + req.URL.RawQuery = query.Encode() + req.Header.Set("Accept", "application/json") + 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 (self *SKsyunClient) request(service, regionId, apiName, apiVersion string, params map[string]string) (jsonutils.JSONObject, error) { + uri := self.getUrl(service, regionId) + if params == nil { + params = map[string]string{} + } + params["Action"] = apiName + params["Version"] = apiVersion + params["Accesskey"] = self.accessKeyId + params["SignatureMethod"] = "HMAC-SHA256" + params["Service"] = service + params["Format"] = "json" + params["SignatureVersion"] = "1.0" + params["Timestamp"] = time.Now().UTC().Format("2006-01-02T15:04:05Z") + values := url.Values{} + for k, v := range params { + values.Set(k, v) + } + uri = fmt.Sprintf("%s?%s", uri, values.Encode()) + req := httputils.NewJsonRequest(httputils.GET, uri, nil) + ksErr := &sKsyunError{} + client := httputils.NewJsonClient(self) + _, resp, err := client.Send(self.ctx, req, ksErr, self.debug) + return resp, err +} + +func (self *SKsyunClient) GetSubAccounts() ([]cloudprovider.SSubAccount, error) { + subAccount := cloudprovider.SSubAccount{} + subAccount.Name = self.cpcfg.Name + subAccount.Account = self.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 + } + self.QueryCashWalletAction() + return self.customerId +} + +type CashWalletDetail struct { + CustomerId string + AvailableAmount float64 + RewardAmount string + FrozenAmount string + Currency string +} + +func (self *SKsyunClient) QueryCashWalletAction() (*CashWalletDetail, error) { + resp, err := self.request("kingpay", "", "QueryCashWalletAction", "V1", nil) + if err != nil { + return nil, err + } + ret := &CashWalletDetail{} + err = resp.Unmarshal(ret, "data") + if err != nil { + return nil, errors.Wrapf(err, "resp.Unmarshal") + } + self.customerId = ret.CustomerId + return ret, nil +} + +func (self *SKsyunClient) GetCapabilities() []string { + caps := []string{ + cloudprovider.CLOUD_CAPABILITY_COMPUTE + cloudprovider.READ_ONLY_SUFFIX, + } + return caps +} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/provider/provider.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/provider/provider.go new file mode 100644 index 0000000000..1f3b807a03 --- /dev/null +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/provider/provider.go @@ -0,0 +1,207 @@ +// 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 provider + +import ( + "context" + + "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/ksyun" +) + +type SKsyunProviderFactory struct { + cloudprovider.SPublicCloudBaseProviderFactory +} + +func (self *SKsyunProviderFactory) GetId() string { + return api.CLOUD_PROVIDER_KSYUN +} + +func (self *SKsyunProviderFactory) GetName() string { + return ksyun.CLOUD_PROVIDER_KSYUN_CN +} + +func (self *SKsyunProviderFactory) ValidateCreateCloudaccountData(ctx context.Context, input cloudprovider.SCloudaccountCredential) (cloudprovider.SCloudaccount, error) { + output := cloudprovider.SCloudaccount{} + if len(input.AccessKeyId) == 0 { + return output, errors.Wrap(cloudprovider.ErrMissingParameter, "access_key_id") + } + if len(input.AccessKeySecret) == 0 { + return output, errors.Wrap(cloudprovider.ErrMissingParameter, "access_key_secret") + } + output.AccessUrl = input.Environment + output.Account = input.AccessKeyId + output.Secret = input.AccessKeySecret + return output, nil +} + +func (self *SKsyunProviderFactory) ValidateUpdateCloudaccountCredential(ctx context.Context, input cloudprovider.SCloudaccountCredential, cloudaccount string) (cloudprovider.SCloudaccount, error) { + output := cloudprovider.SCloudaccount{} + if len(input.AccessKeyId) == 0 { + return output, errors.Wrap(cloudprovider.ErrMissingParameter, "access_key_id") + } + if len(input.AccessKeySecret) == 0 { + return output, errors.Wrap(cloudprovider.ErrMissingParameter, "access_key_secret") + } + output = cloudprovider.SCloudaccount{ + Account: input.AccessKeyId, + Secret: input.AccessKeySecret, + } + return output, nil +} + +func (self *SKsyunProviderFactory) GetProvider(cfg cloudprovider.ProviderConfig) (cloudprovider.ICloudProvider, error) { + client, err := ksyun.NewKsyunClient( + ksyun.NewKsyunClientConfig( + cfg.Account, + cfg.Secret, + ).CloudproviderConfig(cfg), + ) + if err != nil { + return nil, err + } + + return &SKsyunProvider{ + SBaseProvider: cloudprovider.NewBaseProvider(self), + client: client, + }, nil +} + +func (self *SKsyunProviderFactory) GetClientRC(info cloudprovider.SProviderInfo) (map[string]string, error) { + return map[string]string{ + "KSYUN_ACCESS_KEY_ID": info.Account, + "KSYUN_ACCESS_KEY_SECRET": info.Secret, + "KSYUN_REGION_ID": ksyun.KSYUN_DEFAULT_REGION, + }, nil +} + +func init() { + factory := SKsyunProviderFactory{} + cloudprovider.RegisterFactory(&factory) +} + +type SKsyunProvider struct { + cloudprovider.SBaseProvider + client *ksyun.SKsyunClient +} + +func (self *SKsyunProvider) GetSysInfo() (jsonutils.JSONObject, error) { + regions, err := self.client.GetRegions() + if err != nil { + return nil, err + } + info := jsonutils.NewDict() + info.Add(jsonutils.NewInt(int64(len(regions))), "region_count") + return info, nil +} + +func (self *SKsyunProvider) GetVersion() string { + return "" +} + +func (self *SKsyunProvider) GetSubAccounts() ([]cloudprovider.SSubAccount, error) { + return self.client.GetSubAccounts() +} + +func (self *SKsyunProvider) GetAccountId() string { + return self.client.GetAccountId() +} + +func (self *SKsyunProvider) GetIRegions() []cloudprovider.ICloudRegion { + regions, err := self.client.GetRegions() + if err != nil { + return nil + } + ret := []cloudprovider.ICloudRegion{} + for i := range regions { + ret = append(ret, ®ions[i]) + } + return ret +} + +func (self *SKsyunProvider) GetIRegionById(extId string) (cloudprovider.ICloudRegion, error) { + region, err := self.client.GetRegion(extId) + if err != nil { + return nil, err + } + return region, nil +} + +func (self *SKsyunProvider) GetBalance() (*cloudprovider.SBalanceInfo, error) { + ret := &cloudprovider.SBalanceInfo{Currency: "CNY", Status: api.CLOUD_PROVIDER_HEALTH_UNKNOWN} + balance, err := self.client.QueryCashWalletAction() + if err != nil { + return ret, err + } + ret.Status = api.CLOUD_PROVIDER_HEALTH_NORMAL + ret.Currency = balance.Currency + if balance.AvailableAmount <= 0 { + if balance.AvailableAmount < 0 { + ret.Status = api.CLOUD_PROVIDER_HEALTH_ARREARS + } else if balance.AvailableAmount < 100 { + ret.Status = api.CLOUD_PROVIDER_HEALTH_INSUFFICIENT + } + } + ret.Amount = balance.AvailableAmount + return ret, nil +} + +func (self *SKsyunProvider) GetIProjects() ([]cloudprovider.ICloudProject, error) { + return []cloudprovider.ICloudProject{}, nil +} + +func (self *SKsyunProvider) CreateIProject(name string) (cloudprovider.ICloudProject, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (self *SKsyunProvider) GetStorageClasses(regionId string) []string { + return []string{} +} + +func (self *SKsyunProvider) GetBucketCannedAcls(regionId string) []string { + return []string{ + string(cloudprovider.ACLPrivate), + string(cloudprovider.ACLPublicRead), + string(cloudprovider.ACLPublicReadWrite), + } +} + +func (self *SKsyunProvider) GetObjectCannedAcls(regionId string) []string { + return []string{ + string(cloudprovider.ACLPrivate), + string(cloudprovider.ACLPublicRead), + string(cloudprovider.ACLPublicReadWrite), + } +} + +func (self *SKsyunProvider) GetCapabilities() []string { + return self.client.GetCapabilities() +} + +func (self *SKsyunProvider) GetIamLoginUrl() string { + return "" +} + +func (self *SKsyunProvider) GetCloudRegionExternalIdPrefix() string { + return api.CLOUD_PROVIDER_KSYUN + "/" +} + +func (self *SKsyunProvider) GetMetrics(opts *cloudprovider.MetricListOptions) ([]cloudprovider.MetricValues, error) { + return nil, cloudprovider.ErrNotImplemented +} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/region.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/region.go new file mode 100644 index 0000000000..dafe5285f1 --- /dev/null +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/region.go @@ -0,0 +1,129 @@ +// 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" +) + +type SRegion struct { + multicloud.SRegion + multicloud.SNoObjectStorageRegion + multicloud.SNoLbRegion + client *SKsyunClient + + Region string + RegionName string +} + +func (self *SRegion) GetId() string { + return self.Region +} + +func (self *SRegion) GetGlobalId() string { + return fmt.Sprintf("%s/%s", api.CLOUD_PROVIDER_KSYUN, self.Region) +} + +func (self *SRegion) GetProvider() string { + return api.CLOUD_PROVIDER_KSYUN +} + +func (self *SRegion) GetCloudEnv() string { + return api.CLOUD_PROVIDER_KSYUN +} + +func (self *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] + if ok { + return geo + } + return cloudprovider.SGeographicInfo{} +} + +func (self *SRegion) GetName() string { + return self.RegionName +} + +func (self *SRegion) GetI18n() cloudprovider.SModelI18nTable { + table := cloudprovider.SModelI18nTable{} + table["name"] = cloudprovider.NewSModelI18nEntry(self.GetName()).CN(self.GetName()).EN(self.Region) + return table +} + +func (self *SRegion) GetStatus() string { + return api.CLOUD_REGION_STATUS_INSERVER +} + +func (self *SRegion) GetClient() *SKsyunClient { + return self.client +} + +func (self *SRegion) CreateEIP(opts *cloudprovider.SEip) (cloudprovider.ICloudEIP, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (region *SRegion) CreateISecurityGroup(conf *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (region *SRegion) GetISecurityGroupById(secgroupId string) (cloudprovider.ICloudSecurityGroup, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (region *SRegion) GetISecurityGroupByName(opts *cloudprovider.SecurityGroupFilterOptions) (cloudprovider.ICloudSecurityGroup, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (self *SRegion) CreateIVpc(opts *cloudprovider.VpcCreateOptions) (cloudprovider.ICloudVpc, error) { + return nil, cloudprovider.ErrNotImplemented +} + +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) GetCapabilities() []string { + return region.client.GetCapabilities() +} + +func (self *SRegion) GetIEipById(eipId string) (cloudprovider.ICloudEIP, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (self *SRegion) GetIEips() ([]cloudprovider.ICloudEIP, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (self *SRegion) GetIZones() ([]cloudprovider.ICloudZone, error) { + return nil, cloudprovider.ErrNotImplemented +} + +func (self *SRegion) GetIZoneById(id string) (cloudprovider.ICloudZone, error) { + return nil, cloudprovider.ErrNotImplemented +} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/loader/loader.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/loader/loader.go index b109c29a18..68f352239f 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/loader/loader.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/loader/loader.go @@ -29,6 +29,7 @@ import ( _ "yunion.io/x/cloudmux/pkg/multicloud/hcso/provider" _ "yunion.io/x/cloudmux/pkg/multicloud/huawei/provider" _ "yunion.io/x/cloudmux/pkg/multicloud/jdcloud/provider" // public clouds + _ "yunion.io/x/cloudmux/pkg/multicloud/ksyun/provider" _ "yunion.io/x/cloudmux/pkg/multicloud/nutanix/provider" // private clouds _ "yunion.io/x/cloudmux/pkg/multicloud/objectstore/ceph/provider" _ "yunion.io/x/cloudmux/pkg/multicloud/objectstore/provider"