mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-10-29 17:58:36 +08:00
feature: support host-local wire (#24490)
Co-authored-by: Qiu Jian <qiujian@yunionyun.com>
This commit is contained in:
@@ -15,8 +15,9 @@
|
||||
package compute
|
||||
|
||||
const (
|
||||
HostVpcBridge = "__vpc_bridge__"
|
||||
HostTapBridge = "__tap_bridge__"
|
||||
HostVpcBridge = "__vpc_bridge__"
|
||||
HostTapBridge = "__tap_bridge__"
|
||||
HostLocalBridge = "brlocal"
|
||||
)
|
||||
|
||||
type SMirrorConfig struct {
|
||||
|
||||
@@ -21,4 +21,7 @@ const (
|
||||
WIRE_STATUS_READY_DEPRECATED = "ready"
|
||||
WIRE_STATUS_MERGE_NETWORK = "merge_network"
|
||||
WIRE_STATUS_MERGE_NETWORK_FAILED = "merge_network_failed"
|
||||
|
||||
DEFAULT_HOST_LOCAL_WIRE_NAME = "hostlocal"
|
||||
DEFAULT_HOST_LOCAL_WIRE_ID = "__host_local__"
|
||||
)
|
||||
|
||||
@@ -1032,22 +1032,25 @@ func getNetworkCountByFilter(ctx context.Context, userCred mcclient.TokenCredent
|
||||
|
||||
q := networks.Query()
|
||||
|
||||
if zone != nil && !utils.IsInStringArray(region.Provider, api.REGIONAL_NETWORK_PROVIDERS) {
|
||||
wires := WireManager.Query("id").Equals("zone_id", zone.Id)
|
||||
q = q.In("wire_id", wires.SubQuery())
|
||||
} else if region != nil {
|
||||
if utils.IsInStringArray(region.Provider, api.REGIONAL_NETWORK_PROVIDERS) {
|
||||
wires := WireManager.Query().SubQuery()
|
||||
vpcs := VpcManager.Query().SubQuery()
|
||||
subq := wires.Query(wires.Field("id")).
|
||||
Join(vpcs, sqlchemy.Equals(wires.Field("vpc_id"), vpcs.Field("id"))).
|
||||
Filter(sqlchemy.Equals(vpcs.Field("cloudregion_id"), region.Id))
|
||||
q = q.Filter(sqlchemy.In(q.Field("wire_id"), subq))
|
||||
if zone != nil || region != nil {
|
||||
wires := WireManager.Query("id")
|
||||
var zoneFilter sqlchemy.ICondition
|
||||
if zone != nil {
|
||||
zoneFilter = sqlchemy.Equals(wires.Field("zone_id"), zone.Id)
|
||||
} else {
|
||||
subq := getRegionZoneSubq(region)
|
||||
wires := WireManager.Query("id").In("zone_id", subq)
|
||||
q = q.In("wire_id", wires.SubQuery())
|
||||
zoneFilter = sqlchemy.In(wires.Field("zone_id"), subq)
|
||||
}
|
||||
vpcs := VpcManager.Query().SubQuery()
|
||||
wires = wires.Join(vpcs, sqlchemy.Equals(wires.Field("vpc_id"), vpcs.Field("id")))
|
||||
wires = wires.Filter(sqlchemy.OR(
|
||||
zoneFilter,
|
||||
sqlchemy.AND(
|
||||
sqlchemy.IsNullOrEmpty(wires.Field("zone_id")),
|
||||
sqlchemy.Equals(vpcs.Field("cloudregion_id"), region.Id),
|
||||
),
|
||||
))
|
||||
q = q.In("wire_id", wires.SubQuery())
|
||||
}
|
||||
|
||||
q = NetworkManager.FilterByOwner(ctx, q, NetworkManager, userCred, ownerId, scope)
|
||||
|
||||
@@ -580,8 +580,13 @@ func (gn *SGuestnetwork) getJsonDescAtHost(ctx context.Context, host *SHost) *ap
|
||||
network, _ = gn.GetNetwork()
|
||||
)
|
||||
if network.isOneCloudVpcNetwork() {
|
||||
// onecloud vpc nic
|
||||
ret = gn.getJsonDescOneCloudVpc(network)
|
||||
} else if network.WireId == api.DEFAULT_HOST_LOCAL_WIRE_ID {
|
||||
// host local nic
|
||||
ret = gn.getJsonDescHostLocal(network)
|
||||
} else {
|
||||
// classic nic
|
||||
netifs := host.getNetifsOnWire(network.WireId)
|
||||
var netif *SNetInterface
|
||||
for i := range netifs {
|
||||
@@ -659,6 +664,13 @@ func (gn *SGuestnetwork) getJsonDescOneCloudVpc(network *SNetwork) *api.Guestnet
|
||||
return desc
|
||||
}
|
||||
|
||||
func (gn *SGuestnetwork) getJsonDescHostLocal(network *SNetwork) *api.GuestnetworkJsonDesc {
|
||||
desc := gn.getJsonDesc()
|
||||
desc.Bridge = api.HostLocalBridge
|
||||
desc.WireId = api.DEFAULT_HOST_LOCAL_WIRE_ID
|
||||
return desc
|
||||
}
|
||||
|
||||
func (gn *SGuestnetwork) getJsonDesc() *api.GuestnetworkJsonDesc {
|
||||
net, _ := gn.GetNetwork()
|
||||
var wire *SWire
|
||||
|
||||
@@ -52,6 +52,7 @@ import (
|
||||
baremetalapi "yunion.io/x/onecloud/pkg/apis/baremetal"
|
||||
billing_api "yunion.io/x/onecloud/pkg/apis/billing"
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
computeapi "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
hostapi "yunion.io/x/onecloud/pkg/apis/host"
|
||||
napi "yunion.io/x/onecloud/pkg/apis/notify"
|
||||
"yunion.io/x/onecloud/pkg/appsrv"
|
||||
@@ -3335,7 +3336,7 @@ func (hh *SHost) GetNetinterfacesWithIdAndCredential(netId string, userCred mccl
|
||||
}
|
||||
|
||||
func (hh *SHost) GetNetworkWithId(netId string, reserved bool) (*SNetwork, error) {
|
||||
var q1, q2, q3 *sqlchemy.SQuery
|
||||
var q1, q2, q3, q4 *sqlchemy.SQuery
|
||||
{
|
||||
// classic network
|
||||
networks := NetworkManager.Query()
|
||||
@@ -3384,8 +3385,34 @@ func (hh *SHost) GetNetworkWithId(netId string, reserved bool) (*SNetwork, error
|
||||
q3 = q3.Filter(sqlchemy.Equals(networks.Field("id"), netId))
|
||||
q3 = q3.Filter(sqlchemy.Equals(hosts.Field("id"), hh.Id))
|
||||
}
|
||||
{
|
||||
// host local network
|
||||
networks := NetworkManager.Query()
|
||||
wires := WireManager.Query().SubQuery()
|
||||
vpcs := VpcManager.Query().SubQuery()
|
||||
regions := CloudregionManager.Query().SubQuery()
|
||||
q4 = networks
|
||||
q4 = q4.Join(wires, sqlchemy.Equals(wires.Field("id"), networks.Field("wire_id")))
|
||||
q4 = q4.Join(vpcs, sqlchemy.Equals(vpcs.Field("id"), wires.Field("vpc_id")))
|
||||
q4 = q4.Join(regions, sqlchemy.Equals(regions.Field("id"), vpcs.Field("cloudregion_id")))
|
||||
q4 = q4.Filter(sqlchemy.Equals(networks.Field("id"), netId))
|
||||
q4 = q4.Filter(
|
||||
sqlchemy.OR(
|
||||
sqlchemy.AND(
|
||||
sqlchemy.Equals(regions.Field("provider"), api.CLOUD_PROVIDER_ONECLOUD),
|
||||
sqlchemy.Equals(vpcs.Field("id"), api.DEFAULT_VPC_ID),
|
||||
sqlchemy.Equals(wires.Field("id"), computeapi.DEFAULT_HOST_LOCAL_WIRE_ID),
|
||||
),
|
||||
sqlchemy.AND(
|
||||
sqlchemy.Equals(regions.Field("provider"), api.CLOUD_PROVIDER_CLOUDPODS),
|
||||
sqlchemy.Equals(vpcs.Field("external_id"), api.DEFAULT_VPC_ID),
|
||||
sqlchemy.Equals(wires.Field("external_id"), computeapi.DEFAULT_HOST_LOCAL_WIRE_ID),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
q := sqlchemy.Union(q1, q2, q3).Query().Distinct()
|
||||
q := sqlchemy.Union(q1, q2, q3, q4).Query().Distinct()
|
||||
|
||||
net := SNetwork{}
|
||||
net.SetModelManager(NetworkManager, &net)
|
||||
|
||||
@@ -18,7 +18,6 @@ import (
|
||||
"time"
|
||||
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/proxy"
|
||||
@@ -87,7 +86,7 @@ func InitDB() error {
|
||||
now := time.Now()
|
||||
err := manager.InitializeData()
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "%s initializeData", manager.Keyword())
|
||||
log.Errorf("%s initializeData fail %s", manager.Keyword(), err)
|
||||
}
|
||||
if cost := time.Now().Sub(now); cost > time.Duration(time.Second)*15 {
|
||||
log.Infof("%s initializeData cost %s", manager.Keyword(), cost.Round(time.Second))
|
||||
|
||||
@@ -1856,6 +1856,11 @@ func (manager *SNetworkManager) ValidateCreateData(ctx context.Context, userCred
|
||||
} else {
|
||||
return input, httperrors.NewInputParameterError("zone and vpc info required when wire is absent")
|
||||
}
|
||||
{
|
||||
if wire.Id == api.DEFAULT_HOST_LOCAL_WIRE_ID {
|
||||
input.ServerType = api.NETWORK_TYPE_HOSTLOCAL
|
||||
}
|
||||
}
|
||||
|
||||
input.WireId = wire.Id
|
||||
if vpc.Status != api.VPC_STATUS_AVAILABLE {
|
||||
@@ -1864,11 +1869,11 @@ 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 = ""
|
||||
}
|
||||
// if input.ServerType != api.NETWORK_TYPE_EIP {
|
||||
// input.BgpType = ""
|
||||
// }
|
||||
// check class metadata
|
||||
if wire != nil {
|
||||
{ // wire != nil
|
||||
var projectId string
|
||||
if len(input.ProjectId) > 0 {
|
||||
projectId = input.ProjectId
|
||||
@@ -1986,6 +1991,9 @@ func (manager *SNetworkManager) ValidateCreateData(ctx context.Context, userCred
|
||||
if ipEnd.NetAddr(masklen) != netAddr {
|
||||
return input, httperrors.NewInputParameterError("start and end ip not in the same subnet")
|
||||
}
|
||||
if wire.Id == api.DEFAULT_HOST_LOCAL_WIRE_ID && len(input.GuestGateway) == 0 {
|
||||
return input, httperrors.NewInputParameterError("host local wire only support gateway ip")
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -2045,6 +2053,9 @@ func (manager *SNetworkManager) ValidateCreateData(ctx context.Context, userCred
|
||||
if !ip6End.NetAddr(masklen6).Equals(netAddr6) {
|
||||
return input, httperrors.NewInputParameterError("v6 start and end ip not in the same subnet")
|
||||
}
|
||||
if wire.Id == api.DEFAULT_HOST_LOCAL_WIRE_ID && len(input.GuestGateway6) == 0 {
|
||||
return input, httperrors.NewInputParameterError("host local wire only support gateway v6 ip")
|
||||
}
|
||||
}
|
||||
|
||||
if ipRange == nil && ipRange6 == nil {
|
||||
@@ -2225,6 +2236,10 @@ func (snet *SNetwork) validateUpdateData(ctx context.Context, userCred mcclient.
|
||||
if endIp.NetAddr(masklen) != netAddr {
|
||||
return input, httperrors.NewInputParameterError("start, end ip must be in the same subnet")
|
||||
}
|
||||
|
||||
if snet.WireId == api.DEFAULT_HOST_LOCAL_WIRE_ID && input.GuestGateway != nil && len(*input.GuestGateway) == 0 {
|
||||
return input, httperrors.NewInputParameterError("host local wire only support gateway ip")
|
||||
}
|
||||
} else {
|
||||
startIp, _ := netutils.NewIPV4Addr(snet.GuestIpStart)
|
||||
netAddr = startIp.NetAddr(masklen)
|
||||
@@ -2287,6 +2302,9 @@ func (snet *SNetwork) validateUpdateData(ctx context.Context, userCred mcclient.
|
||||
if !netRange.EndIp().NetAddr(masklen6).Equals(netAddr6) {
|
||||
return input, httperrors.NewInputParameterError("start, end v6 ip must be in the same subnet")
|
||||
}
|
||||
if snet.WireId == api.DEFAULT_HOST_LOCAL_WIRE_ID && input.GuestGateway6 != nil && len(*input.GuestGateway6) == 0 {
|
||||
return input, httperrors.NewInputParameterError("host local wire only support gateway ip")
|
||||
}
|
||||
} else if len(snet.GuestIp6Start) > 0 {
|
||||
startIp, _ := netutils.NewIPV6Addr(snet.GuestIp6Start)
|
||||
netAddr6 = startIp.NetAddr(masklen6)
|
||||
@@ -2346,8 +2364,13 @@ func (snet *SNetwork) validateUpdateData(ctx context.Context, userCred mcclient.
|
||||
}
|
||||
}
|
||||
|
||||
if len(input.ServerType) > 0 && !api.IsInNetworkTypes(input.ServerType, api.ALL_NETWORK_TYPES) {
|
||||
return input, errors.Wrapf(httperrors.ErrInputParameter, "invalid server_type %q", input.ServerType)
|
||||
if len(input.ServerType) > 0 {
|
||||
if !api.IsInNetworkTypes(input.ServerType, api.ALL_NETWORK_TYPES) {
|
||||
return input, errors.Wrapf(httperrors.ErrInputParameter, "invalid server_type %q", input.ServerType)
|
||||
}
|
||||
if snet.WireId == api.DEFAULT_HOST_LOCAL_WIRE_ID && input.ServerType != api.NETWORK_TYPE_HOSTLOCAL {
|
||||
return input, httperrors.NewInputParameterError("host local wire only support hostlocal server_type")
|
||||
}
|
||||
}
|
||||
|
||||
return input, nil
|
||||
@@ -2706,28 +2729,42 @@ func (manager *SNetworkManager) ListItemFilter(
|
||||
hostsQ := hosts.SubQuery()
|
||||
classicWiresIdQ = classicWiresIdQ.Join(hostsQ, sqlchemy.Equals(netifs.Field("baremetal_id"), hostsQ.Field("id")))
|
||||
|
||||
wireIdQ := classicWiresIdQ.SubQuery()
|
||||
wireIdQueries := []sqlchemy.IQuery{
|
||||
classicWiresIdQ,
|
||||
}
|
||||
|
||||
if input.HostType == api.HOST_TYPE_HYPERVISOR {
|
||||
// should consider VPC network
|
||||
vpcHostQ := HostManager.Query().IsNotEmpty("ovn_version")
|
||||
if len(input.HostType) > 0 {
|
||||
vpcHostQ = vpcHostQ.Equals("host_type", input.HostType)
|
||||
}
|
||||
if input.HostType == api.HOST_TYPE_HYPERVISOR || input.HostType == api.HOST_TYPE_CONTAINER {
|
||||
vpcHostQ := HostManager.Query().Equals("host_type", input.HostType)
|
||||
if len(input.HostId) > 0 {
|
||||
vpcHostQ = vpcHostQ.In("id", input.HostId)
|
||||
}
|
||||
hostCnt, err := vpcHostQ.CountWithError()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "vpcHostQ.CountWithError")
|
||||
}
|
||||
if hostCnt > 0 {
|
||||
// should consider host local wire
|
||||
hostLocalWireQ := WireManager.Query("id").Equals("id", api.DEFAULT_HOST_LOCAL_WIRE_ID)
|
||||
wireIdQueries = append(wireIdQueries, hostLocalWireQ)
|
||||
}
|
||||
vpcHostQ = vpcHostQ.IsNotEmpty("ovn_version")
|
||||
vpcHostCnt, err := vpcHostQ.CountWithError()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "vpcHostQ.CountWithError")
|
||||
}
|
||||
if vpcHostCnt > 0 {
|
||||
// should consider VPC network wire
|
||||
vpcWiresIdQ := WireManager.Query("id").NotEquals("vpc_id", api.DEFAULT_VPC_ID)
|
||||
|
||||
wireIdUnion := sqlchemy.Union(classicWiresIdQ, vpcWiresIdQ)
|
||||
wireIdQ = wireIdUnion.Query().SubQuery()
|
||||
wireIdQueries = append(wireIdQueries, vpcWiresIdQ)
|
||||
}
|
||||
}
|
||||
var wireIdQ *sqlchemy.SSubQuery
|
||||
if len(wireIdQueries) > 1 {
|
||||
wireIdQ = sqlchemy.Union(wireIdQueries...).Query().SubQuery()
|
||||
} else {
|
||||
wireIdQ = classicWiresIdQ.SubQuery()
|
||||
}
|
||||
|
||||
additionalQ := NetworkAdditionalWireManager.Query("network_id")
|
||||
additionalQ = additionalQ.Join(wireIdQ, sqlchemy.Equals(wireIdQ.Field("id"), additionalQ.Field("wire_id")))
|
||||
q = q.Filter(sqlchemy.OR(
|
||||
|
||||
@@ -35,6 +35,7 @@ import (
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
identityapi "yunion.io/x/onecloud/pkg/apis/identity"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/consts"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
|
||||
@@ -813,6 +814,7 @@ func (manager *SVpcManager) InitializeData() error {
|
||||
defVpc.IsDefault = true
|
||||
defVpc.IsPublic = true
|
||||
defVpc.PublicScope = string(rbacscope.ScopeSystem)
|
||||
defVpc.DomainId = identityapi.DEFAULT_DOMAIN_ID
|
||||
err = manager.TableSpec().Insert(context.TODO(), &defVpc)
|
||||
if err != nil {
|
||||
log.Errorf("Insert default vpc fail: %s", err)
|
||||
|
||||
@@ -22,7 +22,6 @@ import (
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/reflectutils"
|
||||
"yunion.io/x/pkg/utils"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
@@ -192,7 +191,7 @@ func (manager *SWireResourceBaseManager) ListItemFilter(
|
||||
}
|
||||
|
||||
if len(query.ZoneList()) > 0 {
|
||||
region := &SCloudregion{}
|
||||
/* region := &SCloudregion{}
|
||||
firstZone := query.FirstZone()
|
||||
sq := ZoneManager.Query().SubQuery()
|
||||
regionQ := CloudregionManager.Query()
|
||||
@@ -210,8 +209,23 @@ func (manager *SWireResourceBaseManager) ListItemFilter(
|
||||
err = regionQ.First(region)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "regionQ.First")
|
||||
} */
|
||||
var err error
|
||||
zoneQuery := api.ZonalFilterListInput{
|
||||
ZonalFilterListBase: query.ZonalFilterListBase,
|
||||
}
|
||||
if utils.IsInStringArray(region.Provider, api.REGIONAL_NETWORK_PROVIDERS) {
|
||||
wireZoneQ := WireManager.Query("zone_id").Snapshot()
|
||||
wireZoneQ, err = manager.SZoneResourceBaseManager.ListItemFilter(ctx, wireZoneQ, userCred, zoneQuery)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SZoneResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
if wireZoneQ.IsAltered() {
|
||||
wireQ = wireQ.Filter(sqlchemy.OR(
|
||||
sqlchemy.IsNullOrEmpty(wireQ.Field("zone_id")),
|
||||
sqlchemy.In(wireQ.Field("zone_id"), wireZoneQ.SubQuery()),
|
||||
))
|
||||
}
|
||||
/*if utils.IsInStringArray(region.Provider, api.REGIONAL_NETWORK_PROVIDERS) {
|
||||
vpcQ := VpcManager.Query().SubQuery()
|
||||
wireQ = wireQ.Join(vpcQ, sqlchemy.Equals(vpcQ.Field("id"), wireQ.Field("vpc_id"))).
|
||||
Filter(sqlchemy.Equals(vpcQ.Field("cloudregion_id"), region.Id))
|
||||
@@ -223,7 +237,7 @@ func (manager *SWireResourceBaseManager) ListItemFilter(
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SZoneResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
if wireQ.IsAltered() {
|
||||
|
||||
@@ -34,6 +34,7 @@ import (
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
identityapi "yunion.io/x/onecloud/pkg/apis/identity"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
@@ -168,6 +169,9 @@ func (wire *SWire) ValidateUpdateData(ctx context.Context, userCred mcclient.Tok
|
||||
}
|
||||
|
||||
func (wire *SWire) ValidateDeleteCondition(ctx context.Context, info *api.WireDetails) error {
|
||||
if wire.Id == api.DEFAULT_HOST_LOCAL_WIRE_ID {
|
||||
return httperrors.NewProtectedResourceError("not allow to delete default host local wire")
|
||||
}
|
||||
if gotypes.IsNil(info) {
|
||||
info = &api.WireDetails{}
|
||||
usage, err := WireManager.TotalResourceCount([]string{wire.Id})
|
||||
@@ -1154,6 +1158,12 @@ func chooseCandidateNetworksByNetworkType(nets []SNetwork, isExit bool, serverTy
|
||||
}
|
||||
|
||||
func (manager *SWireManager) InitializeData() error {
|
||||
{
|
||||
err := manager.initHostLocalWire()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "initHostLocalWire")
|
||||
}
|
||||
}
|
||||
{
|
||||
err := manager.initVpcId()
|
||||
if err != nil {
|
||||
@@ -1966,3 +1976,36 @@ func (wire *SWire) Delete(ctx context.Context, userCred mcclient.TokenCredential
|
||||
}
|
||||
return wire.SStatusInfrasResourceBase.Delete(ctx, userCred)
|
||||
}
|
||||
|
||||
func (manager *SWireManager) initHostLocalWire() error {
|
||||
if _, err := manager.FetchById(api.DEFAULT_HOST_LOCAL_WIRE_ID); err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
defWire := SWire{}
|
||||
defWire.SetModelManager(WireManager, &defWire)
|
||||
|
||||
defWire.Id = api.DEFAULT_HOST_LOCAL_WIRE_ID
|
||||
defWire.Name = api.DEFAULT_HOST_LOCAL_WIRE_NAME
|
||||
defWire.VpcId = api.DEFAULT_VPC_ID
|
||||
defWire.ZoneId = "" // host local wire is not associated with a zone
|
||||
defWire.ManagerId = "" // host local wire is not associated with a manager
|
||||
defWire.IsEmulated = false
|
||||
defWire.ExternalId = "" // host local wire is not associated with an external id
|
||||
defWire.IsPublic = true
|
||||
defWire.PublicScope = string(rbacscope.ScopeSystem)
|
||||
defWire.Status = api.WIRE_STATUS_AVAILABLE
|
||||
defWire.Description = "Host local wire"
|
||||
defWire.Bandwidth = 10000
|
||||
defWire.Mtu = 1500
|
||||
defWire.ScheduleRank = 0
|
||||
defWire.DomainId = identityapi.DEFAULT_DOMAIN_ID
|
||||
err = manager.TableSpec().Insert(context.TODO(), &defWire)
|
||||
if err != nil {
|
||||
log.Errorf("Insert default host local wire fail: %s", err)
|
||||
}
|
||||
return err
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -2520,12 +2520,8 @@ func (s *SKVMGuestInstance) compareDescNetworks(newDesc *desc.SGuestDesc,
|
||||
func getNicBridge(nic *desc.SGuestNetwork) string {
|
||||
if nic.Bridge == "" && nic.Vpc.Provider == api.VPC_PROVIDER_OVN {
|
||||
return options.HostOptions.OvnIntegrationBridge
|
||||
} else if nic.Bridge == api.HostTapBridge {
|
||||
return options.HostOptions.TapBridgeName
|
||||
} else if nic.Bridge == api.HostVpcBridge {
|
||||
return options.HostOptions.OvnIntegrationBridge
|
||||
} else {
|
||||
return nic.Bridge
|
||||
return options.HostOptions.NicBridgeDevName(nic.Bridge)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,14 +34,28 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/util/procutils"
|
||||
)
|
||||
|
||||
func (h *SHostInfo) findExternalInterfaces() []string {
|
||||
interfaces := make([]string, 0)
|
||||
for i := 0; i < len(h.Nics); i++ {
|
||||
if !h.Nics[i].IsHostLocal() && len(h.Nics[i].Ip) > 0 {
|
||||
interfaces = append(interfaces, h.Nics[i].Bridge)
|
||||
}
|
||||
}
|
||||
if len(options.HostOptions.ListenInterface) > 0 {
|
||||
interfaces = append(interfaces, options.HostOptions.ListenInterface)
|
||||
}
|
||||
return interfaces
|
||||
}
|
||||
|
||||
func (h *SHostInfo) finalizeNetworkSetup(ctx context.Context) error {
|
||||
for i := 0; i < len(h.Nics); i++ {
|
||||
if err := h.Nics[i].SetupDhcpRelay(); err != nil {
|
||||
return errors.Wrapf(err, "SetupDhcpRelay %s", h.Nics[i])
|
||||
}
|
||||
}
|
||||
extInterfaces := h.findExternalInterfaces()
|
||||
for i := 0; i < len(h.Nics); i++ {
|
||||
if err := h.Nics[i].setupHostLocalNetworks(ctx); err != nil {
|
||||
if err := h.Nics[i].setupHostLocalNetworks(ctx, extInterfaces); err != nil {
|
||||
return errors.Wrapf(err, "SetupHostLocalNetworks %s", h.Nics[i])
|
||||
}
|
||||
}
|
||||
@@ -52,7 +66,7 @@ func (n *SNIC) String() string {
|
||||
return fmt.Sprintf("%s/%s/%s", n.Inter, n.Bridge, n.Ip)
|
||||
}
|
||||
|
||||
func (n *SNIC) setupHostLocalNetworks(ctx context.Context) error {
|
||||
func (n *SNIC) setupHostLocalNetworks(ctx context.Context, extInterfaces []string) error {
|
||||
nets, err := n.fetchHostLocalNetworks(ctx)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "fetchHostLocalNetworks")
|
||||
@@ -63,7 +77,7 @@ func (n *SNIC) setupHostLocalNetworks(ctx context.Context) error {
|
||||
if len(net.GuestGateway) == 0 {
|
||||
continue
|
||||
}
|
||||
err := n.setupHostLocalNet(ctx, net)
|
||||
err := n.setupHostLocalNet(ctx, net, extInterfaces)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "setupHostLocalNet of %s", jsonutils.Marshal(net))
|
||||
}
|
||||
@@ -75,15 +89,15 @@ func (n *SNIC) setupHostLocalNetworks(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *SNIC) setupHostLocalNet(ctx context.Context, netInfo computeapis.NetworkDetails) error {
|
||||
func (n *SNIC) setupHostLocalNet(ctx context.Context, netInfo computeapis.NetworkDetails, extInterfaces []string) error {
|
||||
// setup gateway ip
|
||||
if err := n.setupSlaveIp(ctx, netInfo.GuestGateway, netInfo.GuestIpMask); err != nil {
|
||||
if err := n.setupSlaveIp(ctx, netInfo.GuestGateway, netInfo.GuestIpMask, extInterfaces); err != nil {
|
||||
return errors.Wrapf(err, "setupSlaveIp %s %s", n, netInfo.GuestGateway)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *SNIC) setupSlaveIp(ctx context.Context, gatewayIp string, maskLen byte) error {
|
||||
func (n *SNIC) setupSlaveIp(ctx context.Context, gatewayIp string, maskLen byte, extInterfaces []string) error {
|
||||
bridgeIf := netutils2.NewNetInterface(n.Bridge)
|
||||
slaveAddrs := bridgeIf.GetSlaveAddresses()
|
||||
var curGatewayIp string
|
||||
@@ -108,7 +122,7 @@ func (n *SNIC) setupSlaveIp(ctx context.Context, gatewayIp string, maskLen byte)
|
||||
}); err != nil {
|
||||
return errors.Wrap(err, "SetupSlaveAddresses")
|
||||
}
|
||||
if err := n.setupMasqueradeRule(ctx, gatewayIp, maskLen); err != nil {
|
||||
if err := n.setupMasqueradeRule(ctx, gatewayIp, maskLen, extInterfaces); err != nil {
|
||||
return errors.Wrap(err, "setupMasqueradeRule")
|
||||
}
|
||||
if isMaskUpdate {
|
||||
@@ -120,7 +134,7 @@ func (n *SNIC) setupSlaveIp(ctx context.Context, gatewayIp string, maskLen byte)
|
||||
log.Warningf("%s: delete addr %s: %v", logPrefix, addr, err)
|
||||
}
|
||||
curMaskLenInt := curMaskLen
|
||||
if err := n.deleteMasqueradeRule(ctx, gatewayIp, byte(curMaskLenInt)); err != nil {
|
||||
if err := n.deleteMasqueradeRule(ctx, gatewayIp, byte(curMaskLenInt), extInterfaces); err != nil {
|
||||
log.Warningf("%s: delete iptables masqueradeRule: %v", logPrefix, err)
|
||||
}
|
||||
}
|
||||
@@ -134,7 +148,7 @@ const (
|
||||
IPTABLES_ACTION_DELETE
|
||||
)
|
||||
|
||||
func (n *SNIC) doMasqueradeRule(ctx context.Context, ipStr string, maskLen byte, action IptablesAction) error {
|
||||
func (n *SNIC) doMasqueradeRule(ctx context.Context, ipStr string, maskLen byte, action IptablesAction, bridge string) error {
|
||||
gwip, err := netutils.NewIPV4Addr(ipStr)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "NewIPV4Addr %s", ipStr)
|
||||
@@ -154,35 +168,56 @@ func (n *SNIC) doMasqueradeRule(ctx context.Context, ipStr string, maskLen byte,
|
||||
return errors.Errorf("unknown action %d", action)
|
||||
}
|
||||
cmd := procutils.NewCommand("iptables", "-t", "nat", actionOpt, "POSTROUTING", "-s",
|
||||
fmt.Sprintf("%s/%s", netip.String(), maskip.String()), "-o", n.Bridge, "-j", "MASQUERADE")
|
||||
fmt.Sprintf("%s/%s", netip.String(), maskip.String()), "-o", bridge, "-j", "MASQUERADE")
|
||||
if err := cmd.Run(); err != nil {
|
||||
return errors.Wrapf(err, "%s masquerade rule", actionInfo)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *SNIC) setupMasqueradeRule(ctx context.Context, ipStr string, maskLen byte) error {
|
||||
return n.doMasqueradeRule(ctx, ipStr, maskLen, IPTABLES_ACTION_APPEND)
|
||||
func (n *SNIC) setupMasqueradeRule(ctx context.Context, ipStr string, maskLen byte, extInterfaces []string) error {
|
||||
if n.IsHostLocal() {
|
||||
for _, inf := range extInterfaces {
|
||||
if err := n.doMasqueradeRule(ctx, ipStr, maskLen, IPTABLES_ACTION_APPEND, inf); err != nil {
|
||||
return errors.Wrapf(err, "setupMasqueradeRule %s %d %s", ipStr, maskLen, inf)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
} else {
|
||||
return n.doMasqueradeRule(ctx, ipStr, maskLen, IPTABLES_ACTION_APPEND, n.Bridge)
|
||||
}
|
||||
}
|
||||
|
||||
func (n *SNIC) deleteMasqueradeRule(ctx context.Context, ipStr string, maskLen byte) error {
|
||||
return n.doMasqueradeRule(ctx, ipStr, maskLen, IPTABLES_ACTION_DELETE)
|
||||
func (n *SNIC) deleteMasqueradeRule(ctx context.Context, ipStr string, maskLen byte, extInterfaces []string) error {
|
||||
if n.IsHostLocal() {
|
||||
for _, inf := range extInterfaces {
|
||||
if err := n.doMasqueradeRule(ctx, ipStr, maskLen, IPTABLES_ACTION_DELETE, inf); err != nil {
|
||||
return errors.Wrapf(err, "deleteMasqueradeRule %s %d %s", ipStr, maskLen, inf)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
} else {
|
||||
return n.doMasqueradeRule(ctx, ipStr, maskLen, IPTABLES_ACTION_DELETE, n.Bridge)
|
||||
}
|
||||
}
|
||||
|
||||
func (n *SNIC) fetchHostLocalNetworks(ctx context.Context) ([]computeapis.NetworkDetails, error) {
|
||||
return fetchHostLocalNetworksByWireId(ctx, n.WireId)
|
||||
}
|
||||
|
||||
func fetchHostLocalNetworksByWireId(ctx context.Context, wireId string) ([]computeapis.NetworkDetails, error) {
|
||||
s := hostutils.GetComputeSession(ctx)
|
||||
params := computeoptions.NetworkListOptions{}
|
||||
params.ServerType = "hostlocal"
|
||||
limit := 50
|
||||
params.Limit = &limit
|
||||
params.Wire = n.WireId
|
||||
params.Scope = "system"
|
||||
total := -1
|
||||
nets := make([]computeapis.NetworkDetails, 0)
|
||||
for total < 0 || len(nets) < total {
|
||||
offset := len(nets)
|
||||
params.Offset = &offset
|
||||
results, err := computemodules.Networks.List(s, jsonutils.Marshal(params))
|
||||
results, err := computemodules.Networks.ListInContext(s, jsonutils.Marshal(params), &computemodules.Wires, wireId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Networks.List")
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
package hostbridge
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
@@ -29,6 +30,7 @@ import (
|
||||
"yunion.io/x/pkg/util/regutils"
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/hostman/guestman/desc"
|
||||
"yunion.io/x/onecloud/pkg/hostman/options"
|
||||
"yunion.io/x/onecloud/pkg/util/fileutils2"
|
||||
@@ -121,19 +123,64 @@ func NewBaseBridgeDriver(bridge, inter, ip string, maskLen int, ip6 string, mask
|
||||
return bd, nil
|
||||
}
|
||||
|
||||
func (d *SBaseBridgeDriver) fetchHostLocalConf() ([]compute.NetworkDetails, error) {
|
||||
hostLocalNics := make([]compute.NetworkDetails, 0)
|
||||
fn := options.HostOptions.HostLocalNetconfPath(d.bridge.String())
|
||||
if fileutils2.IsFile(fn) {
|
||||
contBytes, err := os.ReadFile(fn)
|
||||
if err != nil {
|
||||
log.Errorf("read host local conf file %s failed: %s", fn, err)
|
||||
return nil, errors.Wrap(err, "read host local conf file")
|
||||
}
|
||||
err = json.Unmarshal(contBytes, &hostLocalNics)
|
||||
if err != nil {
|
||||
log.Errorf("unmarshal host local conf file %s failed: %s", fn, err)
|
||||
return nil, errors.Wrap(err, "unmarshal host local conf file")
|
||||
}
|
||||
return hostLocalNics, nil
|
||||
}
|
||||
return hostLocalNics, nil
|
||||
}
|
||||
|
||||
func (d *SBaseBridgeDriver) hostLocalGatewayIps() ([]string, error) {
|
||||
hostLocalNics, err := d.fetchHostLocalConf()
|
||||
if err != nil {
|
||||
log.Errorf("fetch host local conf failed: %s", err)
|
||||
return nil, errors.Wrap(err, "fetch host local conf")
|
||||
}
|
||||
gatewayIps := make([]string, 0)
|
||||
for _, net := range hostLocalNics {
|
||||
if net.GuestGateway != "" {
|
||||
gatewayIps = append(gatewayIps, net.GuestGateway)
|
||||
}
|
||||
if net.GuestGateway6 != "" {
|
||||
gatewayIps = append(gatewayIps, net.GuestGateway6)
|
||||
}
|
||||
}
|
||||
return gatewayIps, nil
|
||||
}
|
||||
|
||||
func (d *SBaseBridgeDriver) FetchConfig() {
|
||||
d.bridge.FetchConfig2(d.ip, d.ip6)
|
||||
hostLocalGatewayIps, _ := d.hostLocalGatewayIps()
|
||||
d.bridge.FetchConfig2(d.ip, d.ip6, hostLocalGatewayIps)
|
||||
d.inter.FetchConfig()
|
||||
}
|
||||
|
||||
func (d *SBaseBridgeDriver) GetMac() string {
|
||||
if len(d.inter.GetMac()) == 0 {
|
||||
d.inter.FetchConfig()
|
||||
dev := d.inter
|
||||
if dev == nil {
|
||||
dev = d.bridge
|
||||
}
|
||||
return d.inter.GetMac()
|
||||
if len(dev.GetMac()) == 0 {
|
||||
dev.FetchConfig()
|
||||
}
|
||||
return dev.GetMac()
|
||||
}
|
||||
|
||||
func (d *SBaseBridgeDriver) GetVlanId() int {
|
||||
if d.inter == nil {
|
||||
return 1
|
||||
}
|
||||
if len(d.inter.GetMac()) == 0 {
|
||||
d.inter.FetchConfig()
|
||||
}
|
||||
@@ -327,7 +374,12 @@ func (d *SBaseBridgeDriver) ConfirmToConfig() (bool, string, error) {
|
||||
return false, "", err
|
||||
}
|
||||
if exist {
|
||||
d.bridge.FetchConfig2(d.ip, d.ip6)
|
||||
hostLocalGatewayIps, err := d.hostLocalGatewayIps()
|
||||
if err != nil {
|
||||
log.Errorf("fetch host local gateway ips failed: %s", err)
|
||||
// return false, "", errors.Wrap(err, "fetch host local gateway ips")
|
||||
}
|
||||
d.bridge.FetchConfig2(d.ip, d.ip6, hostLocalGatewayIps)
|
||||
if len(d.ip) > 0 {
|
||||
if len(d.bridge.Addr) == 0 {
|
||||
log.Infof("bridge %s has no ip assignment initially", d.bridge)
|
||||
|
||||
@@ -100,6 +100,9 @@ func (o *SOVSBridgeDriver) SetupBridgeDev() error {
|
||||
}
|
||||
|
||||
func (d *SOVSBridgeDriver) PersistentConfig() error {
|
||||
if d.inter == nil {
|
||||
return nil
|
||||
}
|
||||
args := []string{
|
||||
"ovs-vsctl", "set", "Bridge", d.bridge.String(),
|
||||
"other-config:hwaddr=" + d.inter.GetMac(),
|
||||
|
||||
@@ -159,8 +159,9 @@ func (h *SHostInfo) GetIsolatedDeviceManager() isolated_device.IsolatedDeviceMan
|
||||
}
|
||||
|
||||
func (h *SHostInfo) GetBridgeDev(bridge string) hostbridge.IBridgeDriver {
|
||||
bridgeDev := options.HostOptions.NicBridgeDevName(bridge)
|
||||
for _, n := range h.Nics {
|
||||
if bridge == n.Bridge {
|
||||
if bridgeDev == n.Bridge {
|
||||
return n.BridgeDev
|
||||
}
|
||||
}
|
||||
@@ -403,6 +404,14 @@ func (h *SHostInfo) parseConfig() error {
|
||||
}
|
||||
h.Nics = append(h.Nics, nic)
|
||||
}
|
||||
{
|
||||
// host local bridge
|
||||
nic, err := NewNIC(fmt.Sprintf("/%s/%s", options.HostOptions.HostLocalBridgeName, api.DEFAULT_HOST_LOCAL_WIRE_NAME))
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "NewNic for host local bridge %s", options.HostOptions.HostLocalBridgeName)
|
||||
}
|
||||
h.Nics = append(h.Nics, nic)
|
||||
}
|
||||
|
||||
if len(options.HostOptions.ListenInterface) > 0 {
|
||||
h.MasterNic = netutils2.NewNetInterface(options.HostOptions.ListenInterface)
|
||||
@@ -1887,6 +1896,9 @@ func (h *SHostInfo) uploadNetworkInfo() error {
|
||||
var hostDetails *api.HostDetails
|
||||
for _, nic := range h.Nics {
|
||||
log.Infof("host nic: %s", jsonutils.Marshal(nic).String())
|
||||
if nic.IsHostLocal() {
|
||||
continue
|
||||
}
|
||||
if len(nic.WireId) == 0 {
|
||||
// nic info not uploaded yet
|
||||
if len(nic.Wire) == 0 {
|
||||
|
||||
@@ -32,6 +32,7 @@ import (
|
||||
"yunion.io/x/pkg/util/netutils"
|
||||
"yunion.io/x/pkg/util/regutils"
|
||||
|
||||
computeapi "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
hostapi "yunion.io/x/onecloud/pkg/apis/host"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/types"
|
||||
"yunion.io/x/onecloud/pkg/hostman/hostinfo/hostbridge"
|
||||
@@ -283,7 +284,7 @@ func NewNIC(desc string) (*SNIC, error) {
|
||||
// in case nic bonding is too slow
|
||||
var max, wait = 30, 0
|
||||
for wait < max {
|
||||
inf := netutils2.NewNetInterfaceWithExpectIp(nic.Inter, nic.Ip, nic.Ip6)
|
||||
inf := netutils2.NewNetInterfaceWithExpectIp(nic.Inter, nic.Ip, nic.Ip6, nil)
|
||||
if len(nic.Ip) > 0 && inf.Addr == nic.Ip {
|
||||
mask, _ := inf.Mask.Size()
|
||||
if mask > 0 {
|
||||
@@ -393,6 +394,21 @@ func NewNIC(desc string) (*SNIC, error) {
|
||||
return nic, nil
|
||||
}
|
||||
|
||||
func (n *SNIC) IsHostLocal() bool {
|
||||
if n.Bridge == options.HostOptions.HostLocalBridgeName {
|
||||
n.setupHostLocal()
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (n *SNIC) setupHostLocal() {
|
||||
if n.WireId == "" {
|
||||
n.Wire = computeapi.DEFAULT_HOST_LOCAL_WIRE_NAME
|
||||
n.WireId = computeapi.DEFAULT_HOST_LOCAL_WIRE_ID
|
||||
}
|
||||
}
|
||||
|
||||
type SSysInfo struct {
|
||||
*types.SSystemInfo
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/structarg"
|
||||
|
||||
computeapi "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
common_options "yunion.io/x/onecloud/pkg/cloudcommon/options"
|
||||
"yunion.io/x/onecloud/pkg/util/fileutils2"
|
||||
"yunion.io/x/onecloud/pkg/util/ovnutils"
|
||||
@@ -196,6 +197,8 @@ type SHostOptions struct {
|
||||
SdnEnableTapMan bool `help:"enable tap service" default:"$SDN_ENABLE_TAP_MAN|true"`
|
||||
TapBridgeName string `help:"bridge name for tap service" default:"brtap"`
|
||||
|
||||
HostLocalBridgeName string `help:"bridge name for host local network" default:"brlocal"`
|
||||
|
||||
SdnAllowConntrackInvalid bool `help:"allow packets marked by conntrack as INVALID to pass" default:"$SDN_ALLOW_CONNTRACK_INVALID|false"`
|
||||
SdnFetchDataFromComputeService bool `help:"fetch network releated data from compute service" default:"$SDN_FETCH_DATA_FROM_COMPUTE_SERVICE|true"`
|
||||
|
||||
@@ -281,6 +284,19 @@ func (o SHostOptions) HostLocalNetconfPath(br string) string {
|
||||
return filepath.Join(o.ServersPath, fmt.Sprintf("host_local_netconf_%s.json", br))
|
||||
}
|
||||
|
||||
func (o SHostOptions) NicBridgeDevName(bridge string) string {
|
||||
switch bridge {
|
||||
case computeapi.HostVpcBridge:
|
||||
return o.OvnIntegrationBridge
|
||||
case computeapi.HostTapBridge:
|
||||
return o.TapBridgeName
|
||||
case computeapi.HostLocalBridge:
|
||||
return o.HostLocalBridgeName
|
||||
default:
|
||||
return bridge
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
HostOptions SHostOptions
|
||||
)
|
||||
|
||||
@@ -34,7 +34,7 @@ type NetworkListOptions struct {
|
||||
Region string `help:"search networks belongs to a CloudRegion" json:"cloudregion"`
|
||||
City string `help:"search networks belongs to a city"`
|
||||
Usable *bool `help:"search usable networks"`
|
||||
ServerType string `help:"search networks belongs to a ServerType" choices:"baremetal|container|eip|guest|ipmi|pxe"`
|
||||
ServerType string `help:"search networks belongs to a ServerType" choices:"baremetal|container|eip|guest|ipmi|pxe|hostlocal"`
|
||||
Schedtag string `help:"filter networks by schedtag"`
|
||||
|
||||
HostSchedtagId string `help:"filter by host schedtag"`
|
||||
|
||||
@@ -116,11 +116,16 @@ func IsNetworksAvailable(ctx context.Context, c core.Candidater, data *api.Sched
|
||||
|
||||
ovnCapable := c.Getter().OvnCapable()
|
||||
ovnNetworks := []*api.CandidateNetwork{}
|
||||
hostLocalNetworks := []*api.CandidateNetwork{}
|
||||
for i := len(networks) - 1; i >= 0; i -= 1 {
|
||||
net := networks[i]
|
||||
if net.Provider == computeapi.CLOUD_PROVIDER_ONECLOUD || net.Provider == computeapi.CLOUD_PROVIDER_CLOUDPODS {
|
||||
networks = append(networks[:i], networks[i+1:]...)
|
||||
ovnNetworks = append(ovnNetworks, net)
|
||||
if net.WireId == computeapi.DEFAULT_HOST_LOCAL_WIRE_ID {
|
||||
hostLocalNetworks = append(hostLocalNetworks, net)
|
||||
} else {
|
||||
ovnNetworks = append(ovnNetworks, net)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,6 +145,10 @@ func IsNetworksAvailable(ctx context.Context, c core.Candidater, data *api.Sched
|
||||
checkNets(ovnNetworks)
|
||||
}
|
||||
|
||||
if len(hostLocalNetworks) > 0 {
|
||||
checkNets(hostLocalNetworks)
|
||||
}
|
||||
|
||||
// reuse network
|
||||
if data.ReuseNetwork {
|
||||
return freeCnt, nil
|
||||
|
||||
+49
-36
@@ -390,11 +390,17 @@ func newBaseHostDesc(b *baseBuilder, host *computemodels.SHost, netGetter *netwo
|
||||
if err := desc.fillOnecloudVpcNetworks(netGetter); err != nil {
|
||||
return nil, fmt.Errorf("Fill onecloud vpc networks error: %v", err)
|
||||
}
|
||||
if err := desc.fillOneCloudHostLocalNetworks(netGetter); err != nil {
|
||||
return nil, fmt.Errorf("Fill onecloud host local networks error: %v", err)
|
||||
}
|
||||
}
|
||||
if sets.NewString(computeapi.HOST_TYPE_HYPERVISOR, computeapi.HOST_TYPE_BAREMETAL).Has(host.HostType) && len(host.ManagerId) > 0 {
|
||||
if sets.NewString(computeapi.HOST_TYPE_HYPERVISOR, computeapi.HOST_TYPE_BAREMETAL, computeapi.HOST_TYPE_CONTAINER).Has(host.HostType) && len(host.ManagerId) > 0 {
|
||||
if err := desc.fillCloudpodsVpcNetworks(netGetter); err != nil {
|
||||
return nil, fmt.Errorf("Fill cloudpods vpc networks error: %v", err)
|
||||
}
|
||||
if err := desc.fillCloudpodsHostLocalNetworks(netGetter); err != nil {
|
||||
return nil, fmt.Errorf("Fill cloudpods host local networks error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := desc.fillZone(host); err != nil {
|
||||
@@ -693,7 +699,7 @@ func (b *BaseHostDesc) fillCloudpodsVpcNetworks(netGetter *networkGetter) error
|
||||
nets := computemodels.NetworkManager.Query()
|
||||
wires := computemodels.WireManager.Query().SubQuery()
|
||||
vpcs := computemodels.VpcManager.Query().SubQuery()
|
||||
regions := computemodels.CloudregionManager.Query().SubQuery()
|
||||
regions := computemodels.CloudregionManager.Query().Equals("provider", computeapi.CLOUD_PROVIDER_CLOUDPODS).SubQuery()
|
||||
q := nets.AppendField(nets.QueryFields()...)
|
||||
q = q.AppendField(
|
||||
vpcs.Field("id", "vpc_id"),
|
||||
@@ -702,44 +708,17 @@ func (b *BaseHostDesc) fillCloudpodsVpcNetworks(netGetter *networkGetter) error
|
||||
q = q.Join(wires, sqlchemy.Equals(wires.Field("id"), nets.Field("wire_id")))
|
||||
q = q.Join(vpcs, sqlchemy.Equals(vpcs.Field("id"), wires.Field("vpc_id")))
|
||||
q = q.Join(regions, sqlchemy.Equals(regions.Field("id"), vpcs.Field("cloudregion_id")))
|
||||
q = q.Filter(sqlchemy.AND(
|
||||
sqlchemy.Equals(regions.Field("provider"), computeapi.CLOUD_PROVIDER_CLOUDPODS),
|
||||
q = q.Filter(
|
||||
sqlchemy.NOT(sqlchemy.Equals(vpcs.Field("external_id"), computeapi.DEFAULT_VPC_ID)),
|
||||
))
|
||||
|
||||
type Row struct {
|
||||
computemodels.SNetwork
|
||||
VpcId string
|
||||
Provider string
|
||||
}
|
||||
rows := []Row{}
|
||||
if err := q.All(&rows); err != nil {
|
||||
return errors.Wrap(err, "query cloudpods vpc networks")
|
||||
}
|
||||
for i := range rows {
|
||||
row := &rows[i]
|
||||
net := &row.SNetwork
|
||||
net.SetModelManager(computemodels.NetworkManager, net)
|
||||
freePort, err := netGetter.GetFreePort(b.SHost, net)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "GetFreeAddressCount for network %s(%s)", net.GetName(), net.GetId())
|
||||
}
|
||||
candidateNet := &api.CandidateNetwork{
|
||||
SNetwork: net,
|
||||
FreePort: freePort,
|
||||
VpcId: row.VpcId,
|
||||
Provider: row.Provider,
|
||||
}
|
||||
b.Networks = append(b.Networks, candidateNet)
|
||||
}
|
||||
return nil
|
||||
)
|
||||
return b.fillNetworksByQuery(netGetter, q)
|
||||
}
|
||||
|
||||
func (b *BaseHostDesc) fillOnecloudVpcNetworks(netGetter *networkGetter) error {
|
||||
nets := computemodels.NetworkManager.Query()
|
||||
wires := computemodels.WireManager.Query().SubQuery()
|
||||
vpcs := computemodels.VpcManager.Query().SubQuery()
|
||||
regions := computemodels.CloudregionManager.Query().SubQuery()
|
||||
regions := computemodels.CloudregionManager.Query().Equals("provider", computeapi.CLOUD_PROVIDER_ONECLOUD).SubQuery()
|
||||
q := nets.AppendField(nets.QueryFields()...)
|
||||
q = q.AppendField(
|
||||
vpcs.Field("id", "vpc_id"),
|
||||
@@ -748,11 +727,45 @@ func (b *BaseHostDesc) fillOnecloudVpcNetworks(netGetter *networkGetter) error {
|
||||
q = q.Join(wires, sqlchemy.Equals(wires.Field("id"), nets.Field("wire_id")))
|
||||
q = q.Join(vpcs, sqlchemy.Equals(vpcs.Field("id"), wires.Field("vpc_id")))
|
||||
q = q.Join(regions, sqlchemy.Equals(regions.Field("id"), vpcs.Field("cloudregion_id")))
|
||||
q = q.Filter(sqlchemy.AND(
|
||||
sqlchemy.Equals(regions.Field("provider"), computeapi.CLOUD_PROVIDER_ONECLOUD),
|
||||
q = q.Filter(
|
||||
sqlchemy.NOT(sqlchemy.Equals(vpcs.Field("id"), computeapi.DEFAULT_VPC_ID)),
|
||||
))
|
||||
)
|
||||
return b.fillNetworksByQuery(netGetter, q)
|
||||
}
|
||||
|
||||
func (b *BaseHostDesc) fillOneCloudHostLocalNetworks(netGetter *networkGetter) error {
|
||||
nets := computemodels.NetworkManager.Query()
|
||||
wires := computemodels.WireManager.Query().Equals("id", computeapi.DEFAULT_HOST_LOCAL_WIRE_ID).SubQuery()
|
||||
vpcs := computemodels.VpcManager.Query().Equals("id", computeapi.DEFAULT_VPC_ID).SubQuery()
|
||||
regions := computemodels.CloudregionManager.Query().Equals("provider", computeapi.CLOUD_PROVIDER_ONECLOUD).SubQuery()
|
||||
q := nets.AppendField(nets.QueryFields()...)
|
||||
q = q.AppendField(
|
||||
vpcs.Field("id", "vpc_id"),
|
||||
regions.Field("provider"),
|
||||
)
|
||||
q = q.Join(wires, sqlchemy.Equals(wires.Field("id"), nets.Field("wire_id")))
|
||||
q = q.Join(vpcs, sqlchemy.Equals(vpcs.Field("id"), wires.Field("vpc_id")))
|
||||
q = q.Join(regions, sqlchemy.Equals(regions.Field("id"), vpcs.Field("cloudregion_id")))
|
||||
return b.fillNetworksByQuery(netGetter, q)
|
||||
}
|
||||
|
||||
func (b *BaseHostDesc) fillCloudpodsHostLocalNetworks(netGetter *networkGetter) error {
|
||||
nets := computemodels.NetworkManager.Query()
|
||||
wires := computemodels.WireManager.Query().Equals("external_id", computeapi.DEFAULT_HOST_LOCAL_WIRE_ID).SubQuery()
|
||||
vpcs := computemodels.VpcManager.Query().Equals("external_id", computeapi.DEFAULT_VPC_ID).SubQuery()
|
||||
regions := computemodels.CloudregionManager.Query().Equals("provider", computeapi.CLOUD_PROVIDER_CLOUDPODS).SubQuery()
|
||||
q := nets.AppendField(nets.QueryFields()...)
|
||||
q = q.AppendField(
|
||||
vpcs.Field("id", "vpc_id"),
|
||||
regions.Field("provider"),
|
||||
)
|
||||
q = q.Join(wires, sqlchemy.Equals(wires.Field("id"), nets.Field("wire_id")))
|
||||
q = q.Join(vpcs, sqlchemy.Equals(vpcs.Field("id"), wires.Field("vpc_id")))
|
||||
q = q.Join(regions, sqlchemy.Equals(regions.Field("id"), vpcs.Field("cloudregion_id")))
|
||||
return b.fillNetworksByQuery(netGetter, q)
|
||||
}
|
||||
|
||||
func (b *BaseHostDesc) fillNetworksByQuery(netGetter *networkGetter, q *sqlchemy.SQuery) error {
|
||||
type Row struct {
|
||||
computemodels.SNetwork
|
||||
VpcId string
|
||||
|
||||
@@ -27,6 +27,7 @@ import (
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/netutils"
|
||||
"yunion.io/x/pkg/util/regutils"
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/types"
|
||||
"yunion.io/x/onecloud/pkg/util/procutils"
|
||||
@@ -477,10 +478,10 @@ func NewNetInterface(name string) *SNetInterface {
|
||||
return n
|
||||
}
|
||||
|
||||
func NewNetInterfaceWithExpectIp(name string, expectIp string, expectIp6 string) *SNetInterface {
|
||||
func NewNetInterfaceWithExpectIp(name string, expectIp string, expectIp6 string, excludeIps []string) *SNetInterface {
|
||||
n := new(SNetInterface)
|
||||
n.name = name
|
||||
n.FetchConfig2(expectIp, expectIp6)
|
||||
n.FetchConfig2(expectIp, expectIp6, excludeIps)
|
||||
return n
|
||||
}
|
||||
|
||||
@@ -503,11 +504,11 @@ func (n *SNetInterface) FetchInter() *net.Interface {
|
||||
}
|
||||
|
||||
func (n *SNetInterface) FetchConfig() {
|
||||
n.FetchConfig2("", "")
|
||||
n.FetchConfig2("", "", nil)
|
||||
}
|
||||
|
||||
// FetchConfig2 is used to fetch config with expectIp and expectIp6
|
||||
func (n *SNetInterface) FetchConfig2(expectIp string, expectIp6 string) {
|
||||
func (n *SNetInterface) FetchConfig2(expectIp string, expectIp6 string, excludeIps []string) {
|
||||
n.Addr = ""
|
||||
n.Mask = nil
|
||||
n.mac = ""
|
||||
@@ -528,6 +529,9 @@ func (n *SNetInterface) FetchConfig2(expectIp string, expectIp6 string) {
|
||||
if strings.HasPrefix(ipnet.IP.To4().String(), SECRET_PREFIX) {
|
||||
n.Addr4LinkLocal = ipnet.IP.String()
|
||||
} else if (len(expectIp) > 0 && ipnet.IP.String() == expectIp) || (len(expectIp) == 0 && n.Addr == "") {
|
||||
if len(excludeIps) > 0 && utils.IsInStringArray(ipnet.IP.String(), excludeIps) {
|
||||
continue
|
||||
}
|
||||
n.Addr = ipnet.IP.String()
|
||||
n.Mask = ipnet.Mask
|
||||
}
|
||||
@@ -535,6 +539,9 @@ func (n *SNetInterface) FetchConfig2(expectIp string, expectIp6 string) {
|
||||
if ipnet.IP.IsLinkLocalUnicast() {
|
||||
n.Addr6LinkLocal = ipnet.IP.String()
|
||||
} else if (len(expectIp6) > 0 && ipnet.IP.String() == expectIp6) || (len(expectIp6) == 0 && n.Addr6 == "") {
|
||||
if len(excludeIps) > 0 && utils.IsInStringArray(ipnet.IP.String(), excludeIps) {
|
||||
continue
|
||||
}
|
||||
n.Addr6 = ipnet.IP.String()
|
||||
n.Mask6 = ipnet.Mask
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user