From b7c3959e041fd3d71bc3cedc89506be10675721b Mon Sep 17 00:00:00 2001 From: Yousong Zhou Date: Wed, 14 Oct 2020 18:16:46 +0800 Subject: [PATCH 1/4] vendor: update yunion.io/x/sqlchemy --- go.mod | 2 +- go.sum | 4 ++-- vendor/modules.txt | 2 +- vendor/yunion.io/x/sqlchemy/update.go | 16 ++++++++++++---- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 62c9057c5f..336e437810 100644 --- a/go.mod +++ b/go.mod @@ -146,7 +146,7 @@ require ( yunion.io/x/ovsdb v0.0.0-20200526071744-27bf0940cbc7 yunion.io/x/pkg v0.0.0-20200814072949-4f1b541857d6 yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e - yunion.io/x/sqlchemy v0.0.0-20201009235752-2ef1a29656b0 + yunion.io/x/sqlchemy v0.0.0-20201014101037-8fe75542e6d8 yunion.io/x/structarg v0.0.0-20200720093445-9f850fa222ce ) diff --git a/go.sum b/go.sum index 4fd276087f..cec9d3787d 100644 --- a/go.sum +++ b/go.sum @@ -1139,7 +1139,7 @@ yunion.io/x/pkg v0.0.0-20200814072949-4f1b541857d6 h1:UarEDTBGkgcgc+nc+PZ75uo9M9 yunion.io/x/pkg v0.0.0-20200814072949-4f1b541857d6/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E= yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e h1:v+EzIadodSwkdZ/7bremd7J8J50Cise/HCylsOJngmo= yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e/go.mod h1:0iFKpOs1y4lbCxeOmq3Xx/0AcQoewVPwj62eRluioEo= -yunion.io/x/sqlchemy v0.0.0-20201009235752-2ef1a29656b0 h1:ETDt3Xc3a6WnbHvhrMUemXVsnWY/RgHrsNRCVFWkCYo= -yunion.io/x/sqlchemy v0.0.0-20201009235752-2ef1a29656b0/go.mod h1:FTdwPdGhMgh4E+UFXc9klI1Ok34fMuybTT+jLhOaIjI= +yunion.io/x/sqlchemy v0.0.0-20201014101037-8fe75542e6d8 h1:AkPrqO37Yi3aICys9qDjTlSdVVGh2pWQ8ET+dSJmhoI= +yunion.io/x/sqlchemy v0.0.0-20201014101037-8fe75542e6d8/go.mod h1:FTdwPdGhMgh4E+UFXc9klI1Ok34fMuybTT+jLhOaIjI= yunion.io/x/structarg v0.0.0-20200720093445-9f850fa222ce h1:kU8xE7O5uZ1GSJVMZHoJ+jrNL7csUQHYGyAPW9QfNpE= yunion.io/x/structarg v0.0.0-20200720093445-9f850fa222ce/go.mod h1:EP6NSv2C0zzqBDTKumv8hPWLb3XvgMZDHQRfyuOrQng= diff --git a/vendor/modules.txt b/vendor/modules.txt index f8330bb30b..341b1dcf39 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1109,7 +1109,7 @@ yunion.io/x/pkg/util/workqueue yunion.io/x/pkg/utils # yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e yunion.io/x/s3cli -# yunion.io/x/sqlchemy v0.0.0-20201009235752-2ef1a29656b0 +# yunion.io/x/sqlchemy v0.0.0-20201014101037-8fe75542e6d8 yunion.io/x/sqlchemy # yunion.io/x/structarg v0.0.0-20200720093445-9f850fa222ce yunion.io/x/structarg diff --git a/vendor/yunion.io/x/sqlchemy/update.go b/vendor/yunion.io/x/sqlchemy/update.go index a122da432a..a606969757 100644 --- a/vendor/yunion.io/x/sqlchemy/update.go +++ b/vendor/yunion.io/x/sqlchemy/update.go @@ -21,6 +21,7 @@ import ( "reflect" "strings" + "yunion.io/x/jsonutils" "yunion.io/x/log" "yunion.io/x/pkg/errors" "yunion.io/x/pkg/gotypes" @@ -74,14 +75,21 @@ func (ud *SUpdateDiff) String() string { utils.TruncateString(ud.new, 32)) } +func (ud SUpdateDiff) jsonObj() jsonutils.JSONObject { + r := jsonutils.NewDict() + r.Set("old", jsonutils.Marshal(ud.old)) + r.Set("new", jsonutils.Marshal(ud.new)) + return r +} + type UpdateDiffs map[string]SUpdateDiff func (uds UpdateDiffs) String() string { - items := make([]string, 0, len(uds)) - for k, v := range uds { - items = append(items, fmt.Sprintf("%s:%s", k, v.String())) + obj := jsonutils.NewDict() + for k := range uds { + obj.Set(k, uds[k].jsonObj()) } - return strings.Join(items, ";") + return obj.String() } func (us *SUpdateSession) saveUpdate(dt interface{}) (UpdateDiffs, error) { From 258ceb7ba8c36f0a613cbe285258e12c1dbb721d Mon Sep 17 00:00:00 2001 From: Yousong Zhou Date: Mon, 19 Oct 2020 10:04:15 +0800 Subject: [PATCH 2/4] networks: add field BgpType --- pkg/apis/compute/network.go | 12 +++++++ pkg/compute/models/elasticips.go | 4 +-- pkg/compute/models/networks.go | 50 ++++++++++++++++++++++++++ pkg/compute/tasks/eip_allocate_task.go | 1 + 4 files changed, 65 insertions(+), 2 deletions(-) diff --git a/pkg/apis/compute/network.go b/pkg/apis/compute/network.go index 4292953be7..aaf3409693 100644 --- a/pkg/apis/compute/network.go +++ b/pkg/apis/compute/network.go @@ -193,6 +193,9 @@ type NetworkCreateInput struct { // deprecated Vlan *int `json:"vlan" yunion-deprecated-by:"vlan_id"` + + // 线路类型 + BgpType string `json:"bgp_type"` } type NetworkDetails struct { @@ -329,3 +332,12 @@ type GetNetworkAddressesOutput struct { // IP子网地址记录 Addresses []SNetworkAddress `json:"addresses"` } + +type NetworkSetBgpTypeInput struct { + apis.Meta + + // description: new BgpType name + // required: true + // example: ChinaTelecom, BGP, etc. + BgpType string `json:"bgp_type"` +} diff --git a/pkg/compute/models/elasticips.go b/pkg/compute/models/elasticips.go index 16bdea0654..6cfa6ce71b 100644 --- a/pkg/compute/models/elasticips.go +++ b/pkg/compute/models/elasticips.go @@ -98,8 +98,8 @@ type SElasticip struct { // 计费类型: 流量、带宽 // example: bandwidth ChargeType string `name:"charge_type" list:"user" create:"required"` - // 目前只有华为云此字段是必需填写的 - BgpType string `list:"user" create:"optional"` + // 线路类型 + BgpType string `width:"64" charset:"utf8" nullable:"false" get:"user" list:"user" create:"optional"` // 是否跟随主机删除而自动释放 AutoDellocate tristate.TriState `default:"false" get:"user" create:"optional" update:"user"` diff --git a/pkg/compute/models/networks.go b/pkg/compute/models/networks.go index 5bdde780f9..67ff84fdf1 100644 --- a/pkg/compute/models/networks.go +++ b/pkg/compute/models/networks.go @@ -119,6 +119,9 @@ type SNetwork struct { // 该网段是否用于自动分配IP地址,如果为false,则用户需要明确选择该网段,才会使用该网段分配IP, // 如果为true,则用户不指定网段时,则自动从该值为true的网络中选择一个分配地址 IsAutoAlloc tristate.TriState `nullable:"true" list:"user" get:"user" update:"user" create:"optional"` + + // 线路类型 + BgpType string `width:"64" charset:"utf8" nullable:"false" get:"user" update:"user" create:"optional"` } func (manager *SNetworkManager) GetContextManagers() [][]db.IModelManager { @@ -1456,6 +1459,9 @@ func (manager *SNetworkManager) ValidateCreateData(ctx context.Context, userCred if input.ServerType == api.NETWORK_TYPE_EIP && vpc.Id != api.DEFAULT_VPC_ID { return input, httperrors.NewInputParameterError("eip network can only exist in default vpc, got %s(%s)", vpc.Name, vpc.Id) } + if input.ServerType != api.NETWORK_TYPE_EIP { + input.BgpType = "" + } var ( ipStart = ipRange.StartIp() @@ -2871,3 +2877,47 @@ func (manager *SNetworkManager) AllowScope(userCred mcclient.TokenCredential) rb } } } + +func (self *SNetwork) AllowPerformSetBgpType(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool { + return self.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, self, "set-isp") +} + +func (self *SNetwork) PerformSetBgpType(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input *api.NetworkSetBgpTypeInput) (jsonutils.JSONObject, error) { + if self.BgpType == input.BgpType { + return nil, nil + } + if self.ServerType != api.NETWORK_TYPE_EIP { + return nil, httperrors.NewInputParameterError("BgpType attribute is only useful for eip network") + } + { + var eips []SElasticip + q := ElasticipManager.Query(). + Equals("network_id", self.Id). + NotEquals("bgp_type", input.BgpType) + if err := db.FetchModelObjects(ElasticipManager, q, &eips); err != nil { + return nil, err + } + for i := range eips { + eip := &eips[i] + if diff, err := db.UpdateWithLock(ctx, eip, func() error { + eip.BgpType = input.BgpType + return nil + }); err != nil { + // no need to retry/restore here. return error + // and retry after user resolves the error + return nil, err + } else { + db.OpsLog.LogEvent(eip, db.ACT_UPDATE, diff, userCred) + } + } + } + if diff, err := db.Update(self, func() error { + self.BgpType = input.BgpType + return nil + }); err != nil { + return nil, err + } else { + db.OpsLog.LogEvent(self, db.ACT_UPDATE, diff, userCred) + } + return nil, nil +} diff --git a/pkg/compute/tasks/eip_allocate_task.go b/pkg/compute/tasks/eip_allocate_task.go index ae3e8e8b8e..f7c7d48427 100644 --- a/pkg/compute/tasks/eip_allocate_task.go +++ b/pkg/compute/tasks/eip_allocate_task.go @@ -99,6 +99,7 @@ func (self *EipAllocateTask) OnInit(ctx context.Context, obj db.IStandaloneModel } _, err = db.Update(eip, func() error { eip.IpAddr = ipAddr + eip.BgpType = network.BgpType return nil }) if err != nil { From 59dd8a0e29ba89587f10e6fe48553fdac629e70e Mon Sep 17 00:00:00 2001 From: Yousong Zhou Date: Sat, 10 Oct 2020 16:29:41 +0800 Subject: [PATCH 3/4] eip: create by BgpType --- pkg/apis/compute/elasticip.go | 3 +++ pkg/compute/regiondrivers/kvm.go | 41 +++++++++++++++++++++++++------- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/pkg/apis/compute/elasticip.go b/pkg/apis/compute/elasticip.go index ab432b3b1e..3f82b79a2a 100644 --- a/pkg/apis/compute/elasticip.go +++ b/pkg/apis/compute/elasticip.go @@ -67,6 +67,9 @@ type SElasticipCreateInput struct { // 子网Id // 私有云创建此参数必传,例如Openstack, ZStack NetworkId string `json:"network_id"` + + // description: BgpType for the new eip + BgpType string `json:"bgp_type"` } type ElasticipDetails struct { diff --git a/pkg/compute/regiondrivers/kvm.go b/pkg/compute/regiondrivers/kvm.go index cea94dbb0b..eb5f6beac8 100644 --- a/pkg/compute/regiondrivers/kvm.go +++ b/pkg/compute/regiondrivers/kvm.go @@ -898,17 +898,40 @@ func (self *SKVMRegionDriver) RequestDeleteVpc(ctx context.Context, userCred mcc } func (self *SKVMRegionDriver) ValidateCreateEipData(ctx context.Context, userCred mcclient.TokenCredential, input *api.SElasticipCreateInput) error { - if len(input.NetworkId) == 0 { - return httperrors.NewMissingParameterError("network_id") - } - _network, err := models.NetworkManager.FetchByIdOrName(userCred, input.NetworkId) - if err != nil { - if err == sql.ErrNoRows { - return httperrors.NewResourceNotFoundError2("network", input.NetworkId) + var network *models.SNetwork + if input.NetworkId != "" { + _network, err := models.NetworkManager.FetchByIdOrName(userCred, input.NetworkId) + if err != nil { + if err == sql.ErrNoRows { + return httperrors.NewResourceNotFoundError2("network", input.NetworkId) + } + return httperrors.NewGeneralError(err) } - return httperrors.NewGeneralError(err) + network = _network.(*models.SNetwork) + input.BgpType = network.BgpType + } else if input.BgpType != "" { + q := models.NetworkManager.Query(). + Equals("server_type", api.NETWORK_TYPE_EIP). + Equals("bgp_type", input.BgpType) + var nets []models.SNetwork + if err := db.FetchModelObjects(models.NetworkManager, q, &nets); err != nil { + return err + } + for i := range nets { + net := &nets[i] + cnt, _ := net.GetFreeAddressCount() + if cnt > 0 { + network = net + input.NetworkId = net.Id + break + } + } + if network == nil { + return httperrors.NewNotFoundError("no available eip network from BgpType %s", input.BgpType) + } + } else { + return httperrors.NewMissingParameterError("network_id, isp") } - network := _network.(*models.SNetwork) if network.ServerType != api.NETWORK_TYPE_EIP { return httperrors.NewInputParameterError("bad network type %q, want %q", network.ServerType, api.NETWORK_TYPE_EIP) } From bc898e9e3b0a6028650912419f5b99ceec3a81a0 Mon Sep 17 00:00:00 2001 From: Yousong Zhou Date: Sat, 10 Oct 2020 16:46:32 +0800 Subject: [PATCH 4/4] climc: eip ops by bgp type --- cmd/climc/shell/compute/elasticips.go | 4 +++ cmd/climc/shell/compute/networks.go | 36 ++++++++++++++++++++++----- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/cmd/climc/shell/compute/elasticips.go b/cmd/climc/shell/compute/elasticips.go index 4ddd787722..94fdd7a5be 100644 --- a/cmd/climc/shell/compute/elasticips.go +++ b/cmd/climc/shell/compute/elasticips.go @@ -52,6 +52,7 @@ func init() { Bandwidth int `help:"Bandwidth in Mbps"` Ip string `help:"IP address of the EIP"` Network string `help:"Network of the EIP"` + BgpType string `help:"BgpType of the EIP" positional:"false"` ChargeType string `help:"bandwidth charge type" choices:"traffic|bandwidth"` } R(&EipCreateOptions{}, "eip-create", "Create an EIP", func(s *mcclient.ClientSession, args *EipCreateOptions) error { @@ -74,6 +75,9 @@ func init() { if len(args.Network) > 0 { params.Add(jsonutils.NewString(args.Network), "network") } + if len(args.BgpType) > 0 { + params.Add(jsonutils.NewString(args.BgpType), "bgp_type") + } if len(args.Ip) > 0 { params.Add(jsonutils.NewString(args.Ip), "ip") diff --git a/cmd/climc/shell/compute/networks.go b/cmd/climc/shell/compute/networks.go index 72c9528eea..da12d621bb 100644 --- a/cmd/climc/shell/compute/networks.go +++ b/cmd/climc/shell/compute/networks.go @@ -69,6 +69,7 @@ func init() { AllocPolicy string `help:"Address allocation policy" choices:"none|stepdown|stepup|random"` ServerType string `help:"Server type" choices:"baremetal|container|eip|guest|ipmi|pxe"` IsAutoAlloc *bool `help:"Auto allocation IP pool"` + BgpType string `help:"Internet service provider name" positional:"false"` Desc string `help:"Description" metavar:"DESCRIPTION"` } R(&NetworkCreateOptions{}, "network-create", "Create a virtual network", func(s *mcclient.ClientSession, args *NetworkCreateOptions) error { @@ -95,6 +96,9 @@ func init() { if len(args.Desc) > 0 { params.Add(jsonutils.NewString(args.Desc), "description") } + if len(args.BgpType) > 0 { + params.Add(jsonutils.NewString(args.BgpType), "bgp_type") + } if args.IsAutoAlloc != nil { params.Add(jsonutils.NewBool(*args.IsAutoAlloc), "is_auto_alloc") } @@ -107,17 +111,21 @@ func init() { }) type NetworkCreateOptions2 struct { - Wire string `help:"ID or Name of wire in which the network is created"` - Vpc string `help:"ID or Name of vpc in which the network is created"` - Zone string `help:"ID or Name of zone in which the network is created"` - NAME string `help:"Name of new network"` - PREFIX string `help:"Start of IPv4 address range"` - Desc string `help:"Description" metavar:"DESCRIPTION"` + Wire string `help:"ID or Name of wire in which the network is created"` + Vpc string `help:"ID or Name of vpc in which the network is created"` + Zone string `help:"ID or Name of zone in which the network is created"` + NAME string `help:"Name of new network"` + PREFIX string `help:"Start of IPv4 address range"` + BgpType string `help:"Internet service provider name" positional:"false"` + Desc string `help:"Description" metavar:"DESCRIPTION"` } R(&NetworkCreateOptions2{}, "network-create2", "Create a virtual network", func(s *mcclient.ClientSession, args *NetworkCreateOptions2) error { params := jsonutils.NewDict() params.Add(jsonutils.NewString(args.NAME), "name") params.Add(jsonutils.NewString(args.PREFIX), "guest_ip_prefix") + if len(args.BgpType) > 0 { + params.Add(jsonutils.NewString(args.BgpType), "bgp_type") + } if len(args.Desc) > 0 { params.Add(jsonutils.NewString(args.Desc), "description") } @@ -253,4 +261,20 @@ func init() { printObject(net) return nil }) + type NetworkSetBgpTypeOptions struct { + ID string `help:"Network to set BgpType" json:"-"` + BgpType *string `help:"new BgpType name"` + } + R(&NetworkSetBgpTypeOptions{}, "network-set-bgp-type", "Set BgpType of a network", func(s *mcclient.ClientSession, args *NetworkSetBgpTypeOptions) error { + params, err := options.StructToParams(args) + if err != nil { + return err + } + net, err := modules.Networks.PerformAction(s, args.ID, "set-bgp-type", params) + if err != nil { + return err + } + printObject(net) + return nil + }) }