mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-01 15:07:17 +08:00
ctyun sync
This commit is contained in:
@@ -236,6 +236,17 @@ func init() {
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&options.SCtyunCloudAccountCreateOptions{}, "cloud-account-create-ctyun", "Create a Ctyun cloud account", func(s *mcclient.ClientSession, args *options.SCtyunCloudAccountCreateOptions) error {
|
||||
params := jsonutils.Marshal(args)
|
||||
params.(*jsonutils.JSONDict).Add(jsonutils.NewString("Ctyun"), "provider")
|
||||
result, err := modules.Cloudaccounts.Create(s, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
type CloudaccountUpdateOptions struct {
|
||||
ID string `help:"ID or Name of cloud account"`
|
||||
Name string `help:"New name to update"`
|
||||
@@ -413,6 +424,19 @@ func init() {
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&options.SCtyunCloudAccountUpdateOptions{}, "cloud-account-update-ctyun", "update a Ctyun cloud account", func(s *mcclient.ClientSession, args *options.SCtyunCloudAccountUpdateOptions) error {
|
||||
params := jsonutils.Marshal(args).(*jsonutils.JSONDict)
|
||||
if params.Size() == 0 {
|
||||
return InvalidUpdateError()
|
||||
}
|
||||
result, err := modules.Cloudaccounts.Update(s, args.ID, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
type CloudaccountShowOptions struct {
|
||||
ID string `help:"ID or Name of cloud account"`
|
||||
}
|
||||
@@ -597,6 +621,16 @@ func init() {
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&options.SCtyunCloudAccountUpdateCredentialOptions{}, "cloud-account-update-credential-ctyun", "Update credential of an Ctyun cloud account", func(s *mcclient.ClientSession, args *options.SCtyunCloudAccountUpdateCredentialOptions) error {
|
||||
params := jsonutils.Marshal(args)
|
||||
result, err := modules.Cloudaccounts.PerformAction(s, args.ID, "update-credential", params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
type CloudaccountSyncOptions struct {
|
||||
ID string `help:"ID or Name of cloud account"`
|
||||
Force bool `help:"Force sync no matter what"`
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
// 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 main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"yunion.io/x/structarg"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/multicloud/ctyun"
|
||||
_ "yunion.io/x/onecloud/pkg/multicloud/ctyun/shell"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
type BaseOptions struct {
|
||||
Help bool `help:"Show help" default:"false"`
|
||||
Debug bool `help:"Show debug" default:"false"`
|
||||
AccessKey string `help:"Access key" default:"$CTYUN_ACCESS_KEY"`
|
||||
Secret string `help:"Secret" default:"$CTYUN_SECRET"`
|
||||
RegionId string `help:"RegionId" default:"$CTYUN_REGION"`
|
||||
SUBCOMMAND string `help:"ctyuncli subcommand" subcommand:"true"`
|
||||
}
|
||||
|
||||
func getSubcommandParser() (*structarg.ArgumentParser, error) {
|
||||
parse, e := structarg.NewArgumentParser(&BaseOptions{},
|
||||
"ctyuncli",
|
||||
"Command-line interface to ctyun API.",
|
||||
`See "ctyuncli help COMMAND" for help on a specific command.`)
|
||||
|
||||
if e != nil {
|
||||
return nil, e
|
||||
}
|
||||
|
||||
subcmd := parse.GetSubcommand()
|
||||
if subcmd == nil {
|
||||
return nil, fmt.Errorf("No subcommand argument.")
|
||||
}
|
||||
type HelpOptions struct {
|
||||
SUBCOMMAND string `help:"sub-command name"`
|
||||
}
|
||||
shellutils.R(&HelpOptions{}, "help", "Show help of a subcommand", func(args *HelpOptions) error {
|
||||
helpstr, e := subcmd.SubHelpString(args.SUBCOMMAND)
|
||||
if e != nil {
|
||||
return e
|
||||
} else {
|
||||
fmt.Print(helpstr)
|
||||
return nil
|
||||
}
|
||||
})
|
||||
for _, v := range shellutils.CommandTable {
|
||||
_, e := subcmd.AddSubParser(v.Options, v.Command, v.Desc, v.Callback)
|
||||
if e != nil {
|
||||
return nil, e
|
||||
}
|
||||
}
|
||||
return parse, nil
|
||||
}
|
||||
|
||||
func showErrorAndExit(e error) {
|
||||
fmt.Fprintf(os.Stderr, "%s", e)
|
||||
fmt.Fprintln(os.Stderr)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func newClient(options *BaseOptions) (*ctyun.SRegion, error) {
|
||||
if len(options.AccessKey) == 0 {
|
||||
return nil, fmt.Errorf("Missing accessKey")
|
||||
}
|
||||
|
||||
if len(options.Secret) == 0 {
|
||||
return nil, fmt.Errorf("Missing secret")
|
||||
}
|
||||
|
||||
cli, err := ctyun.NewSCtyunClient("", "", "",
|
||||
options.AccessKey, options.Secret, options.Debug)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
region := cli.GetRegion(options.RegionId)
|
||||
if region == nil {
|
||||
return nil, fmt.Errorf("No such region %s", options.RegionId)
|
||||
}
|
||||
|
||||
return region, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
parser, e := getSubcommandParser()
|
||||
if e != nil {
|
||||
showErrorAndExit(e)
|
||||
}
|
||||
e = parser.ParseArgs(os.Args[1:], false)
|
||||
options := parser.Options().(*BaseOptions)
|
||||
|
||||
if options.Help {
|
||||
fmt.Print(parser.HelpString())
|
||||
} else {
|
||||
subcmd := parser.GetSubcommand()
|
||||
subparser := subcmd.GetSubParser()
|
||||
if e != nil {
|
||||
if subparser != nil {
|
||||
fmt.Print(subparser.Usage())
|
||||
} else {
|
||||
fmt.Print(parser.Usage())
|
||||
}
|
||||
showErrorAndExit(e)
|
||||
} else {
|
||||
suboptions := subparser.Options()
|
||||
if options.SUBCOMMAND == "help" {
|
||||
e = subcmd.Invoke(suboptions)
|
||||
} else {
|
||||
var region *ctyun.SRegion
|
||||
region, e = newClient(options)
|
||||
if e != nil {
|
||||
showErrorAndExit(e)
|
||||
}
|
||||
e = subcmd.Invoke(region, suboptions)
|
||||
}
|
||||
if e != nil {
|
||||
showErrorAndExit(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,6 +40,7 @@ const (
|
||||
CLOUD_PROVIDER_UCLOUD = "Ucloud"
|
||||
CLOUD_PROVIDER_ZSTACK = "ZStack"
|
||||
CLOUD_PROVIDER_GOOGLE = "Google"
|
||||
CLOUD_PROVIDER_CTYUN = "Ctyun"
|
||||
|
||||
CLOUD_PROVIDER_GENERICS3 = "S3"
|
||||
CLOUD_PROVIDER_CEPH = "Ceph"
|
||||
@@ -65,6 +66,7 @@ const (
|
||||
CLOUD_ACCESS_ENV_AZURE_CHINA = CLOUD_PROVIDER_AZURE
|
||||
CLOUD_ACCESS_ENV_HUAWEI_GLOBAL = CLOUD_PROVIDER_HUAWEI + "-int"
|
||||
CLOUD_ACCESS_ENV_HUAWEI_CHINA = CLOUD_PROVIDER_HUAWEI
|
||||
CLOUD_ACCESS_ENV_CTYUN_CHINA = CLOUD_PROVIDER_CTYUN
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -84,6 +86,7 @@ var (
|
||||
CLOUD_PROVIDER_UCLOUD,
|
||||
CLOUD_PROVIDER_ZSTACK,
|
||||
CLOUD_PROVIDER_GOOGLE,
|
||||
CLOUD_PROVIDER_CTYUN,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -37,6 +37,23 @@ const (
|
||||
CITY_KAOHSIUNG = "Kaohsiung" //高雄市
|
||||
CITY_CHENG_DU = "Chengdu" //成都
|
||||
CITY_CHONG_QING = "Chongqing" //重庆
|
||||
CITY_LAN_ZHOU = "Lanzhou" //兰州
|
||||
CITY_TAI_YUAN = "Taiyuan" //太原
|
||||
CITY_TIAN_JIN = "Tianjin" //天津
|
||||
CITY_WU_LU_MU_QI = "Wulumuqi" //乌鲁木齐
|
||||
CITY_NAN_NING = "Nanning" //南宁
|
||||
CITY_ZHENG_ZHOU = "Zhengzhou" //郑州
|
||||
CITY_KUN_MING = "Kunming" //昆明
|
||||
CITY_XI_AN = "Xian" //西安
|
||||
CITY_HAI_KOU = "Haikou" //海口
|
||||
CITY_WU_HU = "Wuhu" //芜湖
|
||||
CITY_FU_ZHOU = "Fuzhou" //福州
|
||||
CITY_WU_HAN = "Wuhan" //武汉
|
||||
CITY_CHANG_SHA = "Changsha" //长沙
|
||||
CITY_SHU_ZHOU = "Shuzhou" //苏州
|
||||
CITY_BAO_DING = "Baoding" //保定
|
||||
CITY_NAN_JING = "Nanjing" //南京
|
||||
CITY_FO_SHAN = "Foshan" //佛山
|
||||
|
||||
// 日本
|
||||
CITY_TOKYO = "Tokyo" //东京
|
||||
|
||||
@@ -141,6 +141,7 @@ const (
|
||||
HYPERVISOR_UCLOUD = "ucloud"
|
||||
HYPERVISOR_ZSTACK = "zstack"
|
||||
HYPERVISOR_GOOGLE = "google"
|
||||
HYPERVISOR_CTYUN = "ctyun"
|
||||
|
||||
// HYPERVISOR_DEFAULT = HYPERVISOR_KVM
|
||||
HYPERVISOR_DEFAULT = HYPERVISOR_KVM
|
||||
@@ -163,6 +164,7 @@ var HYPERVISORS = []string{
|
||||
HYPERVISOR_UCLOUD,
|
||||
HYPERVISOR_ZSTACK,
|
||||
HYPERVISOR_GOOGLE,
|
||||
HYPERVISOR_CTYUN,
|
||||
}
|
||||
|
||||
var ONECLOUD_HYPERVISORS = []string{
|
||||
@@ -179,6 +181,7 @@ var PUBLIC_CLOUD_HYPERVISORS = []string{
|
||||
HYPERVISOR_HUAWEI,
|
||||
HYPERVISOR_UCLOUD,
|
||||
HYPERVISOR_GOOGLE,
|
||||
HYPERVISOR_CTYUN,
|
||||
}
|
||||
|
||||
var PRIVATE_CLOUD_HYPERVISORS = []string{
|
||||
@@ -202,6 +205,7 @@ var HYPERVISOR_HOSTTYPE = map[string]string{
|
||||
HYPERVISOR_UCLOUD: HOST_TYPE_UCLOUD,
|
||||
HYPERVISOR_ZSTACK: HOST_TYPE_ZSTACK,
|
||||
HYPERVISOR_GOOGLE: HOST_TYPE_GOOGLE,
|
||||
HYPERVISOR_CTYUN: HOST_TYPE_CTYUN,
|
||||
}
|
||||
|
||||
var HOSTTYPE_HYPERVISOR = map[string]string{
|
||||
@@ -218,6 +222,7 @@ var HOSTTYPE_HYPERVISOR = map[string]string{
|
||||
HOST_TYPE_UCLOUD: HYPERVISOR_UCLOUD,
|
||||
HOST_TYPE_ZSTACK: HYPERVISOR_ZSTACK,
|
||||
HOST_TYPE_GOOGLE: HYPERVISOR_GOOGLE,
|
||||
HOST_TYPE_CTYUN: HYPERVISOR_CTYUN,
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
@@ -32,6 +32,7 @@ const (
|
||||
HOST_TYPE_UCLOUD = "ucloud"
|
||||
HOST_TYPE_ZSTACK = "zstack"
|
||||
HOST_TYPE_GOOGLE = "google"
|
||||
HOST_TYPE_CTYUN = "ctyun"
|
||||
|
||||
HOST_TYPE_DEFAULT = HOST_TYPE_HYPERVISOR
|
||||
|
||||
@@ -108,6 +109,7 @@ var HOST_TYPES = []string{
|
||||
HOST_TYPE_OPENSTACK,
|
||||
HOST_TYPE_UCLOUD,
|
||||
HOST_TYPE_ZSTACK,
|
||||
HOST_TYPE_CTYUN,
|
||||
}
|
||||
|
||||
var NIC_TYPES = []string{NIC_TYPE_IPMI, NIC_TYPE_ADMIN}
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
// 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 compute
|
||||
|
||||
import "yunion.io/x/onecloud/pkg/apis"
|
||||
|
||||
@@ -75,6 +75,11 @@ const (
|
||||
STORAGE_GOOGLE_LOCAL_STORAGE = "local-storage" //本地SSD暂存盘 (最多8个)
|
||||
STORAGE_GOOGLE_PD_STANDARD = "pd-standard" //标准永久性磁盘
|
||||
STORAGE_GOOGLE_PD_SSD = "pd-ssd" //SSD永久性磁盘
|
||||
|
||||
// ctyun storage type
|
||||
STORAGE_CTYUN_SSD = "SSD" // 超高IO云硬盘
|
||||
STORAGE_CTYUN_SAS = "SAS" // 高IO云硬盘
|
||||
STORAGE_CTYUN_SATA = "SATA" // 普通IO云硬盘
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
// 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 apis
|
||||
|
||||
type BaseListInput struct {
|
||||
|
||||
@@ -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 (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/compute/models"
|
||||
)
|
||||
|
||||
type SCtyunGuestDriver struct {
|
||||
SManagedVirtualizedGuestDriver
|
||||
}
|
||||
|
||||
func (self *SCtyunGuestDriver) GetHypervisor() string {
|
||||
return api.HYPERVISOR_CTYUN
|
||||
}
|
||||
|
||||
func (self *SCtyunGuestDriver) GetProvider() string {
|
||||
return api.CLOUD_PROVIDER_CTYUN
|
||||
}
|
||||
|
||||
func (self *SCtyunGuestDriver) GetQuotaPlatformID() []string {
|
||||
return []string{
|
||||
api.CLOUD_ENV_PUBLIC_CLOUD,
|
||||
api.CLOUD_PROVIDER_CTYUN,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SCtyunGuestDriver) GetDefaultSysDiskBackend() string {
|
||||
return api.STORAGE_CTYUN_SAS
|
||||
}
|
||||
|
||||
func (self *SCtyunGuestDriver) GetDeployStatus() ([]string, error) {
|
||||
return []string{api.VM_READY, api.VM_RUNNING}, nil
|
||||
}
|
||||
|
||||
func (self *SCtyunGuestDriver) GetMinimalSysDiskSizeGb() int {
|
||||
return 10
|
||||
}
|
||||
|
||||
func (self *SCtyunGuestDriver) GetGuestInitialStateAfterCreate() string {
|
||||
return api.VM_RUNNING
|
||||
}
|
||||
|
||||
func (self *SCtyunGuestDriver) GetDetachDiskStatus() ([]string, error) {
|
||||
return []string{api.VM_READY, api.VM_RUNNING}, nil
|
||||
}
|
||||
|
||||
func (self *SCtyunGuestDriver) GetAttachDiskStatus() ([]string, error) {
|
||||
return []string{api.VM_READY, api.VM_RUNNING}, nil
|
||||
}
|
||||
|
||||
func (self *SCtyunGuestDriver) GetChangeConfigStatus() ([]string, error) {
|
||||
return []string{api.VM_READY}, nil
|
||||
}
|
||||
|
||||
func (self *SCtyunGuestDriver) GetRebuildRootStatus() ([]string, error) {
|
||||
return []string{api.VM_READY, api.VM_RUNNING}, nil
|
||||
}
|
||||
|
||||
func (self *SCtyunGuestDriver) GetGuestInitialStateAfterRebuild() string {
|
||||
return api.VM_RUNNING
|
||||
}
|
||||
|
||||
func (self *SCtyunGuestDriver) ValidateResizeDisk(guest *models.SGuest, disk *models.SDisk, storage *models.SStorage) error {
|
||||
if !utils.IsInStringArray(guest.Status, []string{api.VM_RUNNING, api.VM_READY}) {
|
||||
return fmt.Errorf("Cannot resize disk when guest in status %s", guest.Status)
|
||||
}
|
||||
if !utils.IsInStringArray(storage.StorageType, []string{api.STORAGE_CTYUN_SATA, api.STORAGE_CTYUN_SAS, api.STORAGE_CTYUN_SSD}) {
|
||||
return fmt.Errorf("Cannot resize disk with unsupported volumes type %s", storage.StorageType)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SCtyunGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string {
|
||||
if desc.OsType == "Windows" {
|
||||
return "Administrator"
|
||||
}
|
||||
|
||||
return "root"
|
||||
}
|
||||
|
||||
func init() {
|
||||
driver := SCtyunGuestDriver{}
|
||||
models.RegisterGuestDriver(&driver)
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
// 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 (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/compute/models"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
)
|
||||
|
||||
type SCtyunHostDriver struct {
|
||||
SManagedVirtualizationHostDriver
|
||||
}
|
||||
|
||||
func init() {
|
||||
driver := SCtyunHostDriver{}
|
||||
models.RegisterHostDriver(&driver)
|
||||
}
|
||||
|
||||
func (self *SCtyunHostDriver) GetHostType() string {
|
||||
return api.HOST_TYPE_CTYUN
|
||||
}
|
||||
|
||||
func (self *SCtyunHostDriver) GetHypervisor() string {
|
||||
return api.HYPERVISOR_CTYUN
|
||||
}
|
||||
|
||||
// 系统盘必须至少40G
|
||||
func (self *SCtyunHostDriver) ValidateDiskSize(storage *models.SStorage, sizeGb int) error {
|
||||
switch storage.StorageType {
|
||||
case api.STORAGE_CTYUN_SSD, api.STORAGE_CTYUN_SATA, api.STORAGE_CTYUN_SAS:
|
||||
if sizeGb < 10 || sizeGb > 32768 {
|
||||
return fmt.Errorf("The %s disk size must be in the range of 10G ~ 32768GB", storage.StorageType)
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("Not support create %s disk", storage.StorageType)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SCtyunHostDriver) ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, snapshot *models.SSnapshot, guests []models.SGuest, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
|
||||
if len(guests) >= 1 {
|
||||
return nil, httperrors.NewBadRequestError("Disk must be dettached")
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
// 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"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/compute/models"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
)
|
||||
|
||||
type SCtyunRegionDriver struct {
|
||||
SManagedVirtualizationRegionDriver
|
||||
}
|
||||
|
||||
func init() {
|
||||
driver := SCtyunRegionDriver{}
|
||||
models.RegisterRegionDriver(&driver)
|
||||
}
|
||||
|
||||
func (self *SCtyunRegionDriver) GetProvider() string {
|
||||
return api.CLOUD_PROVIDER_CTYUN
|
||||
}
|
||||
|
||||
func (self *SCtyunRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
|
||||
return nil, httperrors.NewNotImplementedError("%s does not currently support creating loadbalancer", self.GetProvider())
|
||||
}
|
||||
|
||||
func (self *SCtyunRegionDriver) ValidateCreateLoadbalancerAclData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
|
||||
return nil, httperrors.NewNotImplementedError("%s does not currently support creating loadbalancer acl", self.GetProvider())
|
||||
}
|
||||
|
||||
func (self *SCtyunRegionDriver) ValidateCreateLoadbalancerCertificateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
|
||||
return nil, httperrors.NewNotImplementedError("%s does not currently support creating loadbalancer certificate", self.GetProvider())
|
||||
}
|
||||
@@ -1,3 +1,17 @@
|
||||
// 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.
|
||||
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
// 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.
|
||||
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
// 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.
|
||||
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -144,6 +144,11 @@ type SS3CloudAccountCreateOptions struct {
|
||||
Endpoint string `help:"S3 endpoint" required:"true" positional:"true" json:"endpoint"`
|
||||
}
|
||||
|
||||
type SCtyunCloudAccountCreateOptions struct {
|
||||
SCloudAccountCreateBaseOptions
|
||||
SAccessKeyCredentialWithEnvironment
|
||||
}
|
||||
|
||||
// update credential options
|
||||
|
||||
type SCloudAccountUpdateCredentialBaseOptions struct {
|
||||
@@ -200,6 +205,11 @@ type SS3CloudAccountUpdateCredentialOptions struct {
|
||||
SAccessKeyCredential
|
||||
}
|
||||
|
||||
type SCtyunCloudAccountUpdateCredentialOptions struct {
|
||||
SCloudAccountUpdateCredentialBaseOptions
|
||||
SAccessKeyCredential
|
||||
}
|
||||
|
||||
// update
|
||||
|
||||
type SCloudAccountUpdateBaseOptions struct {
|
||||
@@ -257,3 +267,7 @@ type SZStackCloudAccountUpdateOptions struct {
|
||||
type SS3CloudAccountUpdateOptions struct {
|
||||
SCloudAccountUpdateBaseOptions
|
||||
}
|
||||
|
||||
type SCtyunCloudAccountUpdateOptions struct {
|
||||
SCloudAccountUpdateBaseOptions
|
||||
}
|
||||
|
||||
@@ -0,0 +1,289 @@
|
||||
// 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 ctyun
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/hmac"
|
||||
"crypto/sha1"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/util/httputils"
|
||||
)
|
||||
|
||||
const (
|
||||
CTYUN_API_HOST = "https://api.ctyun.cn"
|
||||
CLOUD_PROVIDER_CTYUN = api.CLOUD_PROVIDER_CTYUN
|
||||
CLOUD_PROVIDER_CTYUN_CN = "天翼云"
|
||||
CTYUN_DEFAULT_REGION = "cn-bj4"
|
||||
|
||||
CTYUN_API_VERSION = "2019-11-22"
|
||||
)
|
||||
|
||||
type SCtyunClient struct {
|
||||
httpClient *http.Client
|
||||
debug bool
|
||||
|
||||
providerId string
|
||||
providerName string
|
||||
projectId string // 项目ID.
|
||||
accessKey string
|
||||
secret string
|
||||
|
||||
iregions []cloudprovider.ICloudRegion
|
||||
}
|
||||
|
||||
func NewSCtyunClient(providerId string, providerName string, projectId string, accessKey string, secret string, debug bool) (*SCtyunClient, error) {
|
||||
client := &SCtyunClient{httpClient: http.DefaultClient, providerId: providerId, providerName: providerName, projectId: projectId, accessKey: accessKey, secret: secret, debug: debug}
|
||||
|
||||
err := client.init()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func (client *SCtyunClient) init() error {
|
||||
err := client.fetchRegions()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (client *SCtyunClient) fetchRegions() error {
|
||||
resp, err := client.DoGet("/apiproxy/v3/order/getZoneConfig", map[string]string{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
zones := []SZone{}
|
||||
err = resp.Unmarshal(&zones, "returnObj")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
regionIds := []string{}
|
||||
regions := map[string]SRegion{}
|
||||
for i := range zones {
|
||||
zone := zones[i]
|
||||
if region, ok := regions[zone.RegionID]; !ok {
|
||||
regionIds = append(regionIds, zone.RegionID)
|
||||
region = SRegion{
|
||||
client: client,
|
||||
Description: zone.ZoneName,
|
||||
ID: zone.RegionID,
|
||||
ParentRegionID: zone.RegionID,
|
||||
izones: []cloudprovider.ICloudZone{&zone},
|
||||
}
|
||||
|
||||
zone.region = ®ion
|
||||
zone.host = &SHost{projectId: client.projectId, zone: &zone}
|
||||
regions[zone.RegionID] = region
|
||||
} else {
|
||||
zone.region = ®ion
|
||||
zone.host = &SHost{projectId: client.projectId, zone: &zone}
|
||||
region.izones = append(region.izones, &zone)
|
||||
}
|
||||
}
|
||||
|
||||
client.iregions = []cloudprovider.ICloudRegion{}
|
||||
for k := range regions {
|
||||
region := regions[k]
|
||||
client.iregions = append(client.iregions, ®ion)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (client *SCtyunClient) DoGet(apiName string, queries map[string]string) (jsonutils.JSONObject, error) {
|
||||
return formRequest(client, httputils.GET, apiName, queries, nil)
|
||||
}
|
||||
|
||||
func (client *SCtyunClient) DoPost(apiName string, params map[string]jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
return formRequest(client, httputils.POST, apiName, nil, params)
|
||||
}
|
||||
|
||||
func formRequest(client *SCtyunClient, method httputils.THttpMethod, apiName string, queries map[string]string, params map[string]jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
header := http.Header{}
|
||||
// signer
|
||||
{
|
||||
content := []string{}
|
||||
for k, v := range queries {
|
||||
content = append(content, v)
|
||||
header.Set(k, v)
|
||||
}
|
||||
|
||||
for _, v := range params {
|
||||
c, _ := v.GetString()
|
||||
content = append(content, c)
|
||||
}
|
||||
|
||||
// contentMd5 := fmt.Sprintf("%x", md5.Sum([]byte(strings.Join(content, "\n"))))
|
||||
// contentMd5 = base64.StdEncoding.EncodeToString([]byte(contentMd5))
|
||||
contentRaw := strings.Join(content, "\n")
|
||||
contentMd5 := utils.GetMD5Base64([]byte(contentRaw))
|
||||
|
||||
// EEE, d MMM yyyy HH:mm:ss z
|
||||
// Mon, 2 Jan 2006 15:04:05 MST
|
||||
requestDate := time.Now().Format("Mon, 2 Jan 2006 15:04:05 MST")
|
||||
hashMac := hmac.New(sha1.New, []byte(client.secret))
|
||||
hashRawString := strings.Join([]string{contentMd5, requestDate, apiName}, "\n")
|
||||
hashMac.Write([]byte(hashRawString))
|
||||
hsum := base64.StdEncoding.EncodeToString(hashMac.Sum(nil))
|
||||
|
||||
header.Set("accessKey", client.accessKey)
|
||||
header.Set("contentMD5", contentMd5)
|
||||
header.Set("requestDate", requestDate)
|
||||
header.Set("hmac", hsum)
|
||||
// 平台类型,整数类型,取值范围:2或3,传2表示2.0自营资源,传3表示3.0合营资源,该参数不需要加密。
|
||||
header.Set("platform", "3")
|
||||
}
|
||||
|
||||
ioData := strings.NewReader("")
|
||||
if method == httputils.GET {
|
||||
for k, v := range queries {
|
||||
header.Set(k, v)
|
||||
}
|
||||
} else {
|
||||
datas := url.Values{}
|
||||
for k, v := range params {
|
||||
c, _ := v.GetString()
|
||||
datas.Add(k, c)
|
||||
}
|
||||
|
||||
ioData = strings.NewReader(datas.Encode())
|
||||
}
|
||||
|
||||
header.Set("Content-Length", strconv.FormatInt(int64(ioData.Len()), 10))
|
||||
header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
|
||||
ctx := context.Background()
|
||||
MAX_RETRY := 3
|
||||
retry := 0
|
||||
|
||||
for retry < MAX_RETRY {
|
||||
resp, err := httputils.Request(
|
||||
client.httpClient,
|
||||
ctx,
|
||||
method,
|
||||
CTYUN_API_HOST+apiName,
|
||||
header,
|
||||
ioData,
|
||||
client.debug)
|
||||
|
||||
_, jsonResp, err := httputils.ParseJSONResponse(resp, err, client.debug)
|
||||
if err == nil {
|
||||
if code, _ := jsonResp.Int("statusCode"); code != 800 {
|
||||
return nil, &httputils.JSONClientError{Code: 400, Details: jsonResp.String()}
|
||||
}
|
||||
|
||||
return jsonResp, nil
|
||||
}
|
||||
|
||||
switch e := err.(type) {
|
||||
case *httputils.JSONClientError:
|
||||
if e.Code >= 499 {
|
||||
time.Sleep(3 * time.Second)
|
||||
retry += 1
|
||||
continue
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("timeout for request: %s", params)
|
||||
}
|
||||
|
||||
func (self *SCtyunClient) GetIRegions() []cloudprovider.ICloudRegion {
|
||||
return self.iregions
|
||||
}
|
||||
|
||||
func (self *SCtyunClient) GetSubAccounts() ([]cloudprovider.SSubAccount, error) {
|
||||
subAccounts := make([]cloudprovider.SSubAccount, 0)
|
||||
for i := range self.iregions {
|
||||
iregion := self.iregions[i]
|
||||
|
||||
s := cloudprovider.SSubAccount{
|
||||
Name: fmt.Sprintf("%s-%s", self.providerName, iregion.GetId()),
|
||||
State: api.CLOUD_PROVIDER_CONNECTED,
|
||||
Account: fmt.Sprintf("%s/%s", self.accessKey, iregion.GetId()),
|
||||
HealthStatus: api.CLOUD_PROVIDER_HEALTH_NORMAL,
|
||||
}
|
||||
|
||||
subAccounts = append(subAccounts, s)
|
||||
}
|
||||
|
||||
return subAccounts, nil
|
||||
}
|
||||
|
||||
func (client *SCtyunClient) GetAccountId() string {
|
||||
return client.accessKey
|
||||
}
|
||||
|
||||
func (self *SCtyunClient) GetIRegionById(id string) (cloudprovider.ICloudRegion, error) {
|
||||
for i := 0; i < len(self.iregions); i += 1 {
|
||||
if self.iregions[i].GetGlobalId() == id {
|
||||
return self.iregions[i], nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func (self *SCtyunClient) GetIProjects() ([]cloudprovider.ICloudProject, error) {
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SCtyunClient) GetAccessEnv() string {
|
||||
return api.CLOUD_ACCESS_ENV_CTYUN_CHINA
|
||||
}
|
||||
|
||||
func (self *SCtyunClient) GetRegions() []SRegion {
|
||||
regions := make([]SRegion, len(self.iregions))
|
||||
for i := 0; i < len(regions); i += 1 {
|
||||
region := self.iregions[i].(*SRegion)
|
||||
regions[i] = *region
|
||||
}
|
||||
return regions
|
||||
}
|
||||
|
||||
func (self *SCtyunClient) GetRegion(regionId string) *SRegion {
|
||||
if len(regionId) == 0 {
|
||||
regionId = CTYUN_DEFAULT_REGION
|
||||
}
|
||||
for i := 0; i < len(self.iregions); i += 1 {
|
||||
if self.iregions[i].GetId() == regionId {
|
||||
return self.iregions[i].(*SRegion)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,440 @@
|
||||
// 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 ctyun
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
billing_api "yunion.io/x/onecloud/pkg/apis/billing"
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/multicloud"
|
||||
)
|
||||
|
||||
// http://ctyun-api-url/apiproxy/v3/ondemand/queryVolumes
|
||||
type SDisk struct {
|
||||
storage *SStorage
|
||||
multicloud.SDisk
|
||||
|
||||
diskDetails *DiskDetails
|
||||
|
||||
ID string `json:"id"`
|
||||
Status string `json:"status"`
|
||||
Name string `json:"name"`
|
||||
CreatedAt int64 `json:"created_at"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
Multiattach bool `json:"multiattach"`
|
||||
ReplicationStatus string `json:"replication_status"`
|
||||
SizeGB int64 `json:"size"`
|
||||
Metadata Metadata `json:"metadata"`
|
||||
VolumeType string `json:"volume_type"`
|
||||
UserID string `json:"user_id"`
|
||||
Shareable bool `json:"shareable"`
|
||||
Encrypted bool `json:"encrypted"`
|
||||
Bootable string `json:"bootable"`
|
||||
AvailabilityZone string `json:"availability_zone"`
|
||||
Attachments []Attachment `json:"attachments"`
|
||||
MasterOrderID string `json:"masterOrderId"`
|
||||
IsSysVolume int `json:"isSysVolume"`
|
||||
WorkOrderResourceID string `json:"workOrderResourceId"`
|
||||
ExpireTime int64 `json:"expireTime"`
|
||||
IsFreeze int64 `json:"isFreeze"`
|
||||
}
|
||||
|
||||
type Attachment struct {
|
||||
VolumeID string `json:"volume_id"`
|
||||
AttachmentID string `json:"attachment_id"`
|
||||
AttachedAt string `json:"attached_at"`
|
||||
ServerID string `json:"server_id"`
|
||||
Device string `json:"device"`
|
||||
ID string `json:"id"`
|
||||
}
|
||||
|
||||
type Metadata struct {
|
||||
OrderID string `json:"orderID"`
|
||||
AttachedMode string `json:"attached_mode"`
|
||||
ResourceSpecCode string `json:"resourceSpecCode"`
|
||||
ProductID string `json:"productID"`
|
||||
Readonly string `json:"readonly"`
|
||||
}
|
||||
|
||||
type DiskDetails struct {
|
||||
ID string `json:"id"`
|
||||
ResEbsID string `json:"resEbsId"`
|
||||
Size int64 `json:"size"`
|
||||
Name string `json:"name"`
|
||||
RegionID string `json:"regionId"`
|
||||
AccountID string `json:"accountId"`
|
||||
UserID string `json:"userId"`
|
||||
HostID string `json:"hostId"`
|
||||
OrderID string `json:"orderId"`
|
||||
Status int64 `json:"status"`
|
||||
Type string `json:"type"`
|
||||
VolumeStatus int64 `json:"volumeStatus"`
|
||||
CreateDate int64 `json:"createDate"`
|
||||
DueDate int64 `json:"dueDate"`
|
||||
ZoneID string `json:"zoneId"`
|
||||
ZoneName string `json:"zoneName"`
|
||||
IsSysVolume int64 `json:"isSysVolume"`
|
||||
IsPackaged int64 `json:"isPackaged"`
|
||||
WorkOrderResourceID string `json:"workOrderResourceId"`
|
||||
IsFreeze int64 `json:"isFreeze"`
|
||||
}
|
||||
|
||||
func (self *SDisk) GetBillingType() string {
|
||||
if self.ExpireTime > 0 {
|
||||
return billing_api.BILLING_TYPE_PREPAID
|
||||
}
|
||||
|
||||
return billing_api.BILLING_TYPE_POSTPAID
|
||||
}
|
||||
|
||||
func (self *SDisk) GetCreatedAt() time.Time {
|
||||
return time.Unix(self.CreatedAt/1000, 0)
|
||||
}
|
||||
|
||||
func (self *SDisk) GetExpiredAt() time.Time {
|
||||
return time.Unix(self.ExpireTime/1000, 0)
|
||||
}
|
||||
|
||||
func (self *SDisk) GetId() string {
|
||||
return self.ID
|
||||
}
|
||||
|
||||
func (self *SDisk) GetName() string {
|
||||
if len(self.Name) > 0 {
|
||||
return self.Name
|
||||
}
|
||||
|
||||
return self.ID
|
||||
}
|
||||
|
||||
func (self *SDisk) GetGlobalId() string {
|
||||
return self.GetId()
|
||||
}
|
||||
|
||||
func (self *SDisk) GetStatus() string {
|
||||
switch self.Status {
|
||||
case "creating", "downloading":
|
||||
return api.DISK_ALLOCATING
|
||||
case "available", "in-use":
|
||||
return api.DISK_READY
|
||||
case "error":
|
||||
return api.DISK_ALLOC_FAILED
|
||||
case "attaching":
|
||||
return api.DISK_ATTACHING
|
||||
case "detaching":
|
||||
return api.DISK_DETACHING
|
||||
case "restoring-backup":
|
||||
return api.DISK_REBUILD
|
||||
case "backing-up":
|
||||
return api.DISK_BACKUP_STARTALLOC
|
||||
case "error_restoring":
|
||||
return api.DISK_BACKUP_ALLOC_FAILED
|
||||
case "uploading":
|
||||
return api.DISK_SAVING
|
||||
case "extending":
|
||||
return api.DISK_RESIZING
|
||||
case "error_extending":
|
||||
return api.DISK_ALLOC_FAILED
|
||||
case "deleting":
|
||||
return api.DISK_DEALLOC
|
||||
case "error_deleting":
|
||||
return api.DISK_DEALLOC_FAILED
|
||||
case "rollbacking":
|
||||
return api.DISK_REBUILD
|
||||
case "error_rollbacking":
|
||||
return api.DISK_UNKNOWN
|
||||
default:
|
||||
return api.DISK_UNKNOWN
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SDisk) Refresh() error {
|
||||
new, err := self.storage.zone.region.GetDisk(self.GetId())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return jsonutils.Update(self, new)
|
||||
}
|
||||
|
||||
func (self *SDisk) IsEmulated() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SDisk) GetMetadata() *jsonutils.JSONDict {
|
||||
data := jsonutils.NewDict()
|
||||
data.Add(jsonutils.NewString(api.HYPERVISOR_CTYUN), "hypervisor")
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
func (self *SDisk) GetProjectId() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SDisk) GetIStorage() (cloudprovider.ICloudStorage, error) {
|
||||
return self.storage, nil
|
||||
}
|
||||
|
||||
func (self *SDisk) GetIStorageId() string {
|
||||
return self.storage.GetId()
|
||||
}
|
||||
|
||||
func (self *SDisk) GetDiskFormat() string {
|
||||
return "vhd"
|
||||
}
|
||||
|
||||
func (self *SDisk) GetDiskSizeMB() int {
|
||||
return int(self.SizeGB * 1024)
|
||||
}
|
||||
|
||||
func (self *SDisk) GetIsAutoDelete() bool {
|
||||
if len(self.Attachments) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
if self.Bootable == "true" {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SDisk) GetTemplateId() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SDisk) GetDiskType() string {
|
||||
if self.Bootable == "true" {
|
||||
return api.DISK_TYPE_SYS
|
||||
} else {
|
||||
return api.DISK_TYPE_DATA
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SDisk) GetFsFormat() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SDisk) GetIsNonPersistent() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SDisk) GetDriver() string {
|
||||
return "scsi"
|
||||
}
|
||||
|
||||
func (self *SDisk) GetCacheMode() string {
|
||||
return "none"
|
||||
}
|
||||
|
||||
func (self *SDisk) GetMountpoint() string {
|
||||
if len(self.Attachments) > 0 {
|
||||
return self.Attachments[0].Device
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SDisk) GetAccessPath() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SDisk) Delete(ctx context.Context) error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SDisk) CreateISnapshot(ctx context.Context, name string, desc string) (cloudprovider.ICloudSnapshot, error) {
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SDisk) GetISnapshot(idStr string) (cloudprovider.ICloudSnapshot, error) {
|
||||
return self.storage.zone.region.GetSnapshot(self.GetId(), idStr)
|
||||
}
|
||||
|
||||
// GET http://ctyun-api-url/apiproxy/v3/ondemand/queryVBSs
|
||||
func (self *SDisk) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) {
|
||||
snapshots, err := self.storage.zone.region.GetSnapshots(self.GetId())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SDisk.GetISnapshots")
|
||||
}
|
||||
|
||||
isnapshots := []cloudprovider.ICloudSnapshot{}
|
||||
for i := range snapshots {
|
||||
isnapshots[i] = &snapshots[i]
|
||||
}
|
||||
|
||||
return isnapshots, nil
|
||||
}
|
||||
|
||||
// POST http://ctyun-api-url/apiproxy/v3/ondemand/updateDiskBackupPolicy
|
||||
func (self *SDisk) GetExtSnapshotPolicyIds() ([]string, error) {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
func (self *SDisk) Resize(ctx context.Context, newSizeMB int64) error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SDisk) Reset(ctx context.Context, snapshotId string) (string, error) {
|
||||
return "", cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SDisk) Rebuild(ctx context.Context) error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SDisk) GetDiskDetails() (*DiskDetails, error) {
|
||||
if self.diskDetails != nil {
|
||||
return self.diskDetails, nil
|
||||
}
|
||||
|
||||
details, err := self.storage.zone.region.GetDiskDetailByDiskId(self.GetId())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SDisk.GetDiskDetails.GetDiskDetailByDiskId")
|
||||
}
|
||||
|
||||
self.diskDetails = details
|
||||
return self.diskDetails, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetDisks() ([]SDisk, error) {
|
||||
params := map[string]string{
|
||||
"regionId": self.GetId(),
|
||||
}
|
||||
|
||||
resp, err := self.client.DoGet("/apiproxy/v3/ondemand/queryVolumes", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Region.GetDisks.DoGet")
|
||||
}
|
||||
|
||||
disks := make([]SDisk, 0)
|
||||
err = resp.Unmarshal(&disks, "returnObj", "volumes")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Region.GetDisks.Unmarshal")
|
||||
}
|
||||
|
||||
for i := range disks {
|
||||
izone, err := self.GetIZoneById(disks[i].AvailabilityZone)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetDisk.GetIZoneById")
|
||||
}
|
||||
|
||||
disks[i].storage = &SStorage{
|
||||
zone: izone.(*SZone),
|
||||
storageType: disks[i].VolumeType,
|
||||
}
|
||||
}
|
||||
|
||||
return disks, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetDisk(diskId string) (*SDisk, error) {
|
||||
params := map[string]string{
|
||||
"regionId": self.GetId(),
|
||||
"volumeId": diskId,
|
||||
}
|
||||
|
||||
resp, err := self.client.DoGet("/apiproxy/v3/ondemand/queryVolumes", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Region.GetDisks.DoGet")
|
||||
}
|
||||
|
||||
disks := make([]SDisk, 0)
|
||||
err = resp.Unmarshal(&disks, "returnObj", "volumes")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Region.GetDisks.Unmarshal")
|
||||
}
|
||||
|
||||
if len(disks) == 0 {
|
||||
return nil, errors.Wrap(cloudprovider.ErrNotFound, "SRegion.GetDisk")
|
||||
} else if len(disks) == 1 {
|
||||
izone, err := self.GetIZoneById(disks[0].AvailabilityZone)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetDisk.GetIZoneById")
|
||||
}
|
||||
|
||||
disks[0].storage = &SStorage{
|
||||
zone: izone.(*SZone),
|
||||
storageType: disks[0].VolumeType,
|
||||
}
|
||||
|
||||
return &disks[0], nil
|
||||
} else {
|
||||
return nil, errors.Wrap(cloudprovider.ErrDuplicateId, "SRegion.GetDisk")
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SRegion) GetDiskDetailByDiskId(diskId string) (*DiskDetails, error) {
|
||||
params := map[string]string{
|
||||
"volumeId": diskId,
|
||||
"regionId": self.GetId(),
|
||||
}
|
||||
|
||||
resp, err := self.client.DoGet("/apiproxy/v3/queryDataDiskDetail", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Region.GetDiskDetailByDiskId.DoGet")
|
||||
}
|
||||
|
||||
disk := &DiskDetails{}
|
||||
err = resp.Unmarshal(disk, "returnObj")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Region.GetDiskDetailByDiskId.Unmarshal")
|
||||
}
|
||||
|
||||
return disk, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) CreateDisk(zoneId, name, diskType, size string) (*SDisk, error) {
|
||||
diskParams := jsonutils.NewDict()
|
||||
diskParams.Set("regionId", jsonutils.NewString(self.GetId()))
|
||||
diskParams.Set("zoneId", jsonutils.NewString(zoneId))
|
||||
diskParams.Set("name", jsonutils.NewString(name))
|
||||
diskParams.Set("type", jsonutils.NewString(diskType))
|
||||
diskParams.Set("size", jsonutils.NewString(size))
|
||||
diskParams.Set("count", jsonutils.NewString("1"))
|
||||
|
||||
params := map[string]jsonutils.JSONObject{
|
||||
"createVolumeInfo": diskParams,
|
||||
}
|
||||
|
||||
resp, err := self.client.DoPost("/apiproxy/v3/ondemand/createVolume", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Region.CreateDisk.DoPost")
|
||||
}
|
||||
|
||||
disk := &SDisk{}
|
||||
err = resp.Unmarshal(disk)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Region.CreateDisk.Unmarshal")
|
||||
}
|
||||
|
||||
izone, err := self.GetIZoneById(disk.AvailabilityZone)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.CreateDisk.GetIZoneById")
|
||||
}
|
||||
|
||||
disk.storage = &SStorage{
|
||||
zone: izone.(*SZone),
|
||||
storageType: disk.VolumeType,
|
||||
}
|
||||
|
||||
return disk, nil
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
// 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 ctyun
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
type SDiskBacupPolicy struct {
|
||||
region *SRegion
|
||||
|
||||
PolicyResourceCount int64 `json:"policy_resource_count"`
|
||||
BackupPolicyName string `json:"backup_policy_name"`
|
||||
ScheduledPolicy ScheduledPolicy `json:"scheduled_policy"`
|
||||
BackupPolicyID string `json:"backup_policy_id"`
|
||||
}
|
||||
|
||||
type ScheduledPolicy struct {
|
||||
RententionNum int `json:"rentention_num"`
|
||||
StartTime string `json:"start_time"`
|
||||
Status string `json:"status"`
|
||||
RemainFirstBackupOfCurMonth string `json:"remain_first_backup_of_curMonth"`
|
||||
Frequency int `json:"frequency"`
|
||||
}
|
||||
|
||||
func (self *SDiskBacupPolicy) GetId() string {
|
||||
return self.BackupPolicyID
|
||||
}
|
||||
|
||||
func (self *SDiskBacupPolicy) GetName() string {
|
||||
return self.BackupPolicyName
|
||||
}
|
||||
|
||||
func (self *SDiskBacupPolicy) GetGlobalId() string {
|
||||
return self.GetId()
|
||||
}
|
||||
|
||||
func (self *SDiskBacupPolicy) GetStatus() string {
|
||||
if self.ScheduledPolicy.Status == "ON" || self.ScheduledPolicy.Status == "OFF" {
|
||||
return api.SNAPSHOT_POLICY_READY
|
||||
}
|
||||
return api.SNAPSHOT_POLICY_UNKNOWN
|
||||
}
|
||||
|
||||
func (self *SDiskBacupPolicy) Refresh() error {
|
||||
policy, err := self.region.GetDiskBackupPolicy(self.GetId())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "SDiskBacupPolicy.Refresh")
|
||||
}
|
||||
|
||||
err = jsonutils.Update(self, policy)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "SDiskBacupPolicy.Refresh.Update")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SDiskBacupPolicy) IsEmulated() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SDiskBacupPolicy) GetMetadata() *jsonutils.JSONDict {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SDiskBacupPolicy) GetProjectId() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SDiskBacupPolicy) IsActivated() bool {
|
||||
if self.ScheduledPolicy.Status == "ON" {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SDiskBacupPolicy) GetRetentionDays() int {
|
||||
return self.ScheduledPolicy.RententionNum
|
||||
}
|
||||
|
||||
func (self *SDiskBacupPolicy) GetRepeatWeekdays() ([]int, error) {
|
||||
return []int{self.ScheduledPolicy.Frequency}, nil
|
||||
}
|
||||
|
||||
func (self *SDiskBacupPolicy) GetTimePoints() ([]int, error) {
|
||||
ret, err := strconv.Atoi(self.ScheduledPolicy.StartTime[0:2])
|
||||
return []int{ret}, err
|
||||
}
|
||||
|
||||
func (self *SRegion) GetDiskBackupPolices() ([]SDiskBacupPolicy, error) {
|
||||
params := map[string]string{
|
||||
"regionId": self.GetId(),
|
||||
}
|
||||
|
||||
resp, err := self.client.DoGet("/apiproxy/v3/ondemand/queryDiskBackupPolicys", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetDiskBackupPolices.DoGet")
|
||||
}
|
||||
|
||||
ret := make([]SDiskBacupPolicy, 0)
|
||||
err = resp.Unmarshal(&ret, "returnObj", "backup_policies")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetDiskBackupPolices.Unmarshal")
|
||||
}
|
||||
|
||||
for i := range ret {
|
||||
ret[i].region = self
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetDiskBackupPolicy(policyId string) (*SDiskBacupPolicy, error) {
|
||||
polices, err := self.GetDiskBackupPolices()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetDiskBackupPolicy.GetDiskBackupPolices")
|
||||
}
|
||||
|
||||
for i := range polices {
|
||||
policy := polices[i]
|
||||
if policy.BackupPolicyID == policyId {
|
||||
return &policy, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors.Wrap(cloudprovider.ErrNotFound, "SRegion.GetDiskBackupPolicy")
|
||||
}
|
||||
|
||||
func (self *SRegion) CreateDiskBackupPolicy(name, startTime, frequency, rententionNum, firstBackup, status string) error {
|
||||
policyParams := jsonutils.NewDict()
|
||||
policyParams.Set("policyName", jsonutils.NewString(name))
|
||||
scheduleParams := jsonutils.NewDict()
|
||||
scheduleParams.Set("startTime", jsonutils.NewString(startTime))
|
||||
scheduleParams.Set("frequency", jsonutils.NewString(frequency))
|
||||
scheduleParams.Set("rententionNum", jsonutils.NewString(rententionNum))
|
||||
scheduleParams.Set("firstBackup", jsonutils.NewString(firstBackup))
|
||||
scheduleParams.Set("status", jsonutils.NewString(status))
|
||||
policyParams.Set("scheduledPolicy", scheduleParams)
|
||||
|
||||
params := map[string]jsonutils.JSONObject{
|
||||
"regionId": jsonutils.NewString(self.GetId()),
|
||||
"jsonStr": policyParams,
|
||||
}
|
||||
|
||||
_, err := self.client.DoPost("/apiproxy/v3/ondemand/createDiskBackupPolicy", params)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "SRegion.CreateDiskBackupPolicy.DoPost")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SRegion) BindingDiskBackupPolicy(policyId, resourceId, resourceType string) error {
|
||||
policyParams := jsonutils.NewDict()
|
||||
policyParams.Set("policyId", jsonutils.NewString(policyId))
|
||||
resourcesParams := jsonutils.NewArray()
|
||||
resourcesParam := jsonutils.NewDict()
|
||||
resourcesParam.Set("resourceId", jsonutils.NewString(resourceId))
|
||||
resourcesParam.Set("resourceType", jsonutils.NewString(resourceType))
|
||||
resourcesParams.Add(resourcesParam)
|
||||
policyParams.Set("resources", resourcesParams)
|
||||
|
||||
params := map[string]jsonutils.JSONObject{
|
||||
"regionId": jsonutils.NewString(self.GetId()),
|
||||
"jsonStr": policyParams,
|
||||
}
|
||||
|
||||
_, err := self.client.DoPost("/apiproxy/v3/ondemand/bindResourceToPolicy", params)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "SRegion.BindingDiskBackupPolicy.DoPost")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SRegion) UnBindDiskBackupPolicy(policyId, resourceId string) error {
|
||||
resourcesParams := jsonutils.NewArray()
|
||||
resourcesParam := jsonutils.NewDict()
|
||||
resourcesParam.Set("resource_id", jsonutils.NewString(resourceId))
|
||||
resourcesParams.Add(resourcesParam)
|
||||
|
||||
params := map[string]jsonutils.JSONObject{
|
||||
"regionId": jsonutils.NewString(self.GetId()),
|
||||
"jsonStr": resourcesParams,
|
||||
"policyId": jsonutils.NewString(policyId),
|
||||
}
|
||||
|
||||
_, err := self.client.DoPost("/apiproxy/v3/ondemand/unBindResourceToPolicy", params)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "SRegion.UnBindDiskBackupPolicy.DoPost")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
package ctyun // import "yunion.io/x/onecloud/pkg/multicloud/ctyun"
|
||||
@@ -0,0 +1,264 @@
|
||||
// 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 ctyun
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
billing_api "yunion.io/x/onecloud/pkg/apis/billing"
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
type SEip struct {
|
||||
region *SRegion
|
||||
|
||||
IPVersion int64 `json:"ip_version"`
|
||||
BandwidthShareType string `json:"bandwidth_share_type"`
|
||||
Type string `json:"type"`
|
||||
PrivateIPAddress string `json:"private_ip_address"`
|
||||
EnterpriseProjectID string `json:"enterprise_project_id"`
|
||||
Status string `json:"status"`
|
||||
PublicIPAddress string `json:"public_ip_address"`
|
||||
ID string `json:"id"`
|
||||
TenantID string `json:"tenant_id"`
|
||||
Profile Profile `json:"profile"`
|
||||
BandwidthName string `json:"bandwidth_name"`
|
||||
BandwidthID string `json:"bandwidth_id"`
|
||||
PortID string `json:"port_id"`
|
||||
BandwidthSize int `json:"bandwidth_size"`
|
||||
CreateTime int64 `json:"create_time"`
|
||||
MasterOrderID string `json:"masterOrderId"`
|
||||
WorkOrderResourceID string `json:"workOrderResourceId"`
|
||||
ExpireTime int64 `json:"expireTime"`
|
||||
IsFreeze int64 `json:"isFreeze"`
|
||||
}
|
||||
|
||||
func (self *SEip) GetBillingType() string {
|
||||
if len(self.MasterOrderID) > 0 {
|
||||
return billing_api.BILLING_TYPE_PREPAID
|
||||
} else {
|
||||
return billing_api.BILLING_TYPE_POSTPAID
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SEip) GetCreatedAt() time.Time {
|
||||
return time.Unix(self.CreateTime/1000, 0)
|
||||
}
|
||||
|
||||
func (self *SEip) GetExpiredAt() time.Time {
|
||||
return time.Unix(self.ExpireTime/1000, 0)
|
||||
}
|
||||
|
||||
func (self *SEip) GetId() string {
|
||||
return self.ID
|
||||
}
|
||||
|
||||
func (self *SEip) GetName() string {
|
||||
return self.BandwidthName
|
||||
}
|
||||
|
||||
func (self *SEip) GetGlobalId() string {
|
||||
return self.GetId()
|
||||
}
|
||||
|
||||
func (self *SEip) GetStatus() string {
|
||||
switch self.Status {
|
||||
case "bind", "unbind":
|
||||
return api.EIP_STATUS_READY
|
||||
case "binding":
|
||||
return api.EIP_STATUS_ALLOCATE
|
||||
case "error":
|
||||
return api.EIP_STATUS_ALLOCATE_FAIL
|
||||
case "unbinding":
|
||||
return api.EIP_STATUS_DEALLOCATE
|
||||
default:
|
||||
return api.EIP_STATUS_UNKNOWN
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SEip) Refresh() error {
|
||||
if self.IsEmulated() {
|
||||
return nil
|
||||
}
|
||||
new, err := self.region.GetEip(self.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return jsonutils.Update(self, new)
|
||||
}
|
||||
|
||||
func (self *SEip) IsEmulated() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SEip) GetMetadata() *jsonutils.JSONDict {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SEip) GetProjectId() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SEip) GetIpAddr() string {
|
||||
return self.PublicIPAddress
|
||||
}
|
||||
|
||||
func (self *SEip) GetMode() string {
|
||||
return api.EIP_MODE_STANDALONE_EIP
|
||||
}
|
||||
|
||||
func (self *SEip) GetINetworkId() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SEip) GetAssociationType() string {
|
||||
orders, err := self.region.GetOrder(self.WorkOrderResourceID)
|
||||
if err != nil {
|
||||
log.Errorf("SEip.GetAssociationType %s", err)
|
||||
return ""
|
||||
}
|
||||
|
||||
for i := range orders {
|
||||
order := orders[i]
|
||||
if strings.Contains(order.ResourceType, "LOADBALANCER") {
|
||||
return api.EIP_ASSOCIATE_TYPE_ELB
|
||||
} else {
|
||||
return api.EIP_ASSOCIATE_TYPE_SERVER
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SEip) GetAssociationExternalId() string {
|
||||
return self.WorkOrderResourceID
|
||||
}
|
||||
|
||||
// http://ctyun-api-url/apiproxy/v3/queryNetworkDetail
|
||||
func (self *SEip) GetBandwidth() int {
|
||||
return self.BandwidthSize
|
||||
}
|
||||
|
||||
func (self *SEip) GetInternetChargeType() string {
|
||||
// todo: fix me
|
||||
return api.EIP_CHARGE_TYPE_BY_BANDWIDTH
|
||||
}
|
||||
|
||||
func (self *SEip) Delete() error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SEip) Associate(instanceId string) error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SEip) Dissociate() error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SEip) ChangeBandwidth(bw int) error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
type Profile struct {
|
||||
OrderID string `json:"order_id"`
|
||||
RegionID string `json:"region_id"`
|
||||
UserID string `json:"user_id"`
|
||||
ProductID string `json:"product_id"`
|
||||
}
|
||||
|
||||
func (self *SRegion) GetEips() ([]SEip, error) {
|
||||
params := map[string]string{
|
||||
"regionId": self.GetId(),
|
||||
}
|
||||
|
||||
eips := make([]SEip, 0)
|
||||
resp, err := self.client.DoGet("/apiproxy/v3/ondemand/queryIps", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetEips.DoGet")
|
||||
}
|
||||
|
||||
err = resp.Unmarshal(&eips, "returnObj", "publicips")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetEips.Unmarshal")
|
||||
}
|
||||
|
||||
for i := range eips {
|
||||
eips[i].region = self
|
||||
}
|
||||
|
||||
return eips, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetEip(eipId string) (*SEip, error) {
|
||||
params := map[string]string{
|
||||
"regionId": self.GetId(),
|
||||
"publicIpId": eipId,
|
||||
}
|
||||
|
||||
eips := make([]SEip, 0)
|
||||
resp, err := self.client.DoGet("/apiproxy/v3/ondemand/queryIps", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetEip.DoGet")
|
||||
}
|
||||
|
||||
err = resp.Unmarshal(&eips, "returnObj", "publicips")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetEip.Unmarshal")
|
||||
}
|
||||
|
||||
if len(eips) == 0 {
|
||||
return nil, errors.Wrap(cloudprovider.ErrNotFound, "SRegion.GetEip")
|
||||
} else if len(eips) == 1 {
|
||||
eips[0].region = self
|
||||
return &eips[0], nil
|
||||
} else {
|
||||
return nil, errors.Wrap(cloudprovider.ErrDuplicateId, "SRegion.GetEip")
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SRegion) CreateEip(zoneId, name, size, shareType string) (*SEip, error) {
|
||||
eipParams := jsonutils.NewDict()
|
||||
eipParams.Set("regionId", jsonutils.NewString(self.GetId()))
|
||||
eipParams.Set("zoneId", jsonutils.NewString(zoneId))
|
||||
eipParams.Set("name", jsonutils.NewString(name))
|
||||
eipParams.Set("type", jsonutils.NewString("5_telcom"))
|
||||
eipParams.Set("size", jsonutils.NewString(size))
|
||||
eipParams.Set("shareType", jsonutils.NewString(shareType))
|
||||
|
||||
params := map[string]jsonutils.JSONObject{
|
||||
"createIpInfo": eipParams,
|
||||
}
|
||||
|
||||
eip := &SEip{}
|
||||
resp, err := self.client.DoPost("/apiproxy/v3/ondemand/createIp", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.CreateEip.DoPost")
|
||||
}
|
||||
|
||||
err = resp.Unmarshal(eip, "returnObj")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.CreateEip.Unmarshal")
|
||||
}
|
||||
|
||||
eip.region = self
|
||||
return eip, nil
|
||||
}
|
||||
@@ -0,0 +1,231 @@
|
||||
// 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 ctyun
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/multicloud"
|
||||
)
|
||||
|
||||
type SHost struct {
|
||||
multicloud.SHostBase
|
||||
zone *SZone
|
||||
|
||||
projectId string
|
||||
}
|
||||
|
||||
func (self *SHost) GetId() string {
|
||||
return fmt.Sprintf("%s-%s", self.zone.region.client.providerId, self.zone.GetId())
|
||||
}
|
||||
|
||||
func (self *SHost) GetName() string {
|
||||
return fmt.Sprintf("%s-%s", self.zone.region.client.providerName, self.zone.GetId())
|
||||
}
|
||||
|
||||
func (self *SHost) GetGlobalId() string {
|
||||
return self.GetId()
|
||||
}
|
||||
|
||||
func (self *SHost) GetStatus() string {
|
||||
return api.HOST_STATUS_RUNNING
|
||||
}
|
||||
|
||||
func (self *SHost) Refresh() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SHost) IsEmulated() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SHost) GetMetadata() *jsonutils.JSONDict {
|
||||
return nil
|
||||
}
|
||||
|
||||
// http://ctyun-api-url/apiproxy/v3/ondemand/queryVMs
|
||||
func (self *SHost) GetIVMs() ([]cloudprovider.ICloudVM, error) {
|
||||
vms, err := self.zone.region.GetVMs()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SHost.GetVMs")
|
||||
}
|
||||
|
||||
ivms := make([]cloudprovider.ICloudVM, len(vms))
|
||||
for i := range vms {
|
||||
ivms[i] = &vms[i]
|
||||
}
|
||||
|
||||
return ivms, nil
|
||||
}
|
||||
|
||||
// http://ctyun-api-url/apiproxy/v3/ondemand/queryVMDetail
|
||||
// http://ctyun-api-url/apiproxy/v3/queryVMDetail
|
||||
func (self *SHost) GetIVMById(id string) (cloudprovider.ICloudVM, error) {
|
||||
return self.zone.region.GetIVMById(id)
|
||||
}
|
||||
|
||||
func (self *SHost) GetIWires() ([]cloudprovider.ICloudWire, error) {
|
||||
return self.zone.GetIWires()
|
||||
}
|
||||
|
||||
func (self *SHost) GetIStorages() ([]cloudprovider.ICloudStorage, error) {
|
||||
return self.zone.GetIStorages()
|
||||
}
|
||||
|
||||
func (self *SHost) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) {
|
||||
return self.zone.GetIStorageById(id)
|
||||
}
|
||||
|
||||
func (self *SHost) GetEnabled() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SHost) GetHostStatus() string {
|
||||
return api.HOST_ONLINE
|
||||
}
|
||||
|
||||
func (self *SHost) GetAccessIp() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SHost) GetAccessMac() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SHost) GetSysInfo() jsonutils.JSONObject {
|
||||
info := jsonutils.NewDict()
|
||||
info.Add(jsonutils.NewString(api.CLOUD_PROVIDER_CTYUN), "manufacture")
|
||||
return info
|
||||
}
|
||||
|
||||
func (self *SHost) GetSN() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SHost) GetCpuCount() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (self *SHost) GetNodeCount() int8 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (self *SHost) GetCpuDesc() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SHost) GetCpuMhz() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (self *SHost) GetMemSizeMB() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (self *SHost) GetStorageSizeMB() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (self *SHost) GetStorageType() string {
|
||||
return api.DISK_TYPE_HYBRID
|
||||
}
|
||||
|
||||
func (self *SHost) GetHostType() string {
|
||||
return api.HOST_TYPE_CTYUN
|
||||
}
|
||||
|
||||
func (self *SHost) GetIsMaintenance() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SHost) GetVersion() string {
|
||||
return CTYUN_API_VERSION
|
||||
}
|
||||
|
||||
func (self *SHost) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudprovider.ICloudVM, error) {
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SHost) GetIHostNics() ([]cloudprovider.ICloudHostNetInterface, error) {
|
||||
return nil, cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
func (self *SRegion) getVMs(vmId string) ([]SInstance, error) {
|
||||
params := map[string]string{
|
||||
"regionId": self.GetId(),
|
||||
}
|
||||
|
||||
if len(vmId) > 0 {
|
||||
params["vmId"] = vmId
|
||||
}
|
||||
|
||||
resp, err := self.client.DoGet("/apiproxy/v3/ondemand/queryVMs", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.getVMs.DoGet")
|
||||
}
|
||||
|
||||
ret := make([]SInstance, 0)
|
||||
err = resp.Unmarshal(&ret, "returnObj", "servers")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.getVMs.Unmarshal")
|
||||
}
|
||||
|
||||
for i := range ret {
|
||||
izone, err := self.GetIZoneById(ret[i].OSEXTAZAvailabilityZone)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.getVMs.GetIZoneById")
|
||||
}
|
||||
|
||||
ret[i].host = &SHost{
|
||||
zone: izone.(*SZone),
|
||||
projectId: self.client.projectId,
|
||||
}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetVMs() ([]SInstance, error) {
|
||||
return self.getVMs("")
|
||||
}
|
||||
|
||||
func (self *SRegion) GetVMById(vmId string) (*SInstance, error) {
|
||||
vms, err := self.getVMs(vmId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetVMById")
|
||||
}
|
||||
|
||||
if len(vms) == 0 {
|
||||
return nil, errors.Wrap(cloudprovider.ErrNotFound, "SRegion.GetVMById")
|
||||
} else if len(vms) == 1 {
|
||||
izone, err := self.GetIZoneById(vms[0].OSEXTAZAvailabilityZone)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetVMById.GetIZoneById")
|
||||
}
|
||||
|
||||
vms[0].host = &SHost{
|
||||
zone: izone.(*SZone),
|
||||
projectId: self.client.projectId,
|
||||
}
|
||||
return &vms[0], nil
|
||||
} else {
|
||||
return nil, errors.Wrap(cloudprovider.ErrDuplicateId, "SRegion.GetVMById")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
// 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 ctyun
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/util/imagetools"
|
||||
)
|
||||
|
||||
const (
|
||||
ImageOwnerPublic string = "gold" // 公共镜像:gold
|
||||
ImageOwnerSelf string = "private" // 私有镜像:private
|
||||
ImageOwnerShared string = "shared" // 共享镜像:shared
|
||||
)
|
||||
|
||||
// http://ctyun-api-url/apiproxy/v3/order/getImages
|
||||
type SImage struct {
|
||||
storageCache *SStoragecache
|
||||
|
||||
ID string `json:"id"`
|
||||
OSType string `json:"osType"`
|
||||
Platform string `json:"platform"`
|
||||
Name string `json:"name"`
|
||||
OSBit int64 `json:"osBit"`
|
||||
MinRAM int64 `json:"minRam"`
|
||||
MinDisk int64 `json:"minDisk"`
|
||||
ImageType string `json:"imageType"`
|
||||
Virtual bool `json:"virtual"`
|
||||
}
|
||||
|
||||
func (self *SImage) GetCreatedAt() time.Time {
|
||||
return time.Time{}
|
||||
}
|
||||
|
||||
func (self *SImage) GetId() string {
|
||||
return self.ID
|
||||
}
|
||||
|
||||
func (self *SImage) GetName() string {
|
||||
return self.Name
|
||||
}
|
||||
|
||||
func (self *SImage) GetGlobalId() string {
|
||||
return self.GetId()
|
||||
}
|
||||
|
||||
func (self *SImage) GetStatus() string {
|
||||
return api.CACHED_IMAGE_STATUS_READY
|
||||
}
|
||||
|
||||
func (self *SImage) Refresh() error {
|
||||
new, err := self.storageCache.region.GetImage(self.GetId())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return jsonutils.Update(self, new)
|
||||
}
|
||||
|
||||
func (self *SImage) IsEmulated() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SImage) GetMetadata() *jsonutils.JSONDict {
|
||||
data := jsonutils.NewDict()
|
||||
if self.OSBit > 0 {
|
||||
data.Add(jsonutils.NewString(self.GetOsArch()), "os_arch")
|
||||
}
|
||||
if len(self.OSType) > 0 {
|
||||
data.Add(jsonutils.NewString(self.GetOsType()), "os_name")
|
||||
}
|
||||
if len(self.Platform) > 0 {
|
||||
data.Add(jsonutils.NewString(self.GetOsDist()), "os_distribution")
|
||||
}
|
||||
|
||||
data.Add(jsonutils.NewString(self.GetOsVersion()), "os_version")
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
func (self *SImage) Delete(ctx context.Context) error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SImage) GetIStoragecache() cloudprovider.ICloudStoragecache {
|
||||
return self.storageCache
|
||||
}
|
||||
|
||||
func (self *SImage) GetSizeByte() int64 {
|
||||
return self.MinDisk * 1024 * 1024 * 1024
|
||||
}
|
||||
|
||||
func (self *SImage) GetImageType() string {
|
||||
switch self.ImageType {
|
||||
case "gold":
|
||||
return cloudprovider.CachedImageTypeSystem
|
||||
case "private":
|
||||
return cloudprovider.CachedImageTypeCustomized
|
||||
case "shared":
|
||||
return cloudprovider.CachedImageTypeShared
|
||||
default:
|
||||
return cloudprovider.CachedImageTypeCustomized
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SImage) GetImageStatus() string {
|
||||
return cloudprovider.IMAGE_STATUS_ACTIVE
|
||||
}
|
||||
|
||||
func (self *SImage) GetOsType() string {
|
||||
return self.OSType
|
||||
}
|
||||
|
||||
func (self *SImage) GetOsDist() string {
|
||||
return self.Platform
|
||||
}
|
||||
|
||||
func (self *SImage) GetOsVersion() string {
|
||||
return imagetools.NormalizeImageInfo(self.Name, "", "", "", "").OsVersion
|
||||
}
|
||||
|
||||
func (self *SImage) GetOsArch() string {
|
||||
return strconv.Itoa(int(self.OSBit))
|
||||
}
|
||||
|
||||
func (self *SImage) GetMinOsDiskSizeGb() int {
|
||||
return int(self.MinDisk)
|
||||
}
|
||||
|
||||
func (self *SImage) GetMinRamSizeMb() int {
|
||||
return int(self.MinRAM)
|
||||
}
|
||||
|
||||
func (self *SImage) GetImageFormat() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SImage) GetCreateTime() time.Time {
|
||||
return time.Time{}
|
||||
}
|
||||
|
||||
func (self *SRegion) GetImages(imageType string) ([]SImage, error) {
|
||||
params := map[string]string{
|
||||
"regionId": self.GetId(),
|
||||
"imageType": imageType,
|
||||
}
|
||||
|
||||
resp, err := self.client.DoGet("/apiproxy/v3/order/getImages", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Region.GetImages.DoGet")
|
||||
}
|
||||
|
||||
images := make([]SImage, 0)
|
||||
err = resp.Unmarshal(&images, "returnObj")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Region.GetImages.Unmarshal")
|
||||
}
|
||||
|
||||
for i := range images {
|
||||
images[i].storageCache = &SStoragecache{
|
||||
region: self,
|
||||
}
|
||||
}
|
||||
|
||||
return images, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetImage(imageId string) (*SImage, error) {
|
||||
images, err := self.GetImages("")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetImage.GetImages")
|
||||
}
|
||||
|
||||
for i := range images {
|
||||
if images[i].GetId() == imageId {
|
||||
images[i].storageCache = &SStoragecache{
|
||||
region: self,
|
||||
}
|
||||
|
||||
return &images[i], nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors.Wrap(cloudprovider.ErrNotFound, "SRegion.GetImage")
|
||||
}
|
||||
@@ -0,0 +1,560 @@
|
||||
// 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 ctyun
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
billing_api "yunion.io/x/onecloud/pkg/apis/billing"
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/multicloud"
|
||||
"yunion.io/x/onecloud/pkg/util/billing"
|
||||
)
|
||||
|
||||
type SInstance struct {
|
||||
multicloud.SInstanceBase
|
||||
|
||||
host *SHost
|
||||
image *SImage
|
||||
|
||||
vmDetails *InstanceDetails
|
||||
|
||||
HostID string `json:"hostId"`
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Status string `json:"status"`
|
||||
TenantID string `json:"tenant_id"`
|
||||
Metadata Metadata `json:"metadata"`
|
||||
Image Image `json:"image"`
|
||||
Flavor FlavorObj `json:"flavor"`
|
||||
Addresses map[string][]Address `json:"addresses"`
|
||||
UserID string `json:"user_id"`
|
||||
Created int64 `json:"created"`
|
||||
DueDate int64 `json:"dueDate"`
|
||||
SecurityGroups []SecurityGroup `json:"security_groups"`
|
||||
OSEXTAZAvailabilityZone string `json:"OS-EXT-AZ:availability_zone"`
|
||||
OSExtendedVolumesVolumesAttached []Volume `json:"os-extended-volumes:volumes_attached"`
|
||||
}
|
||||
|
||||
type InstanceDetails struct {
|
||||
HostID string `json:"hostId"`
|
||||
Name string `json:"name"`
|
||||
Status string `json:"status"`
|
||||
PrivateIPS []PrivateIP `json:"privateIps"`
|
||||
PublicIPS []PublicIP `json:"publicIps"`
|
||||
Volumes []Volume `json:"volumes"`
|
||||
Created string `json:"created"`
|
||||
FlavorObj FlavorObj `json:"flavorObj"`
|
||||
}
|
||||
|
||||
type Address struct {
|
||||
Addr string `json:"addr"`
|
||||
OSEXTIPSType string `json:"OS-EXT-IPS:type"`
|
||||
Version int64 `json:"version"`
|
||||
OSEXTIPSMACMACAddr string `json:"OS-EXT-IPS-MAC:mac_addr"`
|
||||
}
|
||||
|
||||
type Image struct {
|
||||
Id string `json:"id"`
|
||||
}
|
||||
|
||||
type SecurityGroup struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type FlavorObj struct {
|
||||
Name string `json:"name"`
|
||||
CPUNum int `json:"cpuNum"`
|
||||
MemSize int `json:"memSize"`
|
||||
ID string `json:"id"`
|
||||
}
|
||||
|
||||
type PrivateIP struct {
|
||||
ID string `json:"id"`
|
||||
Address string `json:"address"`
|
||||
}
|
||||
|
||||
type PublicP struct {
|
||||
ID string `json:"id"`
|
||||
Address string `json:"address"`
|
||||
Bandwidth string `json:"bandwidth"`
|
||||
}
|
||||
|
||||
func (self *SInstance) GetBillingType() string {
|
||||
if self.DueDate > 0 {
|
||||
return billing_api.BILLING_TYPE_PREPAID
|
||||
} else {
|
||||
return billing_api.BILLING_TYPE_POSTPAID
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SInstance) GetCreatedAt() time.Time {
|
||||
return time.Unix(self.Created/1000, 0)
|
||||
}
|
||||
|
||||
func (self *SInstance) GetExpiredAt() time.Time {
|
||||
return time.Unix(self.DueDate/1000, 0)
|
||||
}
|
||||
|
||||
func (self *SInstance) GetId() string {
|
||||
return self.ID
|
||||
}
|
||||
|
||||
func (self *SInstance) GetName() string {
|
||||
return self.Name
|
||||
}
|
||||
|
||||
func (self *SInstance) GetGlobalId() string {
|
||||
return self.GetId()
|
||||
}
|
||||
|
||||
func (self *SInstance) GetStatus() string {
|
||||
switch self.Status {
|
||||
case "RUNNING", "ACTIVE":
|
||||
return api.VM_RUNNING
|
||||
case "RESTARTING", "BUILD", "RESIZE", "VERIFY_RESIZE":
|
||||
return api.VM_STARTING
|
||||
case "STOPPING", "HARD_REBOOT":
|
||||
return api.VM_STOPPING
|
||||
case "STOPPED", "SHUTOFF":
|
||||
return api.VM_READY
|
||||
default:
|
||||
return api.VM_UNKNOWN
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SInstance) Refresh() error {
|
||||
new, err := self.host.zone.region.GetVMById(self.GetId())
|
||||
new.host = self.host
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if new.Status == "DELETED" {
|
||||
log.Debugf("Instance already terminated.")
|
||||
return cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
return jsonutils.Update(self, new)
|
||||
}
|
||||
|
||||
func (self *SInstance) IsEmulated() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SInstance) GetMetadata() *jsonutils.JSONDict {
|
||||
data := jsonutils.NewDict()
|
||||
lowerOs := self.GetOSType()
|
||||
if strings.HasPrefix(lowerOs, "win") {
|
||||
lowerOs = "win"
|
||||
}
|
||||
priceKey := fmt.Sprintf("%s::%s::%s", self.host.zone.region.GetId(), self.GetInstanceType(), lowerOs)
|
||||
data.Add(jsonutils.NewString(priceKey), "price_key")
|
||||
data.Add(jsonutils.NewString(self.host.zone.GetGlobalId()), "zone_ext_id")
|
||||
return data
|
||||
}
|
||||
|
||||
func (self *SInstance) GetProjectId() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SInstance) GetIHost() cloudprovider.ICloudHost {
|
||||
return self.host
|
||||
}
|
||||
|
||||
// GET http://ctyun-api-url/apiproxy/v3/queryDataDiskByVMId
|
||||
func (self *SInstance) GetIDisks() ([]cloudprovider.ICloudDisk, error) {
|
||||
err := self.Refresh()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SInstance.GetIDisks.Refresh")
|
||||
}
|
||||
|
||||
disks, err := self.host.zone.region.GetVMDisks(self.GetId())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SInstance.GetIDisks.GetVMDisks")
|
||||
}
|
||||
|
||||
idisks := make([]cloudprovider.ICloudDisk, 0)
|
||||
for i := range disks {
|
||||
disk := disks[i]
|
||||
idisks[i] = &disk
|
||||
}
|
||||
|
||||
return idisks, nil
|
||||
}
|
||||
|
||||
func (self *SInstance) GetINics() ([]cloudprovider.ICloudNic, error) {
|
||||
nics, err := self.host.zone.region.GetNics(self.GetId())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SInstance.GetINics")
|
||||
}
|
||||
|
||||
inics := make([]cloudprovider.ICloudNic, len(nics))
|
||||
for i := range nics {
|
||||
inics[i] = &nics[i]
|
||||
}
|
||||
|
||||
return inics, nil
|
||||
}
|
||||
|
||||
// GET http://ctyun-api-urlapiproxy/v3/queryNetworkByVMId
|
||||
func (self *SInstance) GetIEIP() (cloudprovider.ICloudEIP, error) {
|
||||
detail, err := self.GetDetails()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SInstance.GetIEIP.GetDetails")
|
||||
}
|
||||
|
||||
if len(detail.PublicIPS) > 0 {
|
||||
return self.host.zone.region.GetEip(detail.PublicIPS[0].ID)
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (self *SInstance) GetDetails() (*InstanceDetails, error) {
|
||||
if self.vmDetails != nil {
|
||||
return self.vmDetails, nil
|
||||
}
|
||||
|
||||
detail, err := self.host.zone.region.GetVMDetails(self.GetId())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SInstance.GetDetails")
|
||||
}
|
||||
|
||||
self.vmDetails = detail
|
||||
return self.vmDetails, nil
|
||||
}
|
||||
|
||||
func (self *SInstance) GetVcpuCount() int {
|
||||
return self.Flavor.CPUNum
|
||||
}
|
||||
|
||||
func (self *SInstance) GetVmemSizeMB() int {
|
||||
return self.Flavor.MemSize * 1024
|
||||
}
|
||||
|
||||
func (self *SInstance) GetBootOrder() string {
|
||||
return "dcn"
|
||||
}
|
||||
|
||||
func (self *SInstance) GetVga() string {
|
||||
return "std"
|
||||
}
|
||||
|
||||
func (self *SInstance) GetVdi() string {
|
||||
return "vnc"
|
||||
}
|
||||
|
||||
func (self *SInstance) GetImage() (*SImage, error) {
|
||||
if self.image != nil {
|
||||
return self.image, nil
|
||||
}
|
||||
|
||||
image, err := self.host.zone.region.GetImage(self.Image.Id)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SInstance.GetImage")
|
||||
}
|
||||
|
||||
self.image = image
|
||||
return self.image, nil
|
||||
}
|
||||
|
||||
func (self *SInstance) GetOSType() string {
|
||||
image, err := self.GetImage()
|
||||
if err != nil {
|
||||
log.Errorf("SInstance.GetOSType %s", err)
|
||||
return ""
|
||||
}
|
||||
|
||||
return image.OSType
|
||||
}
|
||||
|
||||
func (self *SInstance) GetOSName() string {
|
||||
image, err := self.GetImage()
|
||||
if err != nil {
|
||||
log.Errorf("SInstance.GetOSName %s", err)
|
||||
return ""
|
||||
}
|
||||
|
||||
return image.Name
|
||||
}
|
||||
|
||||
func (self *SInstance) GetBios() string {
|
||||
return "BIOS"
|
||||
}
|
||||
|
||||
func (self *SInstance) GetMachine() string {
|
||||
return "pc"
|
||||
}
|
||||
|
||||
func (self *SInstance) GetInstanceType() string {
|
||||
return self.Flavor.ID
|
||||
}
|
||||
|
||||
func (self *SInstance) GetSecurityGroupIds() ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (self *SInstance) AssignSecurityGroup(secgroupId string) error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SInstance) SetSecurityGroups(secgroupIds []string) error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SInstance) GetHypervisor() string {
|
||||
return api.HYPERVISOR_CTYUN
|
||||
}
|
||||
|
||||
func (self *SInstance) StartVM(ctx context.Context) error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SInstance) StopVM(ctx context.Context, isForce bool) error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SInstance) DeleteVM(ctx context.Context) error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SInstance) UpdateVM(ctx context.Context, name string) error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SInstance) UpdateUserData(userData string) error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SInstance) RebuildRoot(ctx context.Context, imageId string, passwd string, publicKey string, sysSizeGB int) (string, error) {
|
||||
return "", cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SInstance) DeployVM(ctx context.Context, name string, username string, password string, publicKey string, deleteKeypair bool, description string) error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SInstance) ChangeConfig(ctx context.Context, config *cloudprovider.SManagedVMChangeConfig) error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
// http://ctyun-api-url/apiproxy/v3/queryVncUrl
|
||||
func (self *SInstance) GetVNCInfo() (jsonutils.JSONObject, error) {
|
||||
url, err := self.host.zone.region.GetInstanceVNCUrl(self.GetId())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := jsonutils.NewDict()
|
||||
ret.Add(jsonutils.NewString(url), "url")
|
||||
ret.Add(jsonutils.NewString("ctyun"), "protocol")
|
||||
ret.Add(jsonutils.NewString(self.GetId()), "instance_id")
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SInstance) AttachDisk(ctx context.Context, diskId string) error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SInstance) DetachDisk(ctx context.Context, diskId string) error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SInstance) CreateDisk(ctx context.Context, sizeMb int, uuid string, driver string) error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SInstance) Renew(bc billing.SBillingCycle) error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SInstance) GetError() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetVMDisks(vmId string) ([]SDisk, error) {
|
||||
params := map[string]string{
|
||||
"VMId": vmId,
|
||||
}
|
||||
|
||||
resp, err := self.client.DoGet("/apiproxy/v3/queryDataDiskByVMId", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetVMDisks.DoGet")
|
||||
}
|
||||
|
||||
ret := make([]SDisk, 0)
|
||||
err = resp.Unmarshal(&ret, "returnObj")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetVMDisks.Unmarshal")
|
||||
}
|
||||
|
||||
disks := []SDisk{}
|
||||
for i := 0; i < len(ret); i += 1 {
|
||||
// 将系统盘放到第0个位置
|
||||
if ret[i].IsSysVolume == 1 {
|
||||
_temp := ret[0]
|
||||
disks[0] = ret[i]
|
||||
disks[i] = _temp
|
||||
}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
type SDiskDetails struct {
|
||||
HostID string `json:"hostId"`
|
||||
Name string `json:"name"`
|
||||
Status string `json:"status"`
|
||||
PrivateIPS []PrivateIP `json:"privateIps"`
|
||||
PublicIPS []PublicIP `json:"publicIps"`
|
||||
Volumes []Volume `json:"volumes"`
|
||||
Created string `json:"created"`
|
||||
FlavorObj FlavorObj `json:"flavorObj"`
|
||||
}
|
||||
|
||||
type PublicIP struct {
|
||||
ID string `json:"id"`
|
||||
Address string `json:"address"`
|
||||
Bandwidth string `json:"bandwidth"`
|
||||
}
|
||||
|
||||
type Volume struct {
|
||||
ID string `json:"id"`
|
||||
Status string `json:"status"`
|
||||
Type string `json:"type"`
|
||||
Size string `json:"size"`
|
||||
Name string `json:"name"`
|
||||
Bootable bool `json:"bootable"`
|
||||
}
|
||||
|
||||
func (self *SRegion) GetVMDetails(vmId string) (*InstanceDetails, error) {
|
||||
params := map[string]string{
|
||||
"regionId": self.GetId(),
|
||||
"vmId": vmId,
|
||||
}
|
||||
|
||||
resp, err := self.client.DoGet("/apiproxy/v3/ondemand/queryVMDetail", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetVMDetails.DoGet")
|
||||
}
|
||||
|
||||
details := &InstanceDetails{}
|
||||
err = resp.Unmarshal(details, "returnObj")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetVMDetails.Unmarshal")
|
||||
}
|
||||
|
||||
return details, nil
|
||||
}
|
||||
|
||||
type SVncInfo struct {
|
||||
Type string `json:"type"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
func (self *SRegion) GetInstanceVNCUrl(vmId string) (string, error) {
|
||||
params := map[string]string{
|
||||
"regionId": self.GetId(),
|
||||
"vmId": vmId,
|
||||
}
|
||||
|
||||
resp, err := self.client.DoGet("/apiproxy/v3/queryVncUrl", params)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "")
|
||||
}
|
||||
|
||||
ret := SVncInfo{}
|
||||
err = resp.Unmarshal(&ret, "returnObj", "console")
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "")
|
||||
}
|
||||
|
||||
return ret.URL, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) CreateInstance(zoneId, name, imageId, volumetype, flavorRef, vpcid, subnetId, secGroupId, adminPass string) error {
|
||||
rootParams := jsonutils.NewDict()
|
||||
rootParams.Set("volumetype", jsonutils.NewString(volumetype))
|
||||
|
||||
nicParams := jsonutils.NewArray()
|
||||
nicParam := jsonutils.NewDict()
|
||||
nicParam.Set("subnet_id", jsonutils.NewString(subnetId))
|
||||
nicParams.Add(nicParam)
|
||||
|
||||
secgroupParams := jsonutils.NewArray()
|
||||
secgroupParam := jsonutils.NewDict()
|
||||
secgroupParam.Set("id", jsonutils.NewString(secGroupId))
|
||||
secgroupParams.Add(secgroupParam)
|
||||
|
||||
extParams := jsonutils.NewDict()
|
||||
extParams.Set("regionID", jsonutils.NewString(self.GetId()))
|
||||
|
||||
serverParams := jsonutils.NewDict()
|
||||
serverParams.Set("availability_zone", jsonutils.NewString(zoneId))
|
||||
serverParams.Set("name", jsonutils.NewString(name))
|
||||
serverParams.Set("imageRef", jsonutils.NewString(imageId))
|
||||
serverParams.Set("root_volume", rootParams)
|
||||
serverParams.Set("flavorRef", jsonutils.NewString(flavorRef))
|
||||
// todo: fix me
|
||||
serverParams.Set("osType", jsonutils.NewString("Linux"))
|
||||
serverParams.Set("vpcid", jsonutils.NewString(vpcid))
|
||||
serverParams.Set("security_groups", secgroupParams)
|
||||
serverParams.Set("nics", nicParams)
|
||||
serverParams.Set("adminPass", jsonutils.NewString(adminPass))
|
||||
serverParams.Set("count", jsonutils.NewString("1"))
|
||||
serverParams.Set("extendparam", extParams)
|
||||
|
||||
vmParams := jsonutils.NewDict()
|
||||
vmParams.Set("server", serverParams)
|
||||
|
||||
params := map[string]jsonutils.JSONObject{
|
||||
"createVMInfo": vmParams,
|
||||
}
|
||||
|
||||
_, err := self.client.DoPost("/apiproxy/v3/ondemand/createVM", params)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "SRegion.CreateInstance.DoPost")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetJob(jobId string) (jsonutils.JSONObject, error) {
|
||||
params := map[string]string{
|
||||
"regionId": self.GetId(),
|
||||
"jobId": jobId,
|
||||
}
|
||||
|
||||
resp, err := self.client.DoGet("/apiproxy/v3/queryJobStatus", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetJob.DoGet")
|
||||
}
|
||||
|
||||
ret := jsonutils.NewDict()
|
||||
err = resp.Unmarshal(&ret)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetJob.Unmarshal")
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
@@ -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 ctyun
|
||||
|
||||
import (
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/netutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
type SInstanceNic struct {
|
||||
instance *SInstance
|
||||
ipAddr string
|
||||
FixedIPS []FixedIP `json:"fixed_ips"`
|
||||
PortState string `json:"port_state"`
|
||||
PortID string `json:"port_id"`
|
||||
MACAddr string `json:"mac_addr"`
|
||||
NetID string `json:"net_id"`
|
||||
}
|
||||
|
||||
type FixedIP struct {
|
||||
IPAddress string `json:"ip_address"`
|
||||
SubnetID string `json:"subnet_id"`
|
||||
}
|
||||
|
||||
func (self *SInstanceNic) GetIP() string {
|
||||
return self.ipAddr
|
||||
}
|
||||
|
||||
func (self *SInstanceNic) GetMAC() string {
|
||||
ip, _ := netutils.NewIPV4Addr(self.ipAddr)
|
||||
return ip.ToMac("00:16:")
|
||||
}
|
||||
|
||||
func (self *SInstanceNic) GetDriver() string {
|
||||
return "virtio"
|
||||
}
|
||||
|
||||
func (self *SInstanceNic) GetINetwork() cloudprovider.ICloudNetwork {
|
||||
network, err := self.instance.host.zone.region.GetNetwork(self.NetID)
|
||||
if err != nil {
|
||||
log.Errorf("SInstanceNic.GetINetwork %s", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
return network
|
||||
}
|
||||
|
||||
func (self *SRegion) GetNics(vmId string) ([]SInstanceNic, error) {
|
||||
params := map[string]string{
|
||||
"regionId": self.GetId(),
|
||||
"vmId": vmId,
|
||||
}
|
||||
|
||||
resp, err := self.client.DoGet("/apiproxy/v3/queryNetworkCards", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetNics.DoGet")
|
||||
}
|
||||
|
||||
ret := make([]SInstanceNic, 0)
|
||||
err = resp.Unmarshal(&ret, "returnObj", "interfaceAttachments")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetNics.Unmarshal")
|
||||
}
|
||||
|
||||
for i := range ret {
|
||||
ins, err := self.GetVMById(vmId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetNics")
|
||||
}
|
||||
|
||||
ret[i].instance = ins
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// 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 ctyun
|
||||
|
||||
// http://ctyun-api-url/apiproxy/v3/order/getZoneConfig
|
||||
type SKeypair struct {
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
// 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 ctyun
|
||||
|
||||
import (
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
var LatitudeAndLongitude = map[string]cloudprovider.SGeographicInfo{
|
||||
"cn-beijing1": {Latitude: 39.997743, Longitude: 116.304542, City: api.CITY_BEI_JING, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-hz1": {Latitude: 30.274084, Longitude: 120.155067, City: api.CITY_HANG_ZHOU, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-gslz1": {Latitude: 36.0613769373, Longitude: 103.8341600069, City: api.CITY_LAN_ZHOU, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-sxty1": {Latitude: 37.8705857132, Longitude: 112.5506634865, City: api.CITY_TAI_YUAN, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-sh1": {Latitude: 31.210344, Longitude: 121.455364, City: api.CITY_SHANG_HAI, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-gz1": {Latitude: 26.6470035286, Longitude: 106.6302113880, City: api.CITY_GUI_YANG, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-sdqd1": {Latitude: 36.067108, Longitude: 120.382607, City: api.CITY_QING_DAO, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-tj1": {Latitude: 39.0850853357, Longitude: 117.1993482089, City: api.CITY_TIAN_JIN, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-xjcj1": {Latitude: 43.8266013700, Longitude: 87.6168405804, City: api.CITY_WU_LU_MU_QI, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-cq1": {Latitude: 29.431585, Longitude: 106.912254, City: api.CITY_CHONG_QING, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-gxnn1": {Latitude: 22.8167372565, Longitude: 108.3669005333, City: api.CITY_NAN_NING, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-hazz1": {Latitude: 34.7533581487, Longitude: 113.6313915479, City: api.CITY_ZHENG_ZHOU, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-ynkm1": {Latitude: 24.8796595146, Longitude: 102.8332118852, City: api.CITY_KUN_MING, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-xian1": {Latitude: 34.3412614674, Longitude: 108.9398165260, City: api.CITY_XI_AN, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-hihk1": {Latitude: 20.0442268036, Longitude: 110.1998910288, City: api.CITY_HAI_KOU, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-ahwh1": {Latitude: 31.3524675159, Longitude: 118.4331307290, City: api.CITY_WU_HU, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-fz1": {Latitude: 26.0741979397, Longitude: 119.2964466153, City: api.CITY_FU_ZHOU, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"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-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_SHU_ZHOU, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"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-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-bj4": {Latitude: 39.904202, Longitude: 116.407394, City: api.CITY_BEI_JING, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-neimeng5": {Latitude: 40.842358, Longitude: 111.749992, City: api.CITY_HU_HE_HAO_TE, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-shanghai5": {Latitude: 31.210344, Longitude: 121.455364, City: api.CITY_SHANG_HAI, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-sh6": {Latitude: 31.210344, Longitude: 121.455364, City: api.CITY_SHANG_HAI, CountryCode: api.COUNTRY_CODE_CN},
|
||||
"cn-gdfs2": {Latitude: 23.0218629843, Longitude: 113.1219225896, City: api.CITY_FO_SHAN, CountryCode: api.COUNTRY_CODE_CN},
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
// 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 ctyun
|
||||
|
||||
import (
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/netutils"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/util/rbacutils"
|
||||
)
|
||||
|
||||
type SNetwork struct {
|
||||
vpc *SVpc
|
||||
wire *SWire
|
||||
|
||||
CIDR string `json:"cidr"`
|
||||
FirstDcn string `json:"firstDcn"`
|
||||
Gateway string `json:"gateway"`
|
||||
Name string `json:"name"`
|
||||
NeutronSubnetID string `json:"neutronSubnetId"`
|
||||
RegionID string `json:"regionId"`
|
||||
ResVLANID string `json:"resVlanId"`
|
||||
SecondDcn string `json:"secondDcn"`
|
||||
VLANStatus string `json:"vlanStatus"`
|
||||
VpcID string `json:"vpcId"`
|
||||
ZoneID string `json:"zoneId"`
|
||||
ZoneName string `json:"zoneName"`
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetId() string {
|
||||
return self.ResVLANID
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetName() string {
|
||||
return self.Name
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetGlobalId() string {
|
||||
return self.GetId()
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetStatus() string {
|
||||
switch self.VLANStatus {
|
||||
case "ACTIVE", "UNKNOWN":
|
||||
return api.NETWORK_STATUS_AVAILABLE
|
||||
case "ERROR":
|
||||
return api.NETWORK_STATUS_UNKNOWN
|
||||
default:
|
||||
return api.NETWORK_STATUS_UNKNOWN
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SNetwork) Refresh() error {
|
||||
log.Debugf("network refresh %s", self.GetId())
|
||||
new, err := self.wire.region.GetNetwork(self.GetId())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return jsonutils.Update(self, new)
|
||||
}
|
||||
|
||||
func (self *SNetwork) IsEmulated() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetMetadata() *jsonutils.JSONDict {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetProjectId() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetIWire() cloudprovider.ICloudWire {
|
||||
return self.wire
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetIpStart() string {
|
||||
pref, _ := netutils.NewIPV4Prefix(self.CIDR)
|
||||
startIp := pref.Address.NetAddr(pref.MaskLen) // 0
|
||||
startIp = startIp.StepUp() // 1
|
||||
startIp = startIp.StepUp() // 2
|
||||
return startIp.String()
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetIpEnd() string {
|
||||
pref, _ := netutils.NewIPV4Prefix(self.CIDR)
|
||||
endIp := pref.Address.BroadcastAddr(pref.MaskLen) // 255
|
||||
endIp = endIp.StepDown() // 254
|
||||
endIp = endIp.StepDown() // 253
|
||||
endIp = endIp.StepDown() // 252
|
||||
return endIp.String()
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetIpMask() int8 {
|
||||
pref, _ := netutils.NewIPV4Prefix(self.CIDR)
|
||||
return pref.MaskLen
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetGateway() string {
|
||||
pref, _ := netutils.NewIPV4Prefix(self.CIDR)
|
||||
endIp := pref.Address.BroadcastAddr(pref.MaskLen) // 255
|
||||
endIp = endIp.StepDown() // 254
|
||||
return endIp.String()
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetServerType() string {
|
||||
return api.NETWORK_TYPE_GUEST
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetIsPublic() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetPublicScope() rbacutils.TRbacScope {
|
||||
return rbacutils.ScopeDomain
|
||||
}
|
||||
|
||||
func (self *SNetwork) Delete() error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetAllocTimeoutSeconds() int {
|
||||
return 120
|
||||
}
|
||||
|
||||
func (self *SRegion) GetNetwroks(vpcId string) ([]SNetwork, error) {
|
||||
querys := map[string]string{
|
||||
"regionId": self.GetId(),
|
||||
}
|
||||
if len(vpcId) > 0 {
|
||||
querys["vpcId"] = vpcId
|
||||
}
|
||||
|
||||
networks := make([]SNetwork, 0)
|
||||
resp, err := self.client.DoGet("/apiproxy/v3/getSubnets", querys)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetNetwroks.DoGet")
|
||||
}
|
||||
|
||||
err = resp.Unmarshal(&networks, "returnObj")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetNetwroks.Unmarshal")
|
||||
}
|
||||
|
||||
for i := range networks {
|
||||
vpc, err := self.GetVpc(networks[i].VpcID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetNetwork.GetVpc")
|
||||
}
|
||||
networks[i].vpc = vpc
|
||||
|
||||
networks[i].wire = &SWire{
|
||||
region: self,
|
||||
vpc: vpc,
|
||||
}
|
||||
|
||||
networks[i].wire.addNetwork(&networks[i])
|
||||
}
|
||||
|
||||
return networks, err
|
||||
}
|
||||
|
||||
func (self *SRegion) GetNetwork(subnetId string) (*SNetwork, error) {
|
||||
querys := map[string]string{
|
||||
"subnetId": subnetId,
|
||||
"regionId": self.GetId(),
|
||||
}
|
||||
|
||||
resp, err := self.client.DoGet("/apiproxy/v3/querySubnetDetail", querys)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetNetwork.DoGet")
|
||||
}
|
||||
|
||||
network := &SNetwork{}
|
||||
err = resp.Unmarshal(network, "returnObj")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetNetwork.Unmarshal")
|
||||
}
|
||||
|
||||
vpc, err := self.GetVpc(network.VpcID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetNetwork.GetVpc")
|
||||
}
|
||||
network.vpc = vpc
|
||||
|
||||
network.wire = &SWire{
|
||||
region: self,
|
||||
vpc: vpc,
|
||||
}
|
||||
|
||||
network.wire.addNetwork(network)
|
||||
return network, err
|
||||
}
|
||||
|
||||
func (self *SRegion) CreateNetwork(vpcId, zoneId, name, cidr, gatewayIp, dhcpEnable string) (*SNetwork, error) {
|
||||
networkParams := jsonutils.NewDict()
|
||||
networkParams.Set("regionId", jsonutils.NewString(self.GetId()))
|
||||
networkParams.Set("zoneId", jsonutils.NewString(zoneId))
|
||||
networkParams.Set("name", jsonutils.NewString(name))
|
||||
networkParams.Set("cidr", jsonutils.NewString(cidr))
|
||||
networkParams.Set("gatewayIp", jsonutils.NewString(gatewayIp))
|
||||
networkParams.Set("dhcpEnable", jsonutils.NewString(dhcpEnable))
|
||||
networkParams.Set("vpcId", jsonutils.NewString(vpcId))
|
||||
// DNS地址,如果主机需要访问公网就需要填写该值,不填写就不能使用DNS解析
|
||||
// networkParams.Set("primaryDns", jsonutils.NewString(primaryDns))
|
||||
// networkParams.Set("secondaryDns", jsonutils.NewString(secondaryDns))
|
||||
|
||||
params := map[string]jsonutils.JSONObject{
|
||||
"jsonStr": networkParams,
|
||||
}
|
||||
|
||||
network := &SNetwork{}
|
||||
resp, err := self.client.DoPost("/apiproxy/v3/createSubnet", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.CreateNetwork.DoPost")
|
||||
}
|
||||
|
||||
err = resp.Unmarshal(network, "returnObj")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.CreateNetwork.Unmarshal")
|
||||
}
|
||||
|
||||
return network, err
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
// 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 ctyun
|
||||
|
||||
import "yunion.io/x/pkg/errors"
|
||||
|
||||
type SOrder struct {
|
||||
OrderItemID string `json:"orderItemId"`
|
||||
InstanceID string `json:"instanceId"`
|
||||
AccountID string `json:"accountId"`
|
||||
UserID string `json:"userId"`
|
||||
InnerOrderID string `json:"innerOrderId"`
|
||||
InnerOrderItemID string `json:"innerOrderItemId"`
|
||||
ProductID string `json:"productId"`
|
||||
MasterOrderID string `json:"masterOrderId"`
|
||||
OrderID string `json:"orderId"`
|
||||
MasterResourceID string `json:"masterResourceId"`
|
||||
ResourceID string `json:"resourceId"`
|
||||
ServiceTag string `json:"serviceTag"`
|
||||
ResourceType string `json:"resourceType"`
|
||||
ResourceInfo string `json:"resourceInfo"`
|
||||
StartDate int64 `json:"startDate"`
|
||||
ExpireDate int64 `json:"expireDate"`
|
||||
CreateDate int64 `json:"createDate"`
|
||||
UpdateDate int64 `json:"updateDate"`
|
||||
Status int64 `json:"status"`
|
||||
WorkOrderID string `json:"workOrderId"`
|
||||
WorkOrderItemID string `json:"workOrderItemId"`
|
||||
SalesEntryID string `json:"salesEntryId"`
|
||||
OrderStatus int64 `json:"orderStatus"`
|
||||
ToOndemand string `json:"toOndemand"`
|
||||
ItemValue string `json:"itemValue"`
|
||||
ChargingStatus int64 `json:"chargingStatus"`
|
||||
ChargingDate int64 `json:"chargingDate"`
|
||||
ResourceConfig string `json:"resourceConfig"`
|
||||
AutoToOnDemand bool `json:"autoToOnDemand"`
|
||||
BuildingChannel int64 `json:"buildingChannel"`
|
||||
IsPlatformSpecific bool `json:"isPlatformSpecific"`
|
||||
BillingOwner int64 `json:"billingOwner"`
|
||||
IsPackage bool `json:"isPackage"`
|
||||
CanRelease bool `json:"canRelease"`
|
||||
IsChargeOff bool `json:"isChargeOff"`
|
||||
IsPublicTest int64 `json:"isPublicTest"`
|
||||
Master bool `json:"master"`
|
||||
ResourceConfigMap ResourceConfigMap `json:"resourceConfigMap"`
|
||||
}
|
||||
|
||||
type ResourceConfigMap struct {
|
||||
AvailabilityZone string `json:"availability_zone"`
|
||||
Value string `json:"value"`
|
||||
Number string `json:"number"`
|
||||
IsSystemVolume bool `json:"isSystemVolume"`
|
||||
VolumeType string `json:"volumeType"`
|
||||
Size int64 `json:"size"`
|
||||
ZoneID string `json:"zoneId"`
|
||||
RegionID string `json:"regionId"`
|
||||
Version string `json:"version"`
|
||||
CycleCnt int64 `json:"cycleCnt"`
|
||||
CycleType int64 `json:"cycleType"`
|
||||
ResEbsID string `json:"resEbsId"`
|
||||
ActualResourceID string `json:"actualResourceId"`
|
||||
}
|
||||
|
||||
func (self *SRegion) GetOrder(orderId string) ([]SOrder, error) {
|
||||
params := map[string]string{
|
||||
"masterOrderId": orderId,
|
||||
}
|
||||
|
||||
resp, err := self.client.DoGet("/apiproxy/v3/order/queryResourceInfoByMasterOrderId", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetOrder.DoGet")
|
||||
}
|
||||
|
||||
ret := make([]SOrder, 0)
|
||||
err = resp.Unmarshal(&ret, "returnObj")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetOrder.DoGet")
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
// 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 ctyun
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
)
|
||||
|
||||
// GET http://ctyun-api-url/apiproxy/v3/ondemand/queryProjectIds
|
||||
type SProject struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
ID string `json:"id"`
|
||||
}
|
||||
|
||||
func (self *SProject) GetRegionID() string {
|
||||
return strings.Split(self.Name, "_")[1]
|
||||
}
|
||||
|
||||
func (self *SProject) GetHealthStatus() string {
|
||||
if self.Enabled {
|
||||
return api.CLOUD_PROVIDER_HEALTH_NORMAL
|
||||
}
|
||||
|
||||
return api.CLOUD_PROVIDER_HEALTH_SUSPENDED
|
||||
}
|
||||
|
||||
func (self *SCtyunClient) FetchProjects() ([]SProject, error) {
|
||||
client, err := NewSCtyunClient("", "", "", self.accessKey, self.secret, self.debug)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "CtyunClient.FetchProjects")
|
||||
}
|
||||
projects := make([]SProject, 0)
|
||||
resp, err := client.DoGet("/apiproxy/v3/ondemand/queryProjectIds", map[string]string{})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "CtyunClient.FetchProjects.DoGet")
|
||||
}
|
||||
|
||||
err = resp.Unmarshal(&projects, "returnObj")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "CtyunClient.FetchProjects.Unmarshal")
|
||||
}
|
||||
|
||||
return projects, err
|
||||
}
|
||||
|
||||
func (self *SRegion) FetchProjects() ([]SProject, error) {
|
||||
return self.client.FetchProjects()
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
package provider // import "yunion.io/x/onecloud/pkg/multicloud/ctyun/provider"
|
||||
@@ -0,0 +1,165 @@
|
||||
// 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"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/multicloud/ctyun"
|
||||
)
|
||||
|
||||
type SCtyunProviderFactory struct {
|
||||
cloudprovider.SPublicCloudBaseProviderFactor
|
||||
}
|
||||
|
||||
func (self *SCtyunProviderFactory) GetId() string {
|
||||
return ctyun.CLOUD_PROVIDER_CTYUN
|
||||
}
|
||||
|
||||
func (self *SCtyunProviderFactory) GetName() string {
|
||||
return ctyun.CLOUD_PROVIDER_CTYUN_CN
|
||||
}
|
||||
|
||||
func (self *SCtyunProviderFactory) IsSupportPrepaidResources() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SCtyunProviderFactory) ValidateCreateCloudaccountData(ctx context.Context, userCred mcclient.TokenCredential, input *api.CloudaccountCreateInput) error {
|
||||
if len(input.AccessKeyId) == 0 {
|
||||
return httperrors.NewMissingParameterError("access_key_id")
|
||||
}
|
||||
if len(input.AccessKeySecret) == 0 {
|
||||
return httperrors.NewMissingParameterError("access_key_secret")
|
||||
}
|
||||
if len(input.Environment) == 0 {
|
||||
return httperrors.NewMissingParameterError("environment")
|
||||
}
|
||||
input.Account = input.AccessKeyId
|
||||
input.Secret = input.AccessKeySecret
|
||||
input.AccessUrl = input.Environment
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SCtyunProviderFactory) ValidateUpdateCloudaccountCredential(ctx context.Context, userCred mcclient.TokenCredential, input *api.CloudaccountCredentialInput, cloudaccount string) (*cloudprovider.SCloudaccount, error) {
|
||||
if len(input.AccessKeyId) == 0 {
|
||||
return nil, httperrors.NewMissingParameterError("access_key_id")
|
||||
}
|
||||
if len(input.AccessKeySecret) == 0 {
|
||||
return nil, httperrors.NewMissingParameterError("access_key_secret")
|
||||
}
|
||||
account := &cloudprovider.SCloudaccount{
|
||||
Account: input.AccessKeyId,
|
||||
Secret: input.AccessKeySecret,
|
||||
}
|
||||
return account, nil
|
||||
}
|
||||
|
||||
func (self *SCtyunProviderFactory) GetProvider(providerId, providerName, url, account, secret string) (cloudprovider.ICloudProvider, error) {
|
||||
segs := strings.Split(account, "/")
|
||||
projectId := ""
|
||||
if len(segs) == 2 {
|
||||
projectId = segs[1]
|
||||
account = segs[0]
|
||||
}
|
||||
|
||||
client, err := ctyun.NewSCtyunClient(providerId, providerName, projectId, account, secret, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &SCtyunProvider{
|
||||
SBaseProvider: cloudprovider.NewBaseProvider(self),
|
||||
client: client,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (self *SCtyunProviderFactory) GetClientRC(url, account, secret string) (map[string]string, error) {
|
||||
return map[string]string{
|
||||
"CTYUN_ACCESS_URL": url,
|
||||
"CTYUN_ACCESS_KEY": account,
|
||||
"CTYUN_SECRET": secret,
|
||||
"CTYUN_REGION": ctyun.CTYUN_DEFAULT_REGION,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
factory := SCtyunProviderFactory{}
|
||||
cloudprovider.RegisterFactory(&factory)
|
||||
}
|
||||
|
||||
type SCtyunProvider struct {
|
||||
cloudprovider.SBaseProvider
|
||||
client *ctyun.SCtyunClient
|
||||
}
|
||||
|
||||
func (self *SCtyunProvider) GetIGlobalnetworks() ([]cloudprovider.ICloudGlobalnetwork, error) {
|
||||
return []cloudprovider.ICloudGlobalnetwork{}, nil
|
||||
}
|
||||
|
||||
func (self *SCtyunProvider) GetIGlobalnetworkById(id string) (cloudprovider.ICloudGlobalnetwork, error) {
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func (self *SCtyunProvider) GetSubAccounts() ([]cloudprovider.SSubAccount, error) {
|
||||
return self.client.GetSubAccounts()
|
||||
}
|
||||
|
||||
func (self *SCtyunProvider) GetAccountId() string {
|
||||
return self.client.GetAccountId()
|
||||
}
|
||||
|
||||
func (self *SCtyunProvider) GetIRegions() []cloudprovider.ICloudRegion {
|
||||
return self.client.GetIRegions()
|
||||
}
|
||||
|
||||
func (self *SCtyunProvider) GetSysInfo() (jsonutils.JSONObject, error) {
|
||||
regions := self.client.GetIRegions()
|
||||
info := jsonutils.NewDict()
|
||||
info.Add(jsonutils.NewInt(int64(len(regions))), "region_count")
|
||||
info.Add(jsonutils.NewString(ctyun.CTYUN_API_VERSION), "api_version")
|
||||
return info, nil
|
||||
}
|
||||
|
||||
func (self *SCtyunProvider) GetVersion() string {
|
||||
return ctyun.CTYUN_API_VERSION
|
||||
}
|
||||
|
||||
func (self *SCtyunProvider) GetIRegionById(id string) (cloudprovider.ICloudRegion, error) {
|
||||
return self.client.GetIRegionById(id)
|
||||
}
|
||||
|
||||
func (self *SCtyunProvider) GetBalance() (float64, string, error) {
|
||||
return 0.0, api.CLOUD_PROVIDER_HEALTH_NORMAL, cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
func (self *SCtyunProvider) GetIProjects() ([]cloudprovider.ICloudProject, error) {
|
||||
return self.client.GetIProjects()
|
||||
}
|
||||
|
||||
func (self *SCtyunProvider) GetStorageClasses(regionId string) []string {
|
||||
return []string{
|
||||
"STANDARD", "WARM", "COLD",
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SCtyunProvider) GetCloudRegionExternalIdPrefix() string {
|
||||
return self.client.GetAccessEnv() + "/"
|
||||
}
|
||||
@@ -0,0 +1,451 @@
|
||||
// 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 ctyun
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/secrules"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/multicloud"
|
||||
)
|
||||
|
||||
type SRegion struct {
|
||||
cloudprovider.SFakeOnPremiseRegion
|
||||
multicloud.SRegion
|
||||
multicloud.SNoObjectStorageRegion
|
||||
|
||||
client *SCtyunClient
|
||||
storageCache *SStoragecache
|
||||
|
||||
Description string `json:"description"`
|
||||
ID string `json:"id"`
|
||||
ParentRegionID string `json:"parent_region_id"`
|
||||
Type string `json:"type"`
|
||||
|
||||
izones []cloudprovider.ICloudZone
|
||||
ivpcs []cloudprovider.ICloudVpc
|
||||
}
|
||||
|
||||
func (self *SRegion) fetchIVpcs() error {
|
||||
vpcs, err := self.GetVpcs()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "SRegion.fetchIVpcs")
|
||||
}
|
||||
|
||||
self.ivpcs = make([]cloudprovider.ICloudVpc, 0)
|
||||
for i := range vpcs {
|
||||
vpc := vpcs[i]
|
||||
vpc.region = self
|
||||
self.ivpcs = append(self.ivpcs, &vpc)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SRegion) fetchInfrastructure() error {
|
||||
if err := self.fetchIVpcs(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i := 0; i < len(self.ivpcs); i += 1 {
|
||||
vpc := self.ivpcs[i].(*SVpc)
|
||||
wire := SWire{region: self, vpc: vpc}
|
||||
vpc.addWire(&wire)
|
||||
|
||||
for j := 0; j < len(self.izones); j += 1 {
|
||||
zone := self.izones[j].(*SZone)
|
||||
zone.addWire(&wire)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetVpcs() ([]SVpc, error) {
|
||||
vpcs := make([]SVpc, 0)
|
||||
params := map[string]string{
|
||||
"regionId": self.GetId(),
|
||||
}
|
||||
resp, err := self.client.DoGet("/apiproxy/v3/getVpcs", params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = resp.Unmarshal(&vpcs, "returnObj")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return vpcs, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) CreateVpc(name, cidr string) (*SVpc, error) {
|
||||
params := map[string]jsonutils.JSONObject{
|
||||
"regionId": jsonutils.NewString(self.GetId()),
|
||||
"name": jsonutils.NewString(name),
|
||||
"cidr": jsonutils.NewString(cidr),
|
||||
}
|
||||
resp, err := self.client.DoPost("/apiproxy/v3/createVPC", params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
vpc := &SVpc{}
|
||||
err = resp.Unmarshal(vpc, "returnObj")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
vpc.region = self
|
||||
return vpc, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetClient() *SCtyunClient {
|
||||
return self.client
|
||||
}
|
||||
|
||||
func (self *SRegion) GetISecurityGroupById(secgroupId string) (cloudprovider.ICloudSecurityGroup, error) {
|
||||
return self.GetSecurityGroupDetails(secgroupId)
|
||||
}
|
||||
|
||||
func (self *SRegion) GetISecurityGroupByName(vpcId string, name string) (cloudprovider.ICloudSecurityGroup, error) {
|
||||
segroups, err := self.GetSecurityGroups(vpcId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetISecurityGroupByName.GetSecurityGroups")
|
||||
}
|
||||
|
||||
for i := range segroups {
|
||||
if segroups[i].Name == name {
|
||||
return &segroups[i], nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors.Wrap(cloudprovider.ErrNotFound, "SRegion.GetISecurityGroupByName.GetSecurityGroups")
|
||||
}
|
||||
|
||||
func (self *SRegion) CreateISecurityGroup(conf *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SRegion) GetId() string {
|
||||
return self.ID
|
||||
}
|
||||
|
||||
func (self *SRegion) GetName() string {
|
||||
return self.ID
|
||||
}
|
||||
|
||||
func (self *SRegion) GetGlobalId() string {
|
||||
return fmt.Sprintf("%s/%s", self.client.GetAccessEnv(), self.ID)
|
||||
}
|
||||
|
||||
func (self *SRegion) GetStatus() string {
|
||||
return api.CLOUD_REGION_STATUS_INSERVER
|
||||
}
|
||||
|
||||
func (self *SRegion) Refresh() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SRegion) IsEmulated() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SRegion) GetMetadata() *jsonutils.JSONDict {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetGeographicInfo() cloudprovider.SGeographicInfo {
|
||||
if info, ok := LatitudeAndLongitude[self.ID]; ok {
|
||||
return info
|
||||
}
|
||||
return cloudprovider.SGeographicInfo{}
|
||||
}
|
||||
|
||||
// http://ctyun-api-url/apiproxy/v3/order/getZoneConfig
|
||||
func (self *SRegion) GetIZones() ([]cloudprovider.ICloudZone, error) {
|
||||
if self.izones == nil {
|
||||
var err error
|
||||
err = self.fetchInfrastructure()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return self.izones, nil
|
||||
}
|
||||
|
||||
// http://ctyun-api-url/apiproxy/v3/getVpcs
|
||||
// http://ctyun-api-url/apiproxy/v3/getVpcs
|
||||
func (self *SRegion) GetIVpcs() ([]cloudprovider.ICloudVpc, error) {
|
||||
if self.ivpcs == nil {
|
||||
err := self.fetchInfrastructure()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return self.ivpcs, nil
|
||||
}
|
||||
|
||||
// http://ctyun-api-url/apiproxy/v3/ondemand/queryIps
|
||||
func (self *SRegion) GetIEips() ([]cloudprovider.ICloudEIP, error) {
|
||||
eips, err := self.GetEips()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetIEips.GetEips")
|
||||
}
|
||||
|
||||
ieips := make([]cloudprovider.ICloudEIP, len(eips))
|
||||
for i := range eips {
|
||||
ieips[i] = &eips[i]
|
||||
}
|
||||
|
||||
return ieips, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIVpcById(id string) (cloudprovider.ICloudVpc, error) {
|
||||
return self.GetVpc(id)
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIZoneById(id string) (cloudprovider.ICloudZone, error) {
|
||||
izones, err := self.GetIZones()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := 0; i < len(izones); i += 1 {
|
||||
if izones[i].GetGlobalId() == id {
|
||||
return izones[i], nil
|
||||
}
|
||||
}
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIEipById(id string) (cloudprovider.ICloudEIP, error) {
|
||||
return self.GetEip(id)
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIVMById(id string) (cloudprovider.ICloudVM, error) {
|
||||
return self.GetVMById(id)
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIDiskById(id string) (cloudprovider.ICloudDisk, error) {
|
||||
return self.GetDisk(id)
|
||||
}
|
||||
|
||||
func (self *SRegion) DeleteSecurityGroup(vpcId, secgroupId string) error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SRegion) SyncSecurityGroup(secgroupId string, vpcId string, name string, desc string, rules []secrules.SecurityRule) (string, error) {
|
||||
return "", cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SRegion) CreateIVpc(name string, desc string, cidr string) (cloudprovider.ICloudVpc, error) {
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SRegion) CreateEIP(eip *cloudprovider.SEip) (cloudprovider.ICloudEIP, error) {
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SRegion) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) {
|
||||
snapshots, err := self.GetSnapshots("")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetISnapshots.GetSnapshots")
|
||||
}
|
||||
|
||||
isnapshots := make([]cloudprovider.ICloudSnapshot, len(snapshots))
|
||||
for i := range snapshots {
|
||||
isnapshots[i] = &snapshots[i]
|
||||
}
|
||||
|
||||
return isnapshots, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetISnapshotById(snapshotId string) (cloudprovider.ICloudSnapshot, error) {
|
||||
snapshots, err := self.GetSnapshots("")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetISnapshotById.GetSnapshots")
|
||||
}
|
||||
|
||||
for i := range snapshots {
|
||||
if snapshots[i].GetId() == snapshotId {
|
||||
return &snapshots[i], nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors.Wrap(cloudprovider.ErrNotFound, "SRegion.GetISnapshotById")
|
||||
}
|
||||
|
||||
func (self *SRegion) CreateSnapshotPolicy(*cloudprovider.SnapshotPolicyInput) (string, error) {
|
||||
return "", cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SRegion) UpdateSnapshotPolicy(*cloudprovider.SnapshotPolicyInput, string) error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SRegion) DeleteSnapshotPolicy(string) error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SRegion) ApplySnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SRegion) CancelSnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SRegion) GetISnapshotPolicies() ([]cloudprovider.ICloudSnapshotPolicy, error) {
|
||||
polices, err := self.GetDiskBackupPolices()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetISnapshotPolicies.GetDiskBackupPolices")
|
||||
}
|
||||
|
||||
ipolices := make([]cloudprovider.ICloudSnapshotPolicy, len(polices))
|
||||
for i := range polices {
|
||||
ipolices[i] = &polices[i]
|
||||
}
|
||||
|
||||
return ipolices, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetISnapshotPolicyById(snapshotPolicyId string) (cloudprovider.ICloudSnapshotPolicy, error) {
|
||||
return self.GetDiskBackupPolicy(snapshotPolicyId)
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIHosts() ([]cloudprovider.ICloudHost, error) {
|
||||
iHosts := make([]cloudprovider.ICloudHost, 0)
|
||||
|
||||
izones, err := self.GetIZones()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := 0; i < len(izones); i += 1 {
|
||||
iZoneHost, err := izones[i].GetIHosts()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iHosts = append(iHosts, iZoneHost...)
|
||||
}
|
||||
return iHosts, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIHostById(id string) (cloudprovider.ICloudHost, error) {
|
||||
izones, err := self.GetIZones()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := 0; i < len(izones); i += 1 {
|
||||
ihost, err := izones[i].GetIHostById(id)
|
||||
if err == nil {
|
||||
return ihost, nil
|
||||
} else if err != cloudprovider.ErrNotFound {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIStorages() ([]cloudprovider.ICloudStorage, error) {
|
||||
iStores := make([]cloudprovider.ICloudStorage, 0)
|
||||
|
||||
izones, err := self.GetIZones()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := 0; i < len(izones); i += 1 {
|
||||
iZoneStores, err := izones[i].GetIStorages()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iStores = append(iStores, iZoneStores...)
|
||||
}
|
||||
return iStores, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) {
|
||||
izones, err := self.GetIZones()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := 0; i < len(izones); i += 1 {
|
||||
istore, err := izones[i].GetIStorageById(id)
|
||||
if err == nil {
|
||||
return istore, nil
|
||||
} else if err != cloudprovider.ErrNotFound {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIStoragecaches() ([]cloudprovider.ICloudStoragecache, error) {
|
||||
storageCache := self.getStoragecache()
|
||||
return []cloudprovider.ICloudStoragecache{storageCache}, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIStoragecacheById(id string) (cloudprovider.ICloudStoragecache, error) {
|
||||
storageCache := self.getStoragecache()
|
||||
if storageCache.GetGlobalId() == id {
|
||||
return storageCache, nil
|
||||
}
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func (self *SRegion) GetProvider() string {
|
||||
return api.CLOUD_PROVIDER_CTYUN
|
||||
}
|
||||
|
||||
func (self *SRegion) GetInstances(instanceId string) ([]SInstance, error) {
|
||||
params := map[string]string{
|
||||
"regionId": self.GetId(),
|
||||
}
|
||||
|
||||
resp, err := self.client.DoGet("/apiproxy/v3/ondemand/queryVMs", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetInstances.DoGet")
|
||||
}
|
||||
|
||||
ret := make([]SInstance, 0)
|
||||
err = resp.Unmarshal(&ret, "returnObj", "servers")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetInstances.Unmarshal")
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetInstanceFlavors() ([]FlavorObj, error) {
|
||||
params := map[string]string{
|
||||
"regionId": self.GetId(),
|
||||
}
|
||||
|
||||
resp, err := self.client.DoGet("/apiproxy/v3/order/getFlavors", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetInstanceFlavors.DoGet")
|
||||
}
|
||||
|
||||
ret := make([]FlavorObj, 0)
|
||||
err = resp.Unmarshal(&ret, "returnObj")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetInstanceFlavors.Unmarshal")
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
// 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 ctyun
|
||||
|
||||
import (
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
)
|
||||
|
||||
type SSecurityGroupRule struct {
|
||||
secgroup *SSecurityGroup
|
||||
|
||||
PortRangeMax int64 `json:"port_range_max"`
|
||||
SecurityGroupID string `json:"security_group_id"`
|
||||
RemoteGroupId string `json:"remote_group_id"`
|
||||
Description string `json:"description"`
|
||||
RemoteIPPrefix string `json:"remote_ip_prefix"`
|
||||
Protocol string `json:"protocol"`
|
||||
Ethertype string `json:"ethertype"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
Direction string `json:"direction"`
|
||||
TenantID string `json:"tenant_id"`
|
||||
ID string `json:"id"`
|
||||
ProjectID string `json:"project_id"`
|
||||
PortRangeMin int64 `json:"port_range_min"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
}
|
||||
|
||||
func (self *SRegion) GetSecurityGroupRules(secgroupId string) ([]SSecurityGroupRule, error) {
|
||||
params := map[string]string{
|
||||
"regionId": self.GetId(),
|
||||
"securityGroupId": secgroupId,
|
||||
}
|
||||
|
||||
resp, err := self.client.DoGet("/apiproxy/v3/getSecurityGroupRules", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetSecurityGroupRules.DoGet")
|
||||
}
|
||||
|
||||
ret := make([]SSecurityGroupRule, 0)
|
||||
err = resp.Unmarshal(&ret, "returnObj", "security_group_rules")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetSecurityGroupRules.Unmarshal")
|
||||
}
|
||||
|
||||
secgroup, err := self.GetSecurityGroupDetails(secgroupId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetSecurityGroupRules.GetSecurityGroupDetails")
|
||||
}
|
||||
|
||||
for i := range ret {
|
||||
ret[i].secgroup = secgroup
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) CreateSecurityGroupRule(groupId, direction, ethertype, protocol, remoteIpPrefix string, portRangeMin, portRangeMax int64) error {
|
||||
ruleParams := jsonutils.NewDict()
|
||||
ruleParams.Set("regionId", jsonutils.NewString(self.GetId()))
|
||||
ruleParams.Set("securityGroupId", jsonutils.NewString(groupId))
|
||||
ruleParams.Set("direction", jsonutils.NewString(direction))
|
||||
ruleParams.Set("ethertype", jsonutils.NewString(ethertype))
|
||||
|
||||
if len(protocol) > 0 {
|
||||
ruleParams.Set("protocol", jsonutils.NewString(protocol))
|
||||
}
|
||||
|
||||
if len(remoteIpPrefix) > 0 {
|
||||
ruleParams.Set("remoteIpPrefix", jsonutils.NewString(remoteIpPrefix))
|
||||
}
|
||||
|
||||
if portRangeMin > 0 {
|
||||
ruleParams.Set("portRangeMin", jsonutils.NewInt(portRangeMin))
|
||||
}
|
||||
|
||||
if portRangeMax > 0 {
|
||||
ruleParams.Set("portRangeMax", jsonutils.NewInt(portRangeMax))
|
||||
}
|
||||
|
||||
params := map[string]jsonutils.JSONObject{
|
||||
"jsonStr": ruleParams,
|
||||
}
|
||||
|
||||
_, err := self.client.DoPost("/apiproxy/v3/createSecurityGroupRule", params)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "SRegion.CreateSecurityGroupRule.DoPost")
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
@@ -0,0 +1,266 @@
|
||||
// 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 ctyun
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/secrules"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
type SSecurityGroup struct {
|
||||
region *SRegion
|
||||
vpc *SVpc
|
||||
|
||||
ID string `json:"id"`
|
||||
ResSecurityGroupID string `json:"resSecurityGroupId"`
|
||||
Name string `json:"name"`
|
||||
AccountID string `json:"accountId"`
|
||||
UserID string `json:"userId"`
|
||||
RegionID string `json:"regionId"`
|
||||
ZoneID string `json:"zoneId"`
|
||||
VpcID string `json:"vpcId"`
|
||||
CreateDate int64 `json:"createDate"`
|
||||
Status int64 `json:"status"`
|
||||
}
|
||||
|
||||
func (self *SSecurityGroup) SyncRules(rules []secrules.SecurityRule) error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SSecurityGroup) Delete() error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SSecurityGroup) GetId() string {
|
||||
return self.ResSecurityGroupID
|
||||
}
|
||||
|
||||
func (self *SSecurityGroup) GetName() string {
|
||||
if len(self.Name) > 0 {
|
||||
return self.Name
|
||||
}
|
||||
return self.ResSecurityGroupID
|
||||
}
|
||||
|
||||
func (self *SSecurityGroup) GetGlobalId() string {
|
||||
return self.GetId()
|
||||
}
|
||||
|
||||
func (self *SSecurityGroup) GetStatus() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SSecurityGroup) Refresh() error {
|
||||
if new, err := self.region.GetSecurityGroupDetails(self.GetId()); err != nil {
|
||||
return err
|
||||
} else {
|
||||
return jsonutils.Update(self, new)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SSecurityGroup) IsEmulated() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SSecurityGroup) GetMetadata() *jsonutils.JSONDict {
|
||||
return jsonutils.NewDict()
|
||||
}
|
||||
|
||||
func (self *SSecurityGroup) GetDescription() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// 判断是否兼容云端安全组规则
|
||||
func compatibleSecurityGroupRule(r SSecurityGroupRule) bool {
|
||||
// 忽略了源地址是安全组的规则
|
||||
if len(r.RemoteGroupId) > 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
// 忽略IPV6
|
||||
if r.Ethertype == "IPv6" {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SSecurityGroup) GetRules() ([]secrules.SecurityRule, error) {
|
||||
_rules, err := self.region.GetSecurityGroupRules(self.GetId())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SSecurityGroup.GetRules.GetSecurityGroupRules")
|
||||
}
|
||||
|
||||
rules := make([]secrules.SecurityRule, 0)
|
||||
for _, r := range _rules {
|
||||
if !compatibleSecurityGroupRule(r) {
|
||||
continue
|
||||
}
|
||||
|
||||
rule, err := self.GetSecurityRule(r, false)
|
||||
if err != nil {
|
||||
return rules, err
|
||||
}
|
||||
|
||||
rules = append(rules, rule)
|
||||
}
|
||||
|
||||
return rules, nil
|
||||
}
|
||||
|
||||
func (self *SSecurityGroup) GetSecurityRule(remoteRule SSecurityGroupRule, withRuleId bool) (secrules.SecurityRule, error) {
|
||||
var err error
|
||||
var direction secrules.TSecurityRuleDirection
|
||||
if remoteRule.Direction == "ingress" {
|
||||
direction = secrules.SecurityRuleIngress
|
||||
} else {
|
||||
direction = secrules.SecurityRuleEgress
|
||||
}
|
||||
|
||||
protocol := secrules.PROTO_ANY
|
||||
if remoteRule.Protocol != "" {
|
||||
protocol = remoteRule.Protocol
|
||||
}
|
||||
|
||||
var portStart int
|
||||
var portEnd int
|
||||
if protocol == secrules.PROTO_ICMP {
|
||||
portStart = -1
|
||||
portEnd = -1
|
||||
} else {
|
||||
portStart = int(remoteRule.PortRangeMin)
|
||||
portEnd = int(remoteRule.PortRangeMax)
|
||||
}
|
||||
|
||||
ipNet := &net.IPNet{}
|
||||
if len(remoteRule.RemoteIPPrefix) > 0 {
|
||||
_, ipNet, err = net.ParseCIDR(remoteRule.RemoteIPPrefix)
|
||||
} else {
|
||||
_, ipNet, err = net.ParseCIDR("0.0.0.0/0")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return secrules.SecurityRule{}, err
|
||||
}
|
||||
|
||||
// withRuleId.将ruleId附加到description字段。该hook有特殊目的,仅在同步安全组时使用。
|
||||
desc := ""
|
||||
if withRuleId {
|
||||
desc = remoteRule.ID
|
||||
} else {
|
||||
desc = remoteRule.Description
|
||||
}
|
||||
|
||||
rule := secrules.SecurityRule{
|
||||
Priority: 1,
|
||||
Action: secrules.SecurityRuleAllow,
|
||||
IPNet: ipNet,
|
||||
Protocol: protocol,
|
||||
Direction: direction,
|
||||
PortStart: portStart,
|
||||
PortEnd: portEnd,
|
||||
Ports: nil,
|
||||
Description: desc,
|
||||
}
|
||||
|
||||
err = rule.ValidateRule()
|
||||
return rule, err
|
||||
}
|
||||
|
||||
func (self *SSecurityGroup) GetVpcId() string {
|
||||
if len(self.VpcID) == 0 {
|
||||
return "normal"
|
||||
}
|
||||
|
||||
return self.VpcID
|
||||
}
|
||||
|
||||
func (self *SRegion) GetSecurityGroupDetails(groupId string) (*SSecurityGroup, error) {
|
||||
params := map[string]string{
|
||||
"regionId": self.GetId(),
|
||||
"securityGroupId": groupId,
|
||||
}
|
||||
|
||||
resp, err := self.client.DoGet("/apiproxy/v3/querySecurityGroupDetail", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetSecurityGroupDetails")
|
||||
}
|
||||
|
||||
ret := &SSecurityGroup{}
|
||||
err = resp.Unmarshal(&ret, "returnObj")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetSecurityGroupDetails.Unmarshal")
|
||||
}
|
||||
|
||||
ret.region = self
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetSecurityGroups(vpcId string) ([]SSecurityGroup, error) {
|
||||
params := map[string]string{
|
||||
"regionId": self.GetId(),
|
||||
"vpcId": vpcId,
|
||||
}
|
||||
|
||||
resp, err := self.client.DoGet("/apiproxy/v3/getSecurityGroups", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetSecurityGroups")
|
||||
}
|
||||
|
||||
ret := make([]SSecurityGroup, 0)
|
||||
err = resp.Unmarshal(&ret, "returnObj")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetSecurityGroups.Unmarshal")
|
||||
}
|
||||
|
||||
for i := range ret {
|
||||
ret[i].region = self
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) CreateSecurityGroup(vpcId, name string) (*SSecurityGroup, error) {
|
||||
params := map[string]jsonutils.JSONObject{
|
||||
"regionId": jsonutils.NewString(self.GetId()),
|
||||
"vpcId": jsonutils.NewString(vpcId),
|
||||
"name": jsonutils.NewString(name),
|
||||
}
|
||||
|
||||
resp, err := self.client.DoPost("/apiproxy/v3/createSecurityGroup", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.CreateSecurityGroup.DoPost")
|
||||
}
|
||||
|
||||
ret := &SSecurityGroup{}
|
||||
err = resp.Unmarshal(ret, "returnObj")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.CreateSecurityGroup.Unmarshal")
|
||||
}
|
||||
|
||||
vpc, err := self.GetVpc(vpcId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.CreateSecurityGroup.GetVpc")
|
||||
}
|
||||
|
||||
ret.vpc = vpc
|
||||
ret.region = self
|
||||
return ret, nil
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
// 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 shell
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/multicloud/ctyun"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type VDiskListOptions struct {
|
||||
}
|
||||
shellutils.R(&VDiskListOptions{}, "disk-list", "List disks", func(cli *ctyun.SRegion, args *VDiskListOptions) error {
|
||||
disks, e := cli.GetDisks()
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
printList(disks, 0, 0, 0, nil)
|
||||
return nil
|
||||
})
|
||||
|
||||
type DiskCreateOptions struct {
|
||||
ZoneId string `help:"zone id"`
|
||||
Name string `help:"disk name"`
|
||||
DiskType string `help:"disk type" choice:"SSD|SAS|SATA"`
|
||||
Size string `help:"disk size"`
|
||||
}
|
||||
shellutils.R(&DiskCreateOptions{}, "disk-create", "Create disk", func(cli *ctyun.SRegion, args *DiskCreateOptions) error {
|
||||
disk, e := cli.CreateDisk(args.ZoneId, args.Name, args.DiskType, args.Size)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
printObject(disk)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
// 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 shell
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/multicloud/ctyun"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type VPolicyListOptions struct {
|
||||
}
|
||||
shellutils.R(&VPolicyListOptions{}, "policy-list", "List polices", func(cli *ctyun.SRegion, args *VPolicyListOptions) error {
|
||||
polices, e := cli.GetDiskBackupPolices()
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
printList(polices, 0, 0, 0, nil)
|
||||
return nil
|
||||
})
|
||||
|
||||
type PolicyCreateOptions struct {
|
||||
Name string `help:"policy name"`
|
||||
StartTime string `help:"startTime"`
|
||||
Frequency string `help:"frequency"`
|
||||
RententionNum string `help:"rententionNum"`
|
||||
FirstBackup string `help:"firstBackup"`
|
||||
Status string `help:"status"`
|
||||
}
|
||||
shellutils.R(&PolicyCreateOptions{}, "policy-create", "Create policy", func(cli *ctyun.SRegion, args *PolicyCreateOptions) error {
|
||||
e := cli.CreateDiskBackupPolicy(args.Name, args.StartTime, args.Frequency, args.RententionNum, args.FirstBackup, args.Status)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
type BindingDiskBackupPolicyOptions struct {
|
||||
PolicyId string `help:"policy id"`
|
||||
ResourceId string `help:"resource id"`
|
||||
ResourceType string `help:"resource type"`
|
||||
}
|
||||
shellutils.R(&BindingDiskBackupPolicyOptions{}, "policy-bind", "Binding policy", func(cli *ctyun.SRegion, args *BindingDiskBackupPolicyOptions) error {
|
||||
e := cli.BindingDiskBackupPolicy(args.PolicyId, args.ResourceId, args.ResourceType)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
type UnBindDiskBackupPolicyOptions struct {
|
||||
PolicyId string `help:"policy id"`
|
||||
ResourceId string `help:"resourceId"`
|
||||
}
|
||||
shellutils.R(&UnBindDiskBackupPolicyOptions{}, "policy-unbind", "Unbind policy", func(cli *ctyun.SRegion, args *UnBindDiskBackupPolicyOptions) error {
|
||||
e := cli.UnBindDiskBackupPolicy(args.PolicyId, args.ResourceId)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
package shell // import "yunion.io/x/onecloud/pkg/multicloud/ctyun/shell"
|
||||
@@ -0,0 +1,48 @@
|
||||
// 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 shell
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/multicloud/ctyun"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type VEipListOptions struct {
|
||||
}
|
||||
shellutils.R(&VEipListOptions{}, "eip-list", "List eips", func(cli *ctyun.SRegion, args *VEipListOptions) error {
|
||||
eips, e := cli.GetEips()
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
printList(eips, 0, 0, 0, nil)
|
||||
return nil
|
||||
})
|
||||
|
||||
type EipCreateOptions struct {
|
||||
ZoneId string `help:"zone id"`
|
||||
Name string `help:"eip name"`
|
||||
Size string `help:"size"`
|
||||
ShareType string `help:"share type" choice:"PER|WHOLE"`
|
||||
}
|
||||
shellutils.R(&EipCreateOptions{}, "eip-create", "Create eip", func(cli *ctyun.SRegion, args *EipCreateOptions) error {
|
||||
eip, e := cli.CreateEip(args.ZoneId, args.Name, args.Size, args.ShareType)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
printObject(eip)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// 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 shell
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/multicloud/ctyun"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type VImageListOptions struct {
|
||||
ImageType string `help:"image type" choices:"gold|private|shared"`
|
||||
}
|
||||
shellutils.R(&VImageListOptions{}, "image-list", "List images", func(cli *ctyun.SRegion, args *VImageListOptions) error {
|
||||
images, e := cli.GetImages(args.ImageType)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
printList(images, 0, 0, 0, nil)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
// 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 shell
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/multicloud/ctyun"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type InstanceListOptions struct {
|
||||
Id string `help:"ID of instance to show"`
|
||||
}
|
||||
shellutils.R(&InstanceListOptions{}, "instance-list", "List intances", func(cli *ctyun.SRegion, args *InstanceListOptions) error {
|
||||
instances, e := cli.GetInstances(args.Id)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
printList(instances, 0, 0, 0, []string{})
|
||||
return nil
|
||||
})
|
||||
|
||||
type InstanceCreateOptions struct {
|
||||
ZoneId string `help:"zone ID of instance"`
|
||||
NAME string `help:"name of instance"`
|
||||
ADMINPASS string `help:"admin password of instance"`
|
||||
ImageId string `help:"image Id of instance"`
|
||||
VolumeType string `help:"volume type of instance"`
|
||||
Flavor string `help:"Flavor of instance"`
|
||||
VpcId string `help:"Vpc of instance"`
|
||||
SubnetId string `help:"subnet Id of instance"`
|
||||
SecGroupId string `help:"security group Id of instance"`
|
||||
}
|
||||
|
||||
shellutils.R(&InstanceCreateOptions{}, "instance-create", "Create intance", func(cli *ctyun.SRegion, args *InstanceCreateOptions) error {
|
||||
e := cli.CreateInstance(args.ZoneId, args.NAME, args.ImageId, args.VolumeType, args.Flavor, args.VpcId, args.SubnetId, args.SecGroupId, args.ADMINPASS)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// 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 shell
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/multicloud/ctyun"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type VJobShowOptions struct {
|
||||
JOBID string `help:"Job ID"`
|
||||
}
|
||||
shellutils.R(&VJobShowOptions{}, "job-show", "Show job", func(cli *ctyun.SRegion, args *VJobShowOptions) error {
|
||||
job, e := cli.GetJob(args.JOBID)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
printObject(job)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
// 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 shell
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/multicloud/ctyun"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type VNetworkListOptions struct {
|
||||
Vpc string `help:"Vpc ID"`
|
||||
}
|
||||
shellutils.R(&VNetworkListOptions{}, "subnet-list", "List subnets", func(cli *ctyun.SRegion, args *VNetworkListOptions) error {
|
||||
vswitches, e := cli.GetNetwroks(args.Vpc)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
printList(vswitches, 0, 0, 0, nil)
|
||||
return nil
|
||||
})
|
||||
|
||||
type NetworkCreateOptions struct {
|
||||
VpcId string `help:"vpc id"`
|
||||
ZoneId string `help:"zone id"`
|
||||
Name string `help:"subnet name"`
|
||||
Cidr string `help:"cidr"`
|
||||
GatewayIp string `help:"gateway ip"`
|
||||
DhcpEnable string `help:"gateway ip" choice:"true|false"`
|
||||
}
|
||||
shellutils.R(&NetworkCreateOptions{}, "subnet-create", "Create subnet", func(cli *ctyun.SRegion, args *NetworkCreateOptions) error {
|
||||
vpc, e := cli.CreateNetwork(args.VpcId, args.ZoneId, args.Name, args.Cidr, args.GatewayIp, args.DhcpEnable)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
printObject(vpc)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// 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 shell
|
||||
|
||||
import "yunion.io/x/onecloud/pkg/util/printutils"
|
||||
|
||||
func printList(data interface{}, total, offset, limit int, columns []string) {
|
||||
printutils.PrintInterfaceList(data, total, offset, limit, columns)
|
||||
}
|
||||
|
||||
func printObject(obj interface{}) {
|
||||
printutils.PrintInterfaceObject(obj)
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// 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 shell
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/multicloud/ctyun"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type VProjectListOptions struct {
|
||||
}
|
||||
shellutils.R(&VProjectListOptions{}, "project-list", "List projects", func(cli *ctyun.SRegion, args *VProjectListOptions) error {
|
||||
projects, e := cli.FetchProjects()
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
printList(projects, 0, 0, 0, nil)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// 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 shell
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/multicloud/ctyun"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type RegionListOptions struct {
|
||||
}
|
||||
shellutils.R(&RegionListOptions{}, "region-list", "List regions", func(cli *ctyun.SRegion, args *RegionListOptions) error {
|
||||
regions := cli.GetClient().GetRegions()
|
||||
printList(regions, 0, 0, 0, nil)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
// 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 shell
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/multicloud/ctyun"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type VSecurityGroupListOptions struct {
|
||||
Vpc string `help:"Vpc ID"`
|
||||
}
|
||||
shellutils.R(&VSecurityGroupListOptions{}, "secgroup-list", "List secgroups", func(cli *ctyun.SRegion, args *VSecurityGroupListOptions) error {
|
||||
secgroups, e := cli.GetSecurityGroups(args.Vpc)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
printList(secgroups, 0, 0, 0, nil)
|
||||
return nil
|
||||
})
|
||||
|
||||
type VSecurityGroupRuleListOptions struct {
|
||||
Group string `help:"Security Group ID"`
|
||||
}
|
||||
shellutils.R(&VSecurityGroupRuleListOptions{}, "secrule-list", "List secgroup rules", func(cli *ctyun.SRegion, args *VSecurityGroupRuleListOptions) error {
|
||||
secrules, e := cli.GetSecurityGroupRules(args.Group)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
printList(secrules, 0, 0, 0, nil)
|
||||
return nil
|
||||
})
|
||||
|
||||
type SecurityGroupCreateOptions struct {
|
||||
VpcId string `help:"vpc id"`
|
||||
Name string `help:"secgroup name"`
|
||||
}
|
||||
shellutils.R(&SecurityGroupCreateOptions{}, "secgroup-create", "Create secgroup", func(cli *ctyun.SRegion, args *SecurityGroupCreateOptions) error {
|
||||
vpc, e := cli.CreateSecurityGroup(args.VpcId, args.Name)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
printObject(vpc)
|
||||
return nil
|
||||
})
|
||||
|
||||
type SecurityGroupRuleCreateOptions struct {
|
||||
Group string `help:"secgroup id"`
|
||||
Direction string `help:"direction"`
|
||||
Ethertype string `help:"ethertype" choice:"IPv4|IPv6"`
|
||||
Protocol string `help:"protocol,icmp,tcp,udp,and so on "`
|
||||
IpPrefix string `help:"remote ip prefix"`
|
||||
PortMin int64 `help:"portRangeMin"`
|
||||
PortMax int64 `help:"portRangeMax"`
|
||||
}
|
||||
shellutils.R(&SecurityGroupRuleCreateOptions{}, "secrule-create", "Create secgroup rule", func(cli *ctyun.SRegion, args *SecurityGroupRuleCreateOptions) error {
|
||||
e := cli.CreateSecurityGroupRule(args.Group, args.Direction, args.Ethertype, args.Protocol, args.IpPrefix, args.PortMin, args.PortMax)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
// 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 shell
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/multicloud/ctyun"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type VpcListOptions struct {
|
||||
}
|
||||
shellutils.R(&VpcListOptions{}, "vpc-list", "List vpcs", func(cli *ctyun.SRegion, args *VpcListOptions) error {
|
||||
vpcs, e := cli.GetVpcs()
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
printList(vpcs, 0, 0, 0, nil)
|
||||
return nil
|
||||
})
|
||||
|
||||
type VpcCreateOptions struct {
|
||||
NAME string `help:"vpc name"`
|
||||
CIDR string `help:"10.0.0.0/8~10.255.255.0/24或者172.16.0.0/12 ~ 172.31.255.0/24或者192.168.0.0/16 ~ 192.168.255.0/24"`
|
||||
}
|
||||
shellutils.R(&VpcCreateOptions{}, "vpc-create", "Create vpc", func(cli *ctyun.SRegion, args *VpcCreateOptions) error {
|
||||
vpc, e := cli.CreateVpc(args.NAME, args.CIDR)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
printObject(vpc)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
// 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 ctyun
|
||||
|
||||
import (
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
type SSnapshot struct {
|
||||
region *SRegion
|
||||
|
||||
Status string `json:"status"`
|
||||
Description string `json:"description"`
|
||||
AvailabilityZone string `json:"availability_zone"`
|
||||
VolumeID string `json:"volume_id"`
|
||||
FailReason string `json:"fail_reason"`
|
||||
ID string `json:"id"`
|
||||
Size int64 `json:"size"`
|
||||
Container string `json:"container"`
|
||||
Name string `json:"name"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
}
|
||||
|
||||
func (self *SSnapshot) GetId() string {
|
||||
return self.ID
|
||||
}
|
||||
|
||||
func (self *SSnapshot) GetName() string {
|
||||
return self.Name
|
||||
}
|
||||
|
||||
func (self *SSnapshot) GetGlobalId() string {
|
||||
return self.GetId()
|
||||
}
|
||||
|
||||
func (self *SSnapshot) GetStatus() string {
|
||||
switch self.Status {
|
||||
case "available":
|
||||
return api.SNAPSHOT_READY
|
||||
case "creating":
|
||||
return api.SNAPSHOT_CREATING
|
||||
case "deleting":
|
||||
return api.SNAPSHOT_DELETING
|
||||
case "error_deleting", "error":
|
||||
return api.SNAPSHOT_FAILED
|
||||
case "rollbacking":
|
||||
return api.SNAPSHOT_ROLLBACKING
|
||||
default:
|
||||
return api.SNAPSHOT_UNKNOWN
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SSnapshot) Refresh() error {
|
||||
snapshot, err := self.region.GetSnapshot(self.VolumeID, self.GetId())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := jsonutils.Update(self, snapshot); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SSnapshot) IsEmulated() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SSnapshot) GetMetadata() *jsonutils.JSONDict {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SSnapshot) GetProjectId() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SSnapshot) GetSizeMb() int32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (self *SSnapshot) GetDiskId() string {
|
||||
return self.VolumeID
|
||||
}
|
||||
|
||||
func (self *SSnapshot) GetDiskType() string {
|
||||
return api.DISK_TYPE_SYS
|
||||
}
|
||||
|
||||
func (self *SSnapshot) Delete() error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SRegion) GetSnapshot(diskId string, snapshotId string) (*SSnapshot, error) {
|
||||
snapshots, err := self.GetSnapshots(diskId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetSnapshot.GetSnapshots")
|
||||
}
|
||||
|
||||
for i := range snapshots {
|
||||
snapshot := snapshots[i]
|
||||
if snapshot.ID == snapshotId {
|
||||
snapshot.region = self
|
||||
return &snapshot, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors.Wrap(errors.ErrNotFound, "SRegion.GetSnapshot")
|
||||
}
|
||||
|
||||
func (self *SRegion) GetSnapshots(diskId string) ([]SSnapshot, error) {
|
||||
params := map[string]string{
|
||||
"regionId": self.GetId(),
|
||||
}
|
||||
|
||||
if len(diskId) > 0 {
|
||||
params["volumeId"] = diskId
|
||||
}
|
||||
|
||||
resp, err := self.client.DoGet("/apiproxy/v3/ondemand/queryVBSDetails", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetSnapshots.DoGet")
|
||||
}
|
||||
|
||||
ret := make([]SSnapshot, 0)
|
||||
err = resp.Unmarshal(&ret, "returnObj", "backups")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetSnapshots.Unmarshal")
|
||||
}
|
||||
|
||||
for i := range ret {
|
||||
ret[i].region = self
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
// 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 ctyun
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
var StorageTypes = []string{
|
||||
api.STORAGE_CTYUN_SAS,
|
||||
api.STORAGE_CTYUN_SATA,
|
||||
api.STORAGE_CTYUN_SSD,
|
||||
}
|
||||
|
||||
type SStorage struct {
|
||||
zone *SZone
|
||||
storageType string
|
||||
}
|
||||
|
||||
func (self *SStorage) GetId() string {
|
||||
return fmt.Sprintf("%s-%s-%s", self.zone.region.client.providerId, self.zone.GetId(), self.storageType)
|
||||
}
|
||||
|
||||
func (self *SStorage) GetName() string {
|
||||
return fmt.Sprintf("%s-%s-%s", self.zone.region.client.providerName, self.zone.GetId(), self.storageType)
|
||||
}
|
||||
|
||||
func (self *SStorage) GetGlobalId() string {
|
||||
return fmt.Sprintf("%s-%s-%s", self.zone.region.client.providerId, self.zone.GetGlobalId(), self.storageType)
|
||||
}
|
||||
|
||||
func (self *SStorage) GetStatus() string {
|
||||
return api.STORAGE_ONLINE
|
||||
}
|
||||
|
||||
func (self *SStorage) Refresh() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SStorage) IsEmulated() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SStorage) GetMetadata() *jsonutils.JSONDict {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SStorage) GetIStoragecache() cloudprovider.ICloudStoragecache {
|
||||
return self.zone.region.getStoragecache()
|
||||
}
|
||||
|
||||
func (self *SStorage) GetIZone() cloudprovider.ICloudZone {
|
||||
return self.zone
|
||||
}
|
||||
|
||||
// http://ctyun-api-url/apiproxy/v3/ondemand/queryVolumes
|
||||
// http://ctyun-api-url/apiproxy/v3/queryDataDisks
|
||||
func (self *SStorage) GetIDisks() ([]cloudprovider.ICloudDisk, error) {
|
||||
disks, err := self.zone.region.GetDisks()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 按storage type 过滤出disk
|
||||
filtedDisks := make([]SDisk, 0)
|
||||
for i := range disks {
|
||||
disk := disks[i]
|
||||
if disk.VolumeType == self.storageType && disk.AvailabilityZone == self.zone.GetId() {
|
||||
filtedDisks = append(filtedDisks, disk)
|
||||
}
|
||||
}
|
||||
|
||||
idisks := make([]cloudprovider.ICloudDisk, len(filtedDisks))
|
||||
for i := 0; i < len(filtedDisks); i += 1 {
|
||||
filtedDisks[i].storage = self
|
||||
idisks[i] = &filtedDisks[i]
|
||||
}
|
||||
return idisks, nil
|
||||
}
|
||||
|
||||
func (self *SStorage) GetStorageType() string {
|
||||
return self.storageType
|
||||
}
|
||||
|
||||
func (self *SStorage) GetMediumType() string {
|
||||
if self.storageType == api.STORAGE_CTYUN_SSD {
|
||||
return api.DISK_TYPE_SSD
|
||||
} else {
|
||||
return api.DISK_TYPE_ROTATE
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SStorage) GetCapacityMB() int64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (self *SStorage) GetStorageConf() jsonutils.JSONObject {
|
||||
return jsonutils.NewDict()
|
||||
}
|
||||
|
||||
func (self *SStorage) GetEnabled() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SStorage) CreateIDisk(name string, sizeGb int, desc string) (cloudprovider.ICloudDisk, error) {
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SStorage) GetIDiskById(idStr string) (cloudprovider.ICloudDisk, error) {
|
||||
if len(idStr) == 0 {
|
||||
log.Debugf("GetIDiskById disk id should not be empty")
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
if disk, err := self.zone.region.GetDisk(idStr); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
disk.storage = self
|
||||
return disk, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SStorage) GetMountPoint() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SStorage) IsSysDiskStore() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SRegion) getStoragecache() *SStoragecache {
|
||||
if self.storageCache == nil {
|
||||
self.storageCache = &SStoragecache{region: self}
|
||||
}
|
||||
return self.storageCache
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
// 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 ctyun
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
)
|
||||
|
||||
type SStoragecache struct {
|
||||
region *SRegion
|
||||
|
||||
iimages []cloudprovider.ICloudImage
|
||||
}
|
||||
|
||||
func (self *SStoragecache) CreateIImage(snapshotId, imageName, osType, imageDesc string) (cloudprovider.ICloudImage, error) {
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SStoragecache) DownloadImage(userCred mcclient.TokenCredential, imageId string, extId string, path string) (jsonutils.JSONObject, error) {
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SStoragecache) UploadImage(ctx context.Context, userCred mcclient.TokenCredential, image *cloudprovider.SImageCreateOption, isForce bool) (string, error) {
|
||||
return "", cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func GetBucketName(regionId string, imageId string) string {
|
||||
return fmt.Sprintf("imgcache-%s-%s", strings.ToLower(regionId), imageId)
|
||||
}
|
||||
|
||||
func (self *SStoragecache) fetchImages() error {
|
||||
imagesGold, err := self.region.GetImages(ImageOwnerPublic)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
imagesSelf, err := self.region.GetImages(ImageOwnerSelf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
self.iimages = make([]cloudprovider.ICloudImage, len(imagesGold)+len(imagesSelf))
|
||||
for i := range imagesGold {
|
||||
imagesGold[i].storageCache = self
|
||||
self.iimages[i] = &imagesGold[i]
|
||||
}
|
||||
for i := range imagesSelf {
|
||||
imagesSelf[i].storageCache = self
|
||||
self.iimages[i+len(imagesGold)] = &imagesSelf[i]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SStoragecache) GetId() string {
|
||||
return fmt.Sprintf("%s-%s", self.region.client.providerId, self.region.GetId())
|
||||
}
|
||||
|
||||
func (self *SStoragecache) GetName() string {
|
||||
return fmt.Sprintf("%s-%s", self.region.client.providerName, self.region.GetId())
|
||||
}
|
||||
|
||||
func (self *SStoragecache) GetGlobalId() string {
|
||||
return fmt.Sprintf("%s-%s", self.region.client.providerId, self.region.GetGlobalId())
|
||||
}
|
||||
|
||||
func (self *SStoragecache) GetStatus() string {
|
||||
return "available"
|
||||
}
|
||||
|
||||
func (self *SStoragecache) Refresh() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SStoragecache) IsEmulated() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SStoragecache) GetMetadata() *jsonutils.JSONDict {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SStoragecache) GetIImages() ([]cloudprovider.ICloudImage, error) {
|
||||
if self.iimages == nil {
|
||||
err := self.fetchImages()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return self.iimages, nil
|
||||
}
|
||||
|
||||
func (self *SStoragecache) GetIImageById(extId string) (cloudprovider.ICloudImage, error) {
|
||||
image, err := self.region.GetImage(extId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SStoragecache.GetIImageById.GetImage")
|
||||
}
|
||||
|
||||
image.storageCache = self
|
||||
return image, err
|
||||
}
|
||||
|
||||
func (self *SStoragecache) GetPath() string {
|
||||
return ""
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
// 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 ctyun
|
||||
|
||||
import (
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/multicloud"
|
||||
)
|
||||
|
||||
type SVpc struct {
|
||||
multicloud.SVpc
|
||||
|
||||
region *SRegion
|
||||
|
||||
iwires []cloudprovider.ICloudWire
|
||||
secgroups []cloudprovider.ICloudSecurityGroup
|
||||
|
||||
ResVpcID string `json:"resVpcId"`
|
||||
Name string `json:"name"`
|
||||
CIDR string `json:"cidr"`
|
||||
ZoneID string `json:"zoneId"`
|
||||
ZoneName string `json:"zoneName"`
|
||||
VpcStatus string `json:"vpcStatus"`
|
||||
RegionID string `json:"regionId"`
|
||||
CreateDate int64 `json:"createDate"`
|
||||
}
|
||||
|
||||
func (self *SVpc) addWire(wire *SWire) {
|
||||
if self.iwires == nil {
|
||||
self.iwires = make([]cloudprovider.ICloudWire, 0)
|
||||
}
|
||||
self.iwires = append(self.iwires, wire)
|
||||
}
|
||||
|
||||
func (self *SVpc) GetId() string {
|
||||
return self.ResVpcID
|
||||
}
|
||||
|
||||
func (self *SVpc) GetName() string {
|
||||
if len(self.Name) > 0 {
|
||||
return self.Name
|
||||
}
|
||||
return self.ResVpcID
|
||||
}
|
||||
|
||||
func (self *SVpc) GetGlobalId() string {
|
||||
return self.GetId()
|
||||
}
|
||||
|
||||
func (self *SVpc) GetStatus() string {
|
||||
return api.VPC_STATUS_AVAILABLE
|
||||
}
|
||||
|
||||
func (self *SVpc) Refresh() error {
|
||||
new, err := self.region.GetVpc(self.GetId())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return jsonutils.Update(self, new)
|
||||
}
|
||||
|
||||
func (self *SVpc) IsEmulated() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SVpc) GetMetadata() *jsonutils.JSONDict {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SVpc) GetRegion() cloudprovider.ICloudRegion {
|
||||
return self.region
|
||||
}
|
||||
|
||||
func (self *SVpc) GetIsDefault() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SVpc) GetCidrBlock() string {
|
||||
return self.CIDR
|
||||
}
|
||||
|
||||
func (self *SVpc) GetIWires() ([]cloudprovider.ICloudWire, error) {
|
||||
if self.iwires == nil {
|
||||
err := self.fetchNetworks()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return self.iwires, nil
|
||||
}
|
||||
|
||||
// http://ctyun-api-url/apiproxy/v3/getSecurityGroupRules
|
||||
// http://ctyun-api-url/apiproxy/v3/getSecurityGroups
|
||||
func (self *SVpc) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) {
|
||||
if self.secgroups == nil {
|
||||
err := self.fetchSecurityGroups()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return self.secgroups, nil
|
||||
}
|
||||
|
||||
func (self *SVpc) GetIRouteTables() ([]cloudprovider.ICloudRouteTable, error) {
|
||||
rts := []cloudprovider.ICloudRouteTable{}
|
||||
return rts, nil
|
||||
}
|
||||
|
||||
func (self *SVpc) Delete() error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SVpc) GetIWireById(wireId string) (cloudprovider.ICloudWire, error) {
|
||||
if self.iwires == nil {
|
||||
err := self.fetchNetworks()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
for i := 0; i < len(self.iwires); i += 1 {
|
||||
if self.iwires[i].GetGlobalId() == wireId {
|
||||
return self.iwires[i], nil
|
||||
}
|
||||
}
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func (self *SVpc) fetchSecurityGroups() error {
|
||||
secgroups, err := self.region.GetSecurityGroups("")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
self.secgroups = make([]cloudprovider.ICloudSecurityGroup, len(secgroups))
|
||||
for i := 0; i < len(secgroups); i++ {
|
||||
secgroups[i].vpc = self
|
||||
self.secgroups[i] = &secgroups[i]
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SVpc) getWireByRegionId(regionId string) *SWire {
|
||||
if len(regionId) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < len(self.iwires); i++ {
|
||||
wire := self.iwires[i].(*SWire)
|
||||
|
||||
if wire.region.GetId() == regionId {
|
||||
return wire
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SVpc) fetchNetworks() error {
|
||||
networks, err := self.region.GetNetwroks(self.GetId())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(networks) == 0 {
|
||||
self.iwires = append(self.iwires, &SWire{region: self.region, vpc: self})
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < len(networks); i += 1 {
|
||||
wire := self.getWireByRegionId(self.region.GetId())
|
||||
networks[i].wire = wire
|
||||
wire.addNetwork(&networks[i])
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetVpc(vpcId string) (*SVpc, error) {
|
||||
params := map[string]string{
|
||||
"vpcId": vpcId,
|
||||
"regionId": self.GetId(),
|
||||
}
|
||||
|
||||
vpc := &SVpc{}
|
||||
resp, err := self.client.DoGet("/apiproxy/v3/queryVPCDetail", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetVpc.DoGet")
|
||||
}
|
||||
|
||||
err = resp.Unmarshal(vpc, "returnObj")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetVpc.Unmarshal")
|
||||
}
|
||||
|
||||
vpc.region = self
|
||||
return vpc, nil
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
// 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 ctyun
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
type SWire struct {
|
||||
region *SRegion
|
||||
vpc *SVpc
|
||||
|
||||
inetworks []cloudprovider.ICloudNetwork
|
||||
}
|
||||
|
||||
func (self *SWire) GetId() string {
|
||||
return fmt.Sprintf("%s-%s", self.vpc.GetId(), self.region.GetId())
|
||||
}
|
||||
|
||||
func (self *SWire) GetName() string {
|
||||
return self.GetId()
|
||||
}
|
||||
|
||||
func (self *SWire) GetGlobalId() string {
|
||||
return fmt.Sprintf("%s-%s", self.vpc.GetGlobalId(), self.region.GetGlobalId())
|
||||
}
|
||||
|
||||
func (self *SWire) GetStatus() string {
|
||||
return "available"
|
||||
}
|
||||
|
||||
func (self *SWire) Refresh() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SWire) IsEmulated() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SWire) GetMetadata() *jsonutils.JSONDict {
|
||||
return nil
|
||||
}
|
||||
|
||||
// http://ctyun-api-url/apiproxy/v3/queryVPCDetail
|
||||
func (self *SWire) GetIVpc() cloudprovider.ICloudVpc {
|
||||
return self.vpc
|
||||
}
|
||||
|
||||
func (self *SWire) GetIZone() cloudprovider.ICloudZone {
|
||||
return nil
|
||||
}
|
||||
|
||||
// http://ctyun-api-url/apiproxy/v3/getSubnets
|
||||
func (self *SWire) GetINetworks() ([]cloudprovider.ICloudNetwork, error) {
|
||||
if self.inetworks == nil {
|
||||
err := self.vpc.fetchNetworks()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return self.inetworks, nil
|
||||
}
|
||||
|
||||
func (self *SWire) GetBandwidth() int {
|
||||
return 10000
|
||||
}
|
||||
|
||||
func (self *SWire) GetINetworkById(netid string) (cloudprovider.ICloudNetwork, error) {
|
||||
networks, err := self.GetINetworks()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := 0; i < len(networks); i += 1 {
|
||||
if networks[i].GetGlobalId() == netid {
|
||||
return networks[i], nil
|
||||
}
|
||||
}
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func (self *SWire) CreateINetwork(name string, cidr string, desc string) (cloudprovider.ICloudNetwork, error) {
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SWire) addNetwork(network *SNetwork) {
|
||||
if self.inetworks == nil {
|
||||
self.inetworks = make([]cloudprovider.ICloudNetwork, 0)
|
||||
}
|
||||
find := false
|
||||
for i := 0; i < len(self.inetworks); i += 1 {
|
||||
if self.inetworks[i].GetId() == network.GetId() {
|
||||
find = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !find {
|
||||
self.inetworks = append(self.inetworks, network)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
// 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 ctyun
|
||||
|
||||
import (
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
type SZone struct {
|
||||
region *SRegion
|
||||
host *SHost
|
||||
|
||||
iwires []cloudprovider.ICloudWire
|
||||
istorages []cloudprovider.ICloudStorage
|
||||
/* 支持的磁盘种类集合 */
|
||||
storageTypes []string
|
||||
|
||||
RegionID string `json:"regionId"`
|
||||
ZoneID string `json:"zoneId"`
|
||||
ZoneName string `json:"zoneName"`
|
||||
ZoneType string `json:"zoneType"`
|
||||
}
|
||||
|
||||
func (self *SZone) addWire(wire *SWire) {
|
||||
if self.iwires == nil {
|
||||
self.iwires = make([]cloudprovider.ICloudWire, 0)
|
||||
}
|
||||
self.iwires = append(self.iwires, wire)
|
||||
}
|
||||
|
||||
func (self *SZone) GetId() string {
|
||||
return self.ZoneID
|
||||
}
|
||||
|
||||
func (self *SZone) GetName() string {
|
||||
return self.ZoneName
|
||||
}
|
||||
|
||||
func (self *SZone) GetGlobalId() string {
|
||||
return self.GetId()
|
||||
}
|
||||
|
||||
func (self *SZone) GetStatus() string {
|
||||
return "enable"
|
||||
}
|
||||
|
||||
func (self *SZone) Refresh() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SZone) IsEmulated() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SZone) GetMetadata() *jsonutils.JSONDict {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SZone) GetIRegion() cloudprovider.ICloudRegion {
|
||||
return self.region
|
||||
}
|
||||
|
||||
func (self *SZone) GetIHosts() ([]cloudprovider.ICloudHost, error) {
|
||||
return []cloudprovider.ICloudHost{self.getHost()}, nil
|
||||
}
|
||||
|
||||
func (self *SZone) GetIHostById(id string) (cloudprovider.ICloudHost, error) {
|
||||
host := self.getHost()
|
||||
if host.GetGlobalId() == id {
|
||||
return host, nil
|
||||
}
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func (self *SZone) GetIStorages() ([]cloudprovider.ICloudStorage, error) {
|
||||
if self.istorages == nil {
|
||||
self.fetchStorages()
|
||||
}
|
||||
return self.istorages, nil
|
||||
}
|
||||
|
||||
func (self *SZone) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) {
|
||||
if self.istorages == nil {
|
||||
self.fetchStorages()
|
||||
}
|
||||
for i := 0; i < len(self.istorages); i += 1 {
|
||||
if self.istorages[i].GetGlobalId() == id {
|
||||
return self.istorages[i], nil
|
||||
}
|
||||
}
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func (self *SZone) getHost() *SHost {
|
||||
if self.host == nil {
|
||||
self.host = &SHost{zone: self, projectId: self.region.client.projectId}
|
||||
}
|
||||
return self.host
|
||||
}
|
||||
|
||||
func (self *SZone) fetchStorages() error {
|
||||
self.getStorageType()
|
||||
self.istorages = make([]cloudprovider.ICloudStorage, len(self.storageTypes))
|
||||
|
||||
for i, sc := range self.storageTypes {
|
||||
storage := SStorage{zone: self, storageType: sc}
|
||||
self.istorages[i] = &storage
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SZone) getStorageType() {
|
||||
if len(self.storageTypes) == 0 {
|
||||
self.storageTypes = StorageTypes
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SZone) GetIWires() ([]cloudprovider.ICloudWire, error) {
|
||||
return self.iwires, nil
|
||||
}
|
||||
@@ -1 +1,15 @@
|
||||
// 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 google // import "yunion.io/x/onecloud/pkg/multicloud/google"
|
||||
|
||||
@@ -1 +1,15 @@
|
||||
// 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 "yunion.io/x/onecloud/pkg/multicloud/google/provider"
|
||||
|
||||
@@ -1 +1,15 @@
|
||||
// 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 shell // import "yunion.io/x/onecloud/pkg/multicloud/google/shell"
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
_ "yunion.io/x/onecloud/pkg/multicloud/aliyun/provider"
|
||||
_ "yunion.io/x/onecloud/pkg/multicloud/aws/provider"
|
||||
_ "yunion.io/x/onecloud/pkg/multicloud/azure/provider"
|
||||
_ "yunion.io/x/onecloud/pkg/multicloud/ctyun/provider"
|
||||
_ "yunion.io/x/onecloud/pkg/multicloud/esxi/provider" // private clouds
|
||||
_ "yunion.io/x/onecloud/pkg/multicloud/google/provider" // public clouds
|
||||
_ "yunion.io/x/onecloud/pkg/multicloud/huawei/provider"
|
||||
|
||||
Reference in New Issue
Block a user