mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-24 16:03:43 +08:00
Merge pull request #10498 from yousong/automated-cherry-pick-of-#10497-upstream-release-3.7
Automated cherry pick of #10497: [rfc] Feature/yousong vpc route
This commit is contained in:
@@ -38,6 +38,8 @@ const (
|
||||
Next_HOP_TYPE_DIRECTCONNECTION = "DirectConnection" //专线
|
||||
Next_HOP_TYPE_VPC = "VPC"
|
||||
Next_HOP_TYPE_VBR = "VBR" // 边界路由器
|
||||
|
||||
Next_HOP_TYPE_IP = "IP"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -21,6 +21,8 @@ import (
|
||||
type Vpc struct {
|
||||
compute_models.SVpc
|
||||
|
||||
RouteTable *RouteTable `json:"-"`
|
||||
|
||||
Wire *Wire `json:"-"`
|
||||
Networks Networks `json:"-"`
|
||||
}
|
||||
@@ -31,6 +33,18 @@ func (el *Vpc) Copy() *Vpc {
|
||||
}
|
||||
}
|
||||
|
||||
type RouteTable struct {
|
||||
compute_models.SRouteTable
|
||||
|
||||
Vpc *Vpc
|
||||
}
|
||||
|
||||
func (el *RouteTable) Copy() *RouteTable {
|
||||
return &RouteTable{
|
||||
SRouteTable: el.SRouteTable,
|
||||
}
|
||||
}
|
||||
|
||||
type Wire struct {
|
||||
compute_models.SWire
|
||||
|
||||
@@ -93,6 +107,7 @@ type Guest struct {
|
||||
Host *Host `json:"-"`
|
||||
AdminSecurityGroup *SecurityGroup `json:"-"`
|
||||
SecurityGroups SecurityGroups `json:"-"`
|
||||
Guestnetworks Guestnetworks `json:"-"`
|
||||
}
|
||||
|
||||
func (el *Guest) Copy() *Guest {
|
||||
|
||||
@@ -41,6 +41,8 @@ type (
|
||||
Guestsecgroups map[string]*Guestsecgroup // key: guestId/secgroupId
|
||||
|
||||
DnsRecords map[string]*DnsRecord
|
||||
|
||||
RouteTables map[string]*RouteTable
|
||||
)
|
||||
|
||||
func (set Vpcs) ModelManager() mcclient_modulebase.IBaseManager {
|
||||
@@ -80,6 +82,28 @@ func (ms Vpcs) joinWires(subEntries Wires) bool {
|
||||
return correct
|
||||
}
|
||||
|
||||
func (ms Vpcs) joinRouteTables(subEntries RouteTables) bool {
|
||||
correct := true
|
||||
for _, subEntry := range subEntries {
|
||||
vpcId := subEntry.VpcId
|
||||
m, ok := ms[vpcId]
|
||||
if !ok {
|
||||
log.Warningf("vpc_id %s of route table %s(%s) is not present", vpcId, subEntry.Name, subEntry.Id)
|
||||
correct = false
|
||||
continue
|
||||
}
|
||||
subEntry.Vpc = m
|
||||
if m.RouteTable != nil {
|
||||
log.Warningf("vpc %s has more than 1 route table available, skipping %s(%s)",
|
||||
m.Name, m.Id, subEntry.Name, subEntry.Id)
|
||||
correct = false
|
||||
continue
|
||||
}
|
||||
m.RouteTable = subEntry
|
||||
}
|
||||
return correct
|
||||
}
|
||||
|
||||
func (ms Vpcs) joinNetworks(subEntries Networks) bool {
|
||||
for _, m := range ms {
|
||||
m.Networks = Networks{}
|
||||
@@ -377,6 +401,11 @@ func (set Guestnetworks) joinGuests(subEntries Guests) bool {
|
||||
continue
|
||||
}
|
||||
gn.Guest = g
|
||||
if g.Guestnetworks == nil {
|
||||
g.Guestnetworks = Guestnetworks{}
|
||||
}
|
||||
rowIdStr := fmt.Sprintf("%d", gn.RowId)
|
||||
g.Guestnetworks[rowIdStr] = gn
|
||||
}
|
||||
return true
|
||||
}
|
||||
@@ -631,3 +660,24 @@ func (set DnsRecords) Copy() apihelper.IModelSet {
|
||||
}
|
||||
return setCopy
|
||||
}
|
||||
|
||||
func (set RouteTables) ModelManager() mcclient_modulebase.IBaseManager {
|
||||
return &mcclient_modules.RouteTables
|
||||
}
|
||||
|
||||
func (set RouteTables) NewModel() db.IModel {
|
||||
return &RouteTable{}
|
||||
}
|
||||
|
||||
func (set RouteTables) AddModel(i db.IModel) {
|
||||
m := i.(*RouteTable)
|
||||
set[m.Id] = m
|
||||
}
|
||||
|
||||
func (set RouteTables) Copy() apihelper.IModelSet {
|
||||
setCopy := RouteTables{}
|
||||
for id, el := range set {
|
||||
setCopy[id] = el.Copy()
|
||||
}
|
||||
return setCopy
|
||||
}
|
||||
|
||||
@@ -34,6 +34,8 @@ type ModelSetsMaxUpdatedAt struct {
|
||||
NetworkAddresses time.Time
|
||||
|
||||
DnsRecords time.Time
|
||||
|
||||
RouteTables time.Time
|
||||
}
|
||||
|
||||
func NewModelSetsMaxUpdatedAt() *ModelSetsMaxUpdatedAt {
|
||||
@@ -51,6 +53,8 @@ func NewModelSetsMaxUpdatedAt() *ModelSetsMaxUpdatedAt {
|
||||
NetworkAddresses: apihelper.PseudoZeroTime,
|
||||
|
||||
DnsRecords: apihelper.PseudoZeroTime,
|
||||
|
||||
RouteTables: apihelper.PseudoZeroTime,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +72,8 @@ type ModelSets struct {
|
||||
NetworkAddresses NetworkAddresses
|
||||
|
||||
DnsRecords DnsRecords
|
||||
|
||||
RouteTables RouteTables
|
||||
}
|
||||
|
||||
func NewModelSets() *ModelSets {
|
||||
@@ -85,6 +91,8 @@ func NewModelSets() *ModelSets {
|
||||
NetworkAddresses: NetworkAddresses{},
|
||||
|
||||
DnsRecords: DnsRecords{},
|
||||
|
||||
RouteTables: RouteTables{},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,6 +112,8 @@ func (mss *ModelSets) ModelSetList() []apihelper.IModelSet {
|
||||
mss.NetworkAddresses,
|
||||
|
||||
mss.DnsRecords,
|
||||
|
||||
mss.RouteTables,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,6 +136,8 @@ func (mss *ModelSets) copy_() *ModelSets {
|
||||
NetworkAddresses: mss.NetworkAddresses.Copy().(NetworkAddresses),
|
||||
|
||||
DnsRecords: mss.DnsRecords.Copy().(DnsRecords),
|
||||
|
||||
RouteTables: mss.RouteTables.Copy().(RouteTables),
|
||||
}
|
||||
return mssCopy
|
||||
}
|
||||
@@ -164,6 +176,7 @@ func (mss *ModelSets) join() bool {
|
||||
mss.Guests.initJoin()
|
||||
var p []bool
|
||||
p = append(p, mss.Vpcs.joinWires(mss.Wires))
|
||||
p = append(p, mss.Vpcs.joinRouteTables(mss.RouteTables))
|
||||
p = append(p, mss.Wires.joinNetworks(mss.Networks))
|
||||
p = append(p, mss.Vpcs.joinNetworks(mss.Networks))
|
||||
p = append(p, mss.Networks.joinGuestnetworks(mss.Guestnetworks))
|
||||
|
||||
@@ -640,6 +640,32 @@ func (keeper *OVNNorthboundKeeper) ClaimGuestnetwork(ctx context.Context, guestn
|
||||
return keeper.cli.Must(ctx, "ClaimGuestnetwork", args)
|
||||
}
|
||||
|
||||
func (keeper *OVNNorthboundKeeper) ClaimRoutes(ctx context.Context, vpc *agentmodels.Vpc, routes resolvedRoutes) error {
|
||||
var irows []types.IRow
|
||||
for _, route := range routes {
|
||||
irows = append(irows, &ovn_nb.LogicalRouterStaticRoute{
|
||||
Policy: ptr("dst-ip"),
|
||||
IpPrefix: route.Cidr,
|
||||
Nexthop: route.NextHop,
|
||||
})
|
||||
}
|
||||
ocVersion := fmt.Sprintf("%s.%d", vpc.UpdatedAt, vpc.UpdateVersion)
|
||||
allFound, args := cmp(&keeper.DB, ocVersion, irows...)
|
||||
if allFound {
|
||||
return nil
|
||||
}
|
||||
lrName := vpcLrName(vpc.Id)
|
||||
for i, irow := range irows {
|
||||
ref := fmt.Sprintf("r%d", i)
|
||||
args = append(args, ovnCreateArgs(irow, ref)...)
|
||||
args = append(args, "--", "add", "Logical_Router", lrName, "static_routes", "@"+ref)
|
||||
}
|
||||
if len(args) > 0 {
|
||||
return keeper.cli.Must(ctx, "ClaimGuestnetwork", args)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (keeper *OVNNorthboundKeeper) ClaimVpcGuestDnsRecords(ctx context.Context, vpc *agentmodels.Vpc) error {
|
||||
var (
|
||||
grs = map[string][]string{}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
// 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 ovn
|
||||
|
||||
import (
|
||||
computeapis "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
agentmodels "yunion.io/x/onecloud/pkg/vpcagent/models"
|
||||
)
|
||||
|
||||
type resolvedRoutes []resolvedRoute
|
||||
|
||||
type resolvedRoute struct {
|
||||
Cidr string
|
||||
NextHop string
|
||||
Network *agentmodels.Network
|
||||
Guestnetwork *agentmodels.Guestnetwork
|
||||
}
|
||||
|
||||
func resolveRoutes(vpc *agentmodels.Vpc, mss *agentmodels.ModelSets) resolvedRoutes {
|
||||
if vpc.RouteTable == nil || vpc.RouteTable.Routes == nil {
|
||||
return nil
|
||||
}
|
||||
var r resolvedRoutes
|
||||
|
||||
routesModel := *vpc.RouteTable.Routes
|
||||
for _, routeModel := range routesModel {
|
||||
switch routeModel.NextHopType {
|
||||
case computeapis.Next_HOP_TYPE_IP:
|
||||
r = append(r, resolvedRoute{
|
||||
Cidr: routeModel.Cidr,
|
||||
NextHop: routeModel.NextHopId,
|
||||
})
|
||||
case computeapis.Next_HOP_TYPE_INSTANCE:
|
||||
guestId := routeModel.NextHopId
|
||||
guest, ok := mss.Guests[guestId]
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
for _, gn := range guest.Guestnetworks {
|
||||
network := gn.Network
|
||||
gnVpc := network.Vpc
|
||||
if gnVpc.Id != vpc.Id {
|
||||
continue
|
||||
}
|
||||
r = append(r, resolvedRoute{
|
||||
Cidr: routeModel.Cidr,
|
||||
NextHop: gn.IpAddr,
|
||||
Network: network,
|
||||
Guestnetwork: gn,
|
||||
})
|
||||
}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
@@ -164,6 +164,8 @@ func (w *Worker) run(ctx context.Context, mss *agentmodels.ModelSets) (err error
|
||||
ovndb.ClaimGuestnetwork(ctx, guestnetwork)
|
||||
}
|
||||
}
|
||||
routes := resolveRoutes(vpc, mss)
|
||||
ovndb.ClaimRoutes(ctx, vpc, routes)
|
||||
}
|
||||
for _, vpc := range mss.Vpcs {
|
||||
if vpc.Id == apis.DEFAULT_VPC_ID {
|
||||
|
||||
Reference in New Issue
Block a user