mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-08-29 03:51:54 +08:00
fix: allow vmware network associate with multiple wires (#18318)
Co-authored-by: Qiu Jian <qiujian@yunionyun.com>
This commit is contained in:
@@ -43,6 +43,7 @@ func init() {
|
||||
cmd.Get("change-owner-candidate-domains", &compute_options.NetworkIdOptions{})
|
||||
cmd.Perform("set-class-metadata", &options.ResourceMetadataOptions{})
|
||||
cmd.Perform("switch-wire", &compute_options.NetworkSwitchWireOptions{})
|
||||
cmd.Perform("sync-additional-wires", &compute_options.NetworkSyncAdditionalWiresOptions{})
|
||||
|
||||
type NetworkShareOptions struct {
|
||||
ID string `help:"ID or Name of the zone to show"`
|
||||
|
||||
@@ -309,6 +309,8 @@ type NetworkDetails struct {
|
||||
Schedtags []SchedtagShortDescDetails `json:"schedtags"`
|
||||
|
||||
IsClassic bool `json:"is_classic"`
|
||||
|
||||
AdditionalWires []SSimpleWire `json:"additional_wires"`
|
||||
}
|
||||
|
||||
type NetworkIpMacDetails struct {
|
||||
@@ -452,3 +454,9 @@ type NetworkSwitchWireInput struct {
|
||||
// example: bcast0
|
||||
WireId string `json:"wire_id"`
|
||||
}
|
||||
|
||||
type NetworSyncAdditionalWiresInput struct {
|
||||
apis.Meta
|
||||
|
||||
WireIds []string `json:"wire_ids"`
|
||||
}
|
||||
|
||||
@@ -88,6 +88,11 @@ type WireResourceInfo struct {
|
||||
Zone string `json:"zone"`
|
||||
}
|
||||
|
||||
type SSimpleWire struct {
|
||||
Wire string
|
||||
WireId string
|
||||
}
|
||||
|
||||
type WireUpdateInput struct {
|
||||
apis.InfrasResourceBaseUpdateInput
|
||||
|
||||
|
||||
@@ -889,8 +889,8 @@ func (gn *SGuestnetwork) IsAllocated() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func GetIPTenantIdPairs() {
|
||||
/*
|
||||
/* func GetIPTenantIdPairs() {
|
||||
|
||||
from guests import Guests
|
||||
from hosts import Hosts
|
||||
from sqlalchemy.sql.expression import bindparam
|
||||
@@ -903,8 +903,8 @@ func GetIPTenantIdPairs() {
|
||||
.join(Hosts, and_(Hosts.id==Guests.host_id,
|
||||
Hosts.deleted==False))
|
||||
return q.all()
|
||||
*/
|
||||
}
|
||||
|
||||
} */
|
||||
|
||||
func (gn *SGuestnetwork) GetVirtualIPs() []string {
|
||||
ips := make([]string, 0)
|
||||
|
||||
@@ -3382,6 +3382,8 @@ func (self *SGuest) Attach2Network(
|
||||
userCred mcclient.TokenCredential,
|
||||
args Attach2NetworkArgs,
|
||||
) ([]SGuestnetwork, error) {
|
||||
log.Debugf("Attach2Network %s", jsonutils.Marshal(args))
|
||||
|
||||
onceArgs := args.onceArgs(0)
|
||||
firstNic, err := self.attach2NetworkOnce(ctx, userCred, onceArgs)
|
||||
if err != nil {
|
||||
@@ -3522,11 +3524,10 @@ func getCloudNicNetwork(ctx context.Context, vnic cloudprovider.ICloudNic, host
|
||||
return host.getNetworkOfIPOnHost(ip)
|
||||
}
|
||||
localNetObj, err := db.FetchByExternalIdAndManagerId(NetworkManager, vnetId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
vpc := VpcManager.Query().SubQuery()
|
||||
// vpc := VpcManager.Query().SubQuery()
|
||||
wire := WireManager.Query().SubQuery()
|
||||
return q.Join(wire, sqlchemy.Equals(q.Field("wire_id"), wire.Field("id"))).
|
||||
Join(vpc, sqlchemy.Equals(wire.Field("vpc_id"), vpc.Field("id"))).
|
||||
Filter(sqlchemy.Equals(vpc.Field("manager_id"), host.ManagerId))
|
||||
Filter(sqlchemy.Equals(wire.Field("manager_id"), host.ManagerId))
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "Cannot find network of external_id %s", vnetId)
|
||||
@@ -3566,6 +3567,8 @@ func (self *SGuest) SyncVMNics(
|
||||
return result
|
||||
}
|
||||
|
||||
log.Debugf("SyncVMNics: removed: %d common: %d add: %d", len(removed), len(commondb), len(added))
|
||||
|
||||
for i := 0; i < len(removed); i += 1 {
|
||||
err = self.detachNetworks(ctx, userCred, []SGuestnetwork{removed[i]}, false, false)
|
||||
if err != nil {
|
||||
@@ -3638,13 +3641,17 @@ func (self *SGuest) SyncVMNics(
|
||||
TryReserved: true,
|
||||
AllocDir: api.IPAllocationDefault,
|
||||
RequireDesignatedIP: true,
|
||||
UseDesignatedIP: true,
|
||||
UseDesignatedIP: false,
|
||||
NicConfs: []SNicConfig{nicConf},
|
||||
})
|
||||
if err != nil {
|
||||
result.AddError(err)
|
||||
continue
|
||||
}
|
||||
if len(ipList) > 0 {
|
||||
// shift
|
||||
ipList = ipList[1:]
|
||||
}
|
||||
result.Add()
|
||||
for i := range guestnetworks {
|
||||
guestnetwork := &guestnetworks[i]
|
||||
|
||||
@@ -0,0 +1,225 @@
|
||||
// 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"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/utils"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/util/netutils2"
|
||||
)
|
||||
|
||||
type SNetworkAdditionalWireManager struct {
|
||||
db.SModelBaseManager
|
||||
}
|
||||
|
||||
var NetworkAdditionalWireManager *SNetworkAdditionalWireManager
|
||||
|
||||
func init() {
|
||||
NetworkAdditionalWireManager = &SNetworkAdditionalWireManager{
|
||||
SModelBaseManager: db.NewModelBaseManager(
|
||||
SNetworkAdditionalWire{},
|
||||
"network_additional_wire_tbl",
|
||||
"network_additional_wire",
|
||||
"network_additional_wires",
|
||||
),
|
||||
}
|
||||
NetworkAdditionalWireManager.SetVirtualObject(NetworkAdditionalWireManager)
|
||||
}
|
||||
|
||||
type SNetworkAdditionalWire struct {
|
||||
db.SModelBase
|
||||
|
||||
NetworkId string `width:"36" charset:"ascii" nullable:"false" primary:"true"`
|
||||
WireId string `width:"36" charset:"ascii" nullable:"false" primary:"true"`
|
||||
Synced *bool
|
||||
Marked *bool
|
||||
}
|
||||
|
||||
func (manager *SNetworkAdditionalWireManager) newRecord(ctx context.Context, netId, wireId string, synced *bool, marked *bool) error {
|
||||
rec := &SNetworkAdditionalWire{
|
||||
NetworkId: netId,
|
||||
WireId: wireId,
|
||||
Synced: synced,
|
||||
Marked: marked,
|
||||
}
|
||||
err := manager.TableSpec().InsertOrUpdate(ctx, rec)
|
||||
return errors.Wrap(err, "InsertOrUpdate")
|
||||
}
|
||||
|
||||
func (manager *SNetworkAdditionalWireManager) networkIdQuery(wireId string) *sqlchemy.SQuery {
|
||||
q := manager.Query("network_id").Equals("wire_id", wireId)
|
||||
q = q.Filter(sqlchemy.OR(
|
||||
sqlchemy.IsTrue(q.Field("synced")),
|
||||
sqlchemy.IsTrue(q.Field("marked")),
|
||||
))
|
||||
return q
|
||||
}
|
||||
|
||||
func (manager *SNetworkAdditionalWireManager) fetchNetworkAdditionalWireIdsQuery(netId string) *sqlchemy.SQuery {
|
||||
q := manager.Query("wire_id").Equals("network_id", netId)
|
||||
q = q.Filter(sqlchemy.OR(
|
||||
sqlchemy.IsTrue(q.Field("synced")),
|
||||
sqlchemy.IsTrue(q.Field("marked")),
|
||||
))
|
||||
return q
|
||||
}
|
||||
|
||||
func (manager *SNetworkAdditionalWireManager) DeleteNetwork(ctx context.Context, netId string) error {
|
||||
False := false
|
||||
wireIds, err := manager.FetchNetworkAdditionalWireIds(netId)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "FetchNetworkAdditionalWireIds")
|
||||
}
|
||||
for _, wireId := range wireIds {
|
||||
err := manager.newRecord(ctx, netId, wireId, &False, &False)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "newRecord")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (manager *SNetworkAdditionalWireManager) DeleteWire(ctx context.Context, wireId string) error {
|
||||
False := false
|
||||
netIds, err := manager.FetchWireAdditionalNetworkIds(wireId)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "FetchWireAdditionalNetworkIds")
|
||||
}
|
||||
for _, netId := range netIds {
|
||||
err := manager.newRecord(ctx, netId, wireId, &False, &False)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "newRecord")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (manager *SNetworkAdditionalWireManager) FetchNetworkAdditionalWireIds(netId string) ([]string, error) {
|
||||
q := manager.fetchNetworkAdditionalWireIdsQuery(netId)
|
||||
ret := make([]SNetworkAdditionalWire, 0)
|
||||
err := db.FetchModelObjects(manager, q, &ret)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "FetchModelObjects")
|
||||
}
|
||||
wireIds := make([]string, len(ret))
|
||||
for i := range ret {
|
||||
wireIds[i] = ret[i].WireId
|
||||
}
|
||||
return wireIds, nil
|
||||
}
|
||||
|
||||
func (manager *SNetworkAdditionalWireManager) FetchWireAdditionalNetworkIds(wireId string) ([]string, error) {
|
||||
q := manager.networkIdQuery(wireId)
|
||||
ret := make([]SNetworkAdditionalWire, 0)
|
||||
err := db.FetchModelObjects(manager, q, &ret)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "FetchModelObjects")
|
||||
}
|
||||
netIds := make([]string, len(ret))
|
||||
for i := range ret {
|
||||
netIds[i] = ret[i].NetworkId
|
||||
}
|
||||
return netIds, nil
|
||||
}
|
||||
|
||||
func (manager *SNetworkAdditionalWireManager) FetchNetworkAdditionalWires(netId string) ([]api.SSimpleWire, error) {
|
||||
subq := manager.fetchNetworkAdditionalWireIdsQuery(netId).SubQuery()
|
||||
q := WireManager.Query("id", "name")
|
||||
q = q.Join(subq, sqlchemy.Equals(q.Field("id"), subq.Field("wire_id")))
|
||||
|
||||
ret := make([]SWire, 0)
|
||||
err := db.FetchModelObjects(WireManager, q, &ret)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "FetchModelObjects")
|
||||
}
|
||||
wires := make([]api.SSimpleWire, len(ret))
|
||||
for i := range ret {
|
||||
wires[i].WireId = ret[i].Id
|
||||
wires[i].Wire = ret[i].Name
|
||||
}
|
||||
return wires, nil
|
||||
}
|
||||
|
||||
func (net *SNetwork) syncAdditionalWires(ctx context.Context, wireIds []string) error {
|
||||
// find out all vmware wires in the same zone
|
||||
wires, err := WireManager.FetchWires(func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
managersQ := CloudproviderManager.Query().Equals("provider", api.CLOUD_PROVIDER_VMWARE).SubQuery()
|
||||
q = q.Join(managersQ, sqlchemy.Equals(q.Field("manager_id"), managersQ.Field("id")))
|
||||
return q
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "FetchWires")
|
||||
}
|
||||
for i := range wires {
|
||||
w := &wires[i]
|
||||
if net.WireId == w.Id {
|
||||
continue
|
||||
}
|
||||
connected := net.checkNetWireConnectivity(ctx, w)
|
||||
var markedPtr *bool
|
||||
if wireIds != nil {
|
||||
marked := false
|
||||
if utils.IsInArray(w.Id, wireIds) {
|
||||
marked = true
|
||||
}
|
||||
markedPtr = &marked
|
||||
}
|
||||
err := NetworkAdditionalWireManager.newRecord(ctx, net.Id, w.Id, &connected, markedPtr)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "NetworkAdditionalWireManager.newRecord")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (net *SNetwork) checkNetWireConnectivity(ctx context.Context, wire *SWire) bool {
|
||||
vmIps := wire.GetMetadata(ctx, "vm_ips", nil)
|
||||
if len(vmIps) > 0 {
|
||||
ips, err := netutils2.ExpandCompactIps(vmIps)
|
||||
if err != nil {
|
||||
log.Errorf("ExpandCompactIps net %s wire %s vm_ips %s fail %s", net.Name, wire.Name, vmIps, err)
|
||||
} else {
|
||||
for _, ip := range ips {
|
||||
if net.Contains(ip) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
vmMacs := wire.GetMetadata(ctx, "vm_macs", nil)
|
||||
if len(vmMacs) > 0 {
|
||||
macs := strings.Split(vmMacs, ",")
|
||||
for _, mac := range macs {
|
||||
gns, err := GuestnetworkManager.fetchGuestNetworks(func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
q = q.Equals("network_id", net.Id).Equals("mac_addr", mac)
|
||||
return q
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("fetchGuestNetworks net %s wire %s mac %s fail %s", net.Name, wire.Name, mac, err)
|
||||
} else if len(gns) > 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
+106
-22
@@ -1074,6 +1074,7 @@ func (manager *SNetworkManager) FetchCustomizeColumns(
|
||||
rows[i].Routes = network.GetRoutes()
|
||||
rows[i].Schedtags = GetSchedtagsDetailsToResourceV2(network, ctx)
|
||||
rows[i].Dns = network.GetDNS(rows[i].Zone)
|
||||
rows[i].AdditionalWires = network.fetchAdditionalWires()
|
||||
|
||||
netIds[i] = network.Id
|
||||
}
|
||||
@@ -1890,19 +1891,25 @@ func (self *SNetwork) CustomizeCreate(ctx context.Context, userCred mcclient.Tok
|
||||
return self.SSharableVirtualResourceBase.CustomizeCreate(ctx, userCred, ownerId, query, data)
|
||||
}
|
||||
|
||||
func (self *SNetwork) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) {
|
||||
self.SSharableVirtualResourceBase.PostCreate(ctx, userCred, ownerId, query, data)
|
||||
vpc, _ := self.GetVpc()
|
||||
func (net *SNetwork) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) {
|
||||
net.SSharableVirtualResourceBase.PostCreate(ctx, userCred, ownerId, query, data)
|
||||
vpc, _ := net.GetVpc()
|
||||
if vpc != nil && vpc.IsManaged() {
|
||||
task, err := taskman.TaskManager.NewTask(ctx, "NetworkCreateTask", self, userCred, data.(*jsonutils.JSONDict), "", "", nil)
|
||||
task, err := taskman.TaskManager.NewTask(ctx, "NetworkCreateTask", net, userCred, data.(*jsonutils.JSONDict), "", "", nil)
|
||||
if err != nil {
|
||||
log.Errorf("networkcreateTask create fail: %s", err)
|
||||
} else {
|
||||
task.ScheduleRun(nil)
|
||||
}
|
||||
} else {
|
||||
self.SetStatus(userCred, api.NETWORK_STATUS_AVAILABLE, "")
|
||||
if err := self.ClearSchedDescCache(); err != nil {
|
||||
{
|
||||
err := net.syncAdditionalWires(ctx, nil)
|
||||
if err != nil {
|
||||
log.Errorf("syncAdditionalWires error: %s", err)
|
||||
}
|
||||
}
|
||||
net.SetStatus(userCred, api.NETWORK_STATUS_AVAILABLE, "")
|
||||
if err := net.ClearSchedDescCache(); err != nil {
|
||||
log.Errorf("network post create clear schedcache error: %v", err)
|
||||
}
|
||||
}
|
||||
@@ -1965,6 +1972,9 @@ func (self *SNetwork) RealDelete(ctx context.Context, userCred mcclient.TokenCre
|
||||
if err := self.SSharableVirtualResourceBase.Delete(ctx, userCred); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := NetworkAdditionalWireManager.DeleteNetwork(ctx, self.Id); err != nil {
|
||||
return errors.Wrap(err, "NetworkAdditionalWireManager.DeleteNetwork")
|
||||
}
|
||||
self.ClearSchedDescCache()
|
||||
return nil
|
||||
}
|
||||
@@ -2039,9 +2049,31 @@ func (manager *SNetworkManager) ListItemFilter(
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SExternalizedResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
q, err = manager.SWireResourceBaseManager.ListItemFilter(ctx, q, userCred, input.WireFilterListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SWireResourceBaseManager.ListItemFilter")
|
||||
{
|
||||
wireFilter := input.WireResourceInput
|
||||
input.Wire = ""
|
||||
input.WireId = ""
|
||||
q, err = manager.SWireResourceBaseManager.ListItemFilter(ctx, q, userCred, input.WireFilterListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SWireResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
if len(wireFilter.WireId) > 0 {
|
||||
wireObj, err := WireManager.FetchByIdOrName(userCred, wireFilter.WireId)
|
||||
if err != nil {
|
||||
if errors.Cause(err) == sql.ErrNoRows {
|
||||
return nil, httperrors.NewResourceNotFoundError2(WireManager.Keyword(), wireFilter.WireId)
|
||||
} else {
|
||||
return nil, errors.Wrapf(err, "WireManager.FetchByIdOrName %s", wireFilter.WireId)
|
||||
}
|
||||
}
|
||||
wireFilter.WireId = wireObj.GetId()
|
||||
wireFilter.Wire = wireObj.GetName()
|
||||
q = q.Filter(sqlchemy.OR(
|
||||
sqlchemy.Equals(q.Field("wire_id"), wireFilter.WireId),
|
||||
sqlchemy.In(q.Field("id"), NetworkAdditionalWireManager.networkIdQuery(wireFilter.WireId).SubQuery()),
|
||||
))
|
||||
}
|
||||
input.WireResourceInput = wireFilter
|
||||
}
|
||||
|
||||
if len(input.RouteTableId) > 0 {
|
||||
@@ -2380,9 +2412,15 @@ func (self *SNetwork) ValidateUpdateCondition(ctx context.Context) error {
|
||||
return self.SSharableVirtualResourceBase.ValidateUpdateCondition(ctx)
|
||||
}
|
||||
|
||||
func (self *SNetwork) PostUpdate(ctx context.Context, userCred mcclient.TokenCredential, query, data jsonutils.JSONObject) {
|
||||
self.SSharableVirtualResourceBase.PostUpdate(ctx, userCred, query, data)
|
||||
self.ClearSchedDescCache()
|
||||
func (net *SNetwork) PostUpdate(ctx context.Context, userCred mcclient.TokenCredential, query, data jsonutils.JSONObject) {
|
||||
net.SSharableVirtualResourceBase.PostUpdate(ctx, userCred, query, data)
|
||||
net.ClearSchedDescCache()
|
||||
if net.IsClassic() {
|
||||
err := net.syncAdditionalWires(ctx, nil)
|
||||
if err != nil {
|
||||
log.Errorf("syncAdditionalWires error %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 清除IP子网数据
|
||||
@@ -2392,9 +2430,9 @@ func (self *SNetwork) PerformPurge(ctx context.Context, userCred mcclient.TokenC
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
vpc, _ := self.GetVpc()
|
||||
if vpc != nil && len(vpc.ExternalId) > 0 {
|
||||
provider := vpc.GetCloudprovider()
|
||||
wire, _ := self.GetWire()
|
||||
if wire != nil && len(wire.ExternalId) > 0 {
|
||||
provider := wire.GetCloudprovider()
|
||||
if provider != nil && provider.GetEnabled() {
|
||||
return nil, httperrors.NewInvalidStatusError("Cannot purge network on enabled cloud provider")
|
||||
}
|
||||
@@ -3004,8 +3042,6 @@ func (net *SNetwork) IsClassic() bool {
|
||||
}
|
||||
|
||||
func (net *SNetwork) getAttachedHosts() ([]SHost, error) {
|
||||
// hns := HostnetworkManager.Query().Equals("network_id", net.Id)
|
||||
// hns = hns.AppendField(hns.Field("baremetal_id").Label("host_id"))
|
||||
guestsQ := GuestManager.Query()
|
||||
gnsQ := GuestnetworkManager.Query().Equals("network_id", net.Id).SubQuery()
|
||||
guestsQ = guestsQ.Join(gnsQ, sqlchemy.Equals(guestsQ.Field("id"), gnsQ.Field("guest_id")))
|
||||
@@ -3033,11 +3069,7 @@ func (net *SNetwork) PerformSwitchWire(
|
||||
input *api.NetworkSwitchWireInput,
|
||||
) (jsonutils.JSONObject, error) {
|
||||
|
||||
vpc, err := net.GetVpc()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetVpc")
|
||||
}
|
||||
if !vpc.IsDefault {
|
||||
if !net.IsClassic() {
|
||||
return nil, errors.Wrap(httperrors.ErrNotSupported, "default vpc only")
|
||||
}
|
||||
|
||||
@@ -3064,6 +3096,9 @@ func (net *SNetwork) PerformSwitchWire(
|
||||
}
|
||||
unreachedHost := make([]string, 0)
|
||||
for i := range hosts {
|
||||
if hosts[i].HostType == api.HOST_TYPE_ESXI {
|
||||
continue
|
||||
}
|
||||
if !hosts[i].IsAttach2Wire(wire.Id) {
|
||||
unreachedHost = append(unreachedHost, hosts[i].Name)
|
||||
}
|
||||
@@ -3080,6 +3115,13 @@ func (net *SNetwork) PerformSwitchWire(
|
||||
return nil, errors.Wrap(err, "update wire_id")
|
||||
}
|
||||
|
||||
{
|
||||
err := net.syncAdditionalWires(ctx, nil)
|
||||
if err != nil {
|
||||
log.Errorf("syncAdditionalWires fail %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
logclient.AddActionLogWithContext(ctx, net, logclient.ACT_UPDATE, diff, userCred, true)
|
||||
db.OpsLog.LogEvent(net, db.ACT_UPDATE, diff, userCred)
|
||||
|
||||
@@ -3112,3 +3154,45 @@ func (net *SNetwork) PerformSwitchWire(
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (net *SNetwork) fetchAdditionalWires() []api.SSimpleWire {
|
||||
wires, err := NetworkAdditionalWireManager.FetchNetworkAdditionalWires(net.Id)
|
||||
if err != nil {
|
||||
log.Errorf("NetworkAdditionalWireManager.FetchNetworkAdditionalWires error %s", err)
|
||||
}
|
||||
return wires
|
||||
}
|
||||
|
||||
func (net *SNetwork) PerformSyncAdditionalWires(
|
||||
ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject,
|
||||
input *api.NetworSyncAdditionalWiresInput,
|
||||
) (jsonutils.JSONObject, error) {
|
||||
if !net.IsClassic() {
|
||||
return nil, errors.Wrap(httperrors.ErrNotSupported, "default vpc only")
|
||||
}
|
||||
|
||||
wireIds := make([]string, 0)
|
||||
errs := make([]error, 0)
|
||||
for _, wireId := range input.WireIds {
|
||||
wireObj, err := WireManager.FetchByIdOrName(userCred, wireId)
|
||||
if err != nil {
|
||||
if errors.Cause(err) == sql.ErrNoRows {
|
||||
errs = append(errs, httperrors.NewResourceNotFoundError2(WireManager.Keyword(), wireId))
|
||||
} else {
|
||||
errs = append(errs, errors.Wrapf(err, "WireManager.FetchByIdOrNam %s", wireId))
|
||||
}
|
||||
}
|
||||
wireIds = append(wireIds, wireObj.GetId())
|
||||
}
|
||||
if len(errs) > 0 {
|
||||
return nil, errors.NewAggregate(errs)
|
||||
}
|
||||
|
||||
err := net.syncAdditionalWires(ctx, wireIds)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "syncAdditionalWires")
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -561,6 +561,10 @@ func (self *purgePair) purgeAll(ctx context.Context) error {
|
||||
"delete from %s where %s in (%s)",
|
||||
self.manager.TableSpec().Name(), self.key, placeholder,
|
||||
)
|
||||
case NetworkAdditionalWireManager.Keyword():
|
||||
sql = fmt.Sprintf("delete from `%s` where `wire_id` in (%s)",
|
||||
self.manager.TableSpec().Name(), placeholder,
|
||||
)
|
||||
default:
|
||||
vars = append([]interface{}{time.Now()}, vars...)
|
||||
}
|
||||
@@ -815,10 +819,10 @@ func (self *SGuest) purge(ctx context.Context, userCred mcclient.TokenCredential
|
||||
}
|
||||
|
||||
func (self *SZone) purgeWires(ctx context.Context, managerId string) error {
|
||||
wires := WireManager.Query("id").Equals("zone_id", self.Id)
|
||||
vpcs := VpcManager.Query().SubQuery()
|
||||
wires = wires.Join(vpcs, sqlchemy.Equals(wires.Field("vpc_id"), vpcs.Field("id"))).
|
||||
Filter(sqlchemy.Equals(vpcs.Field("manager_id"), managerId))
|
||||
wires := WireManager.Query("id").Equals("zone_id", self.Id).Equals("manager_id", managerId)
|
||||
// vpcs := VpcManager.Query().SubQuery()
|
||||
// wires = wires.Join(vpcs, sqlchemy.Equals(wires.Field("vpc_id"), vpcs.Field("id"))).
|
||||
// Filter(sqlchemy.Equals(vpcs.Field("manager_id"), managerId))
|
||||
|
||||
hostwires := HostwireManagerDeprecated.Query("row_id").In("wire_id", wires.SubQuery())
|
||||
isolateds := IsolatedDeviceManager.Query("id").In("wire_id", wires.SubQuery())
|
||||
@@ -848,6 +852,7 @@ func (self *SZone) purgeWires(ctx context.Context, managerId string) error {
|
||||
{manager: NetworkManager, key: "id", q: networks},
|
||||
{manager: IsolatedDeviceManager, key: "id", q: isolateds},
|
||||
{manager: HostwireManagerDeprecated, key: "row_id", q: hostwires},
|
||||
{manager: NetworkAdditionalWireManager, key: "id", q: wires},
|
||||
{manager: WireManager, key: "id", q: wires},
|
||||
}
|
||||
for i := range pairs {
|
||||
|
||||
@@ -349,11 +349,11 @@ func (svpc *SVpc) GetRouteTableCount() (int, error) {
|
||||
return svpc.GetRouteTableQuery().CountWithError()
|
||||
}
|
||||
|
||||
func (svpc *SVpc) getCloudProviderInfo() SCloudProviderInfo {
|
||||
/*func (svpc *SVpc) getCloudProviderInfo() SCloudProviderInfo {
|
||||
region, _ := svpc.GetRegion()
|
||||
provider := svpc.GetCloudprovider()
|
||||
return MakeCloudProviderInfo(region, nil, provider)
|
||||
}
|
||||
}*/
|
||||
|
||||
func (svpc *SVpc) GetRegion() (*SCloudregion, error) {
|
||||
region, err := CloudregionManager.FetchById(svpc.CloudregionId)
|
||||
@@ -1375,6 +1375,8 @@ func (svpc *SVpc) initWire(ctx context.Context, zone *SZone, externalId string)
|
||||
wire.IsPublic = svpc.IsPublic
|
||||
wire.PublicScope = svpc.PublicScope
|
||||
|
||||
wire.ManagerId = svpc.ManagerId
|
||||
|
||||
wire.SetModelManager(WireManager, wire)
|
||||
err := WireManager.TableSpec().Insert(ctx, wire)
|
||||
if err != nil {
|
||||
|
||||
@@ -55,40 +55,48 @@ func ValidateWireResourceInput(userCred mcclient.TokenCredential, input api.Wire
|
||||
return wireObj.(*SWire), input, nil
|
||||
}
|
||||
|
||||
func (self *SWireResourceBase) GetWire() (*SWire, error) {
|
||||
w, err := WireManager.FetchById(self.WireId)
|
||||
func (wireRes *SWireResourceBase) GetWire() (*SWire, error) {
|
||||
w, err := WireManager.FetchById(wireRes.WireId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "GetWire(%s)", self.WireId)
|
||||
return nil, errors.Wrapf(err, "GetWire(%s)", wireRes.WireId)
|
||||
}
|
||||
return w.(*SWire), nil
|
||||
}
|
||||
|
||||
func (self *SWireResourceBase) GetCloudproviderId() string {
|
||||
vpc, _ := self.GetVpc()
|
||||
if vpc != nil {
|
||||
return vpc.ManagerId
|
||||
func (wireRes *SWireResourceBase) GetCloudproviderId() string {
|
||||
wire, _ := wireRes.GetWire()
|
||||
if wire != nil {
|
||||
return wire.ManagerId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SWireResourceBase) GetVpc() (*SVpc, error) {
|
||||
wire, err := self.GetWire()
|
||||
func (wireRes *SWireResourceBase) GetProviderName() string {
|
||||
wire, _ := wireRes.GetWire()
|
||||
if wire == nil {
|
||||
return wire.GetProviderName()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (wireRes *SWireResourceBase) GetVpc() (*SVpc, error) {
|
||||
wire, err := wireRes.GetWire()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "GetWire")
|
||||
}
|
||||
return wire.GetVpc()
|
||||
}
|
||||
|
||||
func (self *SWireResourceBase) GetRegion() (*SCloudregion, error) {
|
||||
vpc, err := self.GetVpc()
|
||||
func (wireRes *SWireResourceBase) GetRegion() (*SCloudregion, error) {
|
||||
vpc, err := wireRes.GetVpc()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "GetVpc")
|
||||
}
|
||||
return vpc.GetRegion()
|
||||
}
|
||||
|
||||
func (self *SWireResourceBase) GetZone() (*SZone, error) {
|
||||
wire, err := self.GetWire()
|
||||
func (wireRes *SWireResourceBase) GetZone() (*SZone, error) {
|
||||
wire, err := wireRes.GetWire()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "GetWire")
|
||||
}
|
||||
@@ -125,6 +133,7 @@ func (manager *SWireResourceBaseManager) FetchCustomizeColumns(
|
||||
|
||||
vpcList := make([]interface{}, len(rows))
|
||||
zoneList := make([]interface{}, len(rows))
|
||||
managerList := make([]interface{}, len(rows))
|
||||
for i := range rows {
|
||||
rows[i] = api.WireResourceInfo{}
|
||||
if _, ok := wires[wireIds[i]]; ok {
|
||||
@@ -135,14 +144,17 @@ func (manager *SWireResourceBaseManager) FetchCustomizeColumns(
|
||||
}
|
||||
vpcList[i] = &SVpcResourceBase{rows[i].VpcId}
|
||||
zoneList[i] = &SZoneResourceBase{rows[i].ZoneId}
|
||||
managerList[i] = &SManagedResourceBase{wires[wireIds[i]].ManagerId}
|
||||
}
|
||||
|
||||
vpcRows := manager.SVpcResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, vpcList, fields, isList)
|
||||
zoneRows := manager.SZoneResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, zoneList, fields, isList)
|
||||
managerRows := manager.SManagedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, managerList, fields, isList)
|
||||
|
||||
for i := range rows {
|
||||
rows[i].VpcResourceInfo = vpcRows[i]
|
||||
rows[i].Zone = zoneRows[i].Zone
|
||||
rows[i].ManagedResourceInfo = managerRows[i]
|
||||
}
|
||||
return rows
|
||||
}
|
||||
@@ -153,7 +165,6 @@ func (manager *SWireResourceBaseManager) ListItemFilter(
|
||||
userCred mcclient.TokenCredential,
|
||||
query api.WireFilterListInput,
|
||||
) (*sqlchemy.SQuery, error) {
|
||||
var err error
|
||||
if len(query.WireId) > 0 {
|
||||
wireObj, _, err := ValidateWireResourceInput(userCred, query.WireResourceInput)
|
||||
if err != nil {
|
||||
@@ -164,9 +175,20 @@ func (manager *SWireResourceBaseManager) ListItemFilter(
|
||||
|
||||
wireQ := WireManager.Query("id").Snapshot()
|
||||
|
||||
wireQ, err = manager.SVpcResourceBaseManager.ListItemFilter(ctx, wireQ, userCred, query.VpcFilterListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SVpcResourceBaseManager.ListItemFilter")
|
||||
{
|
||||
var err error
|
||||
mangedFilter := query.ManagedResourceListInput
|
||||
query.ManagedResourceListInput = api.ManagedResourceListInput{}
|
||||
wireQ, err = manager.SVpcResourceBaseManager.ListItemFilter(ctx, wireQ, userCred, query.VpcFilterListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SVpcResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
wireQ, err = manager.SManagedResourceBaseManager.ListItemFilter(ctx, wireQ, userCred, mangedFilter)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
// recover managed filter
|
||||
query.ManagedResourceListInput = mangedFilter
|
||||
}
|
||||
|
||||
if len(query.ZoneList()) > 0 {
|
||||
@@ -244,7 +266,7 @@ func (manager *SWireResourceBaseManager) OrderByExtraFields(
|
||||
}
|
||||
orderQ := WireManager.Query("id")
|
||||
orderSubQ := orderQ.SubQuery()
|
||||
orderQ, orders, fields := manager.GetOrderBySubQuery(orderQ, orderSubQ, orderQ.Field("id"), userCred, query, nil, nil)
|
||||
_, orders, fields := manager.GetOrderBySubQuery(orderQ, orderSubQ, orderQ.Field("id"), userCred, query, nil, nil)
|
||||
q = q.LeftJoin(orderSubQ, sqlchemy.Equals(q.Field("wire_id"), orderSubQ.Field("id")))
|
||||
q = db.OrderByFields(q, orders, fields)
|
||||
return q, nil
|
||||
@@ -323,8 +345,8 @@ func (manager *SWireResourceBaseManager) GetExportKeys() []string {
|
||||
return keys
|
||||
}
|
||||
|
||||
func (self *SWireResourceBase) GetChangeOwnerCandidateDomainIds() []string {
|
||||
wire, _ := self.GetWire()
|
||||
func (wireRes *SWireResourceBase) GetChangeOwnerCandidateDomainIds() []string {
|
||||
wire, _ := wireRes.GetWire()
|
||||
if wire != nil {
|
||||
return wire.GetChangeOwnerCandidateDomainIds()
|
||||
}
|
||||
|
||||
+143
-35
@@ -72,6 +72,8 @@ type SWire struct {
|
||||
db.SStatusInfrasResourceBase
|
||||
db.SExternalizedResourceBase
|
||||
|
||||
SManagedResourceBase
|
||||
|
||||
SVpcResourceBase `wdith:"36" charset:"ascii" nullable:"false" list:"domain" create:"domain_required" update:""`
|
||||
SZoneResourceBase `width:"36" charset:"ascii" nullable:"true" list:"domain" create:"domain_required" update:""`
|
||||
|
||||
@@ -204,14 +206,14 @@ func (manager *SWireManager) GetOrCreateWireForClassicNetwork(ctx context.Contex
|
||||
name = fmt.Sprintf("emulate for zone %s vpc %s classic network", zone.Name, vpc.Id)
|
||||
}
|
||||
_wire, err := db.FetchByExternalIdAndManagerId(manager, externalId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
sq := VpcManager.Query().SubQuery()
|
||||
return q.Join(sq, sqlchemy.Equals(sq.Field("id"), q.Field("vpc_id"))).Filter(sqlchemy.Equals(sq.Field("manager_id"), vpc.ManagerId))
|
||||
q = q.Equals("manager_id", vpc.ManagerId)
|
||||
return q
|
||||
})
|
||||
if err == nil {
|
||||
return _wire.(*SWire), nil
|
||||
}
|
||||
if errors.Cause(err) != sql.ErrNoRows {
|
||||
return nil, errors.Wrap(err, "db.FetchByExternalId")
|
||||
return nil, errors.Wrap(err, "db.FetchByExternalIdAndManagerId")
|
||||
}
|
||||
wire := &SWire{}
|
||||
wire.VpcId = vpc.Id
|
||||
@@ -220,6 +222,7 @@ func (manager *SWireManager) GetOrCreateWireForClassicNetwork(ctx context.Contex
|
||||
wire.ExternalId = externalId
|
||||
wire.IsEmulated = true
|
||||
wire.Name = name
|
||||
wire.ManagerId = vpc.ManagerId
|
||||
err = manager.TableSpec().Insert(ctx, wire)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Insert wire for classic network")
|
||||
@@ -376,6 +379,8 @@ func (swire *SWire) syncWithCloudWire(ctx context.Context, userCred mcclient.Tok
|
||||
swire.Description = extWire.GetDescription()
|
||||
}
|
||||
|
||||
swire.ManagerId = provider.Id
|
||||
|
||||
if zone != nil {
|
||||
swire.ZoneId = zone.Id
|
||||
} else {
|
||||
@@ -436,6 +441,7 @@ func (manager *SWireManager) newFromCloudWire(ctx context.Context, userCred mccl
|
||||
wire.Status = extWire.GetStatus()
|
||||
wire.Description = extWire.GetDescription()
|
||||
wire.VpcId = vpc.Id
|
||||
wire.ManagerId = provider.Id
|
||||
region, err := vpc.GetRegion()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "GetRegion for vpc %s(%s)", vpc.Name, vpc.Id)
|
||||
@@ -765,8 +771,8 @@ func filterWiresCountQuery(q *sqlchemy.SQuery, hostTypes, providers, brands []st
|
||||
if len(rangeObjs) > 0 || len(providers) > 0 || len(brands) > 0 || len(cloudEnv) > 0 {
|
||||
vpcs := VpcManager.Query().SubQuery()
|
||||
q = q.Join(vpcs, sqlchemy.Equals(q.Field("vpc_id"), vpcs.Field("id")))
|
||||
q = CloudProviderFilter(q, vpcs.Field("manager_id"), providers, brands, cloudEnv)
|
||||
q = RangeObjectsFilter(q, rangeObjs, vpcs.Field("cloudregion_id"), q.Field("zone_id"), vpcs.Field("manager_id"), nil, nil)
|
||||
q = CloudProviderFilter(q, q.Field("manager_id"), providers, brands, cloudEnv)
|
||||
q = RangeObjectsFilter(q, rangeObjs, vpcs.Field("cloudregion_id"), q.Field("zone_id"), q.Field("manager_id"), nil, nil)
|
||||
}
|
||||
|
||||
return q
|
||||
@@ -862,7 +868,12 @@ func (manager *SWireManager) TotalCount(
|
||||
}
|
||||
|
||||
func (swire *SWire) getNetworkQuery(userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, scope rbacscope.TRbacScope) *sqlchemy.SQuery {
|
||||
q := NetworkManager.Query().Equals("wire_id", swire.Id)
|
||||
additionalNicIds := NetworkAdditionalWireManager.networkIdQuery(swire.Id)
|
||||
q := NetworkManager.Query()
|
||||
q = q.Filter(sqlchemy.OR(
|
||||
sqlchemy.Equals(q.Field("wire_id"), swire.Id),
|
||||
sqlchemy.In(q.Field("id"), additionalNicIds.SubQuery()),
|
||||
))
|
||||
if ownerId != nil {
|
||||
q = NetworkManager.FilterByOwner(q, NetworkManager, userCred, ownerId, scope)
|
||||
}
|
||||
@@ -1044,15 +1055,37 @@ func chooseCandidateNetworksByNetworkType(nets []SNetwork, isExit bool, serverTy
|
||||
}
|
||||
|
||||
func (manager *SWireManager) InitializeData() error {
|
||||
wires := make([]SWire, 0)
|
||||
q := manager.Query()
|
||||
q.Filter(sqlchemy.OR(sqlchemy.IsEmpty(q.Field("vpc_id")), sqlchemy.IsEmpty(q.Field("status")), sqlchemy.Equals(q.Field("status"), "init"), sqlchemy.Equals(q.Field("status"), api.WIRE_STATUS_READY_DEPRECATED)))
|
||||
err := db.FetchModelObjects(manager, q, &wires)
|
||||
if err != nil {
|
||||
return err
|
||||
{
|
||||
err := manager.initVpcId()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "initVpcId")
|
||||
}
|
||||
}
|
||||
for _, w := range wires {
|
||||
db.Update(&w, func() error {
|
||||
{
|
||||
err := manager.initManagerId()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "initManagerId")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (manager *SWireManager) initVpcId() error {
|
||||
wires, err := manager.FetchWires(func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
q = q.Filter(sqlchemy.OR(
|
||||
sqlchemy.IsEmpty(q.Field("vpc_id")),
|
||||
sqlchemy.IsEmpty(q.Field("status")),
|
||||
sqlchemy.Equals(q.Field("status"), "init"),
|
||||
sqlchemy.Equals(q.Field("status"), api.WIRE_STATUS_READY_DEPRECATED),
|
||||
))
|
||||
return q
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "FetchWires")
|
||||
}
|
||||
for i := range wires {
|
||||
w := wires[i]
|
||||
_, err := db.Update(&w, func() error {
|
||||
if len(w.VpcId) == 0 {
|
||||
w.VpcId = api.DEFAULT_VPC_ID
|
||||
}
|
||||
@@ -1061,10 +1094,55 @@ func (manager *SWireManager) InitializeData() error {
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Update")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (manager *SWireManager) initManagerId() error {
|
||||
wires, err := manager.FetchWires(func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
vpcs := VpcManager.Query().SubQuery()
|
||||
q = q.Join(vpcs, sqlchemy.Equals(q.Field("vpc_id"), vpcs.Field("id")))
|
||||
q = q.Filter(sqlchemy.OR(
|
||||
sqlchemy.IsNull(q.Field("manager_id")),
|
||||
sqlchemy.NotEquals(q.Field("manager_id"), vpcs.Field("manager_id")),
|
||||
))
|
||||
q = q.IsNullOrEmpty("manager_id")
|
||||
return q
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "FetchWires")
|
||||
}
|
||||
for i := range wires {
|
||||
w := wires[i]
|
||||
vpc, err := w.GetVpc()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "GetVpc")
|
||||
}
|
||||
_, err = db.Update(&w, func() error {
|
||||
w.ManagerId = vpc.ManagerId
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Update")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (manager *SWireManager) FetchWires(filter func(q *sqlchemy.SQuery) *sqlchemy.SQuery) ([]SWire, error) {
|
||||
wires := make([]SWire, 0)
|
||||
q := manager.Query()
|
||||
q = filter(q)
|
||||
err := db.FetchModelObjects(manager, q, &wires)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "FetchModelObjects")
|
||||
}
|
||||
return wires, nil
|
||||
}
|
||||
|
||||
func (wire *SWire) isOneCloudVpcWire() bool {
|
||||
return IsOneCloudVpcResource(wire)
|
||||
}
|
||||
@@ -1129,17 +1207,12 @@ func (manager *SWireManager) FetchWireById(wireId string) *SWire {
|
||||
}
|
||||
|
||||
func (manager *SWireManager) FetchWireByExternalId(managerId, extId string) (*SWire, error) {
|
||||
vpcsQ := VpcManager.Query("id")
|
||||
vpcsQ = vpcsQ.Filter(sqlchemy.OR(
|
||||
sqlchemy.Equals(vpcsQ.Field("manager_id"), managerId),
|
||||
sqlchemy.Equals(vpcsQ.Field("id"), api.DEFAULT_VPC_ID),
|
||||
))
|
||||
vpcs := vpcsQ.SubQuery()
|
||||
q := manager.Query().In("vpc_id", vpcs).Equals("external_id", extId)
|
||||
wires := make([]SWire, 0)
|
||||
err := db.FetchModelObjects(manager, q, &wires)
|
||||
wires, err := manager.FetchWires(func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
q = q.Equals("manager_id", managerId).Equals("external_id", extId)
|
||||
return q
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "FetchModelObjects")
|
||||
return nil, errors.Wrap(err, "FetchWires")
|
||||
}
|
||||
switch len(wires) {
|
||||
case 0:
|
||||
@@ -1338,9 +1411,18 @@ func (manager *SWireManager) ListItemFilter(
|
||||
) (*sqlchemy.SQuery, error) {
|
||||
var err error
|
||||
|
||||
q, err = manager.SVpcResourceBaseManager.ListItemFilter(ctx, q, userCred, query.VpcFilterListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SVpcResourceBaseManager.ListItemFilter")
|
||||
{
|
||||
managedFilter := query.ManagedResourceListInput
|
||||
query.ManagedResourceListInput = api.ManagedResourceListInput{}
|
||||
q, err = manager.SVpcResourceBaseManager.ListItemFilter(ctx, q, userCred, query.VpcFilterListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SVpcResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
q, err = manager.SManagedResourceBaseManager.ListItemFilter(ctx, q, userCred, managedFilter)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
query.ManagedResourceListInput = managedFilter
|
||||
}
|
||||
|
||||
q, err = manager.SExternalizedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ExternalizedResourceBaseListInput)
|
||||
@@ -1505,6 +1587,8 @@ func (manager *SWireManager) FetchCustomizeColumns(
|
||||
stdRows := manager.SStatusInfrasResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
|
||||
vpcRows := manager.SVpcResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
|
||||
zoneRows := manager.SZoneResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
|
||||
|
||||
managerList := make([]interface{}, len(rows))
|
||||
wireIds := make([]string, len(objs))
|
||||
for i := range rows {
|
||||
rows[i] = api.WireDetails{
|
||||
@@ -1514,26 +1598,30 @@ func (manager *SWireManager) FetchCustomizeColumns(
|
||||
}
|
||||
wire := objs[i].(*SWire)
|
||||
wireIds[i] = wire.Id
|
||||
managerList[i] = &SManagedResourceBase{wire.ManagerId}
|
||||
}
|
||||
|
||||
managerRows := manager.SManagedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, managerList, fields, isList)
|
||||
usage, err := manager.TotalResourceCount(wireIds)
|
||||
if err != nil {
|
||||
log.Errorf("TotalResourceCount error: %v", err)
|
||||
return rows
|
||||
}
|
||||
for i := range rows {
|
||||
rows[i].WireUsage, _ = usage[wireIds[i]]
|
||||
rows[i].WireUsage = usage[wireIds[i]]
|
||||
rows[i].ManagedResourceInfo = managerRows[i]
|
||||
}
|
||||
|
||||
return rows
|
||||
}
|
||||
|
||||
func (man *SWireManager) removeWiresByVpc(ctx context.Context, userCred mcclient.TokenCredential, vpc *SVpc) error {
|
||||
wires := []SWire{}
|
||||
q := man.Query().Equals("vpc_id", vpc.Id)
|
||||
err := db.FetchModelObjects(man, q, &wires)
|
||||
wires, err := man.FetchWires(func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
q = q.Equals("vpc_id", vpc.Id)
|
||||
return q
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrap(err, "FetchWires")
|
||||
}
|
||||
var errs []error
|
||||
for i := range wires {
|
||||
@@ -1545,17 +1633,17 @@ func (man *SWireManager) removeWiresByVpc(ctx context.Context, userCred mcclient
|
||||
return errors.NewAggregate(errs)
|
||||
}
|
||||
|
||||
func (swire *SWire) IsManaged() bool {
|
||||
/*func (swire *SWire) IsManaged() bool {
|
||||
vpc, _ := swire.GetVpc()
|
||||
if vpc == nil {
|
||||
return false
|
||||
}
|
||||
return vpc.IsManaged()
|
||||
}
|
||||
}*/
|
||||
|
||||
func (model *SWire) CustomizeCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
|
||||
vpc, _ := model.GetVpc()
|
||||
if !data.Contains("public_scope") {
|
||||
vpc, _ := model.GetVpc()
|
||||
if !model.IsManaged() && db.IsAdminAllowPerform(ctx, userCred, model, "public") && ownerId.GetProjectDomainId() == userCred.GetProjectDomainId() && vpc != nil && vpc.IsPublic && vpc.PublicScope == string(rbacscope.ScopeSystem) {
|
||||
model.SetShare(rbacscope.ScopeSystem)
|
||||
} else {
|
||||
@@ -1564,6 +1652,7 @@ func (model *SWire) CustomizeCreate(ctx context.Context, userCred mcclient.Token
|
||||
data.(*jsonutils.JSONDict).Set("public_scope", jsonutils.NewString(model.PublicScope))
|
||||
}
|
||||
model.Status = api.WIRE_STATUS_AVAILABLE
|
||||
model.ManagerId = vpc.ManagerId
|
||||
return model.SInfrasResourceBase.CustomizeCreate(ctx, userCred, ownerId, query, data)
|
||||
}
|
||||
|
||||
@@ -1714,3 +1803,22 @@ func (swire *SWire) GetDetailsTopology(ctx context.Context, userCred mcclient.To
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (wire *SWire) GetCloudproviderId() string {
|
||||
return wire.SManagedResourceBase.GetCloudproviderId()
|
||||
}
|
||||
|
||||
func (wire *SWire) GetCloudprovider() *SCloudprovider {
|
||||
return wire.SManagedResourceBase.GetCloudprovider()
|
||||
}
|
||||
|
||||
func (wire *SWire) GetProviderName() string {
|
||||
return wire.SManagedResourceBase.GetProviderName()
|
||||
}
|
||||
|
||||
func (wire *SWire) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
if err := NetworkAdditionalWireManager.DeleteWire(ctx, wire.Id); err != nil {
|
||||
return errors.Wrap(err, "NetworkAdditionalWireManager.DeleteWire")
|
||||
}
|
||||
return wire.SStatusInfrasResourceBase.Delete(ctx, userCred)
|
||||
}
|
||||
|
||||
@@ -66,6 +66,7 @@ func InitHandlers(app *appsrv.Application) {
|
||||
models.GuestcdromManager,
|
||||
models.GuestFloppyManager,
|
||||
models.NetInterfaceManager,
|
||||
models.NetworkAdditionalWireManager,
|
||||
|
||||
models.QuotaManager,
|
||||
models.QuotaUsageManager,
|
||||
|
||||
@@ -230,3 +230,17 @@ func (opts *NetworkSwitchWireOptions) GetId() string {
|
||||
func (opts *NetworkSwitchWireOptions) Params() (jsonutils.JSONObject, error) {
|
||||
return jsonutils.Marshal(opts), nil
|
||||
}
|
||||
|
||||
type NetworkSyncAdditionalWiresOptions struct {
|
||||
ID string `help:"ID or Name of resource to update"`
|
||||
|
||||
api.NetworSyncAdditionalWiresInput
|
||||
}
|
||||
|
||||
func (opts *NetworkSyncAdditionalWiresOptions) GetId() string {
|
||||
return opts.ID
|
||||
}
|
||||
|
||||
func (opts *NetworkSyncAdditionalWiresOptions) Params() (jsonutils.JSONObject, error) {
|
||||
return jsonutils.Marshal(opts), nil
|
||||
}
|
||||
|
||||
+6
-1
@@ -634,7 +634,12 @@ func (b *BaseHostDesc) fillNetworks(host *computemodels.SHost, netGetter *networ
|
||||
nets := make([]computemodels.SNetwork, 0)
|
||||
allNets := network.Manager.GetStore().GetAll()
|
||||
for _, net := range allNets {
|
||||
if wireIds.Has(net.WireId) {
|
||||
netAdditionalWireIds, err := computemodels.NetworkAdditionalWireManager.FetchNetworkAdditionalWireIds(net.Id)
|
||||
if err != nil {
|
||||
log.Errorf("NetworkAdditionalWireManager.FetchNetworkAdditionalWireIds %s error %s", net.Id, err)
|
||||
netAdditionalWireIds = []string{}
|
||||
}
|
||||
if wireIds.Has(net.WireId) || wireIds.HasAny(netAdditionalWireIds...) {
|
||||
nets = append(nets, net)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
// 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 netutils2
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/pkg/errors"
|
||||
)
|
||||
|
||||
func ExpandCompactIps(ipstr string) ([]string, error) {
|
||||
ips := make([]string, 0)
|
||||
ipSegs := strings.Split(strings.TrimSpace(ipstr), ";")
|
||||
for _, ipSeg := range ipSegs {
|
||||
parts := strings.Split(ipSeg, ".")
|
||||
if len(parts) <= 3 {
|
||||
return nil, errors.Wrap(errors.ErrInvalidFormat, ipSeg)
|
||||
}
|
||||
hosts := strings.Split(parts[3], ",")
|
||||
for _, host := range hosts {
|
||||
if strings.Index(host, "-") > 0 {
|
||||
subhosts := strings.Split(host, "-")
|
||||
if len(subhosts) != 2 {
|
||||
return nil, errors.Wrap(errors.ErrInvalidFormat, ipSeg)
|
||||
}
|
||||
start, err := strconv.Atoi(subhosts[0])
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(errors.ErrInvalidFormat, ipSeg)
|
||||
}
|
||||
end, err := strconv.Atoi(subhosts[1])
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(errors.ErrInvalidFormat, ipSeg)
|
||||
}
|
||||
for i := start; i <= end; i++ {
|
||||
ips = append(ips, fmt.Sprintf("%s.%s.%s.%d", parts[0], parts[1], parts[2], i))
|
||||
}
|
||||
} else {
|
||||
ips = append(ips, fmt.Sprintf("%s.%s.%s.%s", parts[0], parts[1], parts[2], host))
|
||||
}
|
||||
}
|
||||
}
|
||||
return ips, nil
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
// 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 netutils2
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestExpandCompactIpds(t *testing.T) {
|
||||
cases := []struct {
|
||||
in string
|
||||
want []string
|
||||
}{
|
||||
{
|
||||
in: "192.168.100.2",
|
||||
want: []string{
|
||||
"192.168.100.2",
|
||||
},
|
||||
},
|
||||
{
|
||||
in: "192.168.100.2,9,10;10.168.200.1",
|
||||
want: []string{
|
||||
"192.168.100.2",
|
||||
"192.168.100.9",
|
||||
"192.168.100.10",
|
||||
"10.168.200.1",
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
out, err := ExpandCompactIps(c.in)
|
||||
if err != nil {
|
||||
t.Errorf("expand %s error %s", c.in, err)
|
||||
} else {
|
||||
if !reflect.DeepEqual(c.want, out) {
|
||||
t.Errorf("expand %s want %s got %s", c.in, c.want, out)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,7 +40,7 @@ func getIfaceIPs(iface *net.Interface) ([]net.IP, error) {
|
||||
func WaitIfaceIps(ifname string) (*net.Interface, []net.IP, error) {
|
||||
iface, err := net.InterfaceByName(ifname)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "net.InterfaceByName")
|
||||
return nil, nil, errors.Wrapf(err, "net.InterfaceByName %s", ifname)
|
||||
}
|
||||
var ips []net.IP
|
||||
MAX := 60
|
||||
|
||||
Reference in New Issue
Block a user