mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-24 16:03:43 +08:00
feat(region): support baidu cloud
This commit is contained in:
@@ -56,6 +56,7 @@ func init() {
|
||||
cmd.CreateWithKeyword("create-proxmox", &options.SProxmoxAccountCreateOptions{})
|
||||
cmd.CreateWithKeyword("create-remotefile", &options.SRemoteFileAccountCreateOptions{})
|
||||
cmd.CreateWithKeyword("create-ksyun", &options.SKsyunCloudAccountCreateOptions{})
|
||||
cmd.CreateWithKeyword("create-baidu", &options.SBaiduCloudAccountCreateOptions{})
|
||||
|
||||
cmd.UpdateWithKeyword("update-vmware", &options.SVMwareCloudAccountUpdateOptions{})
|
||||
cmd.UpdateWithKeyword("update-aliyun", &options.SAliyunCloudAccountUpdateOptions{})
|
||||
@@ -78,6 +79,7 @@ func init() {
|
||||
cmd.UpdateWithKeyword("update-incloudsphere", &options.SInCloudSphereAccountUpdateOptions{})
|
||||
cmd.UpdateWithKeyword("update-proxmox", &options.SProxmoxAccountUpdateOptions{})
|
||||
cmd.UpdateWithKeyword("update-ksyun", &options.SKsyunCloudAccountUpdateOptions{})
|
||||
cmd.UpdateWithKeyword("update-baidu", &options.SBaiduCloudAccountUpdateOptions{})
|
||||
|
||||
cmd.Perform("update-credential", &options.CloudaccountUpdateCredentialOptions{})
|
||||
|
||||
@@ -103,6 +105,7 @@ func init() {
|
||||
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("update-credential-baidu", "update-credential", &options.SBaiduCloudAccountUpdateCredentialOptions{})
|
||||
|
||||
cmd.PerformWithKeyword("test-connectivity-google", "test-connectivity", &options.SGoogleCloudAccountUpdateCredentialOptions{})
|
||||
cmd.PerformWithKeyword("test-connectivity-vmware", "test-connectivity", &options.SVMwareCloudAccountUpdateCredentialOptions{})
|
||||
|
||||
@@ -63,6 +63,7 @@ func init() {
|
||||
"monitor",
|
||||
"bingocloud",
|
||||
"ksyun",
|
||||
"baidu",
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
@@ -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.20230807074306-1afe20f5d67a
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230807123447-600aceed37b6
|
||||
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
|
||||
|
||||
@@ -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.20230807074306-1afe20f5d67a h1:AwlwxsGXNxk80dri0FBlDb5oWSOnq5lXHeke6icd0pA=
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230807074306-1afe20f5d67a/go.mod h1:2sgCN7nRPQL3woLfdgqLDd92vwAHqtlz3KKiHxC5BAw=
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230807123447-600aceed37b6 h1:YZ2vDD4g6VqaLI43Ubi6DpsiJFDztfDAXgRRStqMiW8=
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230807123447-600aceed37b6/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=
|
||||
|
||||
@@ -66,6 +66,7 @@ const (
|
||||
CLOUD_PROVIDER_REMOTEFILE = compute.CLOUD_PROVIDER_REMOTEFILE
|
||||
CLOUD_PROVIDER_H3C = compute.CLOUD_PROVIDER_H3C
|
||||
CLOUD_PROVIDER_KSYUN = compute.CLOUD_PROVIDER_KSYUN
|
||||
CLOUD_PROVIDER_BAIDU = compute.CLOUD_PROVIDER_BAIDU
|
||||
|
||||
CLOUD_PROVIDER_GENERICS3 = compute.CLOUD_PROVIDER_GENERICS3
|
||||
CLOUD_PROVIDER_CEPH = compute.CLOUD_PROVIDER_CEPH
|
||||
@@ -144,6 +145,7 @@ var (
|
||||
CLOUD_PROVIDER_REMOTEFILE,
|
||||
CLOUD_PROVIDER_H3C,
|
||||
CLOUD_PROVIDER_KSYUN,
|
||||
CLOUD_PROVIDER_BAIDU,
|
||||
}
|
||||
|
||||
CLOUD_PROVIDER_HOST_TYPE_MAP = map[string][]string{
|
||||
@@ -227,6 +229,9 @@ var (
|
||||
CLOUD_PROVIDER_KSYUN: {
|
||||
HOST_TYPE_KSYUN,
|
||||
},
|
||||
CLOUD_PROVIDER_BAIDU: {
|
||||
HOST_TYPE_BAIDU,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -198,6 +198,7 @@ const (
|
||||
HYPERVISOR_REMOTEFILE = compute.HYPERVISOR_REMOTEFILE
|
||||
HYPERVISOR_H3C = compute.HYPERVISOR_H3C
|
||||
HYPERVISOR_KSYUN = compute.HYPERVISOR_KSYUN
|
||||
HYPERVISOR_BAIDU = compute.HYPERVISOR_BAIDU
|
||||
|
||||
// HYPERVISOR_DEFAULT = HYPERVISOR_KVM
|
||||
HYPERVISOR_DEFAULT = HYPERVISOR_KVM
|
||||
@@ -272,6 +273,7 @@ var HYPERVISORS = []string{
|
||||
HYPERVISOR_REMOTEFILE,
|
||||
HYPERVISOR_H3C,
|
||||
HYPERVISOR_KSYUN,
|
||||
HYPERVISOR_BAIDU,
|
||||
}
|
||||
|
||||
var ONECLOUD_HYPERVISORS = []string{
|
||||
@@ -292,6 +294,7 @@ var PUBLIC_CLOUD_HYPERVISORS = []string{
|
||||
HYPERVISOR_ECLOUD,
|
||||
HYPERVISOR_JDCLOUD,
|
||||
HYPERVISOR_KSYUN,
|
||||
HYPERVISOR_BAIDU,
|
||||
}
|
||||
|
||||
var PRIVATE_CLOUD_HYPERVISORS = []string{
|
||||
@@ -341,6 +344,7 @@ var HYPERVISOR_HOSTTYPE = map[string]string{
|
||||
HYPERVISOR_REMOTEFILE: HOST_TYPE_REMOTEFILE,
|
||||
HYPERVISOR_H3C: HOST_TYPE_H3C,
|
||||
HYPERVISOR_KSYUN: HOST_TYPE_KSYUN,
|
||||
HYPERVISOR_BAIDU: HOST_TYPE_BAIDU,
|
||||
}
|
||||
|
||||
var HOSTTYPE_HYPERVISOR = map[string]string{
|
||||
@@ -372,6 +376,7 @@ var HOSTTYPE_HYPERVISOR = map[string]string{
|
||||
HOST_TYPE_REMOTEFILE: HYPERVISOR_REMOTEFILE,
|
||||
HOST_TYPE_H3C: HYPERVISOR_H3C,
|
||||
HOST_TYPE_KSYUN: HYPERVISOR_KSYUN,
|
||||
HOST_TYPE_BAIDU: HYPERVISOR_BAIDU,
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
@@ -51,6 +51,7 @@ const (
|
||||
HOST_TYPE_REMOTEFILE = compute.HOST_TYPE_REMOTEFILE
|
||||
HOST_TYPE_H3C = compute.HOST_TYPE_H3C
|
||||
HOST_TYPE_KSYUN = compute.HOST_TYPE_KSYUN
|
||||
HOST_TYPE_BAIDU = compute.HOST_TYPE_BAIDU
|
||||
|
||||
HOST_TYPE_DEFAULT = HOST_TYPE_HYPERVISOR
|
||||
|
||||
@@ -142,6 +143,7 @@ var HOST_TYPES = []string{
|
||||
HOST_TYPE_REMOTEFILE,
|
||||
HOST_TYPE_H3C,
|
||||
HOST_TYPE_KSYUN,
|
||||
HOST_TYPE_BAIDU,
|
||||
}
|
||||
|
||||
var ALL_NIC_TYPES = []compute.TNicType{NIC_TYPE_IPMI, NIC_TYPE_ADMIN, NIC_TYPE_NORMAL}
|
||||
|
||||
@@ -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 SBaiduGuestDriver struct {
|
||||
SManagedVirtualizedGuestDriver
|
||||
}
|
||||
|
||||
func init() {
|
||||
driver := SBaiduGuestDriver{}
|
||||
models.RegisterGuestDriver(&driver)
|
||||
}
|
||||
|
||||
func (self *SBaiduGuestDriver) DoScheduleSKUFilter() bool { return false }
|
||||
|
||||
func (self *SBaiduGuestDriver) GetHypervisor() string {
|
||||
return api.HYPERVISOR_BAIDU
|
||||
}
|
||||
|
||||
func (self *SBaiduGuestDriver) GetProvider() string {
|
||||
return api.CLOUD_PROVIDER_BAIDU
|
||||
}
|
||||
|
||||
func (self *SBaiduGuestDriver) GetDefaultSysDiskBackend() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SBaiduGuestDriver) GetMinimalSysDiskSizeGb() int {
|
||||
return 20
|
||||
}
|
||||
|
||||
func (self *SBaiduGuestDriver) 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_BAIDU
|
||||
keys.Brand = api.CLOUD_PROVIDER_BAIDU
|
||||
keys.Hypervisor = api.HYPERVISOR_BAIDU
|
||||
return keys
|
||||
}
|
||||
|
||||
func (self *SBaiduGuestDriver) 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 *SBaiduGuestDriver) GetGuestInitialStateAfterCreate() string {
|
||||
return api.VM_READY
|
||||
}
|
||||
|
||||
func (self *SBaiduGuestDriver) GetGuestInitialStateAfterRebuild() string {
|
||||
return api.VM_READY
|
||||
}
|
||||
|
||||
func (self *SBaiduGuestDriver) AllowReconfigGuest() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SBaiduGuestDriver) IsSupportedBillingCycle(bc billing.SBillingCycle) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SBaiduGuestDriver) IsSupportPublicipToEip() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SBaiduGuestDriver) IsSupportSetAutoRenew() bool {
|
||||
return false
|
||||
}
|
||||
@@ -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 SBaiduHostDriver struct {
|
||||
SManagedVirtualizationHostDriver
|
||||
}
|
||||
|
||||
func init() {
|
||||
driver := SBaiduHostDriver{}
|
||||
models.RegisterHostDriver(&driver)
|
||||
}
|
||||
|
||||
func (self *SBaiduHostDriver) GetHostType() string {
|
||||
return api.HOST_TYPE_BAIDU
|
||||
}
|
||||
|
||||
func (self *SBaiduHostDriver) GetHypervisor() string {
|
||||
return api.HYPERVISOR_BAIDU
|
||||
}
|
||||
@@ -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 SBaiduRegionDriver struct {
|
||||
SManagedVirtualizationRegionDriver
|
||||
}
|
||||
|
||||
func init() {
|
||||
driver := SBaiduRegionDriver{}
|
||||
models.RegisterRegionDriver(&driver)
|
||||
}
|
||||
|
||||
func (self *SBaiduRegionDriver) GetProvider() string {
|
||||
return api.CLOUD_PROVIDER_BAIDU
|
||||
}
|
||||
|
||||
func (self *SBaiduRegionDriver) IsAllowSecurityGroupNameRepeat() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SBaiduRegionDriver) GenerateSecurityGroupName(name string) string {
|
||||
return name
|
||||
}
|
||||
|
||||
func (self *SBaiduRegionDriver) IsSecurityGroupBelongVpc() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SBaiduRegionDriver) ValidateCreateSnapshotData(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, storage *models.SStorage, input *api.SnapshotCreateInput) error {
|
||||
return nil
|
||||
}
|
||||
@@ -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|Ksyun" 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|Baidu" 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"`
|
||||
|
||||
@@ -1308,3 +1308,33 @@ type SKsyunCloudAccountUpdateCredentialOptions struct {
|
||||
func (opts *SKsyunCloudAccountUpdateCredentialOptions) Params() (jsonutils.JSONObject, error) {
|
||||
return jsonutils.Marshal(opts), nil
|
||||
}
|
||||
|
||||
type SBaiduCloudAccountCreateOptions struct {
|
||||
SCloudAccountCreateBaseOptions
|
||||
SAccessKeyCredential
|
||||
}
|
||||
|
||||
func (opts *SBaiduCloudAccountCreateOptions) Params() (jsonutils.JSONObject, error) {
|
||||
params := jsonutils.Marshal(opts)
|
||||
params.(*jsonutils.JSONDict).Add(jsonutils.NewString("Baidu"), "provider")
|
||||
return params, nil
|
||||
}
|
||||
|
||||
type SBaiduCloudAccountUpdateOptions struct {
|
||||
SCloudAccountUpdateBaseOptions
|
||||
}
|
||||
|
||||
func (opts *SBaiduCloudAccountUpdateOptions) Params() (jsonutils.JSONObject, error) {
|
||||
params := jsonutils.Marshal(opts).(*jsonutils.JSONDict)
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
type SBaiduCloudAccountUpdateCredentialOptions struct {
|
||||
SCloudAccountIdOptions
|
||||
SAccessKeyCredential
|
||||
}
|
||||
|
||||
func (opts *SBaiduCloudAccountUpdateCredentialOptions) Params() (jsonutils.JSONObject, error) {
|
||||
return jsonutils.Marshal(opts), nil
|
||||
}
|
||||
|
||||
@@ -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|ksyun"`
|
||||
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|baidu"`
|
||||
Region string `help:"Show servers in cloudregion"`
|
||||
WithEip *bool `help:"Show Servers with EIP"`
|
||||
WithoutEip *bool `help:"Show Servers without EIP"`
|
||||
|
||||
Vendored
+3
-1
@@ -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.20230807074306-1afe20f5d67a
|
||||
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230807123447-600aceed37b6
|
||||
## explicit; go 1.18
|
||||
yunion.io/x/cloudmux/pkg/apis
|
||||
yunion.io/x/cloudmux/pkg/apis/billing
|
||||
@@ -1456,6 +1456,8 @@ yunion.io/x/cloudmux/pkg/multicloud/azure
|
||||
yunion.io/x/cloudmux/pkg/multicloud/azure/concurrent
|
||||
yunion.io/x/cloudmux/pkg/multicloud/azure/progress
|
||||
yunion.io/x/cloudmux/pkg/multicloud/azure/provider
|
||||
yunion.io/x/cloudmux/pkg/multicloud/baidu
|
||||
yunion.io/x/cloudmux/pkg/multicloud/baidu/provider
|
||||
yunion.io/x/cloudmux/pkg/multicloud/bingocloud
|
||||
yunion.io/x/cloudmux/pkg/multicloud/bingocloud/provider
|
||||
yunion.io/x/cloudmux/pkg/multicloud/ctyun
|
||||
|
||||
+1
@@ -41,6 +41,7 @@ const (
|
||||
CLOUD_PROVIDER_REMOTEFILE = "RemoteFile"
|
||||
CLOUD_PROVIDER_H3C = "H3C"
|
||||
CLOUD_PROVIDER_KSYUN = "Ksyun"
|
||||
CLOUD_PROVIDER_BAIDU = "Baidu"
|
||||
|
||||
CLOUD_PROVIDER_GENERICS3 = "S3"
|
||||
CLOUD_PROVIDER_CEPH = "Ceph"
|
||||
|
||||
+1
@@ -74,6 +74,7 @@ const (
|
||||
HYPERVISOR_REMOTEFILE = "remotefile"
|
||||
HYPERVISOR_H3C = "h3c"
|
||||
HYPERVISOR_KSYUN = "ksyun"
|
||||
HYPERVISOR_BAIDU = "baidu"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
+1
@@ -43,6 +43,7 @@ const (
|
||||
HOST_TYPE_REMOTEFILE = "remotefile"
|
||||
HOST_TYPE_H3C = "h3c"
|
||||
HOST_TYPE_KSYUN = "ksyun"
|
||||
HOST_TYPE_BAIDU = "baidu"
|
||||
|
||||
// # possible status
|
||||
HOST_ONLINE = "online"
|
||||
|
||||
+18
@@ -50,6 +50,12 @@ var (
|
||||
City: CITY_GUANG_ZHOU,
|
||||
CountryCode: COUNTRY_CODE_CN,
|
||||
}
|
||||
RegionSuzhou = cloudprovider.SGeographicInfo{
|
||||
Latitude: 31.328,
|
||||
Longitude: 120.479,
|
||||
City: CITY_SU_ZHOU,
|
||||
CountryCode: COUNTRY_CODE_CN,
|
||||
}
|
||||
RegionDalian = cloudprovider.SGeographicInfo{
|
||||
Latitude: 38.91400300000001,
|
||||
Longitude: 121.614682,
|
||||
@@ -74,6 +80,12 @@ var (
|
||||
City: CITY_QING_DAO,
|
||||
CountryCode: COUNTRY_CODE_CN,
|
||||
}
|
||||
RegionBaoDing = cloudprovider.SGeographicInfo{
|
||||
Latitude: 38.871,
|
||||
Longitude: 115.393,
|
||||
City: CITY_BAO_DING,
|
||||
CountryCode: COUNTRY_CODE_CN,
|
||||
}
|
||||
RegionZhangjiakou = cloudprovider.SGeographicInfo{
|
||||
Latitude: 40.767544,
|
||||
Longitude: 114.886337,
|
||||
@@ -92,6 +104,12 @@ var (
|
||||
City: CITY_HANG_ZHOU,
|
||||
CountryCode: COUNTRY_CODE_CN,
|
||||
}
|
||||
RegionWuhan = cloudprovider.SGeographicInfo{
|
||||
Latitude: 30.568,
|
||||
Longitude: 114.136,
|
||||
City: CITY_WU_HAN,
|
||||
CountryCode: COUNTRY_CODE_CN,
|
||||
}
|
||||
RegionShenzhen = cloudprovider.SGeographicInfo{
|
||||
Latitude: 22.543097,
|
||||
Longitude: 114.057861,
|
||||
|
||||
+261
@@ -0,0 +1,261 @@
|
||||
// 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 baidu
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"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_BAIDU_CN = "百度云"
|
||||
BAIDU_DEFAULT_REGION = "bj"
|
||||
ISO8601 = "2006-01-02T15:04:05Z"
|
||||
)
|
||||
|
||||
type BaiduClientConfig struct {
|
||||
cpcfg cloudprovider.ProviderConfig
|
||||
accessKeyId string
|
||||
accessKeySecret string
|
||||
|
||||
debug bool
|
||||
}
|
||||
|
||||
type SBaiduClient struct {
|
||||
*BaiduClientConfig
|
||||
|
||||
client *http.Client
|
||||
lock sync.Mutex
|
||||
ctx context.Context
|
||||
|
||||
ownerId string
|
||||
}
|
||||
|
||||
func NewBaiduClientConfig(accessKeyId, accessKeySecret string) *BaiduClientConfig {
|
||||
cfg := &BaiduClientConfig{
|
||||
accessKeyId: accessKeyId,
|
||||
accessKeySecret: accessKeySecret,
|
||||
}
|
||||
return cfg
|
||||
}
|
||||
|
||||
func (self *BaiduClientConfig) Debug(debug bool) *BaiduClientConfig {
|
||||
self.debug = debug
|
||||
return self
|
||||
}
|
||||
|
||||
func (self *BaiduClientConfig) CloudproviderConfig(cpcfg cloudprovider.ProviderConfig) *BaiduClientConfig {
|
||||
self.cpcfg = cpcfg
|
||||
return self
|
||||
}
|
||||
|
||||
func NewBaiduClient(cfg *BaiduClientConfig) (*SBaiduClient, error) {
|
||||
client := &SBaiduClient{
|
||||
BaiduClientConfig: cfg,
|
||||
ctx: context.Background(),
|
||||
}
|
||||
client.ctx = context.WithValue(client.ctx, "time", time.Now())
|
||||
_, err := client.getOwnerId()
|
||||
return client, err
|
||||
}
|
||||
|
||||
func (self *SBaiduClient) GetRegions() []SRegion {
|
||||
ret := []SRegion{}
|
||||
for k, v := range regions {
|
||||
ret = append(ret, SRegion{
|
||||
client: self,
|
||||
Region: k,
|
||||
RegionName: v,
|
||||
})
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (self *SBaiduClient) GetRegion(id string) (*SRegion, error) {
|
||||
regions := self.GetRegions()
|
||||
for i := range regions {
|
||||
if regions[i].Region == id {
|
||||
regions[i].client = self
|
||||
return ®ions[i], nil
|
||||
}
|
||||
}
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func (self *SBaiduClient) getUrl(service, regionId, resource string) (string, error) {
|
||||
if len(regionId) == 0 {
|
||||
regionId = BAIDU_DEFAULT_REGION
|
||||
}
|
||||
switch service {
|
||||
case "bbc":
|
||||
return fmt.Sprintf("https://bbc.%s.baidubce.com/%s", regionId, strings.TrimPrefix(resource, "/")), nil
|
||||
case "bos":
|
||||
return fmt.Sprintf("https://%s.bcebos.com", regionId), nil
|
||||
case "billing":
|
||||
return fmt.Sprintf("https://billing.baidubce.com/%s", strings.TrimPrefix(resource, "/")), nil
|
||||
default:
|
||||
return "", errors.Wrapf(cloudprovider.ErrNotSupported, service)
|
||||
}
|
||||
}
|
||||
|
||||
func (cli *SBaiduClient) 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) {
|
||||
if cli.cpcfg.ReadOnly {
|
||||
if req.Method == "GET" {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, errors.Wrapf(cloudprovider.ErrAccountReadOnly, "%s %s", req.Method, req.URL.Path)
|
||||
}
|
||||
return nil, nil
|
||||
})
|
||||
return cli.client
|
||||
}
|
||||
|
||||
type sBaiduError struct {
|
||||
StatusCode int `json:"statusCode"`
|
||||
RequestId string `json:"requestId"`
|
||||
Code string
|
||||
Message string
|
||||
}
|
||||
|
||||
func (self *sBaiduError) Error() string {
|
||||
return jsonutils.Marshal(self).String()
|
||||
}
|
||||
|
||||
func (self *sBaiduError) ParseErrorFromJsonResponse(statusCode int, status string, body jsonutils.JSONObject) error {
|
||||
if body != nil {
|
||||
body.Unmarshal(self)
|
||||
}
|
||||
self.StatusCode = statusCode
|
||||
return self
|
||||
}
|
||||
|
||||
func (self *SBaiduClient) Do(req *http.Request) (*http.Response, error) {
|
||||
client := self.getDefaultClient()
|
||||
|
||||
req.Header.Set("Content-Type", "application/json; charset=utf-8")
|
||||
req.Header.Set("x-bce-date", time.Now().UTC().Format(ISO8601))
|
||||
req.Header.Set("host", req.Host)
|
||||
|
||||
signature, err := self.sign(req)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "sign")
|
||||
}
|
||||
|
||||
req.Header.Set("Authorization", signature)
|
||||
return client.Do(req)
|
||||
}
|
||||
|
||||
func (self *SBaiduClient) list(service, regionId, resource string, params map[string]interface{}) (jsonutils.JSONObject, error) {
|
||||
return self.request(httputils.GET, service, regionId, resource, params)
|
||||
}
|
||||
|
||||
func (self *SBaiduClient) post(service, regionId, resource string, params map[string]interface{}) (jsonutils.JSONObject, error) {
|
||||
return self.request(httputils.POST, service, regionId, resource, params)
|
||||
}
|
||||
|
||||
func (self *SBaiduClient) request(method httputils.THttpMethod, service, regionId, resource string, params map[string]interface{}) (jsonutils.JSONObject, error) {
|
||||
uri, err := self.getUrl(service, regionId, resource)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if params == nil {
|
||||
params = map[string]interface{}{}
|
||||
}
|
||||
values := url.Values{}
|
||||
if method == httputils.GET && len(params) > 0 {
|
||||
for k, v := range params {
|
||||
values.Set(k, v.(string))
|
||||
}
|
||||
uri = fmt.Sprintf("%s?%s", uri, values.Encode())
|
||||
}
|
||||
req := httputils.NewJsonRequest(method, uri, params)
|
||||
bErr := &sBaiduError{}
|
||||
client := httputils.NewJsonClient(self)
|
||||
_, resp, err := client.Send(self.ctx, req, bErr, self.debug)
|
||||
return resp, err
|
||||
}
|
||||
|
||||
func (self *SBaiduClient) 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 *SBaiduClient) getOwnerId() (string, error) {
|
||||
if len(self.ownerId) > 0 {
|
||||
return self.ownerId, nil
|
||||
}
|
||||
resp, err := self.list("bos", "bj", "/", nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
self.ownerId, err = resp.GetString("owner", "id")
|
||||
return self.ownerId, err
|
||||
}
|
||||
|
||||
func (self *SBaiduClient) GetAccountId() string {
|
||||
ownerId, _ := self.getOwnerId()
|
||||
return ownerId
|
||||
}
|
||||
|
||||
type CashBalance struct {
|
||||
CashBalance float64
|
||||
}
|
||||
|
||||
func (self *SBaiduClient) QueryBalance() (*CashBalance, error) {
|
||||
resp, err := self.post("billing", "", "/v1/finance/cash/balance", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := &CashBalance{}
|
||||
err = resp.Unmarshal(ret)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "resp.Unmarshal")
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SBaiduClient) GetCapabilities() []string {
|
||||
caps := []string{
|
||||
cloudprovider.CLOUD_CAPABILITY_COMPUTE + cloudprovider.READ_ONLY_SUFFIX,
|
||||
}
|
||||
return caps
|
||||
}
|
||||
+200
@@ -0,0 +1,200 @@
|
||||
// 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/baidu"
|
||||
)
|
||||
|
||||
type SBaiduProviderFactory struct {
|
||||
cloudprovider.SPublicCloudBaseProviderFactory
|
||||
}
|
||||
|
||||
func (self *SBaiduProviderFactory) GetId() string {
|
||||
return api.CLOUD_PROVIDER_BAIDU
|
||||
}
|
||||
|
||||
func (self *SBaiduProviderFactory) GetName() string {
|
||||
return baidu.CLOUD_PROVIDER_BAIDU_CN
|
||||
}
|
||||
|
||||
func (self *SBaiduProviderFactory) 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 *SBaiduProviderFactory) 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 *SBaiduProviderFactory) GetProvider(cfg cloudprovider.ProviderConfig) (cloudprovider.ICloudProvider, error) {
|
||||
client, err := baidu.NewBaiduClient(
|
||||
baidu.NewBaiduClientConfig(
|
||||
cfg.Account,
|
||||
cfg.Secret,
|
||||
).CloudproviderConfig(cfg),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &SBaiduProvider{
|
||||
SBaseProvider: cloudprovider.NewBaseProvider(self),
|
||||
client: client,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (self *SBaiduProviderFactory) GetClientRC(info cloudprovider.SProviderInfo) (map[string]string, error) {
|
||||
return map[string]string{
|
||||
"BAIDU_ACCESS_KEY_ID": info.Account,
|
||||
"BAIDU_ACCESS_KEY_SECRET": info.Secret,
|
||||
"BAIDU_REGION_ID": baidu.BAIDU_DEFAULT_REGION,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
factory := SBaiduProviderFactory{}
|
||||
cloudprovider.RegisterFactory(&factory)
|
||||
}
|
||||
|
||||
type SBaiduProvider struct {
|
||||
cloudprovider.SBaseProvider
|
||||
client *baidu.SBaiduClient
|
||||
}
|
||||
|
||||
func (self *SBaiduProvider) GetSysInfo() (jsonutils.JSONObject, error) {
|
||||
regions := self.client.GetRegions()
|
||||
info := jsonutils.NewDict()
|
||||
info.Add(jsonutils.NewInt(int64(len(regions))), "region_count")
|
||||
return info, nil
|
||||
}
|
||||
|
||||
func (self *SBaiduProvider) GetVersion() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SBaiduProvider) GetSubAccounts() ([]cloudprovider.SSubAccount, error) {
|
||||
return self.client.GetSubAccounts()
|
||||
}
|
||||
|
||||
func (self *SBaiduProvider) GetAccountId() string {
|
||||
return self.client.GetAccountId()
|
||||
}
|
||||
|
||||
func (self *SBaiduProvider) GetIRegions() []cloudprovider.ICloudRegion {
|
||||
regions := self.client.GetRegions()
|
||||
ret := []cloudprovider.ICloudRegion{}
|
||||
for i := range regions {
|
||||
ret = append(ret, ®ions[i])
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (self *SBaiduProvider) GetIRegionById(extId string) (cloudprovider.ICloudRegion, error) {
|
||||
region, err := self.client.GetRegion(extId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return region, nil
|
||||
}
|
||||
|
||||
func (self *SBaiduProvider) GetBalance() (*cloudprovider.SBalanceInfo, error) {
|
||||
ret := &cloudprovider.SBalanceInfo{Currency: "CNY", Status: api.CLOUD_PROVIDER_HEALTH_UNKNOWN}
|
||||
balance, err := self.client.QueryBalance()
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
ret.Status = api.CLOUD_PROVIDER_HEALTH_NORMAL
|
||||
if balance.CashBalance <= 0 {
|
||||
if balance.CashBalance < 0 {
|
||||
ret.Status = api.CLOUD_PROVIDER_HEALTH_ARREARS
|
||||
} else if balance.CashBalance < 100 {
|
||||
ret.Status = api.CLOUD_PROVIDER_HEALTH_INSUFFICIENT
|
||||
}
|
||||
}
|
||||
ret.Amount = balance.CashBalance
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SBaiduProvider) GetIProjects() ([]cloudprovider.ICloudProject, error) {
|
||||
return []cloudprovider.ICloudProject{}, nil
|
||||
}
|
||||
|
||||
func (self *SBaiduProvider) CreateIProject(name string) (cloudprovider.ICloudProject, error) {
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SBaiduProvider) GetStorageClasses(regionId string) []string {
|
||||
return []string{}
|
||||
}
|
||||
|
||||
func (self *SBaiduProvider) GetBucketCannedAcls(regionId string) []string {
|
||||
return []string{
|
||||
string(cloudprovider.ACLPrivate),
|
||||
string(cloudprovider.ACLPublicRead),
|
||||
string(cloudprovider.ACLPublicReadWrite),
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SBaiduProvider) GetObjectCannedAcls(regionId string) []string {
|
||||
return []string{
|
||||
string(cloudprovider.ACLPrivate),
|
||||
string(cloudprovider.ACLPublicRead),
|
||||
string(cloudprovider.ACLPublicReadWrite),
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SBaiduProvider) GetCapabilities() []string {
|
||||
return self.client.GetCapabilities()
|
||||
}
|
||||
|
||||
func (self *SBaiduProvider) GetIamLoginUrl() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SBaiduProvider) GetCloudRegionExternalIdPrefix() string {
|
||||
return api.CLOUD_PROVIDER_BAIDU + "/"
|
||||
}
|
||||
|
||||
func (self *SBaiduProvider) GetMetrics(opts *cloudprovider.MetricListOptions) ([]cloudprovider.MetricValues, error) {
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
}
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
// 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 baidu
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
api "yunion.io/x/cloudmux/pkg/apis/compute"
|
||||
"yunion.io/x/cloudmux/pkg/cloudprovider"
|
||||
"yunion.io/x/cloudmux/pkg/multicloud"
|
||||
)
|
||||
|
||||
var regions = map[string]string{
|
||||
"bj": "北京",
|
||||
"gz": "广州",
|
||||
"su": "苏州",
|
||||
"hkg": "香港",
|
||||
"fwh": "武汉",
|
||||
"bd": "保定",
|
||||
"sin": "新加坡",
|
||||
"fsh": "上海",
|
||||
}
|
||||
|
||||
type SRegion struct {
|
||||
multicloud.SRegion
|
||||
multicloud.SNoObjectStorageRegion
|
||||
multicloud.SNoLbRegion
|
||||
client *SBaiduClient
|
||||
|
||||
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_BAIDU, self.Region)
|
||||
}
|
||||
|
||||
func (self *SRegion) GetProvider() string {
|
||||
return api.CLOUD_PROVIDER_BAIDU
|
||||
}
|
||||
|
||||
func (self *SRegion) GetCloudEnv() string {
|
||||
return api.CLOUD_PROVIDER_BAIDU
|
||||
}
|
||||
|
||||
func (self *SRegion) GetGeographicInfo() cloudprovider.SGeographicInfo {
|
||||
geo, ok := map[string]cloudprovider.SGeographicInfo{
|
||||
"bj": api.RegionBeijing,
|
||||
"gz": api.RegionGuangzhou,
|
||||
"su": api.RegionSuzhou,
|
||||
"hkg": api.RegionHongkong,
|
||||
"fwh": api.RegionHangzhou,
|
||||
"bd": api.RegionBaoDing,
|
||||
"sin": api.RegionSingapore,
|
||||
"fsh": 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() *SBaiduClient {
|
||||
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
|
||||
}
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
// 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 baidu
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/pkg/errors"
|
||||
)
|
||||
|
||||
func uriEncode(uri string, encodeSlash bool) string {
|
||||
var byte_buf bytes.Buffer
|
||||
for _, b := range []byte(uri) {
|
||||
if (b >= 'A' && b <= 'Z') || (b >= 'a' && b <= 'z') || (b >= '0' && b <= '9') ||
|
||||
b == '-' || b == '_' || b == '.' || b == '~' || (b == '/' && !encodeSlash) {
|
||||
byte_buf.WriteByte(b)
|
||||
} else {
|
||||
byte_buf.WriteString(fmt.Sprintf("%%%02X", b))
|
||||
}
|
||||
}
|
||||
return byte_buf.String()
|
||||
}
|
||||
|
||||
func getCanonicalURIPath(path string) string {
|
||||
if len(path) == 0 {
|
||||
return "/"
|
||||
}
|
||||
canonical_path := path
|
||||
if strings.HasPrefix(path, "/") {
|
||||
canonical_path = path[1:]
|
||||
}
|
||||
|
||||
canonical_path = uriEncode(canonical_path, false)
|
||||
return "/" + canonical_path
|
||||
}
|
||||
|
||||
func getCanonicalQueryString(params url.Values) string {
|
||||
if len(params) == 0 {
|
||||
return ""
|
||||
}
|
||||
result := make([]string, 0, len(params))
|
||||
for k, v := range params {
|
||||
if strings.ToLower(k) == strings.ToLower("authorization") {
|
||||
continue
|
||||
}
|
||||
item := ""
|
||||
if len(v) == 0 {
|
||||
item = fmt.Sprintf("%s=", uriEncode(k, true))
|
||||
} else {
|
||||
item = fmt.Sprintf("%s=%s", uriEncode(k, true), uriEncode(params.Get(k), true))
|
||||
}
|
||||
result = append(result, item)
|
||||
}
|
||||
sort.Strings(result)
|
||||
return strings.Join(result, "&")
|
||||
}
|
||||
|
||||
func getCanonicalHeaders(headers http.Header,
|
||||
headersToSign map[string]bool) (string, []string) {
|
||||
canonicalHeaders := make([]string, 0, len(headers))
|
||||
signHeaders := make([]string, 0, len(headersToSign))
|
||||
for k := range headers {
|
||||
headKey := strings.ToLower(k)
|
||||
if headKey == strings.ToLower("authorization") {
|
||||
continue
|
||||
}
|
||||
_, headExists := headersToSign[headKey]
|
||||
if headExists ||
|
||||
(strings.HasPrefix(headKey, "x-bce-") &&
|
||||
(headKey != "x-bce-request-id")) {
|
||||
|
||||
headVal := strings.TrimSpace(headers.Get(k))
|
||||
encoded := uriEncode(headKey, true) + ":" + uriEncode(headVal, true)
|
||||
canonicalHeaders = append(canonicalHeaders, encoded)
|
||||
signHeaders = append(signHeaders, headKey)
|
||||
}
|
||||
}
|
||||
sort.Strings(canonicalHeaders)
|
||||
sort.Strings(signHeaders)
|
||||
return strings.Join(canonicalHeaders, "\n"), signHeaders
|
||||
}
|
||||
|
||||
func (self *SBaiduClient) sign(req *http.Request) (string, error) {
|
||||
signKeyInfo := fmt.Sprintf("%s/%s/%s/%d",
|
||||
"bce-auth-v1",
|
||||
self.accessKeyId,
|
||||
time.Now().UTC().Format(ISO8601),
|
||||
1800)
|
||||
hasher := hmac.New(sha256.New, []byte(self.accessKeySecret))
|
||||
hasher.Write([]byte(signKeyInfo))
|
||||
signKey := hex.EncodeToString(hasher.Sum(nil))
|
||||
canonicalUri := getCanonicalURIPath(req.URL.Path)
|
||||
params, err := url.ParseQuery(req.URL.RawQuery)
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "ParseQuery")
|
||||
}
|
||||
canonicalQueryString := getCanonicalQueryString(params)
|
||||
canonicalHeaders, signedHeadersArr := getCanonicalHeaders(req.Header, map[string]bool{
|
||||
"host": true,
|
||||
"Content-Length": true,
|
||||
"Content-Type": true,
|
||||
"Content-Md5": true,
|
||||
})
|
||||
|
||||
signedHeaders := ""
|
||||
if len(signedHeadersArr) > 0 {
|
||||
sort.Strings(signedHeadersArr)
|
||||
signedHeaders = strings.Join(signedHeadersArr, ";")
|
||||
}
|
||||
|
||||
canonicalParts := []string{req.Method, canonicalUri, canonicalQueryString, canonicalHeaders}
|
||||
canonicalReq := strings.Join(canonicalParts, "\n")
|
||||
hasher = hmac.New(sha256.New, []byte(signKey))
|
||||
hasher.Write([]byte(canonicalReq))
|
||||
signature := hex.EncodeToString(hasher.Sum(nil))
|
||||
|
||||
return signKeyInfo + "/" + signedHeaders + "/" + signature, nil
|
||||
}
|
||||
+3
-3
@@ -40,17 +40,17 @@ var LatitudeAndLongitude = map[string]cloudprovider.SGeographicInfo{
|
||||
"cn-nmhh1": {Latitude: 40.842358, Longitude: 111.749992, City: api.CITY_HU_HE_HAO_TE, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-shanghai2": {Latitude: 31.210344, Longitude: 121.455364, City: api.CITY_SHANG_HAI, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-snxy1": {Latitude: 34.3412614674, Longitude: 108.9398165260, City: api.CITY_XI_AN, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-hbwh1": {Latitude: 30.5927599029, Longitude: 114.3052387810, City: api.CITY_WU_HAN, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-hbwh1": api.RegionWuhan,
|
||||
"cn-hncs1": {Latitude: 28.2277765095, Longitude: 112.9388453666, City: api.CITY_CHANG_SHA, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-guangzhou2": {Latitude: 23.12911, Longitude: 113.264385, City: api.CITY_GUANG_ZHOU, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-guizhou2": {Latitude: 26.6470035286, Longitude: 106.6302113880, City: api.CITY_GUI_YANG, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-jssz1": {Latitude: 31.2983479333, Longitude: 120.5831894861, City: api.CITY_SU_ZHOU, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-jssz1": api.RegionSuzhou,
|
||||
"cn-sccd1": {Latitude: 30.572815, Longitude: 104.066803, City: api.CITY_CHENG_DU, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-guangzhou3": {Latitude: 23.12911, Longitude: 113.264385, City: api.CITY_GUANG_ZHOU, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-shanghai3": {Latitude: 31.210344, Longitude: 121.455364, City: api.CITY_SHANG_HAI, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-neimeng4": {Latitude: 40.842358, Longitude: 111.749992, City: api.CITY_HU_HE_HAO_TE, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-beijing3": {Latitude: 39.904202, Longitude: 116.407394, City: api.CITY_BEI_JING, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-baoding1": {Latitude: 38.8739745619, Longitude: 115.4646082830, City: api.CITY_BAO_DING, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-baoding1": api.RegionBaoDing,
|
||||
"cn-nj2": {Latitude: 32.0584065670, Longitude: 118.7964897811, City: api.CITY_NAN_JING, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-gdgz1": {Latitude: 23.12911, Longitude: 113.264385, City: api.CITY_GUANG_ZHOU, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-bj1": {Latitude: 39.904202, Longitude: 116.407394, City: api.CITY_BEI_JING, CountryCode: api.COUNTRY_CODE_CN},
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ var LatitudeAndLongitude = map[string]cloudprovider.SGeographicInfo{
|
||||
"beijing-1": {Latitude: 39.904202, Longitude: 116.407394, City: api.CITY_BEI_JING, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"hunan-1": {Latitude: 28.2277765095, Longitude: 112.9388453666, City: api.CITY_CHANG_SHA, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"wuxi-1": {Latitude: 31.2983479333, Longitude: 120.5831894861, City: api.CITY_SU_ZHOU, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"dongguan-1": {Latitude: 23.129110, Longitude: 113.264381, City: api.CITY_GUANG_ZHOU, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"dongguan-1": api.RegionSuzhou,
|
||||
"yaan-1": {Latitude: 30.572815, Longitude: 104.066803, City: api.CITY_CHENG_DU, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"zhengzhou-1": {Latitude: 34.7533581487, Longitude: 113.6313915479, City: api.CITY_ZHENG_ZHOU, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"beijing-2": {Latitude: 39.904202, Longitude: 116.407394, City: api.CITY_BEI_JING, CountryCode: api.COUNTRY_CODE_CN},
|
||||
|
||||
+1
@@ -21,6 +21,7 @@ import (
|
||||
_ "yunion.io/x/cloudmux/pkg/multicloud/apsara/provider" // aliyun apsara stack
|
||||
_ "yunion.io/x/cloudmux/pkg/multicloud/aws/provider"
|
||||
_ "yunion.io/x/cloudmux/pkg/multicloud/azure/provider"
|
||||
_ "yunion.io/x/cloudmux/pkg/multicloud/baidu/provider"
|
||||
_ "yunion.io/x/cloudmux/pkg/multicloud/bingocloud/provider" // private clouds
|
||||
_ "yunion.io/x/cloudmux/pkg/multicloud/ctyun/provider"
|
||||
_ "yunion.io/x/cloudmux/pkg/multicloud/ecloud/provider" // public clouds
|
||||
|
||||
Reference in New Issue
Block a user