Merge branch 'master' of https://github.com/yunionio/onecloud into feature/zxc-nodata-master

This commit is contained in:
zhaoxiangchun
2020-11-25 12:06:28 +08:00
393 changed files with 32512 additions and 6314 deletions
@@ -2,7 +2,7 @@
策略名称: {{.name}}
触发时间: {{.start_time}}
报警级别: {{.level}}
触发条件: {{.description}}
触发条件: {{.description | unescaped}}
资源数量:{{len .matches}}
资源名称:{{.resource_name}}
@@ -2,7 +2,7 @@
AlertName: {{.name}}
Time: {{.start_time}}
Level: {{.level}}
TriggerCondition: {{html .description}}
TriggerCondition: {{.description | unescaped}}
ResourceCount: {{len .matches}}
ResourceName: {{.resource_name}}
+144
View File
@@ -0,0 +1,144 @@
// 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/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud/apsara"
_ "yunion.io/x/onecloud/pkg/multicloud/apsara/shell"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
type BaseOptions struct {
Debug bool `help:"debug mode"`
Help bool `help:"Show help"`
AccessKey string `help:"Access key" default:"$APSARA_ACCESS_KEY" metavar:"APSARA_ACCESS_KEY"`
Secret string `help:"Secret" default:"$APSARA_SECRET" metavar:"APSARA_SECRET"`
cloudprovider.SApsaraEndpoints `help:"Endpoints for Apsara"`
RegionId string `help:"RegionId" default:"$APSARA_REGION" metavar:"APSARA_REGION"`
SUBCOMMAND string `help:"apsaracli subcommand" subcommand:"true"`
}
func getSubcommandParser() (*structarg.ArgumentParser, error) {
parse, e := structarg.NewArgumentParser(&BaseOptions{},
"apsaracli",
"Command-line interface to apsara API.",
`See "apsaracli 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) (*apsara.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 := apsara.NewApsaraClient(
apsara.NewApsaraClientConfig(
options.AccessKey,
options.Secret,
options.SApsaraEndpoints,
).Debug(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())
return
}
subcmd := parser.GetSubcommand()
subparser := subcmd.GetSubParser()
if e != nil {
if subparser != nil {
fmt.Print(subparser.Usage())
} else {
fmt.Print(parser.Usage())
}
showErrorAndExit(e)
}
suboptions := subparser.Options()
if options.SUBCOMMAND == "help" {
e = subcmd.Invoke(suboptions)
} else {
var region *apsara.SRegion
region, e = newClient(options)
if e != nil {
showErrorAndExit(e)
}
e = subcmd.Invoke(region, suboptions)
}
if e != nil {
showErrorAndExit(e)
}
}
+9 -4
View File
@@ -398,6 +398,7 @@ func init() {
AllowedHeaders []string
MaxAgeSeconds int
ExposeHeaders []string
RuleId string
}
R(&BucketSetCorsOption{}, "bucket-set-cors", "Set bucket cors", func(s *mcclient.ClientSession, args *BucketSetCorsOption) error {
@@ -407,8 +408,9 @@ func init() {
AllowedHeaders: args.AllowedHeaders,
MaxAgeSeconds: args.MaxAgeSeconds,
ExposeHeaders: args.ExposeHeaders,
Id: args.RuleId,
}
rules := api.BucketCORSRules{Rules: []api.BucketCORSRule{rule}}
rules := api.BucketCORSRules{Data: []api.BucketCORSRule{rule}}
result, err := modules.Buckets.PerformAction(s, args.ID, "set-cors", jsonutils.Marshal(rules))
if err != nil {
return err
@@ -430,10 +432,13 @@ func init() {
})
type BucketDeleteCorsOption struct {
ID string `help:"ID or name of bucket" json:"-"`
ID string `help:"ID or name of bucket" json:"-"`
Id []string `"help:Id of rules to delete"`
}
R(&BucketGetWebsiteConfOption{}, "bucket-delete-cors", "Delete bucket cors", func(s *mcclient.ClientSession, args *BucketGetWebsiteConfOption) error {
result, err := modules.Buckets.PerformAction(s, args.ID, "delete-cors", nil)
R(&BucketDeleteCorsOption{}, "bucket-delete-cors", "Delete bucket cors", func(s *mcclient.ClientSession, args *BucketDeleteCorsOption) error {
input := api.BucketCORSRuleDeleteInput{}
input.Id = args.Id
result, err := modules.Buckets.PerformAction(s, args.ID, "delete-cors", jsonutils.Marshal(input))
if err != nil {
return err
}
@@ -0,0 +1,32 @@
// 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/cmd/climc/shell"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/options"
)
func init() {
cmd := shell.NewResourceCmd(&modules.InterVpcNetworks).WithKeyword("inter-vpc-network")
cmd.List(&options.InterVpcNetworkListOPtions{})
cmd.Show(&options.InterVpcNetworkIdOPtions{})
cmd.Create(&options.InterVpcNetworkCreateOPtions{})
cmd.Delete(&options.InterVpcNetworkIdOPtions{})
cmd.Perform("syncstatus", &options.InterVpcNetworkIdOPtions{})
cmd.Perform("addvpc", &options.InterVpcNetworkAddVpcOPtions{})
cmd.Perform("removevpc", &options.InterVpcNetworkRemoveVpcOPtions{})
}
@@ -0,0 +1,29 @@
// 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/cmd/climc/shell"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/options"
)
func init() {
cmd := shell.NewResourceCmd(&modules.InterVpcNetworkRouteSets).WithKeyword("inter-vpc-network-routeset")
cmd.List(&options.InterVpcNetworkRouteListOptions{})
cmd.Show(&options.InterVpcNetworkRouteIdptions{})
cmd.Perform("enable", &options.InterVpcNetworkRouteIdptions{})
cmd.Perform("disable", &options.InterVpcNetworkRouteIdptions{})
}
+10 -145
View File
@@ -15,155 +15,20 @@
package compute
import (
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/cmd/climc/shell"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/options"
)
func init() {
type SchedtagListOptions struct {
options.BaseListOptions
Type string `help:"Filter by resource type"`
}
R(&SchedtagListOptions{}, "schedtag-list", "List schedule tags", func(s *mcclient.ClientSession, args *SchedtagListOptions) error {
var params *jsonutils.JSONDict
{
var err error
params, err = args.BaseListOptions.Params()
if err != nil {
return err
cmd := shell.NewResourceCmd(&modules.Schedtags)
}
}
if len(args.Type) > 0 {
params.Add(jsonutils.NewString(args.Type), "resource_type")
}
result, err := modules.Schedtags.List(s, params)
if err != nil {
return err
}
printList(result, modules.Schedtags.GetColumns(s))
return nil
})
type SchedtagShowOptions struct {
ID string `help:"ID or Name of the scheduler tag to show"`
}
R(&SchedtagShowOptions{}, "schedtag-show", "Show scheduler tag details", func(s *mcclient.ClientSession, args *SchedtagShowOptions) error {
result, err := modules.Schedtags.Get(s, args.ID, nil)
if err != nil {
return err
}
printObject(result)
return nil
})
R(&SchedtagShowOptions{}, "schedtag-delete", "Delete a scheduler tag", func(s *mcclient.ClientSession, args *SchedtagShowOptions) error {
result, err := modules.Schedtags.Delete(s, args.ID, nil)
if err != nil {
return err
}
printObject(result)
return nil
})
type SchedtagCreateOptions struct {
NAME string `help:"Name of new schedtag"`
Strategy string `help:"Policy" choices:"require|exclude|prefer|avoid"`
Desc string `help:"Description"`
Scope string `help:"Resource scope" choices:"system|domain|project"`
Type string `help:"Resource type" choices:"hosts|storages|networks|cloudproviders|cloudregions|zones"`
}
R(&SchedtagCreateOptions{}, "schedtag-create", "Create a schedule tag", func(s *mcclient.ClientSession, args *SchedtagCreateOptions) error {
params := jsonutils.NewDict()
params.Add(jsonutils.NewString(args.NAME), "name")
if len(args.Strategy) > 0 {
params.Add(jsonutils.NewString(args.Strategy), "default_strategy")
}
if len(args.Desc) > 0 {
params.Add(jsonutils.NewString(args.Desc), "description")
}
if len(args.Type) > 0 {
params.Add(jsonutils.NewString(args.Type), "resource_type")
}
if len(args.Scope) > 0 {
params.Add(jsonutils.NewString(args.Scope), "scope")
}
schedtag, err := modules.Schedtags.Create(s, params)
if err != nil {
return err
}
printObject(schedtag)
return nil
})
type SchedtagUpdateOptions struct {
ID string `help:"ID or Name of schetag"`
Name string `help:"New name of schedtag"`
Strategy string `help:"Policy" choices:"require|exclude|prefer|avoid"`
Desc string `help:"Description"`
ClearStrategy bool `help:"Clear default schedule policy"`
}
R(&SchedtagUpdateOptions{}, "schedtag-update", "Update a schedule tag", func(s *mcclient.ClientSession, args *SchedtagUpdateOptions) error {
params := jsonutils.NewDict()
if len(args.Name) > 0 {
params.Add(jsonutils.NewString(args.Name), "name")
}
if len(args.Strategy) > 0 {
params.Add(jsonutils.NewString(args.Strategy), "default_strategy")
}
if len(args.Desc) > 0 {
params.Add(jsonutils.NewString(args.Desc), "description")
}
if args.ClearStrategy {
params.Add(jsonutils.NewString(""), "default_strategy")
}
if params.Size() == 0 {
return fmt.Errorf("No valid data to update")
}
schedtag, err := modules.Schedtags.Update(s, args.ID, params)
if err != nil {
return err
}
printObject(schedtag)
return nil
})
type SetScopeOptions struct {
ID []string `help:"ID or Name of schetag"`
Project string `help:"ID or Name of project"`
Domain string `help:"ID or Name of domain"`
System bool `help:"Set to system scope"`
}
R(&SetScopeOptions{}, "schedtag-set-scope", "Set schedtag scope", func(s *mcclient.ClientSession, args *SetScopeOptions) error {
params := jsonutils.NewDict()
domainId := args.Domain
projectId := args.Project
if args.System {
domainId = ""
projectId = ""
}
params.Add(jsonutils.NewString(domainId), "domain")
params.Add(jsonutils.NewString(projectId), "project")
ret := modules.Schedtags.BatchPerformAction(s, args.ID, "set-scope", params)
printBatchResults(ret, modules.Schedtags.GetColumns(s))
return nil
})
R(&options.ResourceMetadataOptions{}, "schedtag-set-user-metadata", "Set metadata of a server", func(s *mcclient.ClientSession, opts *options.ResourceMetadataOptions) error {
params, err := opts.Params()
if err != nil {
return err
}
result, err := modules.Schedtags.PerformAction(s, opts.ID, "user-metadata", params)
if err != nil {
return err
}
printObject(result)
return nil
})
cmd.List(new(options.SchedtagListOptions))
cmd.Show(new(options.SchedtagShowOptions))
cmd.Delete(new(options.SchedtagShowOptions))
cmd.Create(new(options.SchedtagCreateOptions))
cmd.Update(new(options.SchedtagUpdateOptions))
cmd.BatchPerform("set-scope", new(options.SchedtagSetScopeOptions))
cmd.PerformWithKeyword("set-user-metadata", "user-metadata", new(options.ResourceMetadataOptions))
cmd.Perform("set-resource", new(options.SchedtagSetResource))
}
+2 -1
View File
@@ -25,7 +25,8 @@ import (
func init() {
type DomainListOptions struct {
options.BaseListOptions
IdpId string `help:"filter by idp_id"`
IdpId string `help:"filter by idp_id"`
IdpEntityId string `help:"filter by idp_entity_id"`
}
R(&DomainListOptions{}, "domain-list", "List domains", func(s *mcclient.ClientSession, args *DomainListOptions) error {
params, err := options.ListStructToParams(args)
@@ -472,6 +472,9 @@ func init() {
AutoCreateProject bool `help:"automatically create a default project when importing domain" json:"-"`
NoAutoCreateProject bool `help:"do not create default project when importing domain" json:"-"`
AutoCreateUser bool `help:"automatically create a user" json:"-"`
NoAutoCreateUser bool `help:"do not automatically create a user" json:"-"`
TargetDomain string `help:"target domain without creating new domain" json:"-"`
api.SOIDCIdpConfigOptions
@@ -488,6 +491,11 @@ func init() {
} else if args.NoAutoCreateProject {
params.Add(jsonutils.JSONFalse, "auto_create_project")
}
if args.AutoCreateUser {
params.Add(jsonutils.JSONTrue, "auto_create_user")
} else if args.NoAutoCreateUser {
params.Add(jsonutils.JSONFalse, "auto_create_user")
}
params.Add(jsonutils.NewString("oidc"), "driver")
params.Add(jsonutils.Marshal(args), "config", "oidc")
+1
View File
@@ -31,6 +31,7 @@ func init() {
OrderByDomain string `help:"order by domain name" choices:"asc|desc"`
Role string `help:"Filter by role"`
IdpId string `help:"filter by idp_id"`
IdpEntityId string `help:"filter by idp_entity_id"`
}
R(&UserListOptions{}, "user-list", "List users", func(s *mcclient.ClientSession, args *UserListOptions) error {
params, err := options.ListStructToParams(args)
-2
View File
@@ -1124,8 +1124,6 @@ vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj
yunion.io/x/executor v0.0.0-20200227030256-a18417815e74 h1:A15C6VdVRWvmQ9pAJHrUs9yan5qKlYH7uaRxHg1kRbk=
yunion.io/x/executor v0.0.0-20200227030256-a18417815e74/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws=
yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051/go.mod h1:4N0/RVzsYL3kH3WE/H1BjUQdFiWu50JGCFQuuy+Z634=
yunion.io/x/jsonutils v0.0.0-20201105032201-9d0fba742954 h1:gGU3uGxw82voqh3tVrTY4q43lLLooqgF662PqOeEpKY=
yunion.io/x/jsonutils v0.0.0-20201105032201-9d0fba742954/go.mod h1:p0nyMqGA/apTxxyLIU/o1k4V7Vujl2O6ey30L594sYE=
yunion.io/x/jsonutils v0.0.0-20201110084044-3e4e1cb49769 h1:LIQ4hhLGQuQK+XxlV+8JrKBuL37WUT+5ZTVxBwHOTD4=
yunion.io/x/jsonutils v0.0.0-20201110084044-3e4e1cb49769/go.mod h1:p0nyMqGA/apTxxyLIU/o1k4V7Vujl2O6ey30L594sYE=
yunion.io/x/log v0.0.0-20190514041436-04ce53b17c6b/go.mod h1:+gauLs73omeJAPlsXcevLsJLKixV+sR/E7WSYTSx1fE=
+2831 -2435
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -658,13 +658,13 @@
{
"id": "Model not found error: cannot find %q with id/name %q",
"message": "Model not found error: cannot find %q with id/name %q",
"translation": "无法通过名称或Id找到%q所指定的资源",
"translation": "无法通过名称或ID找到%q%q",
"position": "pkg/cloudcommon/validators/errors.go:157:17"
},
{
"id": "Model not found error: cannot find %q with id/name %q: %s",
"message": "Model not found error: cannot find %q with id/name %q: %s",
"translation": "无法通过名称或Id找到%q所指定的资源%s",
"translation": "无法通过名称或ID找到%q%q%s",
"position": "pkg/cloudcommon/validators/errors.go:157:17"
},
{
+7
View File
@@ -23,6 +23,7 @@ import (
type CloudeventListInput struct {
apis.ModelBaseListInput
apis.ProjectizedResourceListInput
compute.CloudenvResourceListInput
@@ -43,3 +44,9 @@ type CloudeventListInput struct {
// 操作日志截止时间
Until time.Time `json:"until"`
}
type CloudeventDetails struct {
apis.ModelBaseDetails
apis.ProjectizedResourceInfo
SCloudevent
}
+49
View File
@@ -0,0 +1,49 @@
// 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.
// Code generated by model-api-gen. DO NOT EDIT.
package cloudevent
import (
time "time"
"yunion.io/x/onecloud/pkg/apis"
)
// SCloudevent is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudevent/models.SCloudevent.
type SCloudevent struct {
apis.SProjectizedResourceBase
EventId int64 `json:"event_id"`
Name string `json:"name"`
Service string `json:"service"`
ResourceType string `json:"resource_type"`
Action string `json:"action"`
RequestId string `json:"request_id"`
Request interface{} `json:"request"`
Account string `json:"account"`
Success bool `json:"success"`
CreatedAt time.Time `json:"created_at"`
CloudproviderId string `json:"cloudprovider_id"`
Manager string `json:"manager"`
Provider string `json:"provider"`
Brand string `json:"brand"`
}
// SCloudprovider is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudevent/models.SCloudprovider.
type SCloudprovider struct {
apis.SEnabledStatusStandaloneResourceBase
apis.SProjectizedResourceBase
SyncStatus string `json:"sync_status"`
Provider string `json:"provider"`
Brand string `json:"brand"`
}
+10 -4
View File
@@ -225,18 +225,24 @@ type BucketCORSRule struct {
AllowedHeaders []string
MaxAgeSeconds int
ExposeHeaders []string
// 规则区别标识
Id string
}
type BucketCORSRules struct {
Rules []BucketCORSRule
Data []BucketCORSRule `json:"data"`
}
type BucketCORSRuleDeleteInput struct {
Id []string
}
func (input *BucketCORSRules) Validate() error {
for i := range input.Rules {
if len(input.Rules[i].AllowedOrigins) == 0 {
for i := range input.Data {
if len(input.Data[i].AllowedOrigins) == 0 {
return httperrors.NewMissingParameterError("allowed_origins")
}
if len(input.Rules[i].AllowedMethods) == 0 {
if len(input.Data[i].AllowedMethods) == 0 {
return httperrors.NewMissingParameterError("allowed_methods")
}
}
+13 -7
View File
@@ -15,17 +15,23 @@
package compute
const (
CDN_AREA_MAINLAND = "mainland"
CDN_AREA_OVERSEAS = "overseas"
CDN_AREA_GLOBAL = "global"
CDN_ORIGIN_TYPE_DOMAIN = "domain"
CDN_ORIGIN_TYPE_IP = "ip"
CDN_ORIGIN_TYPE_BUCKET = "bucket"
CDN_DOMAIN_STATUS_ONLINE = "online"
CDN_DOMAIN_STATUS_OFFLINE = "offline"
CDN_DOMAIN_STATUS_PROCESSING = "processing"
CDN_DOMAIN_STATUS_REJECTED = "rejected"
CDN_DOMAIN_AREA_MAINLAND = "mainland"
CDN_DOMAIN_AREA_OVERSEAS = "overseas"
CDN_DOMAIN_AREA_GLOBAL = "global"
CDN_DOMAIN_ORIGIN_TYPE_DOMAIN = "domain"
CDN_DOMAIN_ORIGIN_TYPE_IP = "ip"
CDN_DOMAIN_ORIGIN_TYPE_BUCKET = "bucket"
)
type CdnDomain struct {
// cdn加速域名
Domain string
// 状态 rejected(域名未审核)|processing(部署中)|online|offline
Status string
// 区域 mainland|overseas|global
Area string
// cdn Cname
@@ -37,5 +43,5 @@ type CdnDomain struct {
}
type CdnDomains struct {
Domains []CdnDomain
Data []CdnDomain `json:"data"`
}
+2
View File
@@ -37,6 +37,7 @@ const (
CLOUD_PROVIDER_ONECLOUD = "OneCloud"
CLOUD_PROVIDER_VMWARE = "VMware"
CLOUD_PROVIDER_ALIYUN = "Aliyun"
CLOUD_PROVIDER_APSARA = "Apsara"
CLOUD_PROVIDER_QCLOUD = "Qcloud"
CLOUD_PROVIDER_AZURE = "Azure"
CLOUD_PROVIDER_AWS = "Aws"
@@ -85,6 +86,7 @@ var (
CLOUD_PROVIDER_ONECLOUD,
CLOUD_PROVIDER_VMWARE,
CLOUD_PROVIDER_ALIYUN,
CLOUD_PROVIDER_APSARA,
CLOUD_PROVIDER_QCLOUD,
CLOUD_PROVIDER_AZURE,
CLOUD_PROVIDER_AWS,
+6
View File
@@ -135,6 +135,9 @@ type DBInstanceCreateInput struct {
// required: true
DiskSizeGB int `json:"disk_size_gb"`
// 指定连接端口
Port int `json:"port"`
// rds初始化密码
// 阿里云不需要此参数
// 华为云会默认创建一个用户,若不传此参数, 则为随机密码
@@ -154,6 +157,9 @@ type DBInstanceCreateInput struct {
// rds实例内存大小
// 若指定实例套餐,此参数将根据套餐设置
VmemSizeMb int `json:"vmem_size_mb"`
// 从备份中创建新实例
DBInstancebackupId string `json:"dbinstancebackup_id"`
}
type SDBInstanceChangeConfigInput struct {
+3
View File
@@ -32,6 +32,9 @@ type ElasticcacheDetails struct {
// 关联安全组列表
Secgroups []apis.StandaloneShortDesc `json:"secgroups"`
// 备可用区列表
SlaveZoneInfos []apis.StandaloneShortDesc `json:"slave_zone_infos"`
}
type ElasticcacheResourceInfo struct {
+1
View File
@@ -20,6 +20,7 @@ type ElasticcacheSkuDetails struct {
apis.StatusStandaloneResourceDetails
CloudregionResourceInfo
ZoneResourceInfoBase
SlaveZoneResourceInfoBase
SElasticcacheSku
}
+8 -1
View File
@@ -151,6 +151,7 @@ const (
HYPERVISOR_XEN = "xen"
HYPERVISOR_ALIYUN = "aliyun"
HYPERVISOR_APSARA = "apsara"
HYPERVISOR_QCLOUD = "qcloud"
HYPERVISOR_AZURE = "azure"
HYPERVISOR_AWS = "aws"
@@ -184,6 +185,7 @@ var HYPERVISORS = []string{
HYPERVISOR_ESXI,
HYPERVISOR_CONTAINER,
HYPERVISOR_ALIYUN,
HYPERVISOR_APSARA,
HYPERVISOR_AZURE,
HYPERVISOR_AWS,
HYPERVISOR_QCLOUD,
@@ -215,6 +217,7 @@ var PUBLIC_CLOUD_HYPERVISORS = []string{
var PRIVATE_CLOUD_HYPERVISORS = []string{
HYPERVISOR_ZSTACK,
HYPERVISOR_OPENSTACK,
HYPERVISOR_APSARA,
}
// var HYPERVISORS = []string{HYPERVISOR_ALIYUN}
@@ -225,6 +228,7 @@ var HYPERVISOR_HOSTTYPE = map[string]string{
HYPERVISOR_ESXI: HOST_TYPE_ESXI,
HYPERVISOR_CONTAINER: HOST_TYPE_KUBELET,
HYPERVISOR_ALIYUN: HOST_TYPE_ALIYUN,
HYPERVISOR_APSARA: HOST_TYPE_APSARA,
HYPERVISOR_AZURE: HOST_TYPE_AZURE,
HYPERVISOR_AWS: HOST_TYPE_AWS,
HYPERVISOR_QCLOUD: HOST_TYPE_QCLOUD,
@@ -242,6 +246,7 @@ var HOSTTYPE_HYPERVISOR = map[string]string{
HOST_TYPE_ESXI: HYPERVISOR_ESXI,
HOST_TYPE_KUBELET: HYPERVISOR_CONTAINER,
HOST_TYPE_ALIYUN: HYPERVISOR_ALIYUN,
HOST_TYPE_APSARA: HYPERVISOR_APSARA,
HOST_TYPE_AZURE: HYPERVISOR_AZURE,
HOST_TYPE_AWS: HYPERVISOR_AWS,
HOST_TYPE_QCLOUD: HYPERVISOR_QCLOUD,
@@ -254,9 +259,11 @@ var HOSTTYPE_HYPERVISOR = map[string]string{
}
const (
VM_DEFAULT_WINDOWS_LOGIN_USER = "Administrator"
VM_DEFAULT_LINUX_LOGIN_USER = "root"
VM_AWS_DEFAULT_LOGIN_USER = "ec2user"
VM_AWS_DEFAULT_WINDOWS_LOGIN_USER = "Administrator"
VM_AZURE_DEFAULT_LOGIN_USER = "toor"
VM_AZURE_DEFAULT_LOGIN_USER = "azureuser"
VM_ZSTACK_DEFAULT_LOGIN_USER = "root"
VM_METADATA_APP_TAGS = "app_tags"
+9
View File
@@ -0,0 +1,9 @@
package compute
const (
MIRROR_JOB = "__mirror_job_status"
MIRROR_JOB_READY = "ready"
MIRROR_JOB_FAILED = "failed"
)
const BASE_INSTANCE_SNAPSHOT_ID = "__base_instance_snapshot_id"
+9
View File
@@ -438,3 +438,12 @@ type ServerResetInput struct {
// 自动启动
AutoStart *bool `json:"auto_start"`
}
type ServerStopInput struct {
// 是否强制关机
IsForce bool `json:"is_force"`
// 是否关机停止计费, 若平台不支持停止计费,此参数无作用
// 目前仅阿里云,腾讯云此参数生效
StopCharging bool `json:"stop_charging"`
}
+2
View File
@@ -24,6 +24,7 @@ const (
HOST_TYPE_XEN = "xen" // # XenServer
HOST_TYPE_ALIYUN = "aliyun"
HOST_TYPE_APSARA = "apsara"
HOST_TYPE_AWS = "aws"
HOST_TYPE_QCLOUD = "qcloud"
HOST_TYPE_AZURE = "azure"
@@ -102,6 +103,7 @@ var HOST_TYPES = []string{
HOST_TYPE_KUBELET,
HOST_TYPE_XEN,
HOST_TYPE_ALIYUN,
HOST_TYPE_APSARA,
HOST_TYPE_AZURE,
HOST_TYPE_AWS,
HOST_TYPE_QCLOUD,
+73
View File
@@ -0,0 +1,73 @@
// 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"
const (
INTER_VPC_NETWORK_STATUS_AVAILABLE = "available"
INTER_VPC_NETWORK_STATUS_CREATING = "creating"
INTER_VPC_NETWORK_STATUS_CREATE_FAILED = "create_failed"
INTER_VPC_NETWORK_STATUS_DELETE_FAILED = "delete_failed"
INTER_VPC_NETWORK_STATUS_DELETING = "deleting"
INTER_VPC_NETWORK_STATUS_ACTIVE = "active"
INTER_VPC_NETWORK_STATUS_ADDVPC = "add_vpc"
INTER_VPC_NETWORK_STATUS_ADDVPC_FAILED = "add_vpc_failed"
INTER_VPC_NETWORK_STATUS_REMOVEVPC = "remove_vpc"
INTER_VPC_NETWORK_STATUS_REMOVEVPC_FAILED = "remove_vpc_failed"
INTER_VPC_NETWORK_STATUS_UPDATEROUTE = "update_route"
INTER_VPC_NETWORK_STATUS_UPDATEROUTE_FAILED = "update_route_failed"
INTER_VPC_NETWORK_STATUS_UNKNOWN = "unknown"
)
type InterVpcNetworkListInput struct {
apis.EnabledStatusInfrasResourceBaseListInput
ManagedResourceListInput
}
type InterVpcNetworkCreateInput struct {
apis.EnabledStatusInfrasResourceBaseCreateInput
ManagerId string `json:"manager_id"`
}
type InterVpcNetworkUpdateInput struct {
apis.EnabledStatusInfrasResourceBaseUpdateInput
}
type InterVpcNetworkDetails struct {
apis.EnabledStatusInfrasResourceBaseDetails
ManagedResourceInfo
VpcCount int `json:"vpc_count"`
}
type InterVpcNetworkSyncstatusInput struct {
}
type InterVpcNetworkAddVpcInput struct {
VpcId string
}
type InterVpcNetworkRemoveVpcInput struct {
VpcId string
}
type InterVpcNetworkFilterListBase struct {
InterVpcNetworkId string `json:"inter_vpc_network_id"`
}
type InterVpcNetworkManagerListInput struct {
apis.EnabledStatusInfrasResourceBaseListInput
ManagedResourceListInput
}
@@ -0,0 +1,42 @@
// 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"
const (
INTER_VPCNETWORK_ATTACHED_INSTAMCE_TYPE_VPC = "VPC"
INTER_VPCNETWORK_ATTACHED_INSTAMCE_TYPE_VBR = "VBR" // 边界路由器
)
type InterVpcNetworkRouteSetEnableInput struct {
apis.PerformEnableInput
}
type InterVpcNetworkRouteSetDisableInput struct {
apis.PerformDisableInput
}
type InterVpcNetworkRouteSetDetails struct {
apis.EnabledStatusStandaloneResourceDetails
VpcResourceInfo
}
type InterVpcNetworkRouteSetListInput struct {
apis.EnabledStatusStandaloneResourceListInput
apis.ExternalizedResourceBaseListInput
VpcFilterListInput
InterVpcNetworkId string
}
+4
View File
@@ -36,10 +36,14 @@ const (
Next_HOP_TYPE_VPCPEERING = "VpcPeering" // vpc对等连接
Next_HOP_TYPE_INTERVPCNETWORK = "InterVpcNetwork" //vpc 互联网络
Next_HOP_TYPE_DIRECTCONNECTION = "DirectConnection" //专线
Next_HOP_TYPE_VPC = "VPC"
Next_HOP_TYPE_VBR = "VBR" // 边界路由器
)
const (
ROUTE_ENTRY_STATUS_AVAILIABLE = "available"
ROUTE_ENTRY_STATUS_CONFLICT = "conflict"
ROUTE_ENTRY_STATUS_DISABLED = "disabled"
ROUTE_ENTRY_STATUS_UNKNOWN = "unknown"
)
+4
View File
@@ -109,3 +109,7 @@ type SchedtagJointsListInput struct {
apis.JointResourceBaseListInput
SchedtagFilterListInput
}
type SchedtagSetResourceInput struct {
ResourceIds []string `json:"resource_ids"`
}
+5 -3
View File
@@ -28,6 +28,7 @@ const (
STORAGE_VSAN = "vsan"
STORAGE_NFS = "nfs"
STORAGE_GPFS = "gpfs"
STORAGE_CIFS = "cifs"
STORAGE_PUBLIC_CLOUD = "cloud"
STORAGE_CLOUD_EFFICIENCY = "cloud_efficiency"
@@ -45,6 +46,7 @@ const (
// aws storage type
STORAGE_GP2_SSD = "gp2" // aws general purpose ssd
STORAGE_IO1_SSD = "io1" // aws Provisioned IOPS SSD
STORAGE_IO2_SSD = "io2" // aws Provisioned IOPS 2 SSD
STORAGE_ST1_HDD = "st1" // aws Throughput Optimized HDD
STORAGE_SC1_HDD = "sc1" // aws Cold HDD
STORAGE_STANDARD_HDD = "standard" // aws Magnetic volumes
@@ -116,7 +118,7 @@ var (
STORAGE_ALL_TYPES = []string{
STORAGE_LOCAL, STORAGE_BAREMETAL, STORAGE_SHEEPDOG,
STORAGE_RBD, STORAGE_DOCKER, STORAGE_NAS, STORAGE_VSAN,
STORAGE_NFS, STORAGE_GPFS,
STORAGE_NFS, STORAGE_GPFS, STORAGE_CIFS,
}
STORAGE_TYPES = []string{STORAGE_LOCAL, STORAGE_BAREMETAL, STORAGE_SHEEPDOG,
STORAGE_RBD, STORAGE_DOCKER, STORAGE_NAS, STORAGE_VSAN, STORAGE_NFS,
@@ -128,12 +130,12 @@ var (
STORAGE_HUAWEI_SSD, STORAGE_HUAWEI_SAS, STORAGE_HUAWEI_SATA,
STORAGE_OPENSTACK_ISCSI, STORAGE_UCLOUD_CLOUD_NORMAL, STORAGE_UCLOUD_CLOUD_SSD,
STORAGE_UCLOUD_LOCAL_NORMAL, STORAGE_UCLOUD_LOCAL_SSD, STORAGE_UCLOUD_EXCLUSIVE_LOCAL_DISK,
STORAGE_ZSTACK_LOCAL_STORAGE, STORAGE_ZSTACK_CEPH, STORAGE_GPFS,
STORAGE_ZSTACK_LOCAL_STORAGE, STORAGE_ZSTACK_CEPH, STORAGE_GPFS, STORAGE_CIFS,
}
HOST_STORAGE_LOCAL_TYPES = []string{STORAGE_LOCAL, STORAGE_BAREMETAL, STORAGE_ZSTACK_LOCAL_STORAGE, STORAGE_OPENSTACK_NOVA}
STORAGE_LIMITED_TYPES = []string{STORAGE_LOCAL, STORAGE_BAREMETAL, STORAGE_NAS, STORAGE_RBD, STORAGE_NFS, STORAGE_GPFS}
STORAGE_LIMITED_TYPES = []string{STORAGE_LOCAL, STORAGE_BAREMETAL, STORAGE_NAS, STORAGE_RBD, STORAGE_NFS, STORAGE_GPFS, STORAGE_VSAN, STORAGE_CIFS}
SHARED_FILE_STORAGE = []string{STORAGE_NFS, STORAGE_GPFS}
FIEL_STORAGE = []string{STORAGE_LOCAL, STORAGE_NFS, STORAGE_GPFS}
+2
View File
@@ -55,6 +55,8 @@ type VpcListInput struct {
DnsZoneFilterListBase
InterVpcNetworkFilterListBase
UsableResourceListInput
UsableVpcResourceListInput
+9
View File
@@ -104,6 +104,15 @@ type Zone1ResourceInfoBase struct {
Zone1ExtId string `json:"zone_1_ext_id"`
}
type SlaveZoneResourceInfoBase struct {
// 可用区名称
// example: 北京2区
SlaveZone string `json:"slave_zone"`
// 纳管云的zoneId
SlaveZoneExtId string `json:"slave_zone_ext_id"`
}
type ZoneResourceInfo struct {
ZoneResourceInfoBase
+6
View File
@@ -167,6 +167,9 @@ type DomainListInput struct {
// 按IDP过滤
IdpId string `json:"idp_id"`
// 按IDP_ENTITY_ID过滤
IdpEntityId string `json:"idp_entity_id"`
}
type UserListInput struct {
@@ -191,6 +194,9 @@ type UserListInput struct {
// 关联IDP
IdpId string `json:"idp_id"`
// 按IDP_ENTITY_ID过滤
IdpEntityId string `json:"idp_entity_id"`
}
type EndpointListInput struct {
+2
View File
@@ -34,7 +34,9 @@ type AlertRecordCreateInput struct {
type AlertRecordRule struct {
Metric string `json:"metric"`
Measurement string `json:"measurement"`
MeasurementDesc string `json:"measurement_desc"`
Field string `json:"field"`
FieldDesc string `json:"field_desc"`
// 比较运算符, 比如: >, <, >=, <=
Comparator string `json:"comparator"`
+2
View File
@@ -56,6 +56,7 @@ type SuggestSysAlertDetails struct {
Suggest string `json:"suggest"`
Brand string `json:"brand"`
Account string `json:"account"`
ResName string `json:"res_name"`
}
type SuggestSysAlertUpdateInput struct {
@@ -76,6 +77,7 @@ type SuggestSysAlertUpdateInput struct {
type SuggestAlertIngoreInput struct {
apis.ScopedResourceCreateInput
BatchIgnore bool `json:"batch_ignore"`
}
type SuggestAlertProblem struct {
+14 -11
View File
@@ -58,27 +58,30 @@ type SuggestSysRuleCreateInput struct {
apis.StandaloneResourceCreateInput
// 查询指标周期
Period string `json:"period"`
TimeFrom string `json:"time_from"`
Type string `json:"type"`
Enabled *bool `json:"enabled"`
Setting *SSuggestSysAlertSetting `json:"setting"`
Period string `json:"period"`
TimeFrom string `json:"time_from"`
Type string `json:"type"`
Enabled *bool `json:"enabled"`
Setting *SSuggestSysAlertSetting `json:"setting"`
IgnoreTimeFrom *bool `json:"ignore_time_from"`
}
type SuggestSysRuleUpdateInput struct {
apis.Meta
// 查询指标周期
Period string `json:"period"`
Name string `json:"name"`
Type string `json:"type"`
Setting *SSuggestSysAlertSetting `json:"setting"`
Enabled *bool `json:"enabled"`
ExecTime time.Time `json:"exec_time"`
Period string `json:"period"`
Name string `json:"name"`
Type string `json:"type"`
Setting *SSuggestSysAlertSetting `json:"setting"`
Enabled *bool `json:"enabled"`
ExecTime time.Time `json:"exec_time"`
IgnorePeriod *bool `json:"ignore_period"`
}
type SuggestSysRuleDetails struct {
apis.StandaloneResourceDetails
CommonAlertMetricDetails []*CommonAlertMetricDetails `json:"common_alert_metric_details"`
ID string `json:"id"`
Name string `json:"name"`
+5
View File
@@ -53,6 +53,7 @@ type SuggestSysRuleConfigDetails struct {
RuleId string `json:"rule_id"`
Rule string `json:"rule"`
RuleEnabled bool `json:"rule_enabled"`
ResName string `json:"res_name"`
}
type SuggestSysRuleConfigListInput struct {
@@ -62,3 +63,7 @@ type SuggestSysRuleConfigListInput struct {
ResourceType *MonitorResourceType `json:"resource_type"`
IgnoreAlert *bool `json:"ignore_alert"`
}
type SuggestSysRuleConfigTypeInfo struct {
Name string `json:"name"`
}
+1 -1
View File
@@ -34,7 +34,7 @@ import (
type SJointResourceBase struct {
SResourceBase
RowId int64 `primary:"true" auto_increment:"true"`
RowId int64 `primary:"true" auto_increment:"true" list:"user"`
}
type SJointResourceBaseManager struct {
+7
View File
@@ -265,4 +265,11 @@ const (
ACT_SYNC_VPCS = "sync_vpcs"
ACT_SYNC_RECORD_SETS = "sync_record_sets"
ACT_NETWORK_ADD_VPC = "network_add_vpc"
ACT_NETWORK_ADD_VPC_FAILED = "network_add_vpc_failed"
ACT_NETWORK_REMOVE_VPC = "network_remove_vpc"
ACT_NETWORK_REMOVE_VPC_FAILED = "network_remove_vpc_failed"
ACT_NETWORK_MODIFY_ROUTE = "network_modify_route"
ACT_NETWORK_MODIFY_ROUTE_FAILED = "network_modify_route_failed"
)
+7 -1
View File
@@ -91,7 +91,9 @@ func getTemplate(ctx context.Context, topic string, contType string, channel npk
if err != nil {
return nil, err
}
tmp, err := template.New(key).Parse(string(cont))
tmp := template.New(key)
tmp.Funcs(template.FuncMap{"unescaped": unescaped})
tmp, err = tmp.Parse(string(cont))
if err != nil {
return nil, err
}
@@ -100,6 +102,10 @@ func getTemplate(ctx context.Context, topic string, contType string, channel npk
return templatesTable[key], nil
}
func unescaped(str string) template.HTML {
return template.HTML(str)
}
func getContent(ctx context.Context, topic string, contType string, channel npk.TNotifyChannel, data jsonutils.JSONObject) (string, error) {
if channel == npk.NotifyByWebhook {
return "", nil
+67
View File
@@ -27,10 +27,13 @@ import (
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/rbacutils"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SCloudeventManager struct {
db.SModelBaseManager
db.SProjectizedResourceBaseManager
}
var CloudeventManager *SCloudeventManager
@@ -49,6 +52,7 @@ func init() {
type SCloudevent struct {
db.SModelBase
db.SProjectizedResourceBase
EventId int64 `primary:"true" auto_increment:"true" list:"user"`
Name string `width:"128" charset:"utf8" nullable:"false" index:"true" list:"user"`
@@ -125,6 +129,67 @@ func (manager *SCloudeventManager) ListItemFilter(
return q, nil
}
func (self *SCloudevent) GetExtraDetails(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
isList bool,
) (api.CloudeventDetails, error) {
return api.CloudeventDetails{}, nil
}
func (manager *SCloudeventManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.CloudeventDetails {
rows := make([]api.CloudeventDetails, len(objs))
base := manager.SModelBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
projRows := manager.SProjectizedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
for i := range rows {
rows[i].ModelBaseDetails = base[i]
rows[i].ProjectizedResourceInfo = projRows[i]
}
return rows
}
func (manager *SCloudeventManager) ResourceScope() rbacutils.TRbacScope {
return rbacutils.ScopeProject
}
func (self *SCloudevent) GetOwnerId() mcclient.IIdentityProvider {
owner := db.SOwnerId{DomainId: self.DomainId, ProjectId: self.ProjectId}
return &owner
}
func (manager *SCloudeventManager) FilterByOwner(q *sqlchemy.SQuery, owner mcclient.IIdentityProvider, scope rbacutils.TRbacScope) *sqlchemy.SQuery {
return manager.SProjectizedResourceBaseManager.FilterByOwner(q, owner, scope)
}
func (manager *SCloudeventManager) FetchOwnerId(ctx context.Context, data jsonutils.JSONObject) (mcclient.IIdentityProvider, error) {
return manager.SProjectizedResourceBaseManager.FetchOwnerId(ctx, data)
}
func (manager *SCloudeventManager) ListItemExportKeys(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, keys stringutils2.SSortedStrings) (*sqlchemy.SQuery, error) {
return manager.SProjectizedResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
}
func (manager *SCloudeventManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
return manager.SProjectizedResourceBaseManager.QueryDistinctExtraField(q, field)
}
func (manager *SCloudeventManager) OrderByExtraFields(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.CloudeventListInput,
) (*sqlchemy.SQuery, error) {
return manager.SProjectizedResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.ProjectizedResourceListInput)
}
func (manager *SCloudeventManager) SyncCloudevent(ctx context.Context, userCred mcclient.TokenCredential, cloudprovider *SCloudprovider, iEvents []cloudprovider.ICloudEvent) int {
count := 0
for _, iEvent := range iEvents {
@@ -142,6 +207,8 @@ func (manager *SCloudeventManager) SyncCloudevent(ctx context.Context, userCred
Brand: cloudprovider.Brand,
CloudproviderId: cloudprovider.Id,
}
event.DomainId = cloudprovider.DomainId
event.ProjectId = cloudprovider.ProjectId
if len(event.Brand) == 0 {
event.Brand = event.Provider
}
+17
View File
@@ -28,6 +28,7 @@ import (
"yunion.io/x/pkg/util/compare"
"yunion.io/x/pkg/util/timeutils"
"yunion.io/x/pkg/utils"
"yunion.io/x/sqlchemy"
proxyapi "yunion.io/x/onecloud/pkg/apis/cloudcommon/proxy"
api "yunion.io/x/onecloud/pkg/apis/compute"
@@ -35,6 +36,7 @@ import (
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudevent/options"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/auth"
"yunion.io/x/onecloud/pkg/mcclient/modules"
@@ -44,6 +46,7 @@ import (
type SCloudproviderManager struct {
db.SEnabledStatusStandaloneResourceBaseManager
db.SProjectizedResourceBaseManager
}
var CloudproviderManager *SCloudproviderManager
@@ -62,6 +65,7 @@ func init() {
type SCloudprovider struct {
db.SEnabledStatusStandaloneResourceBase
db.SProjectizedResourceBase
SyncStatus string
LastSync time.Time
@@ -111,6 +115,17 @@ func (manager *SCloudproviderManager) GetLocalCloudproviders() ([]SCloudprovider
return dbProviders, nil
}
func (manager *SCloudproviderManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SEnabledStatusStandaloneResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
return q, httperrors.ErrNotFound
}
func (manager *SCloudproviderManager) syncCloudproviders(ctx context.Context, userCred mcclient.TokenCredential) compare.SyncResult {
result := compare.SyncResult{}
providers, err := manager.GetRegionCloudproviders(ctx, userCred)
@@ -176,6 +191,8 @@ func (provider *SCloudprovider) syncWithRegionProvider(ctx context.Context, user
provider.Status = cloudprovider.Status
provider.Enabled = cloudprovider.Enabled
provider.Brand = cloudprovider.Brand
provider.ProjectId = cloudprovider.ProjectId
provider.DomainId = cloudprovider.DomainId
return nil
})
return err
+2
View File
@@ -17,6 +17,8 @@ package cloudprovider
type SCdnDomain struct {
// cdn加速域名
Domain string
// 状态 rejected(域名未审核)|processing(部署中)|online|offline
Status string
// 区域 mainland|overseas|global
Area string
// cdn Cname
+27
View File
@@ -94,6 +94,9 @@ type SCloudaccountCredential struct {
GCPPrivateKeyId string `json:"gcp_private_key_id"`
// Google服务账号秘钥 (gcp)
GCPPrivateKey string `json:"gcp_private_key"`
// 阿里云专有云Endpoints
*SApsaraEndpoints
}
type SCloudaccount struct {
@@ -155,6 +158,8 @@ type ProviderConfig struct {
AccountId string
SApsaraEndpoints
ProxyFunc httputils.TransportProxyFunc
}
@@ -285,6 +290,10 @@ type ICloudProvider interface {
GetICloudDnsZones() ([]ICloudDnsZone, error)
GetICloudDnsZoneById(id string) (ICloudDnsZone, error)
CreateICloudDnsZone(opts *SDnsZoneCreateOptions) (ICloudDnsZone, error)
GetICloudInterVpcNetworks() ([]ICloudInterVpcNetwork, error)
GetICloudInterVpcNetworkById(id string) (ICloudInterVpcNetwork, error)
CreateICloudInterVpcNetwork(opts *SInterVpcNetworkCreateOptions) (ICloudInterVpcNetwork, error)
}
func IsSupportProject(prod ICloudProvider) bool {
@@ -295,6 +304,10 @@ func IsSupportDnsZone(prod ICloudProvider) bool {
return utils.IsInStringArray(CLOUD_CAPABILITY_DNSZONE, prod.GetCapabilities())
}
func IsSupportInterVpcNetwork(prod ICloudProvider) bool {
return utils.IsInStringArray(CLOUD_CAPABILITY_INTERVPCNETWORK, prod.GetCapabilities())
}
func IsSupportCompute(prod ICloudProvider) bool {
return utils.IsInStringArray(CLOUD_CAPABILITY_COMPUTE, prod.GetCapabilities())
}
@@ -497,6 +510,20 @@ func (self *SBaseProvider) GetSamlEntityId() string {
return ""
}
func (self *SBaseProvider) GetSamlSpInitiatedLoginUrl(idpName string) string {
return ""
}
func (self *SBaseProvider) GetICloudInterVpcNetworks() ([]ICloudInterVpcNetwork, error) {
return nil, ErrNotImplemented
}
func (self *SBaseProvider) GetICloudInterVpcNetworkById(id string) (ICloudInterVpcNetwork, error) {
return nil, ErrNotImplemented
}
func (self *SBaseProvider) CreateICloudInterVpcNetwork(opts *SInterVpcNetworkCreateOptions) (ICloudInterVpcNetwork, error) {
return nil, ErrNotImplemented
}
func NewBaseProvider(factory ICloudProviderFactory) SBaseProvider {
return SBaseProvider{factory: factory}
}
+13 -11
View File
@@ -41,17 +41,19 @@ const (
)
const (
CLOUD_CAPABILITY_PROJECT = "project"
CLOUD_CAPABILITY_COMPUTE = "compute"
CLOUD_CAPABILITY_NETWORK = "network"
CLOUD_CAPABILITY_LOADBALANCER = "loadbalancer"
CLOUD_CAPABILITY_OBJECTSTORE = "objectstore"
CLOUD_CAPABILITY_RDS = "rds"
CLOUD_CAPABILITY_CACHE = "cache" // 弹性缓存包含redis、memcached
CLOUD_CAPABILITY_EVENT = "event"
CLOUD_CAPABILITY_CLOUDID = "cloudid"
CLOUD_CAPABILITY_DNSZONE = "dnszone"
CLOUD_CAPABILITY_PUBLIC_IP = "public_ip"
CLOUD_CAPABILITY_PROJECT = "project"
CLOUD_CAPABILITY_COMPUTE = "compute"
CLOUD_CAPABILITY_NETWORK = "network"
CLOUD_CAPABILITY_LOADBALANCER = "loadbalancer"
CLOUD_CAPABILITY_OBJECTSTORE = "objectstore"
CLOUD_CAPABILITY_RDS = "rds"
CLOUD_CAPABILITY_CACHE = "cache" // 弹性缓存包含redis、memcached
CLOUD_CAPABILITY_EVENT = "event"
CLOUD_CAPABILITY_CLOUDID = "cloudid"
CLOUD_CAPABILITY_DNSZONE = "dnszone"
CLOUD_CAPABILITY_PUBLIC_IP = "public_ip"
CLOUD_CAPABILITY_INTERVPCNETWORK = "intervpcnetwork"
CLOUD_CAPABILITY_SAML_AUTH = "saml_auth" // 是否支持SAML 2.0
)
const (
+11
View File
@@ -16,6 +16,14 @@ package cloudprovider
import "yunion.io/x/onecloud/pkg/util/billing"
type TBackupMethod string
const (
BackupMethodLogical = TBackupMethod("Logical")
BackupMethodPhysical = TBackupMethod("Physical")
BackupMethodUnknown = TBackupMethod("")
)
type SDBInstanceNetwork struct {
IP string
NetworkId string
@@ -61,6 +69,9 @@ type SManagedDBInstanceCreateConfig struct {
BillingCycle *billing.SBillingCycle
Tags map[string]string
// 仅从备份恢复到新实例用到
RdsId string
}
type SManagedDBInstanceChangeConfig struct {
+29
View File
@@ -0,0 +1,29 @@
// 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 cloudprovider
type SApsaraEndpoints struct {
EcsEndpoint string `default:"$APSARA_ECS_ENDPOINT" metavar:"APSARA_ECS_ENDPOINT"`
RdsEndpoint string `default:"$APSARA_RDS_ENDPOINT"`
VpcEndpoint string `default:"$APSARA_VPC_ENDPOINT"`
KvsEndpoint string `default:"$APSARA_KVS_ENDPOINT"`
SlbEndpoint string `default:"$APSARA_SLB_ENDPOINT"`
OssEndpoint string `default:"$APSARA_OSS_ENDPOINT"`
StsEndpoint string `default:"$APSARA_STS_ENDPOINT"`
ActionTrailEndpoint string `default:"$APSARA_ACTION_TRAIL_ENDPOINT"`
RamEndpoint string `default:"$APSARA_RAM_ENDPOINT"`
MetricsEndpoint string `default:"$APSRRA_METRICS_ENDPOINT"`
ResourcemanagerEndpoint string `default:"$APSARA_RESOURCEMANAGER_ENDPOINT"`
}
+37
View File
@@ -26,6 +26,38 @@ import (
"yunion.io/x/onecloud/pkg/util/seclib2"
)
type SDistDefaultAccount struct {
// 操作系统发行版
OsDistribution string
// 默认用户名
DefaultAccount string
// 是否可更改
Changeable bool
}
type SOsDefaultAccount struct {
// 默认用户名
DefaultAccount string
// 是否可更改用户名
Changeable bool
// 禁止使用的账号
DisabledAccounts []string
// 各操作系统发行版的默认用户名信息
DistAccounts []SDistDefaultAccount
}
type SDefaultAccount struct {
Linux SOsDefaultAccount
Windows SOsDefaultAccount
}
type SInstanceCapability struct {
Provider string
Hypervisor string
DefaultAccount SDefaultAccount
}
type SDiskInfo struct {
StorageExternalId string
StorageType string
@@ -46,6 +78,11 @@ type SPublicIpInfo struct {
PublicIpChargeType TElasticipChargeType
}
type ServerStopOptions struct {
IsForce bool
StopCharging bool
}
type SManagedVMCreateConfig struct {
Name string
ExternalImageId string
+37
View File
@@ -0,0 +1,37 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cloudprovider
type SInterVpcNetworkAttachVpcOption struct {
VpcId string
VpcRegionId string
VpcAuthorityOwnerId string
}
type SInterVpcNetworkDetachVpcOption struct {
VpcId string
VpcRegionId string
VpcAuthorityOwnerId string
}
type SVpcJointInterVpcNetworkOption struct {
InterVpcNetworkId string
NetworkAuthorityOwnerId string
}
type SInterVpcNetworkCreateOptions struct {
Name string
Desc string
}
+3 -1
View File
@@ -105,6 +105,8 @@ type SBucketCORSRule struct {
AllowedHeaders []string
MaxAgeSeconds int
ExposeHeaders []string
// 规则区别标识
Id string
}
type SBucketRefererConf struct {
@@ -216,7 +218,7 @@ type ICloudBucket interface {
SetCORS(rules []SBucketCORSRule) error
GetCORSRules() ([]SBucketCORSRule, error)
DeleteCORS() error
DeleteCORS(id []string) error
SetReferer(conf SBucketRefererConf) error
GetReferer() (SBucketRefererConf, error)
+29 -2
View File
@@ -294,7 +294,7 @@ type ICloudVM interface {
// GetSecurityGroup() ICloudSecurityGroup
StartVM(ctx context.Context) error
StopVM(ctx context.Context, isForce bool) error
StopVM(ctx context.Context, opts *ServerStopOptions) error
DeleteVM(ctx context.Context) error
UpdateVM(ctx context.Context, name string) error
@@ -417,7 +417,6 @@ type ICloudDisk interface {
Delete(ctx context.Context) error
CreateISnapshot(ctx context.Context, name string, desc string) (ICloudSnapshot, error)
GetISnapshot(idStr string) (ICloudSnapshot, error)
GetISnapshots() ([]ICloudSnapshot, error)
GetExtSnapshotPolicyIds() ([]string, error)
@@ -476,7 +475,10 @@ type ICloudVpc interface {
GetICloudVpcPeeringConnectionById(id string) (ICloudVpcPeeringConnection, error)
CreateICloudVpcPeeringConnection(opts *VpcPeeringConnectionCreateOptions) (ICloudVpcPeeringConnection, error)
AcceptICloudVpcPeeringConnection(id string) error
GetAuthorityOwnerId() string
ProposeJoinICloudInterVpcNetwork(opts *SVpcJointInterVpcNetworkOption) error
}
type ICloudWire interface {
@@ -849,6 +851,9 @@ type ICloudDBInstanceBackup interface {
GetBackupSizeMb() int
GetDBNames() string
GetBackupMode() string
GetBackupMethod() TBackupMethod
CreateICloudDBInstance(opts *SManagedDBInstanceCreateConfig) (ICloudDBInstance, error)
Delete() error
}
@@ -1127,3 +1132,25 @@ type ICloudrole interface {
Delete() error
}
type ICloudInterVpcNetwork interface {
ICloudResource
GetAuthorityOwnerId() string
GetICloudVpcIds() ([]string, error)
AttachVpc(opts *SInterVpcNetworkAttachVpcOption) error
DetachVpc(opts *SInterVpcNetworkDetachVpcOption) error
Delete() error
GetIRoutes() ([]ICloudInterVpcNetworkRoute, error)
EnableRouteEntry(routeId string) error
DisableRouteEntry(routeId string) error
}
type ICloudInterVpcNetworkRoute interface {
ICloudResource
GetInstanceId() string
GetInstanceType() string
GetInstanceRegionId() string
GetEnabled() bool
GetCidr() string
}
+17
View File
@@ -164,6 +164,23 @@ func (self *SAliyunGuestDriver) GetGuestInitialStateAfterRebuild() string {
return api.VM_READY
}
func (self *SAliyunGuestDriver) GetInstanceCapability() cloudprovider.SInstanceCapability {
return cloudprovider.SInstanceCapability{
Hypervisor: self.GetHypervisor(),
Provider: self.GetProvider(),
DefaultAccount: cloudprovider.SDefaultAccount{
Linux: cloudprovider.SOsDefaultAccount{
DefaultAccount: api.VM_DEFAULT_LINUX_LOGIN_USER,
Changeable: false,
},
Windows: cloudprovider.SOsDefaultAccount{
DefaultAccount: api.VM_DEFAULT_WINDOWS_LOGIN_USER,
Changeable: false,
},
},
}
}
func (self *SAliyunGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string {
userName := "root"
if desc.OsType == "Windows" {
+84
View File
@@ -0,0 +1,84 @@
// 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 (
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/billing"
"yunion.io/x/onecloud/pkg/util/rbacutils"
)
type SApsaraGuestDriver struct {
SAliyunGuestDriver
}
func init() {
driver := SApsaraGuestDriver{}
models.RegisterGuestDriver(&driver)
}
func (self *SApsaraGuestDriver) GetHypervisor() string {
return api.HYPERVISOR_APSARA
}
func (self *SApsaraGuestDriver) GetProvider() string {
return api.CLOUD_PROVIDER_APSARA
}
func (self *SApsaraGuestDriver) GetComputeQuotaKeys(scope rbacutils.TRbacScope, ownerId mcclient.IIdentityProvider, brand string) models.SComputeResourceKeys {
keys := models.SComputeResourceKeys{}
keys.SBaseProjectQuotaKeys = quotas.OwnerIdProjectQuotaKeys(scope, ownerId)
keys.CloudEnv = api.CLOUD_ENV_PRIVATE_CLOUD
keys.Provider = api.CLOUD_PROVIDER_APSARA
keys.Brand = api.CLOUD_PROVIDER_APSARA
keys.Hypervisor = api.HYPERVISOR_APSARA
return keys
}
func (self *SApsaraGuestDriver) GetGuestInitialStateAfterCreate() string {
return api.VM_READY
}
func (self *SApsaraGuestDriver) GetGuestInitialStateAfterRebuild() string {
return api.VM_READY
}
func (self *SApsaraGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string {
userName := "root"
if desc.OsType == "Windows" {
userName = "Administrator"
}
return userName
}
func (self *SApsaraGuestDriver) AllowReconfigGuest() bool {
return true
}
func (self *SApsaraGuestDriver) IsSupportedBillingCycle(bc billing.SBillingCycle) bool {
return false
}
func (self *SApsaraGuestDriver) IsSupportPublicipToEip() bool {
return false
}
func (self *SApsaraGuestDriver) IsSupportSetAutoRenew() bool {
return false
}
+20 -2
View File
@@ -86,6 +86,23 @@ func (self *SAwsGuestDriver) GetWindowsUserDataType() string {
return cloudprovider.CLOUD_EC2
}
func (self *SAwsGuestDriver) GetInstanceCapability() cloudprovider.SInstanceCapability {
return cloudprovider.SInstanceCapability{
Hypervisor: self.GetHypervisor(),
Provider: self.GetProvider(),
DefaultAccount: cloudprovider.SDefaultAccount{
Linux: cloudprovider.SOsDefaultAccount{
DefaultAccount: api.VM_DEFAULT_LINUX_LOGIN_USER,
Changeable: false,
},
Windows: cloudprovider.SOsDefaultAccount{
DefaultAccount: api.VM_DEFAULT_WINDOWS_LOGIN_USER,
Changeable: false,
},
},
}
}
func (self *SAwsGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string {
// return fetchAwsUserName(desc)
if desc.OsType == "Windows" {
@@ -125,6 +142,7 @@ func (self *SAwsGuestDriver) GetStorageTypes() []string {
return []string{
api.STORAGE_GP2_SSD,
api.STORAGE_IO1_SSD,
api.STORAGE_IO2_SSD,
api.STORAGE_ST1_HDD,
api.STORAGE_SC1_HDD,
api.STORAGE_STANDARD_HDD,
@@ -181,10 +199,10 @@ func (self *SAwsGuestDriver) ValidateResizeDisk(guest *models.SGuest, disk *mode
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 disk.DiskType == api.DISK_TYPE_SYS && !utils.IsInStringArray(storage.StorageType, []string{api.STORAGE_IO1_SSD, api.STORAGE_STANDARD_HDD, api.STORAGE_GP2_SSD}) {
if disk.DiskType == api.DISK_TYPE_SYS && !utils.IsInStringArray(storage.StorageType, []string{api.STORAGE_IO1_SSD, api.STORAGE_IO2_SSD, api.STORAGE_STANDARD_HDD, api.STORAGE_GP2_SSD}) {
return fmt.Errorf("Cannot resize system disk with unsupported volumes type %s", storage.StorageType)
}
if !utils.IsInStringArray(storage.StorageType, []string{api.STORAGE_GP2_SSD, api.STORAGE_IO1_SSD, api.STORAGE_ST1_HDD, api.STORAGE_SC1_HDD, api.STORAGE_STANDARD_HDD}) {
if !utils.IsInStringArray(storage.StorageType, []string{api.STORAGE_GP2_SSD, api.STORAGE_IO1_SSD, api.STORAGE_IO2_SSD, api.STORAGE_ST1_HDD, api.STORAGE_SC1_HDD, api.STORAGE_STANDARD_HDD}) {
return fmt.Errorf("Cannot resize %s disk", storage.StorageType)
}
return nil
+17
View File
@@ -222,6 +222,23 @@ func (self *SAzureGuestDriver) GetGuestInitialStateAfterRebuild() string {
return api.VM_READY
}
func (self *SAzureGuestDriver) GetInstanceCapability() cloudprovider.SInstanceCapability {
return cloudprovider.SInstanceCapability{
Hypervisor: self.GetHypervisor(),
Provider: self.GetProvider(),
DefaultAccount: cloudprovider.SDefaultAccount{
Linux: cloudprovider.SOsDefaultAccount{
DefaultAccount: api.VM_AZURE_DEFAULT_LOGIN_USER,
Changeable: false,
},
Windows: cloudprovider.SOsDefaultAccount{
DefaultAccount: api.VM_DEFAULT_WINDOWS_LOGIN_USER,
Changeable: false,
},
},
}
}
func (self *SAzureGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string {
return api.VM_AZURE_DEFAULT_LOGIN_USER
}
+9 -1
View File
@@ -30,6 +30,7 @@ import (
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/baremetal"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/compute/options"
@@ -56,6 +57,13 @@ func (self *SBaremetalGuestDriver) GetProvider() string {
return api.CLOUD_PROVIDER_ONECLOUD
}
func (self *SBaremetalGuestDriver) GetInstanceCapability() cloudprovider.SInstanceCapability {
return cloudprovider.SInstanceCapability{
Hypervisor: self.GetHypervisor(),
Provider: self.GetProvider(),
}
}
func (self *SBaremetalGuestDriver) GetComputeQuotaKeys(scope rbacutils.TRbacScope, ownerId mcclient.IIdentityProvider, brand string) models.SComputeResourceKeys {
keys := models.SComputeResourceKeys{}
keys.SBaseProjectQuotaKeys = quotas.OwnerIdProjectQuotaKeys(scope, ownerId)
@@ -322,7 +330,7 @@ func (self *SBaremetalGuestDriver) RequestStopGuestForDelete(ctx context.Context
!guest.PendingDeleted &&
!overridePendingDelete &&
!purge {
return guest.StartGuestStopTask(ctx, task.GetUserCred(), true, task.GetTaskId())
return guest.StartGuestStopTask(ctx, task.GetUserCred(), true, false, task.GetTaskId())
}
if host != nil && !host.GetEnabled() && !purge {
return fmt.Errorf("fail to contact baremetal")
+8
View File
@@ -24,6 +24,7 @@ import (
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/compute/options"
"yunion.io/x/onecloud/pkg/httperrors"
@@ -57,6 +58,13 @@ func (self *SContainerDriver) GetProvider() string {
return api.CLOUD_PROVIDER_ONECLOUD
}
func (self *SContainerDriver) GetInstanceCapability() cloudprovider.SInstanceCapability {
return cloudprovider.SInstanceCapability{
Hypervisor: self.GetHypervisor(),
Provider: self.GetProvider(),
}
}
// for backward compatibility, deprecated driver
func (self *SContainerDriver) GetComputeQuotaKeys(scope rbacutils.TRbacScope, ownerId mcclient.IIdentityProvider, brand string) models.SComputeResourceKeys {
keys := models.SComputeResourceKeys{}
+17
View File
@@ -39,6 +39,23 @@ func (self *SCtyunGuestDriver) GetProvider() string {
return api.CLOUD_PROVIDER_CTYUN
}
func (self *SCtyunGuestDriver) GetInstanceCapability() cloudprovider.SInstanceCapability {
return cloudprovider.SInstanceCapability{
Hypervisor: self.GetHypervisor(),
Provider: self.GetProvider(),
DefaultAccount: cloudprovider.SDefaultAccount{
Linux: cloudprovider.SOsDefaultAccount{
DefaultAccount: api.VM_DEFAULT_LINUX_LOGIN_USER,
Changeable: false,
},
Windows: cloudprovider.SOsDefaultAccount{
DefaultAccount: api.VM_DEFAULT_WINDOWS_LOGIN_USER,
Changeable: false,
},
},
}
}
func (self *SCtyunGuestDriver) GetComputeQuotaKeys(scope rbacutils.TRbacScope, ownerId mcclient.IIdentityProvider, brand string) models.SComputeResourceKeys {
keys := models.SComputeResourceKeys{}
keys.SBaseProjectQuotaKeys = quotas.OwnerIdProjectQuotaKeys(scope, ownerId)
+17
View File
@@ -66,6 +66,23 @@ func (self *SESXiGuestDriver) GetProvider() string {
return api.CLOUD_PROVIDER_VMWARE
}
func (self *SESXiGuestDriver) GetInstanceCapability() cloudprovider.SInstanceCapability {
return cloudprovider.SInstanceCapability{
Hypervisor: self.GetHypervisor(),
Provider: self.GetProvider(),
DefaultAccount: cloudprovider.SDefaultAccount{
Linux: cloudprovider.SOsDefaultAccount{
DefaultAccount: api.VM_DEFAULT_LINUX_LOGIN_USER,
Changeable: true,
},
Windows: cloudprovider.SOsDefaultAccount{
DefaultAccount: api.VM_DEFAULT_WINDOWS_LOGIN_USER,
Changeable: false,
},
},
}
}
func (self *SESXiGuestDriver) GetComputeQuotaKeys(scope rbacutils.TRbacScope, ownerId mcclient.IIdentityProvider, brand string) models.SComputeResourceKeys {
keys := models.SComputeResourceKeys{}
keys.SBaseProjectQuotaKeys = quotas.OwnerIdProjectQuotaKeys(scope, ownerId)
+15
View File
@@ -65,6 +65,21 @@ func (self *SGoogleGuestDriver) GetProvider() string {
return api.CLOUD_PROVIDER_GOOGLE
}
func (self *SGoogleGuestDriver) GetInstanceCapability() cloudprovider.SInstanceCapability {
return cloudprovider.SInstanceCapability{
Hypervisor: self.GetHypervisor(),
Provider: self.GetProvider(),
DefaultAccount: cloudprovider.SDefaultAccount{
Linux: cloudprovider.SOsDefaultAccount{
DefaultAccount: api.VM_DEFAULT_LINUX_LOGIN_USER,
},
Windows: cloudprovider.SOsDefaultAccount{
DefaultAccount: api.VM_DEFAULT_WINDOWS_LOGIN_USER,
},
},
}
}
func (self *SGoogleGuestDriver) GetDefaultSysDiskBackend() string {
return api.STORAGE_GOOGLE_PD_STANDARD
}
+15
View File
@@ -110,6 +110,21 @@ func (self *SHuaweiGuestDriver) GetGuestInitialStateAfterRebuild() string {
return api.VM_RUNNING
}
func (self *SHuaweiGuestDriver) GetInstanceCapability() cloudprovider.SInstanceCapability {
return cloudprovider.SInstanceCapability{
Hypervisor: self.GetHypervisor(),
Provider: self.GetProvider(),
DefaultAccount: cloudprovider.SDefaultAccount{
Linux: cloudprovider.SOsDefaultAccount{
DefaultAccount: api.VM_DEFAULT_LINUX_LOGIN_USER,
},
Windows: cloudprovider.SOsDefaultAccount{
DefaultAccount: api.VM_DEFAULT_WINDOWS_LOGIN_USER,
},
},
}
}
func (self *SHuaweiGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string {
userName := "root"
if desc.OsType == "Windows" {
+19 -2
View File
@@ -32,6 +32,7 @@ import (
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/compute/options"
"yunion.io/x/onecloud/pkg/httperrors"
@@ -68,6 +69,22 @@ func (self *SKVMGuestDriver) GetComputeQuotaKeys(scope rbacutils.TRbacScope, own
return keys
}
func (self *SKVMGuestDriver) GetInstanceCapability() cloudprovider.SInstanceCapability {
return cloudprovider.SInstanceCapability{
Hypervisor: self.GetHypervisor(),
Provider: self.GetProvider(),
DefaultAccount: cloudprovider.SDefaultAccount{
Linux: cloudprovider.SOsDefaultAccount{
DefaultAccount: api.VM_DEFAULT_LINUX_LOGIN_USER,
Changeable: true,
},
Windows: cloudprovider.SOsDefaultAccount{
DefaultAccount: api.VM_DEFAULT_WINDOWS_LOGIN_USER,
},
},
}
}
func (self *SKVMGuestDriver) GetDefaultSysDiskBackend() string {
return api.STORAGE_LOCAL
}
@@ -298,13 +315,13 @@ func (self *SKVMGuestDriver) RequestSyncstatusOnHost(ctx context.Context, guest
}
func (self *SKVMGuestDriver) OnDeleteGuestFinalCleanup(ctx context.Context, guest *models.SGuest, userCred mcclient.TokenCredential) error {
if ispId := guest.GetMetadata("__base_instance_snapshot_id", userCred); len(ispId) > 0 {
if ispId := guest.GetMetadata(api.BASE_INSTANCE_SNAPSHOT_ID, userCred); len(ispId) > 0 {
ispM, err := models.InstanceSnapshotManager.FetchById(ispId)
if err == nil {
isp := ispM.(*models.SInstanceSnapshot)
isp.DecRefCount(ctx, userCred)
}
guest.SetMetadata(ctx, "__base_instance_snapshot_id", "", userCred)
guest.SetMetadata(ctx, api.BASE_INSTANCE_SNAPSHOT_ID, "", userCred)
}
return nil
}
+11 -14
View File
@@ -651,8 +651,7 @@ func (self *SManagedVirtualizedGuestDriver) RequestUndeployGuestOnHost(ctx conte
if errors.Cause(err) == cloudprovider.ErrNotFound {
return nil, nil
}
log.Errorf("host.GetIHost fail %s", err)
return nil, err
return nil, errors.Wrapf(err, "host.GetIHost")
}
// 创建失败时external id为空。此时直接返回即可。不需要再调用公有云api
@@ -665,14 +664,11 @@ func (self *SManagedVirtualizedGuestDriver) RequestUndeployGuestOnHost(ctx conte
if errors.Cause(err) == cloudprovider.ErrNotFound {
return nil, nil
}
log.Errorf("ihost.GetIVMById fail %s", err)
return nil, err
return nil, errors.Wrapf(err, "ihost.GetIVMById(%s)", guest.ExternalId)
}
err = ivm.DeleteVM(ctx)
if err != nil {
log.Errorf("ivm.DeleteVM fail %s", err)
return nil, err
return nil, errors.Wrapf(err, "ivm.DeleteVM")
}
for _, guestdisk := range guest.GetDisks() {
@@ -684,16 +680,14 @@ func (self *SManagedVirtualizedGuestDriver) RequestUndeployGuestOnHost(ctx conte
if errors.Cause(err) == cloudprovider.ErrNotFound {
continue
}
log.Errorf("disk.GetIDisk fail %s", err)
return nil, err
return nil, errors.Wrapf(err, "disk.GetIDisk")
}
if idisk.GetStatus() == api.DISK_DEALLOC {
continue
}
err = idisk.Delete(ctx)
if err != nil {
log.Errorf("idisk.Delete fail %s", err)
return nil, err
return nil, errors.Wrapf(err, "idisk.Delete")
}
}
}
@@ -706,13 +700,16 @@ func (self *SManagedVirtualizedGuestDriver) RequestStopOnHost(ctx context.Contex
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
ihost, err := host.GetIHost()
if err != nil {
return nil, err
return nil, errors.Wrapf(err, "host.GetIHost")
}
ivm, err := ihost.GetIVMById(guest.ExternalId)
if err != nil {
return nil, err
return nil, errors.Wrapf(err, "ihost.GetIVMById")
}
err = ivm.StopVM(ctx, true)
opts := &cloudprovider.ServerStopOptions{}
task.GetParams().Unmarshal(&opts)
err = ivm.StopVM(ctx, opts)
return nil, err
})
return nil
+21 -1
View File
@@ -64,6 +64,23 @@ func (self *SOpenStackGuestDriver) GetProvider() string {
return api.CLOUD_PROVIDER_OPENSTACK
}
func (self *SOpenStackGuestDriver) GetInstanceCapability() cloudprovider.SInstanceCapability {
return cloudprovider.SInstanceCapability{
Hypervisor: self.GetHypervisor(),
Provider: self.GetProvider(),
DefaultAccount: cloudprovider.SDefaultAccount{
Linux: cloudprovider.SOsDefaultAccount{
DefaultAccount: api.VM_DEFAULT_LINUX_LOGIN_USER,
Changeable: false,
},
Windows: cloudprovider.SOsDefaultAccount{
DefaultAccount: api.VM_DEFAULT_WINDOWS_LOGIN_USER,
Changeable: false,
},
},
}
}
func (self *SOpenStackGuestDriver) GetComputeQuotaKeys(scope rbacutils.TRbacScope, ownerId mcclient.IIdentityProvider, brand string) models.SComputeResourceKeys {
keys := models.SComputeResourceKeys{}
keys.SBaseProjectQuotaKeys = quotas.OwnerIdProjectQuotaKeys(scope, ownerId)
@@ -268,7 +285,10 @@ func (self *SOpenStackGuestDriver) RemoteDeployGuestForRebuildRoot(ctx context.C
log.Debugf("VMrebuildRoot %s new instance, wait status %s ...", iVM.GetGlobalId(), initialState)
cloudprovider.WaitStatus(iVM, initialState, time.Second*5, time.Second*1800)
iVM.StopVM(ctx, true)
opts := &cloudprovider.ServerStopOptions{
IsForce: true,
}
iVM.StopVM(ctx, opts)
iDisks, err = iVM.GetIDisks()
if err != nil {
+24
View File
@@ -243,6 +243,30 @@ func (self *SQcloudGuestDriver) GetUserDataType() string {
return cloudprovider.CLOUD_SHELL
}
func (self *SQcloudGuestDriver) GetInstanceCapability() cloudprovider.SInstanceCapability {
return cloudprovider.SInstanceCapability{
Hypervisor: self.GetHypervisor(),
Provider: self.GetProvider(),
DefaultAccount: cloudprovider.SDefaultAccount{
Linux: cloudprovider.SOsDefaultAccount{
DefaultAccount: api.VM_DEFAULT_LINUX_LOGIN_USER,
Changeable: false,
DistAccounts: []cloudprovider.SDistDefaultAccount{
{
OsDistribution: "Ubuntu",
DefaultAccount: "ubuntu",
Changeable: false,
},
},
},
Windows: cloudprovider.SOsDefaultAccount{
DefaultAccount: api.VM_DEFAULT_WINDOWS_LOGIN_USER,
Changeable: false,
},
},
}
}
func (self *SQcloudGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string {
userName := "root"
if desc.ImageType == "system" {
+15
View File
@@ -96,6 +96,21 @@ func (self *SUCloudGuestDriver) ValidateResizeDisk(guest *models.SGuest, disk *m
return nil
}
func (self *SUCloudGuestDriver) GetInstanceCapability() cloudprovider.SInstanceCapability {
return cloudprovider.SInstanceCapability{
Hypervisor: self.GetHypervisor(),
Provider: self.GetProvider(),
DefaultAccount: cloudprovider.SDefaultAccount{
Linux: cloudprovider.SOsDefaultAccount{
DefaultAccount: api.VM_DEFAULT_LINUX_LOGIN_USER,
},
Windows: cloudprovider.SOsDefaultAccount{
DefaultAccount: api.VM_DEFAULT_WINDOWS_LOGIN_USER,
},
},
}
}
func (self *SUCloudGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string {
if desc.OsType == "Windows" {
return "Administrator"
+1 -1
View File
@@ -226,7 +226,7 @@ func (self *SVirtualizedGuestDriver) RequestStopGuestForDelete(ctx context.Conte
host = guest.GetHost()
}
if host != nil && host.GetEnabled() && host.HostStatus == api.HOST_ONLINE {
return guest.StartGuestStopTask(ctx, task.GetUserCred(), true, task.GetTaskId())
return guest.StartGuestStopTask(ctx, task.GetUserCred(), true, false, task.GetTaskId())
}
if host != nil && !jsonutils.QueryBoolean(task.GetParams(), "purge", false) {
return fmt.Errorf("fail to contact host")
+15
View File
@@ -158,6 +158,21 @@ func (self *SZStackGuestDriver) IsWindowsUserDataTypeNeedEncode() bool {
return true
}
func (self *SZStackGuestDriver) GetInstanceCapability() cloudprovider.SInstanceCapability {
return cloudprovider.SInstanceCapability{
Hypervisor: self.GetHypervisor(),
Provider: self.GetProvider(),
DefaultAccount: cloudprovider.SDefaultAccount{
Linux: cloudprovider.SOsDefaultAccount{
DefaultAccount: api.VM_DEFAULT_LINUX_LOGIN_USER,
},
Windows: cloudprovider.SOsDefaultAccount{
DefaultAccount: api.VM_DEFAULT_WINDOWS_LOGIN_USER,
},
},
}
}
func (self *SZStackGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string {
userName := "root"
if desc.OsType == "Windows" {
+37
View File
@@ -0,0 +1,37 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package hostdrivers
import (
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/compute/models"
)
type SApsaraHostDriver struct {
SAliyunHostDriver
}
func init() {
driver := SApsaraHostDriver{}
models.RegisterHostDriver(&driver)
}
func (self *SApsaraHostDriver) GetHostType() string {
return api.HOST_TYPE_APSARA
}
func (self *SApsaraHostDriver) GetHypervisor() string {
return api.HYPERVISOR_APSARA
}
+1 -1
View File
@@ -49,7 +49,7 @@ func (self *SAwsHostDriver) ValidateDiskSize(storage *models.SStorage, sizeGb in
if sizeGb < 1 || sizeGb > 16384 {
return fmt.Errorf("The %s disk size must be in the range of 1G ~ 16384GB", storage.StorageType)
}
} else if storage.StorageType == api.STORAGE_IO1_SSD {
} else if storage.StorageType == api.STORAGE_IO1_SSD || storage.StorageType == api.STORAGE_IO2_SSD {
if sizeGb < 4 || sizeGb > 16384 {
return fmt.Errorf("The %s disk size must be in the range of 4G ~ 16384GB", storage.StorageType)
}
+14 -11
View File
@@ -1367,13 +1367,14 @@ func (bucket *SBucket) PerformSetCors(
return nil, errors.Wrap(err, "GetIBucket")
}
rules := []cloudprovider.SBucketCORSRule{}
for i := range input.Rules {
for i := range input.Data {
rules = append(rules, cloudprovider.SBucketCORSRule{
AllowedOrigins: input.Rules[i].AllowedOrigins,
AllowedMethods: input.Rules[i].AllowedMethods,
AllowedHeaders: input.Rules[i].AllowedHeaders,
MaxAgeSeconds: input.Rules[i].MaxAgeSeconds,
ExposeHeaders: input.Rules[i].ExposeHeaders,
AllowedOrigins: input.Data[i].AllowedOrigins,
AllowedMethods: input.Data[i].AllowedMethods,
AllowedHeaders: input.Data[i].AllowedHeaders,
MaxAgeSeconds: input.Data[i].MaxAgeSeconds,
ExposeHeaders: input.Data[i].ExposeHeaders,
Id: input.Data[i].Id,
})
}
err = iBucket.SetCORS(rules)
@@ -1388,7 +1389,7 @@ func (bucket *SBucket) PerformSetCors(
func (bucket *SBucket) AllowPerformDeleteCors(
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
input jsonutils.JSONObject,
input api.BucketCORSRuleDeleteInput,
) bool {
return bucket.IsOwner(userCred)
}
@@ -1397,13 +1398,13 @@ func (bucket *SBucket) PerformDeleteCors(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
input jsonutils.JSONObject,
input api.BucketCORSRuleDeleteInput,
) (jsonutils.JSONObject, error) {
iBucket, err := bucket.GetIBucket()
if err != nil {
return nil, errors.Wrap(err, "GetIBucket")
}
err = iBucket.DeleteCORS()
err = iBucket.DeleteCORS(input.Id)
if err != nil {
return nil, httperrors.NewInternalServerError("iBucket.DeleteCORS error %s", err)
}
@@ -1436,12 +1437,13 @@ func (bucket *SBucket) GetDetailsCors(
}
for i := range corsRules {
rules.Rules = append(rules.Rules, api.BucketCORSRule{
rules.Data = append(rules.Data, api.BucketCORSRule{
AllowedOrigins: corsRules[i].AllowedOrigins,
AllowedMethods: corsRules[i].AllowedMethods,
AllowedHeaders: corsRules[i].AllowedHeaders,
MaxAgeSeconds: corsRules[i].MaxAgeSeconds,
ExposeHeaders: corsRules[i].ExposeHeaders,
Id: corsRules[i].Id,
})
}
@@ -1471,8 +1473,9 @@ func (bucket *SBucket) GetDetailsCdnDomain(
return domains, httperrors.NewInternalServerError("iBucket.GetCdnDomains error %s", err)
}
for i := range cdnDomains {
domains.Domains = append(domains.Domains, api.CdnDomain{
domains.Data = append(domains.Data, api.CdnDomain{
Domain: cdnDomains[i].Domain,
Status: cdnDomains[i].Status,
Area: cdnDomains[i].Area,
Cname: cdnDomains[i].Cname,
Origin: cdnDomains[i].Origin,
+14
View File
@@ -48,6 +48,9 @@ type SCapabilities struct {
DisabledRdsEngineBrands []string `json:",allowempty"`
CloudIdBrands []string `json:",allowempty"`
DisabledCloudIdBrands []string `json:",allowempty"`
// 支持SAML 2.0
SamlAuthBrands []string `json:",allowempty"`
DisabledSamlAuthBrands []string `json:",allowempty"`
PublicIpBrands []string `json:",allowempty"`
NetworkManageBrands []string `json:",allowempty"`
DisabledNetworkManageBrands []string `json:",allowempty"`
@@ -77,6 +80,8 @@ type SCapabilities struct {
StorageTypes3 map[string]map[string]*SimpleStorageInfo `json:",allowempty"`
DataStorageTypes2 map[string][]string `json:",allowempty"`
DataStorageTypes3 map[string]map[string]*SimpleStorageInfo `json:",allowempty"`
InstanceCapabilities []cloudprovider.SInstanceCapability
}
func GetCapabilities(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, region *SCloudregion, zone *SZone) (SCapabilities, error) {
@@ -109,6 +114,13 @@ func GetCapabilities(ctx context.Context, userCred mcclient.TokenCredential, que
domainId = ""
}
capa.Hypervisors = getHypervisors(region, zone, domainId)
capa.InstanceCapabilities = []cloudprovider.SInstanceCapability{}
for _, hypervisor := range capa.Hypervisors {
driver := GetDriver(hypervisor)
if driver != nil {
capa.InstanceCapabilities = append(capa.InstanceCapabilities, driver.GetInstanceCapability())
}
}
getBrands(region, zone, domainId, &capa)
// capa.Brands, capa.ComputeEngineBrands, capa.NetworkManageBrands, capa.ObjectStorageBrands = a, c, n, o
capa.ResourceTypes = getResourceTypes(region, zone, domainId)
@@ -273,6 +285,7 @@ func getBrands(region *SCloudregion, zone *SZone, domainId string, capa *SCapabi
capa.CloudIdBrands, _ = CloudaccountManager.getBrandsOfCapability(region, zone, domainId, tristate.True, cloudprovider.CLOUD_CAPABILITY_CLOUDID)
capa.PublicIpBrands, _ = CloudaccountManager.getBrandsOfCapability(region, zone, domainId, tristate.True, cloudprovider.CLOUD_CAPABILITY_PUBLIC_IP)
capa.LoadbalancerEngineBrands, _ = CloudaccountManager.getBrandsOfCapability(region, zone, domainId, tristate.True, cloudprovider.CLOUD_CAPABILITY_LOADBALANCER)
capa.SamlAuthBrands, _ = CloudaccountManager.getBrandsOfCapability(region, zone, domainId, tristate.True, cloudprovider.CLOUD_CAPABILITY_SAML_AUTH)
if utils.IsInStringArray(api.HYPERVISOR_KVM, capa.Hypervisors) || utils.IsInStringArray(api.HYPERVISOR_BAREMETAL, capa.Hypervisors) {
capa.Brands = append(capa.Brands, api.ONECLOUD_BRAND_ONECLOUD)
@@ -291,6 +304,7 @@ func getBrands(region *SCloudregion, zone *SZone, domainId string, capa *SCapabi
capa.DisabledNetworkManageBrands, _ = CloudaccountManager.getBrandsOfCapability(region, zone, domainId, tristate.False, cloudprovider.CLOUD_CAPABILITY_NETWORK)
capa.DisabledObjectStorageBrands, _ = CloudaccountManager.getBrandsOfCapability(region, zone, domainId, tristate.False, cloudprovider.CLOUD_CAPABILITY_OBJECTSTORE)
capa.DisabledCloudIdBrands, _ = CloudaccountManager.getBrandsOfCapability(region, zone, domainId, tristate.False, cloudprovider.CLOUD_CAPABILITY_CLOUDID)
capa.DisabledSamlAuthBrands, _ = CloudaccountManager.getBrandsOfCapability(region, zone, domainId, tristate.False, cloudprovider.CLOUD_CAPABILITY_SAML_AUTH)
return
}
+17
View File
@@ -991,6 +991,15 @@ func (manager *SCloudaccountManager) validateCreateData(
input.AutoCreateProject = &createProject
}
endpoints := cloudprovider.SApsaraEndpoints{}
if input.SCloudaccountCredential.SApsaraEndpoints != nil {
if input.Options == nil {
input.Options = jsonutils.NewDict()
}
endpoints = *input.SCloudaccountCredential.SApsaraEndpoints
input.Options.Update(jsonutils.Marshal(input.SCloudaccountCredential.SApsaraEndpoints))
}
input.SCloudaccount, err = providerDriver.ValidateCreateCloudaccountData(ctx, userCred, input.SCloudaccountCredential)
if err != nil {
return input, err
@@ -1044,6 +1053,8 @@ func (manager *SCloudaccountManager) validateCreateData(
Account: input.Account,
Secret: input.Secret,
ProxyFunc: proxyFunc,
SApsaraEndpoints: endpoints,
})
if err != nil {
if err == cloudprovider.ErrNoSuchProvder {
@@ -1419,6 +1430,10 @@ func (self *SCloudaccount) getProviderInternal() (cloudprovider.ICloudProvider,
if err != nil {
return nil, fmt.Errorf("Invalid password %s", err)
}
endpoints := cloudprovider.SApsaraEndpoints{}
if self.Provider == api.CLOUD_PROVIDER_APSARA && self.Options != nil {
self.Options.Unmarshal(&endpoints)
}
return cloudprovider.GetProvider(cloudprovider.ProviderConfig{
Id: self.Id,
Name: self.Name,
@@ -1427,6 +1442,8 @@ func (self *SCloudaccount) getProviderInternal() (cloudprovider.ICloudProvider,
Account: self.Account,
Secret: secret,
SApsaraEndpoints: endpoints,
ProxyFunc: self.proxyFunc(),
})
}
+113
View File
@@ -26,6 +26,7 @@ import (
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/tristate"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/pkg/util/timeutils"
"yunion.io/x/pkg/utils"
"yunion.io/x/sqlchemy"
@@ -811,6 +812,11 @@ func (self *SCloudprovider) GetProvider() (cloudprovider.ICloudProvider, error)
account := self.GetCloudaccount()
endpoints := cloudprovider.SApsaraEndpoints{}
if account.Options != nil {
account.Options.Unmarshal(&endpoints)
}
return cloudprovider.GetProvider(cloudprovider.ProviderConfig{
Id: self.Id,
Name: self.Name,
@@ -819,6 +825,8 @@ func (self *SCloudprovider) GetProvider() (cloudprovider.ICloudProvider, error)
Account: self.Account,
Secret: passwd,
ProxyFunc: account.proxyFunc(),
SApsaraEndpoints: endpoints,
})
}
@@ -1698,3 +1706,108 @@ func (self *SCloudprovider) PerformSetSchedtag(ctx context.Context, userCred mcc
func (self *SCloudprovider) GetSchedtagJointManager() ISchedtagJointManager {
return CloudproviderschedtagManager
}
func (self *SCloudprovider) GetInterVpcNetworks() ([]SInterVpcNetwork, error) {
networks := []SInterVpcNetwork{}
q := InterVpcNetworkManager.Query().Equals("manager_id", self.Id)
err := db.FetchModelObjects(InterVpcNetworkManager, q, &networks)
if err != nil {
return nil, errors.Wrapf(err, "db.FetchModelObjects")
}
return networks, nil
}
func (self *SCloudprovider) SyncInterVpcNetwork(ctx context.Context, userCred mcclient.TokenCredential, interVpcNetworks []cloudprovider.ICloudInterVpcNetwork) ([]SInterVpcNetwork, []cloudprovider.ICloudInterVpcNetwork, compare.SyncResult) {
lockman.LockRawObject(ctx, self.Keyword(), fmt.Sprintf("%s-interVpcNetwork", self.Id))
defer lockman.ReleaseRawObject(ctx, self.Keyword(), fmt.Sprintf("%s-interVpcNetwork", self.Id))
result := compare.SyncResult{}
localNetworks := []SInterVpcNetwork{}
remoteNetworks := []cloudprovider.ICloudInterVpcNetwork{}
dbNetworks, err := self.GetInterVpcNetworks()
if err != nil {
result.Error(errors.Wrapf(err, "GetInterVpcNetworks"))
return nil, nil, result
}
removed := make([]SInterVpcNetwork, 0)
commondb := make([]SInterVpcNetwork, 0)
commonext := make([]cloudprovider.ICloudInterVpcNetwork, 0)
added := make([]cloudprovider.ICloudInterVpcNetwork, 0)
err = compare.CompareSets(dbNetworks, interVpcNetworks, &removed, &commondb, &commonext, &added)
if err != nil {
result.Error(err)
return nil, nil, result
}
for i := 0; i < len(removed); i += 1 {
err = removed[i].syncRemove(ctx, userCred)
if err != nil {
result.DeleteError(err)
continue
}
result.Delete()
}
for i := 0; i < len(commondb); i += 1 {
err = commondb[i].SyncWithCloudInterVpcNetwork(ctx, userCred, commonext[i])
if err != nil {
result.UpdateError(errors.Wrapf(err, "SyncWithCloudInterVpcNetwork"))
continue
}
localNetworks = append(localNetworks, commondb[i])
remoteNetworks = append(remoteNetworks, commonext[i])
result.Update()
}
for i := 0; i < len(added); i += 1 {
network, err := InterVpcNetworkManager.newFromCloudInterVpcNetwork(ctx, userCred, added[i], self)
if err != nil {
result.AddError(err)
continue
}
localNetworks = append(localNetworks, *network)
remoteNetworks = append(remoteNetworks, added[i])
result.Add()
}
return localNetworks, remoteNetworks, result
}
func (self *SCloudprovider) SyncCallSyncCloudproviderInterVpcNetwork(ctx context.Context, userCred mcclient.TokenCredential) {
driver, err := self.GetProvider()
if err != nil {
log.Errorf("failed to get ICloudProvider from SCloudprovider:%s %s", self.GetName(), self.Id)
return
}
if cloudprovider.IsSupportInterVpcNetwork(driver) {
networks, err := driver.GetICloudInterVpcNetworks()
if err != nil {
log.Errorf("failed to get inter vpc network for Manager %s error: %v", self.Id, err)
return
} else {
localNetwork, remoteNetwork, result := self.SyncInterVpcNetwork(ctx, userCred, networks)
if result.IsError() {
return
}
for i := range localNetwork {
lockman.LockObject(ctx, &localNetwork[i])
defer lockman.ReleaseObject(ctx, &localNetwork[i])
if localNetwork[i].Deleted {
return
}
localNetwork[i].SyncInterVpcNetworkRouteSets(ctx, userCred, remoteNetwork[i])
}
log.Infof("Sync inter vpc network for cloudaccount %s result: %s", self.GetName(), result.Result())
return
}
}
}
+24
View File
@@ -866,6 +866,10 @@ func syncDBInstanceResource(ctx context.Context, userCred mcclient.TokenCredenti
if err != nil {
log.Errorf("syncDBInstanceAccounts: %v", err)
}
err = syncDBInstanceBackups(ctx, userCred, syncResults, localInstance, remoteInstance)
if err != nil {
log.Errorf("syncDBInstanceBackups: %v", err)
}
}
func syncDBInstanceNetwork(ctx context.Context, userCred mcclient.TokenCredential, syncResults SSyncResultSet, localInstance *SDBInstance, remoteInstance cloudprovider.ICloudDBInstance) error {
@@ -901,6 +905,26 @@ func syncDBInstanceSecgroups(ctx context.Context, userCred mcclient.TokenCredent
return nil
}
func syncDBInstanceBackups(ctx context.Context, userCred mcclient.TokenCredential, syncResults SSyncResultSet, localInstance *SDBInstance, remoteInstance cloudprovider.ICloudDBInstance) error {
backups, err := remoteInstance.GetIDBInstanceBackups()
if err != nil {
return errors.Wrapf(err, "GetIDBInstanceBackups")
}
region := localInstance.GetRegion()
provider := localInstance.GetCloudprovider()
result := DBInstanceBackupManager.SyncDBInstanceBackups(ctx, userCred, provider, localInstance, region, backups)
syncResults.Add(DBInstanceBackupManager, result)
msg := result.Result()
log.Infof("SyncDBInstanceBackups for dbinstance %s result: %s", localInstance.Name, msg)
if result.IsError() {
return result.AllError()
}
return nil
}
func syncDBInstanceParameters(ctx context.Context, userCred mcclient.TokenCredential, syncResults SSyncResultSet, localInstance *SDBInstance, remoteInstance cloudprovider.ICloudDBInstance) error {
parameters, err := remoteInstance.GetIDBInstanceParameters()
if err != nil {
+88 -4
View File
@@ -85,9 +85,8 @@ type SDBInstanceBackup struct {
// example: 32
BackupSizeMb int `nullable:"false" list:"user" json:"backup_size_mb"`
// RDS实例Id
// example: 239b9663-6d06-4ef4-8cfc-320a7fb6660d
// DBInstanceId string `width:"36" charset:"ascii" name:"dbinstance_id" nullable:"false" list:"user" create:"required" index:"true"`
// 备份方式 Logical|Physical
BackupMethod string `width:"32" charset:"ascii" nullable:"true" list:"user" create:"optional" json:"backup_method"`
}
func (manager *SDBInstanceBackupManager) GetContextManagers() [][]db.IModelManager {
@@ -381,6 +380,22 @@ func (backup *SDBInstanceBackup) GetIDBInstanceBackup() (cloudprovider.ICloudDBI
if err != nil {
return nil, errors.Wrapf(err, "GetIDBInstance")
}
err = cloudprovider.Wait(time.Second*3, time.Second*15, func() (bool, error) {
backups, err := iRds.GetIDBInstanceBackups()
if err != nil {
return false, errors.Wrapf(err, "GetIDBInstanceBackups")
}
for i := range backups {
if backups[i].GetGlobalId() == backup.ExternalId {
return true, nil
}
}
log.Warningf("failed to found backup %s", backup.ExternalId)
return false, nil
})
if err != nil {
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "timeout for search backup %s", backup.ExternalId)
}
backups, err := iRds.GetIDBInstanceBackups()
if err != nil {
return nil, errors.Wrapf(err, "GetIDBInstanceBackups")
@@ -390,7 +405,7 @@ func (backup *SDBInstanceBackup) GetIDBInstanceBackup() (cloudprovider.ICloudDBI
return backups[i], nil
}
}
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "externalId: %s", backup.ExternalId)
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "search backup %s", backup.ExternalId)
}
iRegion, err := backup.GetIRegion()
@@ -464,6 +479,7 @@ func (self *SDBInstanceBackup) SyncWithCloudDBInstanceBackup(
self.Engine = extBackup.GetEngine()
self.EngineVersion = extBackup.GetEngineVersion()
self.DBNames = extBackup.GetDBNames()
self.BackupMethod = string(extBackup.GetBackupMethod())
if dbinstanceId := extBackup.GetDBInstanceId(); len(dbinstanceId) > 0 {
//有可能云上删除了实例,未删除备份
@@ -522,6 +538,7 @@ func (manager *SDBInstanceBackupManager) newFromCloudDBInstanceBackup(
backup.BackupSizeMb = extBackup.GetBackupSizeMb()
backup.DBNames = extBackup.GetDBNames()
backup.BackupMode = extBackup.GetBackupMode()
backup.BackupMethod = string(extBackup.GetBackupMethod())
backup.ExternalId = extBackup.GetGlobalId()
if dbinstanceId := extBackup.GetDBInstanceId(); len(dbinstanceId) > 0 {
@@ -616,3 +633,70 @@ func (manager *SDBInstanceBackupManager) ListItemExportKeys(ctx context.Context,
func (self *SDBInstanceBackup) GetChangeOwnerCandidateDomainIds() []string {
return self.SManagedResourceBase.GetChangeOwnerCandidateDomainIds()
}
func (self *SDBInstanceBackup) fillRdsConfig(output *api.DBInstanceCreateInput) error {
if self.Status != api.DBINSTANCE_BACKUP_READY {
return fmt.Errorf("backup %s status is %s require %s", self.Name, self.Status, api.DBINSTANCE_BACKUP_READY)
}
if len(self.DBInstanceId) == 0 {
if len(self.Engine) == 0 {
return fmt.Errorf("backup engine %s is unknown", self.Name)
}
output.Engine = self.Engine
if len(self.EngineVersion) == 0 {
return fmt.Errorf("backup engine version %s is unknown", self.Name)
}
output.EngineVersion = self.EngineVersion
return nil
}
rds, err := self.GetDBInstance()
if err != nil {
return errors.Wrapf(err, "backup.GetDBInstance")
}
if len(output.NetworkId) == 0 {
networks, err := rds.GetDBNetworks()
if err != nil {
return errors.Wrapf(err, "GetDBNetworks")
}
if len(networks) > 0 {
output.NetworkId = networks[0].NetworkId
}
}
if output.VcpuCount == 0 {
output.VcpuCount = rds.VcpuCount
}
if output.VmemSizeMb == 0 {
output.VmemSizeMb = rds.VmemSizeMb
}
if output.DiskSizeGB == 0 {
output.DiskSizeGB = rds.DiskSizeGB
}
if output.Port == 0 {
output.Port = rds.Port
}
if len(output.Category) == 0 {
output.Category = rds.Category
}
if len(output.StorageType) == 0 {
output.StorageType = rds.StorageType
}
output.Engine = rds.Engine
output.EngineVersion = rds.EngineVersion
if len(output.InstanceType) == 0 {
output.InstanceType = rds.InstanceType
}
if len(output.VpcId) == 0 {
output.VpcId = rds.VpcId
}
if len(output.Zone1) == 0 {
output.Zone1 = rds.Zone1
}
if len(output.Zone2) == 0 {
output.Zone2 = rds.Zone2
}
if len(output.Zone3) == 0 {
output.Zone3 = rds.Zone3
}
return nil
}
+39 -18
View File
@@ -132,6 +132,9 @@ type SDBInstance struct {
Zone2 string `width:"36" charset:"ascii" nullable:"false" create:"optional" list:"user"`
// 可用区3
Zone3 string `width:"36" charset:"ascii" nullable:"false" create:"optional" list:"user"`
// 从备份创建新实例
DBInstancebackupId string `width:"36" name:"dbinstancebackup_id" charset:"ascii" nullable:"false" create:"optional"`
}
func (manager *SDBInstanceManager) GetContextManagers() [][]db.IModelManager {
@@ -284,6 +287,17 @@ func (manager *SDBInstanceManager) BatchCreateValidateCreateData(ctx context.Con
}
func (man *SDBInstanceManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input api.DBInstanceCreateInput) (api.DBInstanceCreateInput, error) {
if len(input.DBInstancebackupId) > 0 {
_backup, err := validators.ValidateModel(userCred, DBInstanceBackupManager, &input.DBInstancebackupId)
if err != nil {
return input, err
}
backup := _backup.(*SDBInstanceBackup)
err = backup.fillRdsConfig(&input)
if err != nil {
return input, err
}
}
for _, v := range map[string]*string{"zone1": &input.Zone1, "zone2": &input.Zone2, "zone3": &input.Zone3} {
if len(*v) > 0 {
_, err := validators.ValidateModel(userCred, ZoneManager, v)
@@ -298,28 +312,35 @@ func (man *SDBInstanceManager) ValidateCreateData(ctx context.Context, userCred
return input, httperrors.NewWeakPasswordError()
}
}
if len(input.NetworkId) == 0 {
return input, httperrors.NewMissingParameterError("network_id")
}
_network, err := validators.ValidateModel(userCred, NetworkManager, &input.NetworkId)
if err != nil {
return input, err
}
network := _network.(*SNetwork)
if len(input.Address) > 0 {
ip := net.ParseIP(input.Address).To4()
if ip == nil {
return input, httperrors.NewInputParameterError("invalid address: %s", input.Address)
var vpc *SVpc
var network *SNetwork
if len(input.NetworkId) > 0 {
_network, err := validators.ValidateModel(userCred, NetworkManager, &input.NetworkId)
if err != nil {
return input, err
}
addr, _ := netutils.NewIPV4Addr(input.Address)
if !network.IsAddressInRange(addr) {
return input, httperrors.NewInputParameterError("Ip %s not in network %s(%s) range", input.Address, network.Name, network.Id)
network = _network.(*SNetwork)
if len(input.Address) > 0 {
ip := net.ParseIP(input.Address).To4()
if ip == nil {
return input, httperrors.NewInputParameterError("invalid address: %s", input.Address)
}
addr, _ := netutils.NewIPV4Addr(input.Address)
if !network.IsAddressInRange(addr) {
return input, httperrors.NewInputParameterError("Ip %s not in network %s(%s) range", input.Address, network.Name, network.Id)
}
}
vpc = network.GetVpc()
} else if len(input.VpcId) > 0 {
_vpc, err := validators.ValidateModel(userCred, VpcManager, &input.VpcId)
if err != nil {
return input, err
}
vpc = _vpc.(*SVpc)
} else {
return input, httperrors.NewMissingParameterError("vpc_id")
}
vpc := network.GetVpc()
input.VpcId = vpc.Id
input.ManagerId = vpc.ManagerId
cloudprovider := vpc.GetCloudprovider()
+50 -1
View File
@@ -218,6 +218,7 @@ func (manager *SElasticcacheManager) FetchCustomizeColumns(
netIds := make([]string, len(objs))
cacheIds := make([]string, len(objs))
zoneIds := []string{}
for i := range rows {
rows[i] = api.ElasticcacheDetails{
VirtualResourceDetails: virtRows[i],
@@ -226,6 +227,13 @@ func (manager *SElasticcacheManager) FetchCustomizeColumns(
}
netIds[i] = objs[i].(*SElasticcache).NetworkId
cacheIds[i] = objs[i].(*SElasticcache).Id
sz := strings.Split(objs[i].(*SElasticcache).SlaveZones, ",")
for j := range sz {
if !utils.IsInStringArray(sz[j], zoneIds) {
zoneIds = append(zoneIds, sz[j])
}
}
}
networks := make(map[string]SNetwork)
@@ -254,9 +262,50 @@ func (manager *SElasticcacheManager) FetchCustomizeColumns(
}
}
// zone ids
if len(zoneIds) > 0 {
zss := fetchElasticcacheSlaveZones(zoneIds)
for i := range objs {
if len(objs[i].(*SElasticcache).SlaveZones) > 0 {
sz := strings.Split(objs[i].(*SElasticcache).SlaveZones, ",")
szi := []apis.StandaloneShortDesc{}
for j := range sz {
if info, ok := zss[sz[j]]; ok {
szi = append(szi, info)
} else {
szi = append(szi, apis.StandaloneShortDesc{Id: sz[j], Name: sz[j]})
}
}
rows[i].SlaveZoneInfos = szi
}
}
}
return rows
}
func fetchElasticcacheSlaveZones(zoneIds []string) map[string]apis.StandaloneShortDesc {
zones := []SZone{}
err := ZoneManager.Query().In("id", zoneIds).All(&zones)
if err != nil {
log.Debugf("fetchElasticcacheSlaveZones.ZoneManager %s", err)
return nil
}
ret := make(map[string]apis.StandaloneShortDesc)
for i := range zones {
zsd := apis.StandaloneShortDesc{
Id: zones[i].Id,
Name: zones[i].Name,
}
ret[zsd.Id] = zsd
}
return ret
}
func (self *SElasticcache) GetElasticcacheParameters() ([]SElasticcacheParameter, error) {
ret := []SElasticcacheParameter{}
q := ElasticcacheParameterManager.Query().Equals("elasticcache_id", self.Id)
@@ -1295,7 +1344,7 @@ func (self *SElasticcache) GetAdminAccount() (*SElasticcacheAccount, error) {
}
}
return nil, httperrors.NewNotFoundError(fmt.Sprintf("no admin account found for elastic cache %s", self.Id))
return nil, httperrors.NewNotFoundError("no admin account found for elastic cache %s", self.Id)
}
func (self *SElasticcache) StartResetPasswordTask(ctx context.Context, userCred mcclient.TokenCredential, params *jsonutils.JSONDict, parentTaskId string) error {
+32
View File
@@ -135,12 +135,44 @@ func (manager *SElasticcacheSkuManager) FetchCustomizeColumns(
stdRows := manager.SStatusStandaloneResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
regRows := manager.SCloudregionResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
zoneRows := manager.SZoneResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
slavezoneRows := manager.FetchSlaveZoneResourceInfos(ctx, userCred, query, objs)
for i := range rows {
rows[i] = api.ElasticcacheSkuDetails{
StatusStandaloneResourceDetails: stdRows[i],
CloudregionResourceInfo: regRows[i],
ZoneResourceInfoBase: zoneRows[i].ZoneResourceInfoBase,
SlaveZoneResourceInfoBase: slavezoneRows[i],
}
}
return rows
}
func (self *SElasticcacheSkuManager) FetchSlaveZoneResourceInfos(ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{}) []api.SlaveZoneResourceInfoBase {
rows := make([]api.SlaveZoneResourceInfoBase, len(objs))
zoneIds := []string{}
for i := range objs {
slavezone := objs[i].(*SElasticcacheSku).SlaveZoneId
if len(slavezone) > 0 {
zoneIds = append(zoneIds, slavezone)
}
}
zones := make(map[string]SZone)
err := db.FetchStandaloneObjectsByIds(ZoneManager, zoneIds, &zones)
if err != nil {
log.Errorf("FetchStandaloneObjectsByIds fail %s", err)
return rows
}
for i := range objs {
if zone, ok := zones[objs[i].(*SElasticcacheSku).SlaveZoneId]; ok {
rows[i].SlaveZone = zone.GetName()
rows[i].SlaveZoneExtId = fetchExternalId(zone.GetExternalId())
}
}
+1
View File
@@ -509,6 +509,7 @@ func (manager *SElasticipManager) newFromCloudEip(ctx context.Context, userCred
eip.ManagerId = provider.Id
eip.CloudregionId = region.Id
eip.ChargeType = extEip.GetInternetChargeType()
eip.Bandwidth = extEip.GetBandwidth()
if networkId := extEip.GetINetworkId(); len(networkId) > 0 {
network, err := db.FetchByExternalIdAndManagerId(NetworkManager, networkId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
wire := WireManager.Query().SubQuery()
+30 -45
View File
@@ -670,13 +670,16 @@ func (self *SGuest) ValidateAttachDisk(ctx context.Context, disk *SDisk) error {
}
}
attached, err := disk.isAttached()
if err != nil {
return httperrors.NewInternalServerError("isAttached check failed %s", err)
}
if attached {
return httperrors.NewInputParameterError("Disk %s has been attached", disk.Name)
if disk.IsLocal() {
attached, err := disk.isAttached()
if err != nil {
return httperrors.NewInternalServerError("isAttached check failed %s", err)
}
if attached {
return httperrors.NewInputParameterError("Disk %s has been attached", disk.Name)
}
}
if len(disk.GetPathAtHost(self.GetHost())) == 0 {
return httperrors.NewInputParameterError("Disk %s not belong the guest's host", disk.Name)
}
@@ -902,14 +905,13 @@ func (self *SGuest) NotifyAdminServerEvent(ctx context.Context, event string, pr
notifyclient.SystemNotifyWithCtx(ctx, priority, event, kwargs)
}
func (self *SGuest) StartGuestStopTask(ctx context.Context, userCred mcclient.TokenCredential, isForce bool, parentTaskId string) error {
func (self *SGuest) StartGuestStopTask(ctx context.Context, userCred mcclient.TokenCredential, isForce, stopCharging bool, parentTaskId string) error {
if len(parentTaskId) == 0 {
self.SetStatus(userCred, api.VM_START_STOP, "")
}
params := jsonutils.NewDict()
if isForce {
params.Add(jsonutils.JSONTrue, "is_force")
}
params.Add(jsonutils.NewBool(isForce), "is_force")
params.Add(jsonutils.NewBool(stopCharging), "stop_charging")
if len(parentTaskId) > 0 {
params.Add(jsonutils.JSONTrue, "subtask")
}
@@ -1018,15 +1020,11 @@ func (self *SGuest) StartInsertIsoTask(ctx context.Context, imageId string, boot
return nil
}
func (self *SGuest) IsDisksShared() bool {
return self.getDefaultStorageType() == api.STORAGE_RBD
}
func (self *SGuest) StartGueststartTask(
ctx context.Context, userCred mcclient.TokenCredential,
data *jsonutils.JSONDict, parentTaskId string,
) error {
if self.Hypervisor == api.HYPERVISOR_KVM && self.IsDisksShared() {
if self.Hypervisor == api.HYPERVISOR_KVM && self.guestDisksStorageTypeIsShared() {
return self.GuestSchedStartTask(ctx, userCred, data, parentTaskId)
} else {
return self.GuestNonSchedStartTask(ctx, userCred, data, parentTaskId)
@@ -2095,6 +2093,12 @@ func (self *SGuest) PerformChangeIpaddr(ctx context.Context, userCred mcclient.T
}
return nil, httperrors.NewBadRequestError("%v", err)
}
if _, err := db.Update(&ngn[0], func() error {
ngn[0].EipId = gn.EipId
return nil
}); err != nil {
return nil, err
}
return ngn, nil
}()
@@ -2756,16 +2760,14 @@ func (self *SGuest) PerformStatus(ctx context.Context, userCred mcclient.TokenCr
status := input.Status
if len(self.BackupHostId) > 0 && status == api.VM_RUNNING {
if len(self.GetMetadata("__mirror_job_status", userCred)) == 0 {
self.SetMetadata(ctx, "__mirror_job_status", "ready", userCred)
}
} else if ispId := self.GetMetadata("__base_instance_snapshot_id", userCred); len(ispId) > 0 {
self.SetMetadata(ctx, api.MIRROR_JOB, api.MIRROR_JOB_READY, userCred)
} else if ispId := self.GetMetadata(api.BASE_INSTANCE_SNAPSHOT_ID, userCred); len(ispId) > 0 {
ispM, err := InstanceSnapshotManager.FetchById(ispId)
if err == nil {
isp := ispM.(*SInstanceSnapshot)
isp.DecRefCount(ctx, userCred)
}
self.SetMetadata(ctx, "__base_instance_snapshot_id", "", userCred)
self.SetMetadata(ctx, api.BASE_INSTANCE_SNAPSHOT_ID, "", userCred)
}
if preStatus != self.Status && !self.isNotRunningStatus(preStatus) && self.isNotRunningStatus(self.Status) {
@@ -2786,14 +2788,12 @@ func (self *SGuest) AllowPerformStop(ctx context.Context,
}
func (self *SGuest) PerformStop(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject,
data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
input api.ServerStopInput) (jsonutils.JSONObject, error) {
// XXX if is force, force stop guest
var isForce = jsonutils.QueryBoolean(data, "is_force", false)
if isForce || utils.IsInStringArray(self.Status, []string{api.VM_RUNNING, api.VM_STOP_FAILED}) {
return nil, self.StartGuestStopTask(ctx, userCred, isForce, "")
} else {
return nil, httperrors.NewInvalidStatusError("Cannot stop server in status %s", self.Status)
if input.IsForce || utils.IsInStringArray(self.Status, []string{api.VM_RUNNING, api.VM_STOP_FAILED}) {
return nil, self.StartGuestStopTask(ctx, userCred, input.IsForce, input.StopCharging, "")
}
return nil, httperrors.NewInvalidStatusError("Cannot stop server in status %s", self.Status)
}
func (self *SGuest) AllowPerformRestart(ctx context.Context,
@@ -3172,13 +3172,12 @@ func (self *SGuest) PerformSwitchToBackup(ctx context.Context, userCred mcclient
return nil, httperrors.NewBadRequestError("Guest no backup host")
}
mirrorJobStatus := self.GetMetadata("__mirror_job_status", userCred)
if mirrorJobStatus != "ready" {
mirrorJobStatus := self.GetMetadata(api.MIRROR_JOB, userCred)
if mirrorJobStatus != api.MIRROR_JOB_READY {
return nil, httperrors.NewBadRequestError("Guest can't switch to backup, mirror job not ready")
}
oldStatus := self.Status
self.SetStatus(userCred, api.VM_SWITCH_TO_BACKUP, "Switch to backup")
deleteBackup := jsonutils.QueryBoolean(data, "delete_backup", false)
purgeBackup := jsonutils.QueryBoolean(data, "purge_backup", false)
@@ -3190,6 +3189,7 @@ func (self *SGuest) PerformSwitchToBackup(ctx context.Context, userCred mcclient
log.Errorln(err)
return nil, err
} else {
self.SetStatus(userCred, api.VM_SWITCH_TO_BACKUP, "Switch to backup")
task.ScheduleRun(nil)
}
return nil, nil
@@ -3292,7 +3292,7 @@ func (self *SGuest) AllowPerformBlockStreamFailed(ctx context.Context, userCred
func (self *SGuest) PerformBlockStreamFailed(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
if len(self.BackupHostId) > 0 {
self.SetMetadata(ctx, "__mirror_job_status", "failed", userCred)
self.SetMetadata(ctx, api.MIRROR_JOB, api.MIRROR_JOB_FAILED, userCred)
}
if self.Status == api.VM_BLOCK_STREAM || self.Status == api.VM_RUNNING {
reason, _ := data.GetString("reason")
@@ -3302,21 +3302,6 @@ func (self *SGuest) PerformBlockStreamFailed(ctx context.Context, userCred mccli
return nil, nil
}
func (self *SGuest) AllowPerformSlaveStarted(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return db.IsAdminAllowPerform(userCred, self, "slave-started")
}
func (self *SGuest) PerformSlaveStarted(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
if self.GetMetadata("__mirror_job_status", userCred) == "failed" {
if port, err := data.Int("nbd_server_port"); err != nil {
return nil, httperrors.NewMissingParameterError("nbd_server_port")
} else {
self.StartMirrorJob(ctx, userCred, port, "")
}
}
return nil, nil
}
func (self *SGuest) StartMirrorJob(ctx context.Context, userCred mcclient.TokenCredential, nbdServerPort int64, parentTaskId string) error {
taskData := jsonutils.NewDict()
taskData.Set("nbd_server_port", jsonutils.NewInt(nbdServerPort))
+1
View File
@@ -96,6 +96,7 @@ type IGuestDriver interface {
GetGuestInitialStateAfterCreate() string
GetGuestInitialStateAfterRebuild() string
GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string
GetInstanceCapability() cloudprovider.SInstanceCapability
OnGuestDeployTaskDataReceived(ctx context.Context, guest *SGuest, task taskman.ITask, data jsonutils.JSONObject) error
+11 -5
View File
@@ -1820,7 +1820,7 @@ func (manager *SGuestManager) SetPropertiesWithInstanceSnapshot(
delete(metadata, "passwd")
metadata["login_key"], _ = utils.EncryptAESBase64(guest.Id, passwd.(string))
}
metadata["__base_instance_snapshot_id"] = isp.Id
metadata[api.BASE_INSTANCE_SNAPSHOT_ID] = isp.Id
guest.SetAllMetadata(ctx, metadata, userCred)
}
}
@@ -3709,11 +3709,17 @@ func (self *SGuest) DeleteAllDisksInDB(ctx context.Context, userCred mcclient.To
}
if disk != nil {
db.OpsLog.LogEvent(disk, db.ACT_DELETE, nil, userCred)
db.OpsLog.LogEvent(disk, db.ACT_DELOCATE, nil, userCred)
err = disk.RealDelete(ctx, userCred)
cnt, err := disk.GetGuestDiskCount()
if err != nil {
return err
return errors.Wrap(err, "disk.GetGuestDiskCount")
}
if cnt == 0 {
db.OpsLog.LogEvent(disk, db.ACT_DELETE, nil, userCred)
db.OpsLog.LogEvent(disk, db.ACT_DELOCATE, nil, userCred)
err = disk.RealDelete(ctx, userCred)
if err != nil {
return errors.Wrap(err, "disk.RealDelete")
}
}
}
}
+1 -1
View File
@@ -107,7 +107,7 @@ func (h *SHostHealthChecker) onHostUnhealthy(ctx context.Context, hostId string)
lockman.LockRawObject(ctx, api.HOST_HEALTH_LOCK_PREFIX, hostId)
defer lockman.ReleaseRawObject(ctx, api.HOST_HEALTH_LOCK_PREFIX, hostId)
host := HostManager.FetchHostById(hostId)
if host.EnableHealthCheck == true {
if host != nil && host.EnableHealthCheck == true {
host.OnHostDown(ctx, auth.AdminCredential())
}
}
+3 -1
View File
@@ -3594,7 +3594,9 @@ func (self *SHost) PerformStop(ctx context.Context, userCred mcclient.TokenCrede
return nil, self.InitializedGuestStop(ctx, userCred, guest)
}
self.SetStatus(userCred, api.BAREMETAL_START_MAINTAIN, "")
return guest.PerformStop(ctx, userCred, query, data)
input := api.ServerStopInput{}
data.Unmarshal(&input)
return guest.PerformStop(ctx, userCred, query, input)
}
}
return nil, self.StartBaremetalUnmaintenanceTask(ctx, userCred, false, "stop")
+568
View File
@@ -0,0 +1,568 @@
// 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 models
import (
"context"
"database/sql"
"fmt"
"gopkg.in/fatih/set.v0"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/tristate"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SInterVpcNetworkManager struct {
db.SEnabledStatusInfrasResourceBaseManager
db.SExternalizedResourceBaseManager
SManagedResourceBaseManager
}
var InterVpcNetworkManager *SInterVpcNetworkManager
func init() {
InterVpcNetworkManager = &SInterVpcNetworkManager{
SEnabledStatusInfrasResourceBaseManager: db.NewEnabledStatusInfrasResourceBaseManager(
SInterVpcNetwork{},
"inter_vpc_networks_tbl",
"inter_vpc_network",
"inter_vpc_networks",
),
}
InterVpcNetworkManager.SetVirtualObject(InterVpcNetworkManager)
}
type SInterVpcNetwork struct {
db.SEnabledStatusInfrasResourceBase
db.SExternalizedResourceBase
SManagedResourceBase
}
func (manager *SInterVpcNetworkManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
q, err := manager.SEnabledStatusInfrasResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
q, err = manager.SManagedResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
return q, httperrors.ErrNotFound
}
func (manager *SInterVpcNetworkManager) OrderByExtraFields(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.InterVpcNetworkManagerListInput,
) (*sqlchemy.SQuery, error) {
q, err := manager.SEnabledStatusInfrasResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.EnabledStatusInfrasResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SInfrasResourceBaseManager.OrderByExtraFields")
}
q, err = manager.SManagedResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.ManagedResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.OrderByExtraFields")
}
return q, nil
}
// 列表
func (manager *SInterVpcNetworkManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.InterVpcNetworkListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SEnabledStatusInfrasResourceBaseManager.ListItemFilter(ctx, q, userCred, query.EnabledStatusInfrasResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SEnabledStatusInfrasResourceBaseManager.ListItemFilter")
}
q, err = manager.SManagedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ManagedResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemFilter")
}
return q, nil
}
func (manager *SInterVpcNetworkManager) ValidateCreateData(
ctx context.Context,
userCred mcclient.TokenCredential,
ownerId mcclient.IIdentityProvider,
query jsonutils.JSONObject,
input api.InterVpcNetworkCreateInput,
) (api.InterVpcNetworkCreateInput, error) {
return input, nil
}
func (self *SInterVpcNetwork) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) {
params := jsonutils.NewDict()
task, err := taskman.TaskManager.NewTask(ctx, "InterVpcNetworkCreateTask", self, userCred, params, "", "", nil)
if err != nil {
return
}
self.SetStatus(userCred, api.INTER_VPC_NETWORK_STATUS_CREATING, "")
task.ScheduleRun(nil)
}
func (self *SInterVpcNetwork) GetExtraDetails(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
isList bool,
) (api.InterVpcNetworkDetails, error) {
return api.InterVpcNetworkDetails{}, nil
}
func (manager *SInterVpcNetworkManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.InterVpcNetworkDetails {
rows := make([]api.InterVpcNetworkDetails, len(objs))
stdRows := manager.SEnabledStatusInfrasResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
vpcNetworkIds := make([]string, len(objs))
for i := range rows {
rows[i] = api.InterVpcNetworkDetails{
EnabledStatusInfrasResourceBaseDetails: stdRows[i],
}
vpcNetwork := objs[i].(*SInterVpcNetwork)
vpcNetworkIds[i] = vpcNetwork.Id
}
vpcNetworkVpcs := []SInterVpcNetworkVpc{}
q := InterVpcNetworkVpcManager.Query().In("inter_vpc_network_id", vpcNetworkIds)
err := db.FetchModelObjects(InterVpcNetworkVpcManager, q, &vpcNetworkVpcs)
if err != nil {
return rows
}
vpcMap := map[string][]string{}
for i := range vpcNetworkVpcs {
if _, ok := vpcMap[vpcNetworkVpcs[i].InterVpcNetworkId]; !ok {
vpcMap[vpcNetworkVpcs[i].InterVpcNetworkId] = []string{}
}
vpcMap[vpcNetworkVpcs[i].InterVpcNetworkId] = append(vpcMap[vpcNetworkVpcs[i].InterVpcNetworkId], vpcNetworkVpcs[i].VpcId)
}
for i := range rows {
rows[i].VpcCount = len(vpcMap[vpcNetworkIds[i]])
}
return rows
}
func (manager *SInterVpcNetworkManager) newFromCloudInterVpcNetwork(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudInterVpcNetwork, provider *SCloudprovider) (*SInterVpcNetwork, error) {
externalVpcIds, err := ext.GetICloudVpcIds()
if err != nil {
return nil, errors.Wrapf(err, "GetICloudVpcIds")
}
vpcIds := []string{}
for i := range externalVpcIds {
vpc, err := db.FetchByExternalIdAndManagerId(VpcManager, externalVpcIds[i], func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
managerQ := CloudproviderManager.Query("id").Equals("provider", provider.Provider)
return q.In("manager_id", managerQ.SubQuery())
})
if err != nil {
if errors.Cause(err) != sql.ErrNoRows {
return nil, errors.Wrapf(err, "vpc.FetchByExternalIdAndManagerId(%s)", externalVpcIds[i])
}
}
vpcIds = append(vpcIds, vpc.GetId())
}
interVpcNetwork := &SInterVpcNetwork{}
interVpcNetwork.SetModelManager(manager, interVpcNetwork)
interVpcNetwork.Name = ext.GetName()
interVpcNetwork.Enabled = tristate.True
interVpcNetwork.Status = ext.GetStatus()
interVpcNetwork.ManagerId = provider.Id
interVpcNetwork.ExternalId = ext.GetGlobalId()
err = manager.TableSpec().Insert(ctx, interVpcNetwork)
if err != nil {
return nil, errors.Wrapf(err, "interVpcNetwork.Insert")
}
for i := range vpcIds {
err := interVpcNetwork.AddVpc(ctx, vpcIds[i])
if err != nil {
return nil, errors.Wrapf(err, "interVpcNetwork.AddVpc(%s)", vpcIds[i])
}
}
SyncCloudDomain(userCred, interVpcNetwork, provider.GetOwnerId())
interVpcNetwork.SyncShareState(ctx, userCred, provider.getAccountShareInfo())
return interVpcNetwork, nil
}
func (self *SInterVpcNetwork) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
task, err := taskman.TaskManager.NewTask(ctx, "InterVpcNetworkDeleteTask", self, userCred, nil, "", "", nil)
if err != nil {
return errors.Wrap(err, "NewTask")
}
self.SetStatus(userCred, api.INTER_VPC_NETWORK_STATUS_DELETING, "")
task.ScheduleRun(nil)
return nil
}
func (self *SInterVpcNetwork) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
err := self.RemoveAllVpc(ctx)
if err != nil {
return errors.Wrapf(err, "RemoveAllVpc")
}
return self.SEnabledStatusInfrasResourceBase.Delete(ctx, userCred)
}
func (self *SInterVpcNetwork) AllowPerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return db.IsAdminAllowPerform(userCred, self, "syncstatus")
}
func (self *SInterVpcNetwork) PerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.InterVpcNetworkSyncstatusInput) (jsonutils.JSONObject, error) {
return nil, StartResourceSyncStatusTask(ctx, userCred, self, "InterVpcNetworkSyncstatusTask", "")
}
func (self *SInterVpcNetwork) syncRemove(ctx context.Context, userCred mcclient.TokenCredential) error {
return self.RealDelete(ctx, userCred)
}
func (self *SInterVpcNetwork) StartInterVpcNetworkAddVpcTask(ctx context.Context, userCred mcclient.TokenCredential, vpc *SVpc) error {
data := jsonutils.NewDict()
data.Set("vpc_id", jsonutils.NewString(vpc.Id))
task, err := taskman.TaskManager.NewTask(ctx, "InterVpcNetworkAddVpcTask", self, userCred, data, "", "", nil)
if err != nil {
return err
}
self.SetStatus(userCred, api.INTER_VPC_NETWORK_STATUS_ADDVPC, "")
task.ScheduleRun(nil)
return nil
}
func (self *SInterVpcNetwork) AllowPerformAddvpc(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return db.IsAdminAllowPerform(userCred, self, "addvpc")
}
func (self *SInterVpcNetwork) PerformAddvpc(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.InterVpcNetworkAddVpcInput) (jsonutils.JSONObject, error) {
if len(input.VpcId) == 0 {
return nil, httperrors.NewMissingParameterError("vpc_id")
}
// get vpc
_vpc, err := VpcManager.FetchByIdOrName(userCred, input.VpcId)
if err != nil {
if errors.Cause(err) == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError2("vpc", input.VpcId)
}
return nil, httperrors.NewGeneralError(err)
}
vpc := _vpc.(*SVpc)
vpcCloudProvider := vpc.GetCloudprovider()
cloudProvider := self.GetCloudprovider()
if err != nil {
return nil, httperrors.NewGeneralError(err)
}
if vpcCloudProvider.Provider != cloudProvider.Provider {
return nil, httperrors.NewNotSupportedError("vpc joint interVpcNetwork on different cloudprovider is not supported")
}
if vpcCloudProvider.AccessUrl != cloudProvider.AccessUrl {
return nil, httperrors.NewNotSupportedError("vpc joint interVpcNetwork on different cloudEnv is not supported")
}
q := InterVpcNetworkVpcManager.Query().Equals("vpc_id", vpc.Id)
vpcNetworkjoints := []SInterVpcNetworkVpc{}
err = db.FetchModelObjects(InterVpcNetworkVpcManager, q, &vpcNetworkjoints)
if err != nil {
return nil, httperrors.NewGeneralError(err)
}
if len(vpcNetworkjoints) > 0 {
return nil, httperrors.NewInputParameterError("vpc %s already connected to a interVpcNetwork", vpc.Id)
}
err = self.StartInterVpcNetworkAddVpcTask(ctx, userCred, vpc)
if err != nil {
return nil, err
}
return nil, nil
}
func (self *SInterVpcNetwork) AllowPerformRemovevpc(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return db.IsAdminAllowPerform(userCred, self, "removevpc")
}
func (self *SInterVpcNetwork) StartInterVpcNetworkRemoveVpcTask(ctx context.Context, userCred mcclient.TokenCredential, vpc *SVpc) error {
data := jsonutils.NewDict()
data.Set("vpc_id", jsonutils.NewString(vpc.Id))
task, err := taskman.TaskManager.NewTask(ctx, "InterVpcNetworkRemoveVpcTask", self, userCred, data, "", "", nil)
if err != nil {
return err
}
self.SetStatus(userCred, api.INTER_VPC_NETWORK_STATUS_REMOVEVPC, "")
task.ScheduleRun(nil)
return nil
}
func (self *SInterVpcNetwork) PerformRemovevpc(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.InterVpcNetworkRemoveVpcInput) (jsonutils.JSONObject, error) {
if len(input.VpcId) == 0 {
return nil, httperrors.NewMissingParameterError("vpc_id")
}
// get vpc
_vpc, err := VpcManager.FetchByIdOrName(userCred, input.VpcId)
if err != nil {
if errors.Cause(err) == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError2("vpc", input.VpcId)
}
return nil, httperrors.NewGeneralError(err)
}
vpc := _vpc.(*SVpc)
q := InterVpcNetworkVpcManager.Query().Equals("inter_vpc_network_id", self.Id).Equals("vpc_id", vpc.Id)
vpcNetworkjoints := []SInterVpcNetworkVpc{}
err = db.FetchModelObjects(InterVpcNetworkVpcManager, q, &vpcNetworkjoints)
if err != nil {
return nil, httperrors.NewGeneralError(err)
}
if len(vpcNetworkjoints) == 0 {
return nil, httperrors.NewInputParameterError("vpc %s is not connected to this interVpcNetwork", vpc.Id)
}
err = self.StartInterVpcNetworkRemoveVpcTask(ctx, userCred, vpc)
if err != nil {
return nil, err
}
return nil, nil
}
func (self *SInterVpcNetwork) AddVpc(ctx context.Context, vpcId string) error {
networkVpc := &SInterVpcNetworkVpc{}
networkVpc.SetModelManager(InterVpcNetworkVpcManager, networkVpc)
networkVpc.VpcId = vpcId
networkVpc.InterVpcNetworkId = self.Id
return InterVpcNetworkVpcManager.TableSpec().Insert(ctx, networkVpc)
}
func (self *SInterVpcNetwork) GetVpcs() ([]SVpc, error) {
sq := InterVpcNetworkVpcManager.Query("vpc_id").Equals("inter_vpc_network_id", self.Id)
q := VpcManager.Query().In("id", sq.SubQuery())
vpcs := []SVpc{}
err := db.FetchModelObjects(VpcManager, q, &vpcs)
if err != nil {
return nil, errors.Wrap(err, "db.FetchModelObjects")
}
return vpcs, nil
}
func (self *SInterVpcNetwork) RemoveVpc(ctx context.Context, vpcId string) error {
q := InterVpcNetworkVpcManager.Query().Equals("inter_vpc_network_id", self.Id).Equals("vpc_id", vpcId)
networkVpcs := []SInterVpcNetworkVpc{}
err := db.FetchModelObjects(InterVpcNetworkVpcManager, q, &networkVpcs)
if err != nil {
return errors.Wrapf(err, "db.FetchModelObjects")
}
for i := range networkVpcs {
err = networkVpcs[i].Delete(ctx, nil)
if err != nil {
return errors.Wrap(err, "Delete")
}
}
return nil
}
func (self *SInterVpcNetwork) RemoveAllVpc(ctx context.Context) error {
q := InterVpcNetworkVpcManager.Query().Equals("inter_vpc_network_id", self.Id)
networkVpcs := []SInterVpcNetworkVpc{}
err := db.FetchModelObjects(InterVpcNetworkVpcManager, q, &networkVpcs)
if err != nil {
return errors.Wrapf(err, "db.FetchModelObjects")
}
for i := range networkVpcs {
err = networkVpcs[i].Delete(ctx, nil)
if err != nil {
return errors.Wrap(err, "Delete")
}
}
return nil
}
func (self *SInterVpcNetwork) SyncWithCloudInterVpcNetwork(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudInterVpcNetwork) error {
_, err := db.Update(self, func() error {
self.ExternalId = ext.GetGlobalId()
self.Status = ext.GetStatus()
self.Name = ext.GetName()
return nil
})
if err != nil {
return errors.Wrapf(err, "db.Update")
}
localVpcs, err := self.GetVpcs()
if err != nil {
return errors.Wrapf(err, "GetVpcs")
}
externalVpcIds, err := ext.GetICloudVpcIds()
if err != nil {
return errors.Wrapf(err, "GetICloudVpcIds")
}
remoteVpcIds := []string{}
manager := self.GetCloudprovider()
for i := range externalVpcIds {
vpc, err := db.FetchByExternalIdAndManagerId(VpcManager, externalVpcIds[i], func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
managerQ := CloudproviderManager.Query("id").Equals("provider", manager.Provider)
return q.In("manager_id", managerQ.SubQuery())
})
if err != nil {
if errors.Cause(err) != sql.ErrNoRows {
return errors.Wrapf(err, "vpc.FetchByExternalIdAndManagerId(%s)", externalVpcIds[i])
}
}
remoteVpcIds = append(remoteVpcIds, vpc.GetId())
}
localVpcIdSet := set.New(set.ThreadSafe)
for i := range localVpcs {
localVpcIdSet.Add(localVpcs[i].Id)
}
remoteVpcIdSet := set.New(set.ThreadSafe)
for i := range remoteVpcIds {
remoteVpcIdSet.Add(remoteVpcIds[i])
}
for _, del := range set.Difference(localVpcIdSet, remoteVpcIdSet).List() {
err := self.RemoveVpc(ctx, del.(string))
if err != nil {
return errors.Wrapf(err, "self.RemoveVpc %s", del.(string))
}
}
for _, add := range set.Difference(remoteVpcIdSet, localVpcIdSet).List() {
err := self.AddVpc(ctx, add.(string))
if err != nil {
return errors.Wrapf(err, "self.RemoveVpc %s", add.(string))
}
}
return nil
}
/*
func (self *SInterVpcNetwork) GetCloudaccount() (*SCloudaccount, error) {
account, err := CloudaccountManager.FetchById(self.CloudaccountId)
if err != nil {
return nil, errors.Wrapf(err, "CloudaccountManager.FetchById(%s)", self.CloudaccountId)
}
return account.(*SCloudaccount), nil
}
*/
func (self *SInterVpcNetwork) GetInterVpcNetworkRouteSets() ([]SInterVpcNetworkRouteSet, error) {
routes := []SInterVpcNetworkRouteSet{}
q := InterVpcNetworkRouteSetManager.Query().Equals("inter_vpc_network_id", self.Id)
err := db.FetchModelObjects(InterVpcNetworkRouteSetManager, q, &routes)
if err != nil {
return nil, errors.Wrapf(err, "db.FetchModelObjects")
}
return routes, nil
}
func (self *SInterVpcNetwork) SyncInterVpcNetworkRouteSets(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudInterVpcNetwork) compare.SyncResult {
lockman.LockRawObject(ctx, self.Keyword(), fmt.Sprintf("%s-records", self.Id))
defer lockman.ReleaseRawObject(ctx, self.Keyword(), fmt.Sprintf("%s-records", self.Id))
syncResult := compare.SyncResult{}
iRoutes, err := ext.GetIRoutes()
if err != nil {
syncResult.Error(errors.Wrapf(err, "GetIRoutes"))
return syncResult
}
dbRouteSets, err := self.GetInterVpcNetworkRouteSets()
if err != nil {
syncResult.Error(errors.Wrapf(err, "GetRouteTableRouteSets"))
return syncResult
}
removed := make([]SInterVpcNetworkRouteSet, 0)
commondb := make([]SInterVpcNetworkRouteSet, 0)
commonext := make([]cloudprovider.ICloudInterVpcNetworkRoute, 0)
added := make([]cloudprovider.ICloudInterVpcNetworkRoute, 0)
if err := compare.CompareSets(dbRouteSets, iRoutes, &removed, &commondb, &commonext, &added); err != nil {
syncResult.Error(err)
return syncResult
}
for i := 0; i < len(removed); i++ {
err := removed[i].syncRemoveRouteSet(ctx, userCred)
if err != nil {
syncResult.DeleteError(err)
} else {
syncResult.Delete()
}
}
for i := 0; i < len(commondb); i++ {
err := commondb[i].syncWithCloudRouteSet(ctx, userCred, self, commonext[i])
if err != nil {
syncResult.UpdateError(err)
continue
}
syncResult.Update()
}
for i := 0; i < len(added); i++ {
_, err := InterVpcNetworkRouteSetManager.newRouteSetFromCloud(ctx, userCred, self, added[i])
if err != nil {
syncResult.AddError(err)
continue
}
syncResult.Add()
}
return syncResult
}
func (self *SInterVpcNetwork) GetProvider() (cloudprovider.ICloudProvider, error) {
provider, err := self.GetCloudprovider().GetProvider()
if err != nil {
return nil, errors.Wrapf(err, "self.GetCloudprovider().GetProvider()")
}
return provider, nil
}
func (self *SInterVpcNetwork) GetICloudInterVpcNetwork() (cloudprovider.ICloudInterVpcNetwork, error) {
provider, err := self.GetProvider()
if err != nil {
return nil, errors.Wrap(err, "snetwork.GetProvider()")
}
iVpcNetwork, err := provider.GetICloudInterVpcNetworkById(self.ExternalId)
if err != nil {
return nil, errors.Wrapf(err, "GetICloudInterVpcNetworkById(%s)", self.ExternalId)
}
return iVpcNetwork, nil
}
@@ -0,0 +1,316 @@
// 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 models
import (
"context"
"database/sql"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/tristate"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SInterVpcNetworkRouteSetManager struct {
db.SEnabledStatusStandaloneResourceBaseManager
db.SExternalizedResourceBaseManager
SVpcResourceBaseManager
}
var InterVpcNetworkRouteSetManager *SInterVpcNetworkRouteSetManager
func init() {
InterVpcNetworkRouteSetManager = &SInterVpcNetworkRouteSetManager{
SEnabledStatusStandaloneResourceBaseManager: db.NewEnabledStatusStandaloneResourceBaseManager(
SInterVpcNetworkRouteSet{},
"inter_vpc_network_route_sets_tbl",
"inter_vpc_network_route_set",
"inter_vpc_network_route_sets",
),
}
InterVpcNetworkRouteSetManager.SetVirtualObject(InterVpcNetworkRouteSetManager)
}
type SInterVpcNetworkRouteSet struct {
db.SEnabledStatusStandaloneResourceBase
db.SExternalizedResourceBase
SVpcResourceBase
InterVpcNetworkId string
Cidr string `width:"36" charset:"ascii" nullable:"true" list:"domain"`
ExtInstanceId string `width:"36" charset:"ascii" nullable:"false" list:"domain"`
ExtInstanceType string `width:"36" charset:"ascii" nullable:"false" list:"domain"`
ExtInstanceRegionId string `width:"36" charset:"ascii" nullable:"false" list:"domain"`
}
func (manager *SInterVpcNetworkRouteSetManager) OrderByExtraFields(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.InterVpcNetworkRouteSetListInput,
) (*sqlchemy.SQuery, error) {
q, err := manager.SEnabledStatusStandaloneResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.EnabledStatusStandaloneResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SStandaloneResourceBaseManager.OrderByExtraFields")
}
q, err = manager.SVpcResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.VpcFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SStandaloneResourceBaseManager.OrderByExtraFields")
}
return q, nil
}
func (manager *SInterVpcNetworkRouteSetManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.InterVpcNetworkRouteSetListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SEnabledStatusStandaloneResourceBaseManager.ListItemFilter(ctx, q, userCred, query.EnabledStatusStandaloneResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SStatusStandaloneResourceBaseManager.ListItemFilter")
}
q, err = manager.SExternalizedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ExternalizedResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SExternalizedResourceBaseManager.ListItemFilter")
}
q, err = manager.SVpcResourceBaseManager.ListItemFilter(ctx, q, userCred, query.VpcFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SExternalizedResourceBaseManager.ListItemFilter")
}
if len(query.InterVpcNetworkId) > 0 {
vpcNetwork, err := InterVpcNetworkManager.FetchByIdOrName(userCred, query.InterVpcNetworkId)
if err != nil {
if errors.Cause(err) == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError2("inter_vpc_network_id", query.InterVpcNetworkId)
}
return nil, httperrors.NewGeneralError(err)
}
q = q.Equals("inter_vpc_network_id", vpcNetwork.GetId())
}
return q, nil
}
func (self *SInterVpcNetworkRouteSet) syncRemoveRouteSet(ctx context.Context, userCred mcclient.TokenCredential) error {
lockman.LockObject(ctx, self)
defer lockman.ReleaseObject(ctx, self)
err := self.ValidateDeleteCondition(ctx)
if err != nil {
return err
}
err = self.RealDelete(ctx, userCred)
return err
}
func (self *SInterVpcNetworkRouteSet) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
return self.SStatusStandaloneResourceBase.Delete(ctx, userCred)
}
func (self *SInterVpcNetworkRouteSet) syncWithCloudRouteSet(ctx context.Context, userCred mcclient.TokenCredential, interVpcNetwork *SInterVpcNetwork, cloudRouteSet cloudprovider.ICloudInterVpcNetworkRoute) error {
vpcId := ""
if cloudRouteSet.GetInstanceType() == api.INTER_VPCNETWORK_ATTACHED_INSTAMCE_TYPE_VPC {
provider := interVpcNetwork.GetCloudprovider()
vpc, err := db.FetchByExternalIdAndManagerId(VpcManager, cloudRouteSet.GetInstanceId(), func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
managerQ := CloudproviderManager.Query("id").Equals("provider", provider.Provider)
return q.In("manager_id", managerQ.SubQuery())
})
if err != nil {
return errors.Wrap(err, "db.FetchByExternalIdAndManagerId(VpcManager")
}
vpcId = vpc.GetId()
}
diff, err := db.UpdateWithLock(ctx, self, func() error {
self.Name = cloudRouteSet.GetName()
self.Enabled = tristate.NewFromBool(cloudRouteSet.GetEnabled())
self.Status = cloudRouteSet.GetStatus()
self.Cidr = cloudRouteSet.GetCidr()
self.InterVpcNetworkId = interVpcNetwork.GetId()
self.VpcId = vpcId
self.ExtInstanceId = cloudRouteSet.GetInstanceId()
self.ExtInstanceType = cloudRouteSet.GetInstanceType()
self.ExtInstanceRegionId = cloudRouteSet.GetInstanceRegionId()
return nil
})
if err != nil {
return err
}
db.OpsLog.LogSyncUpdate(self, diff, userCred)
return nil
}
func (manager *SInterVpcNetworkRouteSetManager) newRouteSetFromCloud(ctx context.Context, userCred mcclient.TokenCredential, interVpcNetwork *SInterVpcNetwork, cloudRouteSet cloudprovider.ICloudInterVpcNetworkRoute) (*SInterVpcNetworkRouteSet, error) {
routeSet := &SInterVpcNetworkRouteSet{
InterVpcNetworkId: interVpcNetwork.GetId(),
Cidr: cloudRouteSet.GetCidr(),
ExtInstanceId: cloudRouteSet.GetInstanceId(),
ExtInstanceType: cloudRouteSet.GetInstanceType(),
ExtInstanceRegionId: cloudRouteSet.GetInstanceRegionId(),
}
if cloudRouteSet.GetInstanceType() == api.INTER_VPCNETWORK_ATTACHED_INSTAMCE_TYPE_VPC {
provider := interVpcNetwork.GetCloudprovider()
vpc, err := db.FetchByExternalIdAndManagerId(VpcManager, cloudRouteSet.GetInstanceId(), func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
managerQ := CloudproviderManager.Query("id").Equals("provider", provider.Provider)
return q.In("manager_id", managerQ.SubQuery())
})
if err != nil {
return nil, errors.Wrap(err, "db.FetchByExternalIdAndManagerId(VpcManager")
}
routeSet.VpcId = vpc.GetId()
}
routeSet.ExternalId = cloudRouteSet.GetId()
routeSet.Name = cloudRouteSet.GetName()
routeSet.Enabled = tristate.NewFromBool(cloudRouteSet.GetEnabled())
routeSet.Status = cloudRouteSet.GetStatus()
routeSet.SetModelManager(manager, routeSet)
if err := manager.TableSpec().Insert(ctx, routeSet); err != nil {
return nil, err
}
db.OpsLog.LogEvent(routeSet, db.ACT_CREATE, routeSet.GetShortDesc(ctx), userCred)
return routeSet, nil
}
func (manager *SInterVpcNetworkRouteSetManager) ListItemExportKeys(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, keys stringutils2.SSortedStrings) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SEnabledStatusStandaloneResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SStatusStandaloneResourceBaseManager.ListItemExportKeys")
}
q, err = manager.SVpcResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SVpcResourceBaseManager.ListItemExportKeys")
}
return q, nil
}
func (manager *SInterVpcNetworkRouteSetManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
q, err := manager.SEnabledStatusStandaloneResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
q, err = manager.SVpcResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
return q, httperrors.ErrNotFound
}
func (self *SInterVpcNetworkRouteSet) GetExtraDetails(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
isList bool,
) (api.InterVpcNetworkRouteSetDetails, error) {
return api.InterVpcNetworkRouteSetDetails{}, nil
}
func (manager *SInterVpcNetworkRouteSetManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.InterVpcNetworkRouteSetDetails {
rows := make([]api.InterVpcNetworkRouteSetDetails, len(objs))
stdRows := manager.SEnabledStatusStandaloneResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
vpcRows := manager.SVpcResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
for i := range rows {
rows[i] = api.InterVpcNetworkRouteSetDetails{
EnabledStatusStandaloneResourceDetails: stdRows[i],
VpcResourceInfo: vpcRows[i],
}
}
return rows
}
func (self *SInterVpcNetworkRouteSet) AllowPerformEnable(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.InterVpcNetworkRouteSetEnableInput) bool {
return db.IsDomainAllowPerform(userCred, self, "enable")
}
func (self *SInterVpcNetworkRouteSet) PerformEnable(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.InterVpcNetworkRouteSetEnableInput) (jsonutils.JSONObject, error) {
_, err := self.SEnabledStatusStandaloneResourceBase.PerformEnable(ctx, userCred, query, input.PerformEnableInput)
if err != nil {
return nil, err
}
network, err := self.GetInterVpcNetwork()
if err != nil {
return nil, errors.Wrap(err, "self.GetInterVpcNetwork()")
}
err = network.StartInterVpcNetworkUpdateRoutesetTask(ctx, userCred, self, "enable")
return nil, err
}
func (self *SInterVpcNetworkRouteSet) AllowPerformDisable(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.InterVpcNetworkRouteSetDisableInput) bool {
return db.IsDomainAllowPerform(userCred, self, "disable")
}
func (self *SInterVpcNetworkRouteSet) PerformDisable(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.InterVpcNetworkRouteSetDisableInput) (jsonutils.JSONObject, error) {
_, err := self.SEnabledStatusStandaloneResourceBase.PerformDisable(ctx, userCred, query, input.PerformDisableInput)
if err != nil {
return nil, err
}
network, err := self.GetInterVpcNetwork()
if err != nil {
return nil, errors.Wrap(err, "self.GetInterVpcNetwork()")
}
err = network.StartInterVpcNetworkUpdateRoutesetTask(ctx, userCred, self, "disable")
return nil, err
}
func (self *SInterVpcNetworkRouteSet) GetInterVpcNetwork() (*SInterVpcNetwork, error) {
network, err := InterVpcNetworkManager.FetchById(self.InterVpcNetworkId)
if err != nil {
return nil, errors.Wrapf(err, "InterVpcNetworkManager.FetchById(%s)", self.InterVpcNetworkId)
}
return network.(*SInterVpcNetwork), nil
}
func (self *SInterVpcNetwork) StartInterVpcNetworkUpdateRoutesetTask(ctx context.Context, userCred mcclient.TokenCredential, routeSet *SInterVpcNetworkRouteSet, routeSetAction string) error {
params := jsonutils.NewDict()
params.Add(jsonutils.NewString(routeSetAction), "action")
params.Add(jsonutils.NewString(routeSet.GetId()), "inter_vpc_network_route_set_id")
task, err := taskman.TaskManager.NewTask(ctx, "InterVpcNetworkUpdateRoutesetTask", self, userCred, params, "", "", nil)
if err != nil {
return errors.Wrap(err, "Start InterVpcNetworkUpdateRoutesetTask fail")
}
self.SetStatus(userCred, api.INTER_VPC_NETWORK_STATUS_UPDATEROUTE, "update route")
task.ScheduleRun(nil)
return nil
}
@@ -0,0 +1,64 @@
// 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 models
import (
"context"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/mcclient"
)
type SInterVpcNetworkVpcManager struct {
db.SJointResourceBaseManager
SInterVpcNetworkResourceBaseManager
}
var InterVpcNetworkVpcManager *SInterVpcNetworkVpcManager
func init() {
db.InitManager(func() {
InterVpcNetworkVpcManager = &SInterVpcNetworkVpcManager{
SJointResourceBaseManager: db.NewJointResourceBaseManager(
SInterVpcNetworkVpc{},
"inter_vpc_network_vpc_tbl",
"inter_vpc_network_vpc",
"inter_vpc_network_vpcs",
InterVpcNetworkManager,
VpcManager,
),
}
InterVpcNetworkManager.SetVirtualObject(InterVpcNetworkManager)
})
}
type SInterVpcNetworkVpc struct {
db.SJointResourceBase
SInterVpcNetworkResourceBase
VpcId string `width:"36" charset:"ascii" nullable:"false" list:"user"`
}
func (manager *SInterVpcNetworkVpcManager) GetMasterFieldName() string {
return "inter_vpc_network_id"
}
func (manager *SInterVpcNetworkVpcManager) GetSlaveFieldName() string {
return "vpc_id"
}
func (self *SInterVpcNetworkVpc) Detach(ctx context.Context, userCred mcclient.TokenCredential) error {
return db.DetachJoint(ctx, userCred, self)
}
@@ -0,0 +1,52 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package models
import (
"context"
"database/sql"
"yunion.io/x/pkg/errors"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
)
type SInterVpcNetworkResourceBase struct {
InterVpcNetworkId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"required" json:"inter_vpc_network_id"`
}
type SInterVpcNetworkResourceBaseManager struct{}
func (manager *SInterVpcNetworkResourceBaseManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.InterVpcNetworkFilterListBase,
) (*sqlchemy.SQuery, error) {
if len(query.InterVpcNetworkId) > 0 {
network, err := InterVpcNetworkManager.FetchByIdOrName(userCred, query.InterVpcNetworkId)
if err != nil {
if errors.Cause(err) == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError2("inter_vpc_network", query.InterVpcNetworkId)
}
return nil, httperrors.NewGeneralError(err)
}
q = q.Equals("inter_vpc_network_id", network.GetId())
}
return q, nil
}
+2 -1
View File
@@ -187,7 +187,8 @@ func (man *SLoadbalancerBackendManager) ValidateBackendVpc(lb *SLoadbalancer, gu
return httperrors.NewBadRequestError("%s", err)
}
if len(lb.VpcId) > 0 {
if vpc.Id != lb.VpcId {
lbVpc := lb.GetVpc()
if lbVpc != nil && !lbVpc.IsEmulated && vpc.Id != lb.VpcId {
return httperrors.NewBadRequestError("guest %s(%s) vpc %s(%s) not same as loadbalancer vpc %s", guest.Name, guest.Id, vpc.Name, vpc.Id, lb.VpcId)
}
return nil
@@ -114,6 +114,10 @@ func (self *SCachedLoadbalancerCertificate) ValidateDeleteCondition(ctx context.
return nil
}
func (self *SCachedLoadbalancerCertificate) ValidatePurgeCondition(ctx context.Context) error {
return nil
}
func (self *SCachedLoadbalancerCertificate) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
return nil
}
+1 -1
View File
@@ -176,7 +176,7 @@ func (lbcert *SCachedLoadbalancerCertificate) purge(ctx context.Context, userCre
lockman.LockObject(ctx, lbcert)
defer lockman.ReleaseObject(ctx, lbcert)
err := lbcert.ValidateDeleteCondition(ctx)
err := lbcert.ValidatePurgeCondition(ctx)
if err != nil {
return err
}
+1
View File
@@ -161,6 +161,7 @@ type IDBInstanceDriver interface {
ValidateResetDBInstancePassword(ctx context.Context, userCred mcclient.TokenCredential, instance *SDBInstance, account string) error
RequestCreateDBInstance(ctx context.Context, userCred mcclient.TokenCredential, dbinstance *SDBInstance, task taskman.ITask) error
RequestCreateDBInstanceFromBackup(ctx context.Context, userCred mcclient.TokenCredential, dbinstance *SDBInstance, task taskman.ITask) error
RequestCreateDBInstanceBackup(ctx context.Context, userCred mcclient.TokenCredential, instance *SDBInstance, backup *SDBInstanceBackup, task taskman.ITask) error
RequestChangeDBInstanceConfig(ctx context.Context, userCred mcclient.TokenCredential, instance *SDBInstance, task taskman.ITask) error
+2
View File
@@ -460,6 +460,7 @@ func (man *SRouteTableManager) newRouteTableFromCloud(userCred mcclient.TokenCre
routeTable.Name = newName
}
// routeTable.ManagerId = vpc.ManagerId
routeTable.Status = cloudRouteTable.GetStatus()
routeTable.ExternalId = cloudRouteTable.GetGlobalId()
routeTable.Description = cloudRouteTable.GetDescription()
// routeTable.ProjectId = userCred.GetProjectId()
@@ -515,6 +516,7 @@ func (self *SRouteTable) SyncWithCloudRouteTable(ctx context.Context, userCred m
}
diff, err := db.UpdateWithLock(ctx, self, func() error {
// self.CloudregionId = routeTable.CloudregionId
self.Status = routeTable.GetStatus()
self.VpcId = vpc.Id
self.Type = routeTable.Type
self.Routes = routeTable.Routes
+20
View File
@@ -172,3 +172,23 @@ func (manager *SSchedtagResourceBaseManager) GetOrderBySubQuery(
func (manager *SSchedtagResourceBaseManager) GetOrderByFields(query api.SchedtagFilterListInput) []string {
return []string{query.OrderBySchedtag, query.OrderByResourceType}
}
func InsertJointResourceSchedtag(ctx context.Context, jointMan ISchedtagJointManager, resourceId, schedtagId string) (ISchedtagJointModel, error) {
newTagObj, err := db.NewModelObject(jointMan)
if err != nil {
return nil, errors.Wrap(err, "NewModelObject")
}
objectKey := jointMan.GetResourceIdKey(jointMan)
createData := jsonutils.NewDict()
createData.Add(jsonutils.NewString(schedtagId), "schedtag_id")
createData.Add(jsonutils.NewString(resourceId), objectKey)
if err := createData.Unmarshal(newTagObj); err != nil {
return nil, errors.Wrapf(err, "Create %s joint schedtag", jointMan.Keyword())
}
if err := newTagObj.GetModelManager().TableSpec().Insert(ctx, newTagObj); err != nil {
return nil, errors.Wrap(err, "Insert to database")
}
return newTagObj.(ISchedtagJointModel), nil
}
+116 -19
View File
@@ -18,6 +18,7 @@ import (
"context"
"database/sql"
"fmt"
"reflect"
"strings"
"yunion.io/x/jsonutils"
@@ -133,6 +134,10 @@ func (manager *SSchedtagManager) GetResourceTypes() []string {
return ret
}
func (manager *SSchedtagManager) GetJointManager(resTypePlural string) ISchedtagJointManager {
return manager.jointsManager[resTypePlural]
}
type SSchedtag struct {
db.SStandaloneResourceBase
db.SScopedResourceBase
@@ -386,14 +391,33 @@ func (self *SSchedtag) ValidateDeleteCondition(ctx context.Context) error {
return self.SStandaloneResourceBase.ValidateDeleteCondition(ctx)
}
func (self *SSchedtag) GetObjects(objs interface{}) error {
// GetObjectPtr wraps the given value with pointer: V => *V, *V => **V, etc.
func GetObjectPtr(obj interface{}) interface{} {
v := reflect.ValueOf(obj)
pt := reflect.PtrTo(v.Type())
pv := reflect.New(pt.Elem())
pv.Elem().Set(v)
return pv.Interface()
}
func (self *SSchedtag) GetResources() ([]IModelWithSchedtag, error) {
objs := make([]interface{}, 0)
q := self.GetObjectQuery()
masterMan := self.GetJointManager().GetMasterManager()
err := db.FetchModelObjects(masterMan, q, objs)
masterMan, err := self.GetResourceManager()
if err != nil {
return err
return nil, err
}
return nil
if err := db.FetchModelObjects(masterMan, q, &objs); err != nil {
return nil, err
}
ret := make([]IModelWithSchedtag, len(objs))
for i := range objs {
obj := objs[i]
ret[i] = GetObjectPtr(obj).(IModelWithSchedtag)
}
return ret, nil
}
func (self *SSchedtag) GetObjectQuery() *sqlchemy.SQuery {
@@ -410,7 +434,16 @@ func (self *SSchedtag) GetObjectQuery() *sqlchemy.SQuery {
}
func (self *SSchedtag) GetJointManager() ISchedtagJointManager {
return SchedtagManager.jointsManager[self.ResourceType]
return SchedtagManager.GetJointManager(self.ResourceType)
}
func (s *SSchedtag) GetResourceManager() (db.IStandaloneModelManager, error) {
jResMan := s.GetJointManager()
if jResMan == nil {
return nil, errors.Errorf("Not found bind joint resource manager by type %q", s.ResourceType)
}
return jResMan.GetMasterManager(), nil
}
func (self *SSchedtag) GetObjectCount() (int, error) {
@@ -585,19 +618,8 @@ func PerformSetResourceSchedtag(obj IModelWithSchedtag, ctx context.Context, use
jointMan := obj.GetSchedtagJointManager()
for _, setTagId := range setTagsId {
if !utils.IsInStringArray(setTagId, oldTagIds) {
if newTagObj, err := db.NewModelObject(jointMan); err != nil {
return nil, httperrors.NewGeneralError(err)
} else {
objectKey := jointMan.GetResourceIdKey(jointMan)
createData := jsonutils.NewDict()
createData.Add(jsonutils.NewString(setTagId), "schedtag_id")
createData.Add(jsonutils.NewString(obj.GetId()), objectKey)
if err := createData.Unmarshal(newTagObj); err != nil {
return nil, httperrors.NewGeneralError(fmt.Errorf("Create %s joint schedtag error: %v", jointMan.Keyword(), err))
}
if err := newTagObj.GetModelManager().TableSpec().Insert(ctx, newTagObj); err != nil {
return nil, httperrors.NewGeneralError(err)
}
if _, err := InsertJointResourceSchedtag(ctx, jointMan, obj.GetId(), setTagId); err != nil {
return nil, errors.Wrapf(err, "InsertJointResourceSchedtag %s %s", obj.GetId(), setTagId)
}
}
}
@@ -649,3 +671,78 @@ func (s *SSchedtag) AllowPerformSetScope(ctx context.Context, userCred mcclient.
func (s *SSchedtag) PerformSetScope(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
return db.PerformSetScope(ctx, s, userCred, data)
}
func (s *SSchedtag) GetJointResourceTag(resId string) (ISchedtagJointModel, error) {
jMan := s.GetJointManager()
jObj, err := db.FetchJointByIds(jMan, resId, s.GetId(), nil)
if err != nil {
return nil, err
}
return jObj.(ISchedtagJointModel), nil
}
func (s *SSchedtag) PerformSetResource(ctx context.Context, userCred mcclient.TokenCredential, _ jsonutils.JSONObject, input *api.SchedtagSetResourceInput) (jsonutils.JSONObject, error) {
if input == nil {
return nil, nil
}
setResIds := make(map[string]IModelWithSchedtag, 0)
resMan, err := s.GetResourceManager()
if err != nil {
return nil, errors.Wrap(err, "get resource manager")
}
// get need set resource ids
for i := 0; i < len(input.ResourceIds); i++ {
resId := input.ResourceIds[i]
res, err := resMan.FetchByIdOrName(userCred, resId)
if err != nil {
if errors.Cause(err) == sql.ErrNoRows {
return nil, httperrors.NewNotFoundError("Resource %s %s not found", s.ResourceType, resId)
}
return nil, errors.Wrapf(err, "Fetch resource %s by id or name", s.ResourceType)
}
setResIds[res.GetId()] = res.(IModelWithSchedtag)
}
// unbind current resources if not in input
curRess, err := s.GetResources()
if err != nil {
return nil, errors.Wrap(err, "Get current bind resources")
}
curResIds := make([]string, 0)
for i := range curRess {
res := curRess[i]
if _, ok := setResIds[res.GetId()]; ok {
curResIds = append(curResIds, res.GetId())
continue
}
jObj, err := s.GetJointResourceTag(res.GetId())
if err != nil {
return nil, errors.Wrapf(err, "Get joint resource tag by id %s", res.GetId())
}
if err := jObj.Detach(ctx, userCred); err != nil {
return nil, errors.Wrap(err, "detach joint tag")
}
}
// bind input resources
jointMan := s.GetJointManager()
for resId := range setResIds {
if utils.IsInStringArray(resId, curResIds) {
// already binded
continue
}
if _, err := InsertJointResourceSchedtag(ctx, jointMan, resId, s.GetId()); err != nil {
return nil, errors.Wrapf(err, "InsertJointResourceSchedtag %s %s", resId, s.GetId())
}
res := setResIds[resId]
if err := res.ClearSchedDescCache(); err != nil {
log.Errorf("Resource %s/%s ClearSchedDescCache error: %v", res.Keyword(), res.GetId(), err)
}
}
return nil, nil
}
+29 -5
View File
@@ -27,6 +27,7 @@ import (
"yunion.io/x/pkg/errors"
v "yunion.io/x/pkg/util/version"
apis "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/compute/options"
"yunion.io/x/onecloud/pkg/mcclient"
@@ -161,13 +162,36 @@ func (self *SSkuResourcesMeta) GetServerSkusByRegionExternalId(regionExternalId
return result, nil
}
func getElaticCacheSkuRegionExtId(regionExtId string) string {
if strings.HasPrefix(regionExtId, apis.CLOUD_ACCESS_ENV_ALIYUN_FINANCE) && strings.HasSuffix(regionExtId, "cn-hangzhou") {
return regionExtId + "-finance"
}
return regionExtId
}
func getElaticCacheSkuZoneId(zoneExtId string) string {
if strings.HasPrefix(zoneExtId, apis.CLOUD_ACCESS_ENV_ALIYUN_FINANCE) {
if strings.HasSuffix(zoneExtId, "cn-hangzhou-finance-b") || strings.HasSuffix(zoneExtId, "cn-hangzhou-finance-c") || strings.HasSuffix(zoneExtId, "cn-hangzhou-finance-d") {
zoneExtId = strings.Replace(zoneExtId, "-finance", "", -1)
} else if strings.Contains(zoneExtId, "cn-hangzhou") {
zoneExtId = strings.Replace(zoneExtId, "-finance", "", 1)
}
}
return zoneExtId
}
func (self *SSkuResourcesMeta) GetElasticCacheSkusByRegionExternalId(regionExternalId string) ([]SElasticcacheSku, error) {
regionId, zoneMaps, err := self.GetRegionIdAndZoneMaps(regionExternalId)
if err != nil {
return nil, errors.Wrap(err, "GetRegionIdAndZoneMaps")
}
result := []SElasticcacheSku{}
objs, err := self.getSkusByRegion(self.ElasticCacheBase, regionExternalId)
// aliyun finance cloud
remoteRegion := getElaticCacheSkuRegionExtId(regionExternalId)
objs, err := self.getSkusByRegion(self.ElasticCacheBase, remoteRegion)
if err != nil {
return nil, errors.Wrap(err, "getSkusByRegion")
}
@@ -179,16 +203,16 @@ func (self *SSkuResourcesMeta) GetElasticCacheSkusByRegionExternalId(regionExter
return nil, errors.Wrapf(err, "obj.Unmarshal")
}
if len(sku.ZoneId) > 0 {
zoneId := self.getZoneIdBySuffix(zoneMaps, sku.ZoneId)
zoneId := self.getZoneIdBySuffix(zoneMaps, getElaticCacheSkuZoneId(sku.ZoneId))
if len(zoneId) == 0 {
return nil, fmt.Errorf("invalid sku %s %s master zoneId: %s", sku.Id, sku.CloudregionId, sku.ZoneId)
return nil, fmt.Errorf("invalid sku %s %s master zoneId: %s", sku.Id, sku.CloudregionId, getElaticCacheSkuZoneId(sku.ZoneId))
}
sku.ZoneId = zoneId
}
if len(sku.SlaveZoneId) > 0 {
zoneId := self.getZoneIdBySuffix(zoneMaps, sku.SlaveZoneId)
zoneId := self.getZoneIdBySuffix(zoneMaps, getElaticCacheSkuZoneId(sku.SlaveZoneId))
if len(zoneId) == 0 {
return nil, fmt.Errorf("invalid sku %s %s slave zoneId: %s", sku.Id, sku.CloudregionId, sku.SlaveZoneId)
return nil, fmt.Errorf("invalid sku %s %s slave zoneId: %s", sku.Id, sku.CloudregionId, getElaticCacheSkuZoneId(sku.SlaveZoneId))
}
sku.SlaveZoneId = zoneId
}
+55 -1
View File
@@ -129,6 +129,17 @@ func (self *SVpc) GetDnsZones() ([]SDnsZone, error) {
return dnsZones, nil
}
func (self *SVpc) GetInterVpcNetworks() ([]SInterVpcNetwork, error) {
sq := InterVpcNetworkVpcManager.Query("inter_vpc_network_id").Equals("vpc_id", self.Id)
q := InterVpcNetworkManager.Query().In("id", sq.SubQuery())
vpcNetworks := []SInterVpcNetwork{}
err := db.FetchModelObjects(InterVpcNetworkManager, q, &vpcNetworks)
if err != nil {
return nil, errors.Wrapf(err, "db.FetchModelObjects")
}
return vpcNetworks, nil
}
func (self *SVpc) GetDnsZoneCount() (int, error) {
sq := DnsZoneVpcManager.Query("dns_zone_id").Equals("vpc_id", self.Id)
q := DnsZoneManager.Query().In("id", sq.SubQuery())
@@ -271,7 +282,7 @@ func (manager *SVpcManager) GetOrCreateVpcForClassicNetwork(ctx context.Context,
vpc.IsDefault = false
vpc.CloudregionId = region.Id
vpc.SetModelManager(manager, vpc)
vpc.Name = fmt.Sprintf("emulated vpc for %s %s classic network", region.Name, cloudprovider.Name)
vpc.Name = "-"
vpc.IsEmulated = true
vpc.SetEnabled(false)
vpc.Status = api.VPC_STATUS_UNAVAILABLE
@@ -719,6 +730,26 @@ func (manager *SVpcManager) InitializeData() error {
}
}
{
vpcs := []SVpc{}
q := manager.Query().IsTrue("is_emulated").IsNotEmpty("external_id").NotEquals("name", "-")
err := db.FetchModelObjects(manager, q, &vpcs)
if err != nil {
return errors.Wrapf(err, "db.FetchModelObjects")
}
for i := range vpcs {
if vpcs[i].ExternalId == manager.getVpcExternalIdForClassicNetwork(vpcs[i].CloudregionId, vpcs[i].ManagerId) {
_, err = db.Update(&vpcs[i], func() error {
vpcs[i].Name = "-"
return nil
})
if err != nil {
return errors.Wrapf(err, "db.Update class vpc name")
}
}
}
}
return nil
}
@@ -916,6 +947,17 @@ func (self *SVpc) RealDelete(ctx context.Context, userCred mcclient.TokenCredent
}
}
vpcNetwork, err := self.GetInterVpcNetworks()
if err != nil {
return errors.Wrapf(err, "self.GetInterVpcNetwork")
}
for i := range vpcNetwork {
err = vpcNetwork[i].RemoveVpc(ctx, self.Id)
if err != nil {
return errors.Wrapf(err, "remove vpc from InterVpcNetwork %s", vpcNetwork[i].Id)
}
}
return self.SEnabledStatusInfrasResourceBase.Delete(ctx, userCred)
}
@@ -1027,6 +1069,18 @@ func (manager *SVpcManager) ListItemFilter(
q = q.In("id", sq.SubQuery())
}
if len(query.InterVpcNetworkId) > 0 {
vpcNetwork, err := InterVpcNetworkManager.FetchByIdOrName(userCred, query.InterVpcNetworkId)
if err != nil {
if errors.Cause(err) == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError2("inter_vpc_network", query.InterVpcNetworkId)
}
return nil, httperrors.NewGeneralError(err)
}
sq := InterVpcNetworkVpcManager.Query("vpc_id").Equals("inter_vpc_network_id", vpcNetwork.GetId())
q = q.In("id", sq.SubQuery())
}
usable := (query.Usable != nil && *query.Usable)
vpcUsable := (query.UsableVpc != nil && *query.UsableVpc)
if vpcUsable || usable {
+21 -20
View File
@@ -1000,25 +1000,26 @@ func (self *SAliyunRegionDriver) ValidateCreateDBInstanceData(ctx context.Contex
return input, httperrors.NewInputParameterError("slave dbinstance not support prepaid billing type")
}
wire := network.GetWire()
if wire == nil {
return input, httperrors.NewGeneralError(fmt.Errorf("failed to found wire for network %s(%s)", network.Name, network.Id))
}
zone := wire.GetZone()
if zone == nil {
return input, httperrors.NewGeneralError(fmt.Errorf("failed to found zone for wire %s(%s)", wire.Name, wire.Id))
}
match := false
for _, sku := range skus {
if utils.IsInStringArray(zone.Id, []string{sku.Zone1, sku.Zone2, sku.Zone3}) {
match = true
break
if network != nil {
wire := network.GetWire()
if wire == nil {
return input, httperrors.NewGeneralError(fmt.Errorf("failed to found wire for network %s(%s)", network.Name, network.Id))
}
zone := wire.GetZone()
if zone == nil {
return input, httperrors.NewGeneralError(fmt.Errorf("failed to found zone for wire %s(%s)", wire.Name, wire.Id))
}
}
if !match {
return input, httperrors.NewInputParameterError("failed to match any skus in the network %s(%s) zone %s(%s)", network.Name, network.Id, zone.Name, zone.Id)
match := false
for _, sku := range skus {
if utils.IsInStringArray(zone.Id, []string{sku.Zone1, sku.Zone2, sku.Zone3}) {
match = true
break
}
}
if !match {
return input, httperrors.NewInputParameterError("failed to match any skus in the network %s(%s) zone %s(%s)", network.Name, network.Id, zone.Name, zone.Id)
}
}
var master *models.SDBInstance
@@ -1204,6 +1205,7 @@ func (self *SAliyunRegionDriver) ValidateCreateElasticcacheData(ctx context.Cont
// validate sku
billingType, _ := data.GetString("billing_type")
zone := zoneV.Model.(*models.SZone)
network := networkV.Model.(*models.SNetwork)
if sku, err := data.GetString("instance_type"); err != nil || len(sku) == 0 {
return nil, httperrors.NewMissingParameterError("instance_type")
} else {
@@ -1213,7 +1215,7 @@ func (self *SAliyunRegionDriver) ValidateCreateElasticcacheData(ctx context.Cont
}
skuModel := _skuModel.(*models.SElasticcacheSku)
if err := ValidateElasticcacheSku(zone.Id, billingType, skuModel); err != nil {
if err := ValidateElasticcacheSku(zone.Id, billingType, skuModel, network); err != nil {
return nil, err
} else {
data.Set("instance_type", jsonutils.NewString(skuModel.InstanceSpec))
@@ -1237,7 +1239,6 @@ func (self *SAliyunRegionDriver) ValidateCreateElasticcacheData(ctx context.Cont
data.Set("billing_cycle", jsonutils.NewString(cycle.String()))
}
network := networkV.Model.(*models.SNetwork)
vpc := network.GetVpc()
if vpc == nil {
return nil, httperrors.NewNotFoundError("network %s related vpc not found", network.GetId())
@@ -1369,7 +1370,7 @@ func (self *SAliyunRegionDriver) ValidateCreateElasticcacheAccountData(ctx conte
accountPrivilegeV.Value)
}
return data, nil
return self.SManagedVirtualizationRegionDriver.ValidateCreateElasticcacheAccountData(ctx, userCred, ownerId, data)
}
func (self *SAliyunRegionDriver) RequestCreateElasticcacheAccount(ctx context.Context, userCred mcclient.TokenCredential, ea *models.SElasticcacheAccount, task taskman.ITask) error {
+33
View File
@@ -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 regiondrivers
import (
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/compute/models"
)
type SApsaraRegionDriver struct {
SAliyunRegionDriver
}
func init() {
driver := SApsaraRegionDriver{}
models.RegisterRegionDriver(&driver)
}
func (self *SApsaraRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_APSARA
}

Some files were not shown because too many files have changed in this diff Show More