mirror of
https://github.com/netbirdio/netbird.git
synced 2025-03-30 18:46:08 +02:00
Add network routes distribution groups (#606)
Updated tests, API, and account manager methods Sync routes to peers in the distribution groups Added store upgrade by adding the All group to routes that don't have them
This commit is contained in:
parent
d1b7c23b19
commit
a387e3cfc2
4
.github/workflows/golang-test-linux.yml
vendored
4
.github/workflows/golang-test-linux.yml
vendored
@ -31,7 +31,7 @@ jobs:
|
|||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: sudo apt update && sudo apt install -y -q libgtk-3-dev libappindicator3-dev libayatana-appindicator3-dev libgl1-mesa-dev xorg-dev
|
run: sudo apt update && sudo apt install -y -q libgtk-3-dev libayatana-appindicator3-dev libgl1-mesa-dev xorg-dev
|
||||||
|
|
||||||
- name: Install modules
|
- name: Install modules
|
||||||
run: go mod tidy
|
run: go mod tidy
|
||||||
@ -60,7 +60,7 @@ jobs:
|
|||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: sudo apt update && sudo apt install -y -q libgtk-3-dev libappindicator3-dev libayatana-appindicator3-dev libgl1-mesa-dev xorg-dev
|
run: sudo apt update && sudo apt install -y -q libgtk-3-dev libayatana-appindicator3-dev libgl1-mesa-dev xorg-dev
|
||||||
|
|
||||||
- name: Install modules
|
- name: Install modules
|
||||||
run: go mod tidy
|
run: go mod tidy
|
||||||
|
2
.github/workflows/golangci-lint.yml
vendored
2
.github/workflows/golangci-lint.yml
vendored
@ -11,7 +11,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
go-version: 1.19.x
|
go-version: 1.19.x
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: sudo apt update && sudo apt install -y -q libgtk-3-dev libappindicator3-dev libayatana-appindicator3-dev libgl1-mesa-dev xorg-dev
|
run: sudo apt update && sudo apt install -y -q libgtk-3-dev libayatana-appindicator3-dev libgl1-mesa-dev xorg-dev
|
||||||
- name: golangci-lint
|
- name: golangci-lint
|
||||||
uses: golangci/golangci-lint-action@v2
|
uses: golangci/golangci-lint-action@v2
|
||||||
with:
|
with:
|
||||||
|
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@ -104,7 +104,7 @@ jobs:
|
|||||||
run: git --no-pager diff --exit-code
|
run: git --no-pager diff --exit-code
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: sudo apt update && sudo apt install -y -q libgtk-3-dev libappindicator3-dev libayatana-appindicator3-dev libgl1-mesa-dev xorg-dev gcc-mingw-w64-x86-64
|
run: sudo apt update && sudo apt install -y -q libgtk-3-dev libayatana-appindicator3-dev libgl1-mesa-dev xorg-dev gcc-mingw-w64-x86-64
|
||||||
- name: Install rsrc
|
- name: Install rsrc
|
||||||
run: go install github.com/akavel/rsrc@v0.10.2
|
run: go install github.com/akavel/rsrc@v0.10.2
|
||||||
- name: Generate windows rsrc
|
- name: Generate windows rsrc
|
||||||
|
@ -75,7 +75,7 @@ type AccountManager interface {
|
|||||||
DeleteRule(accountId, ruleID string) error
|
DeleteRule(accountId, ruleID string) error
|
||||||
ListRules(accountID, userID string) ([]*Rule, error)
|
ListRules(accountID, userID string) ([]*Rule, error)
|
||||||
GetRoute(accountID, routeID, userID string) (*route.Route, error)
|
GetRoute(accountID, routeID, userID string) (*route.Route, error)
|
||||||
CreateRoute(accountID string, prefix, peer, description, netID string, masquerade bool, metric int, enabled bool) (*route.Route, error)
|
CreateRoute(accountID string, prefix, peer, description, netID string, masquerade bool, metric int, groups []string, enabled bool) (*route.Route, error)
|
||||||
SaveRoute(accountID string, route *route.Route) error
|
SaveRoute(accountID string, route *route.Route) error
|
||||||
UpdateRoute(accountID string, routeID string, operations []RouteUpdateOperation) (*route.Route, error)
|
UpdateRoute(accountID string, routeID string, operations []RouteUpdateOperation) (*route.Route, error)
|
||||||
DeleteRoute(accountID, routeID string) error
|
DeleteRoute(accountID, routeID string) error
|
||||||
@ -137,31 +137,41 @@ type UserInfo struct {
|
|||||||
Status string `json:"-"`
|
Status string `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPeersRoutes returns all active routes of provided peers
|
// getRoutesToSync returns the enabled routes for the peer ID and the routes
|
||||||
func (a *Account) GetPeersRoutes(givenPeers []*Peer) []*route.Route {
|
// from the ACL peers that have distribution groups associated with the peer ID
|
||||||
//TODO Peer.ID migration: we will need to replace search by Peer.ID here
|
func (a *Account) getRoutesToSync(peerID string, aclPeers []*Peer) []*route.Route {
|
||||||
routes := make([]*route.Route, 0)
|
routes := a.getEnabledRoutesByPeer(peerID)
|
||||||
for _, peer := range givenPeers {
|
groupListMap := a.getPeerGroups(peerID)
|
||||||
peerRoutes := a.GetPeerRoutes(peer.Key)
|
for _, peer := range aclPeers {
|
||||||
activeRoutes := make([]*route.Route, 0)
|
activeRoutes := a.getEnabledRoutesByPeer(peer.Key)
|
||||||
for _, pr := range peerRoutes {
|
filteredRoutes := a.filterRoutesByGroups(activeRoutes, groupListMap)
|
||||||
if pr.Enabled {
|
routes = append(routes, filteredRoutes...)
|
||||||
activeRoutes = append(activeRoutes, pr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(activeRoutes) > 0 {
|
|
||||||
routes = append(routes, activeRoutes...)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return routes
|
return routes
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPeerRoutes returns a list of routes of a given peer
|
// filterRoutesByGroups returns a list with routes that have distribution groups in the group's map
|
||||||
func (a *Account) GetPeerRoutes(peerPubKey string) []*route.Route {
|
func (a *Account) filterRoutesByGroups(routes []*route.Route, groupListMap lookupMap) []*route.Route {
|
||||||
|
var filteredRoutes []*route.Route
|
||||||
|
for _, r := range routes {
|
||||||
|
for _, groupID := range r.Groups {
|
||||||
|
_, found := groupListMap[groupID]
|
||||||
|
if found {
|
||||||
|
filteredRoutes = append(filteredRoutes, r)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filteredRoutes
|
||||||
|
}
|
||||||
|
|
||||||
|
// getEnabledRoutesByPeer returns a list of routes of a given peer
|
||||||
|
func (a *Account) getEnabledRoutesByPeer(peerPubKey string) []*route.Route {
|
||||||
//TODO Peer.ID migration: we will need to replace search by Peer.ID here
|
//TODO Peer.ID migration: we will need to replace search by Peer.ID here
|
||||||
var routes []*route.Route
|
var routes []*route.Route
|
||||||
for _, r := range a.Routes {
|
for _, r := range a.Routes {
|
||||||
if r.Peer == peerPubKey {
|
if r.Peer == peerPubKey && r.Enabled {
|
||||||
routes = append(routes, r)
|
routes = append(routes, r)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -299,6 +309,19 @@ func (a *Account) getUserGroups(userID string) ([]string, error) {
|
|||||||
return user.AutoGroups, nil
|
return user.AutoGroups, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *Account) getPeerGroups(peerID string) lookupMap {
|
||||||
|
groupList := make(lookupMap)
|
||||||
|
for groupID, group := range a.Groups {
|
||||||
|
for _, id := range group.Peers {
|
||||||
|
if id == peerID {
|
||||||
|
groupList[groupID] = struct{}{}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return groupList
|
||||||
|
}
|
||||||
|
|
||||||
func (a *Account) getSetupKeyGroups(setupKey string) ([]string, error) {
|
func (a *Account) getSetupKeyGroups(setupKey string) ([]string, error) {
|
||||||
key, err := a.FindSetupKey(setupKey)
|
key, err := a.FindSetupKey(setupKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1075,7 +1075,7 @@ func TestFileStore_GetRoutesByPrefix(t *testing.T) {
|
|||||||
assert.Contains(t, routeIDs, "route-2")
|
assert.Contains(t, routeIDs, "route-2")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAccount_GetPeersRoutes(t *testing.T) {
|
func TestAccount_GetRoutesToSync(t *testing.T) {
|
||||||
_, prefix, err := route.ParseNetwork("192.168.64.0/24")
|
_, prefix, err := route.ParseNetwork("192.168.64.0/24")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -1084,6 +1084,7 @@ func TestAccount_GetPeersRoutes(t *testing.T) {
|
|||||||
Peers: map[string]*Peer{
|
Peers: map[string]*Peer{
|
||||||
"peer-1": {Key: "peer-1"}, "peer-2": {Key: "peer-2"}, "peer-3": {Key: "peer-1"},
|
"peer-1": {Key: "peer-1"}, "peer-2": {Key: "peer-2"}, "peer-3": {Key: "peer-1"},
|
||||||
},
|
},
|
||||||
|
Groups: map[string]*Group{"group1": {ID: "group1", Peers: []string{"peer-1", "peer-2"}}},
|
||||||
Routes: map[string]*route.Route{
|
Routes: map[string]*route.Route{
|
||||||
"route-1": {
|
"route-1": {
|
||||||
ID: "route-1",
|
ID: "route-1",
|
||||||
@ -1095,6 +1096,7 @@ func TestAccount_GetPeersRoutes(t *testing.T) {
|
|||||||
Masquerade: false,
|
Masquerade: false,
|
||||||
Metric: 999,
|
Metric: 999,
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
|
Groups: []string{"group1"},
|
||||||
},
|
},
|
||||||
"route-2": {
|
"route-2": {
|
||||||
ID: "route-2",
|
ID: "route-2",
|
||||||
@ -1106,11 +1108,12 @@ func TestAccount_GetPeersRoutes(t *testing.T) {
|
|||||||
Masquerade: false,
|
Masquerade: false,
|
||||||
Metric: 999,
|
Metric: 999,
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
|
Groups: []string{"group1"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
routes := account.GetPeersRoutes([]*Peer{{Key: "peer-1"}, {Key: "peer-2"}, {Key: "non-existing-peer"}})
|
routes := account.getRoutesToSync("peer-2", []*Peer{{Key: "peer-1"}, {Key: "peer-3"}})
|
||||||
|
|
||||||
assert.Len(t, routes, 2)
|
assert.Len(t, routes, 2)
|
||||||
routeIDs := make(map[string]struct{}, 2)
|
routeIDs := make(map[string]struct{}, 2)
|
||||||
@ -1120,6 +1123,9 @@ func TestAccount_GetPeersRoutes(t *testing.T) {
|
|||||||
assert.Contains(t, routeIDs, "route-1")
|
assert.Contains(t, routeIDs, "route-1")
|
||||||
assert.Contains(t, routeIDs, "route-2")
|
assert.Contains(t, routeIDs, "route-2")
|
||||||
|
|
||||||
|
emptyRoutes := account.getRoutesToSync("peer-3", []*Peer{{Key: "peer-1"}, {Key: "peer-2"}})
|
||||||
|
|
||||||
|
assert.Len(t, emptyRoutes, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAccount_Copy(t *testing.T) {
|
func TestAccount_Copy(t *testing.T) {
|
||||||
|
@ -78,15 +78,7 @@ func getPeersCustomZone(account *Account, dnsDomain string) nbdns.CustomZone {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getPeerNSGroups(account *Account, peerID string) []*nbdns.NameServerGroup {
|
func getPeerNSGroups(account *Account, peerID string) []*nbdns.NameServerGroup {
|
||||||
groupList := make(lookupMap)
|
groupList := account.getPeerGroups(peerID)
|
||||||
for groupID, group := range account.Groups {
|
|
||||||
for _, id := range group.Peers {
|
|
||||||
if id == peerID {
|
|
||||||
groupList[groupID] = struct{}{}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var peerNSGroups []*nbdns.NameServerGroup
|
var peerNSGroups []*nbdns.NameServerGroup
|
||||||
|
|
||||||
|
@ -105,6 +105,19 @@ func restore(file string) (*FileStore, error) {
|
|||||||
if len(existingLabels) != len(account.Peers) {
|
if len(existingLabels) != len(account.Peers) {
|
||||||
addPeerLabelsToAccount(account, existingLabels)
|
addPeerLabelsToAccount(account, existingLabels)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
allGroup, err := account.GetGroupAll()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("unable to find the All group, this should happen only when migrate from a version that didn't support groups. Error: %v", err)
|
||||||
|
// if the All group didn't exist we probably don't have routes to update
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, route := range account.Routes {
|
||||||
|
if len(route.Groups) == 0 {
|
||||||
|
route.Groups = []string{allGroup.ID}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// we need this persist to apply changes we made to account.Peers (we set them to Disconnected)
|
// we need this persist to apply changes we made to account.Peers (we set them to Disconnected)
|
||||||
|
@ -379,6 +379,11 @@ components:
|
|||||||
masquerade:
|
masquerade:
|
||||||
description: Indicate if peer should masquerade traffic to this route's prefix
|
description: Indicate if peer should masquerade traffic to this route's prefix
|
||||||
type: boolean
|
type: boolean
|
||||||
|
groups:
|
||||||
|
description: Route group tag groups
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
required:
|
required:
|
||||||
- id
|
- id
|
||||||
- description
|
- description
|
||||||
@ -388,6 +393,7 @@ components:
|
|||||||
- network
|
- network
|
||||||
- metric
|
- metric
|
||||||
- masquerade
|
- masquerade
|
||||||
|
- groups
|
||||||
Route:
|
Route:
|
||||||
allOf:
|
allOf:
|
||||||
- type: object
|
- type: object
|
||||||
@ -410,7 +416,7 @@ components:
|
|||||||
path:
|
path:
|
||||||
description: Route field to update in form /<field>
|
description: Route field to update in form /<field>
|
||||||
type: string
|
type: string
|
||||||
enum: [ "network","network_id","description","enabled","peer","metric","masquerade" ]
|
enum: [ "network","network_id","description","enabled","peer","metric","masquerade", "groups" ]
|
||||||
required:
|
required:
|
||||||
- path
|
- path
|
||||||
Nameserver:
|
Nameserver:
|
||||||
|
@ -65,6 +65,7 @@ const (
|
|||||||
const (
|
const (
|
||||||
RoutePatchOperationPathDescription RoutePatchOperationPath = "description"
|
RoutePatchOperationPathDescription RoutePatchOperationPath = "description"
|
||||||
RoutePatchOperationPathEnabled RoutePatchOperationPath = "enabled"
|
RoutePatchOperationPathEnabled RoutePatchOperationPath = "enabled"
|
||||||
|
RoutePatchOperationPathGroups RoutePatchOperationPath = "groups"
|
||||||
RoutePatchOperationPathMasquerade RoutePatchOperationPath = "masquerade"
|
RoutePatchOperationPathMasquerade RoutePatchOperationPath = "masquerade"
|
||||||
RoutePatchOperationPathMetric RoutePatchOperationPath = "metric"
|
RoutePatchOperationPathMetric RoutePatchOperationPath = "metric"
|
||||||
RoutePatchOperationPathNetwork RoutePatchOperationPath = "network"
|
RoutePatchOperationPathNetwork RoutePatchOperationPath = "network"
|
||||||
@ -296,6 +297,9 @@ type Route struct {
|
|||||||
// Enabled Route status
|
// Enabled Route status
|
||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
|
|
||||||
|
// Groups Route group tag groups
|
||||||
|
Groups []string `json:"groups"`
|
||||||
|
|
||||||
// Id Route Id
|
// Id Route Id
|
||||||
Id string `json:"id"`
|
Id string `json:"id"`
|
||||||
|
|
||||||
@ -344,6 +348,9 @@ type RouteRequest struct {
|
|||||||
// Enabled Route status
|
// Enabled Route status
|
||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
|
|
||||||
|
// Groups Route group tag groups
|
||||||
|
Groups []string `json:"groups"`
|
||||||
|
|
||||||
// Masquerade Indicate if peer should masquerade traffic to this route's prefix
|
// Masquerade Indicate if peer should masquerade traffic to this route's prefix
|
||||||
Masquerade bool `json:"masquerade"`
|
Masquerade bool `json:"masquerade"`
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ func (h *Routes) CreateRouteHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
newRoute, err := h.accountManager.CreateRoute(account.Id, newPrefix.String(), peerKey, req.Description, req.NetworkId, req.Masquerade, req.Metric, req.Enabled)
|
newRoute, err := h.accountManager.CreateRoute(account.Id, newPrefix.String(), peerKey, req.Description, req.NetworkId, req.Masquerade, req.Metric, req.Groups, req.Enabled)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.WriteError(err, w)
|
util.WriteError(err, w)
|
||||||
return
|
return
|
||||||
@ -162,6 +162,7 @@ func (h *Routes) UpdateRouteHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
Metric: req.Metric,
|
Metric: req.Metric,
|
||||||
Description: req.Description,
|
Description: req.Description,
|
||||||
Enabled: req.Enabled,
|
Enabled: req.Enabled,
|
||||||
|
Groups: req.Groups,
|
||||||
}
|
}
|
||||||
|
|
||||||
err = h.accountManager.SaveRoute(account.Id, newRoute)
|
err = h.accountManager.SaveRoute(account.Id, newRoute)
|
||||||
@ -298,6 +299,16 @@ func (h *Routes) PatchRouteHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
Type: server.UpdateRouteEnabled,
|
Type: server.UpdateRouteEnabled,
|
||||||
Values: patch.Value,
|
Values: patch.Value,
|
||||||
})
|
})
|
||||||
|
case api.RoutePatchOperationPathGroups:
|
||||||
|
if patch.Op != api.RoutePatchOperationOpReplace {
|
||||||
|
util.WriteError(status.Errorf(status.InvalidArgument,
|
||||||
|
"groups field only accepts replace operation, got %s", patch.Op), w)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
operations = append(operations, server.RouteUpdateOperation{
|
||||||
|
Type: server.UpdateRouteGroups,
|
||||||
|
Values: patch.Value,
|
||||||
|
})
|
||||||
default:
|
default:
|
||||||
util.WriteError(status.Errorf(status.InvalidArgument, "invalid patch path"), w)
|
util.WriteError(status.Errorf(status.InvalidArgument, "invalid patch path"), w)
|
||||||
return
|
return
|
||||||
@ -383,5 +394,6 @@ func toRouteResponse(account *server.Account, serverRoute *route.Route) *api.Rou
|
|||||||
NetworkType: serverRoute.NetworkType.String(),
|
NetworkType: serverRoute.NetworkType.String(),
|
||||||
Masquerade: serverRoute.Masquerade,
|
Masquerade: serverRoute.Masquerade,
|
||||||
Metric: serverRoute.Metric,
|
Metric: serverRoute.Metric,
|
||||||
|
Groups: serverRoute.Groups,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ const (
|
|||||||
notFoundPeerID = "100.64.0.200"
|
notFoundPeerID = "100.64.0.200"
|
||||||
existingPeerKey = "existingPeerKey"
|
existingPeerKey = "existingPeerKey"
|
||||||
testAccountID = "test_id"
|
testAccountID = "test_id"
|
||||||
|
existingGroupID = "testGroup"
|
||||||
)
|
)
|
||||||
|
|
||||||
var baseExistingRoute = &route.Route{
|
var baseExistingRoute = &route.Route{
|
||||||
@ -39,6 +40,7 @@ var baseExistingRoute = &route.Route{
|
|||||||
Metric: 9999,
|
Metric: 9999,
|
||||||
Masquerade: false,
|
Masquerade: false,
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
|
Groups: []string{existingGroupID},
|
||||||
}
|
}
|
||||||
|
|
||||||
var testingAccount = &server.Account{
|
var testingAccount = &server.Account{
|
||||||
@ -64,7 +66,7 @@ func initRoutesTestData() *Routes {
|
|||||||
}
|
}
|
||||||
return nil, status.Errorf(status.NotFound, "route with ID %s not found", routeID)
|
return nil, status.Errorf(status.NotFound, "route with ID %s not found", routeID)
|
||||||
},
|
},
|
||||||
CreateRouteFunc: func(accountID string, network, peer, description, netID string, masquerade bool, metric int, enabled bool) (*route.Route, error) {
|
CreateRouteFunc: func(accountID string, network, peer, description, netID string, masquerade bool, metric int, groups []string, enabled bool) (*route.Route, error) {
|
||||||
networkType, p, _ := route.ParseNetwork(network)
|
networkType, p, _ := route.ParseNetwork(network)
|
||||||
return &route.Route{
|
return &route.Route{
|
||||||
ID: existingRouteID,
|
ID: existingRouteID,
|
||||||
@ -75,6 +77,7 @@ func initRoutesTestData() *Routes {
|
|||||||
Description: description,
|
Description: description,
|
||||||
Masquerade: masquerade,
|
Masquerade: masquerade,
|
||||||
Enabled: enabled,
|
Enabled: enabled,
|
||||||
|
Groups: groups,
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
SaveRouteFunc: func(_ string, _ *route.Route) error {
|
SaveRouteFunc: func(_ string, _ *route.Route) error {
|
||||||
@ -116,6 +119,8 @@ func initRoutesTestData() *Routes {
|
|||||||
routeToUpdate.Masquerade, _ = strconv.ParseBool(operation.Values[0])
|
routeToUpdate.Masquerade, _ = strconv.ParseBool(operation.Values[0])
|
||||||
case server.UpdateRouteEnabled:
|
case server.UpdateRouteEnabled:
|
||||||
routeToUpdate.Enabled, _ = strconv.ParseBool(operation.Values[0])
|
routeToUpdate.Enabled, _ = strconv.ParseBool(operation.Values[0])
|
||||||
|
case server.UpdateRouteGroups:
|
||||||
|
routeToUpdate.Groups = operation.Values
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("no operation")
|
return nil, fmt.Errorf("no operation")
|
||||||
}
|
}
|
||||||
@ -181,7 +186,7 @@ func TestRoutesHandlers(t *testing.T) {
|
|||||||
requestType: http.MethodPost,
|
requestType: http.MethodPost,
|
||||||
requestPath: "/api/routes",
|
requestPath: "/api/routes",
|
||||||
requestBody: bytes.NewBuffer(
|
requestBody: bytes.NewBuffer(
|
||||||
[]byte(fmt.Sprintf("{\"Description\":\"Post\",\"Network\":\"192.168.0.0/16\",\"network_id\":\"awesomeNet\",\"Peer\":\"%s\"}", existingPeerID))),
|
[]byte(fmt.Sprintf("{\"Description\":\"Post\",\"Network\":\"192.168.0.0/16\",\"network_id\":\"awesomeNet\",\"Peer\":\"%s\",\"groups\":[\"%s\"]}", existingPeerID, existingGroupID))),
|
||||||
expectedStatus: http.StatusOK,
|
expectedStatus: http.StatusOK,
|
||||||
expectedBody: true,
|
expectedBody: true,
|
||||||
expectedRoute: &api.Route{
|
expectedRoute: &api.Route{
|
||||||
@ -193,13 +198,14 @@ func TestRoutesHandlers(t *testing.T) {
|
|||||||
NetworkType: route.IPv4NetworkString,
|
NetworkType: route.IPv4NetworkString,
|
||||||
Masquerade: false,
|
Masquerade: false,
|
||||||
Enabled: false,
|
Enabled: false,
|
||||||
|
Groups: []string{existingGroupID},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "POST Not Found Peer",
|
name: "POST Not Found Peer",
|
||||||
requestType: http.MethodPost,
|
requestType: http.MethodPost,
|
||||||
requestPath: "/api/routes",
|
requestPath: "/api/routes",
|
||||||
requestBody: bytes.NewBufferString(fmt.Sprintf("{\"Description\":\"Post\",\"Network\":\"192.168.0.0/16\",\"network_id\":\"awesomeNet\",\"Peer\":\"%s\"}", notFoundPeerID)),
|
requestBody: bytes.NewBufferString(fmt.Sprintf("{\"Description\":\"Post\",\"Network\":\"192.168.0.0/16\",\"network_id\":\"awesomeNet\",\"Peer\":\"%s\",\"groups\":[\"%s\"]}", notFoundPeerID, existingGroupID)),
|
||||||
expectedStatus: http.StatusNotFound,
|
expectedStatus: http.StatusNotFound,
|
||||||
expectedBody: false,
|
expectedBody: false,
|
||||||
},
|
},
|
||||||
@ -207,7 +213,7 @@ func TestRoutesHandlers(t *testing.T) {
|
|||||||
name: "POST Invalid Network Identifier",
|
name: "POST Invalid Network Identifier",
|
||||||
requestType: http.MethodPost,
|
requestType: http.MethodPost,
|
||||||
requestPath: "/api/routes",
|
requestPath: "/api/routes",
|
||||||
requestBody: bytes.NewBufferString(fmt.Sprintf("{\"Description\":\"Post\",\"Network\":\"192.168.0.0/16\",\"network_id\":\"12345678901234567890qwertyuiopqwertyuiop1\",\"Peer\":\"%s\"}", existingPeerID)),
|
requestBody: bytes.NewBufferString(fmt.Sprintf("{\"Description\":\"Post\",\"Network\":\"192.168.0.0/16\",\"network_id\":\"12345678901234567890qwertyuiopqwertyuiop1\",\"Peer\":\"%s\",\"groups\":[\"%s\"]}", existingPeerID, existingGroupID)),
|
||||||
expectedStatus: http.StatusUnprocessableEntity,
|
expectedStatus: http.StatusUnprocessableEntity,
|
||||||
expectedBody: false,
|
expectedBody: false,
|
||||||
},
|
},
|
||||||
@ -215,7 +221,7 @@ func TestRoutesHandlers(t *testing.T) {
|
|||||||
name: "POST Invalid Network",
|
name: "POST Invalid Network",
|
||||||
requestType: http.MethodPost,
|
requestType: http.MethodPost,
|
||||||
requestPath: "/api/routes",
|
requestPath: "/api/routes",
|
||||||
requestBody: bytes.NewBufferString(fmt.Sprintf("{\"Description\":\"Post\",\"Network\":\"192.168.0.0/34\",\"network_id\":\"awesomeNet\",\"Peer\":\"%s\"}", existingPeerID)),
|
requestBody: bytes.NewBufferString(fmt.Sprintf("{\"Description\":\"Post\",\"Network\":\"192.168.0.0/34\",\"network_id\":\"awesomeNet\",\"Peer\":\"%s\",\"groups\":[\"%s\"]}", existingPeerID, existingGroupID)),
|
||||||
expectedStatus: http.StatusUnprocessableEntity,
|
expectedStatus: http.StatusUnprocessableEntity,
|
||||||
expectedBody: false,
|
expectedBody: false,
|
||||||
},
|
},
|
||||||
@ -223,7 +229,7 @@ func TestRoutesHandlers(t *testing.T) {
|
|||||||
name: "PUT OK",
|
name: "PUT OK",
|
||||||
requestType: http.MethodPut,
|
requestType: http.MethodPut,
|
||||||
requestPath: "/api/routes/" + existingRouteID,
|
requestPath: "/api/routes/" + existingRouteID,
|
||||||
requestBody: bytes.NewBufferString(fmt.Sprintf("{\"Description\":\"Post\",\"Network\":\"192.168.0.0/16\",\"network_id\":\"awesomeNet\",\"Peer\":\"%s\"}", existingPeerID)),
|
requestBody: bytes.NewBufferString(fmt.Sprintf("{\"Description\":\"Post\",\"Network\":\"192.168.0.0/16\",\"network_id\":\"awesomeNet\",\"Peer\":\"%s\",\"groups\":[\"%s\"]}", existingPeerID, existingGroupID)),
|
||||||
expectedStatus: http.StatusOK,
|
expectedStatus: http.StatusOK,
|
||||||
expectedBody: true,
|
expectedBody: true,
|
||||||
expectedRoute: &api.Route{
|
expectedRoute: &api.Route{
|
||||||
@ -235,13 +241,14 @@ func TestRoutesHandlers(t *testing.T) {
|
|||||||
NetworkType: route.IPv4NetworkString,
|
NetworkType: route.IPv4NetworkString,
|
||||||
Masquerade: false,
|
Masquerade: false,
|
||||||
Enabled: false,
|
Enabled: false,
|
||||||
|
Groups: []string{existingGroupID},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "PUT Not Found Route",
|
name: "PUT Not Found Route",
|
||||||
requestType: http.MethodPut,
|
requestType: http.MethodPut,
|
||||||
requestPath: "/api/routes/" + notFoundRouteID,
|
requestPath: "/api/routes/" + notFoundRouteID,
|
||||||
requestBody: bytes.NewBufferString(fmt.Sprintf("{\"Description\":\"Post\",\"Network\":\"192.168.0.0/16\",\"network_id\":\"awesomeNet\",\"Peer\":\"%s\"}", existingPeerID)),
|
requestBody: bytes.NewBufferString(fmt.Sprintf("{\"Description\":\"Post\",\"Network\":\"192.168.0.0/16\",\"network_id\":\"awesomeNet\",\"Peer\":\"%s\",\"groups\":[\"%s\"]}", existingPeerID, existingGroupID)),
|
||||||
expectedStatus: http.StatusNotFound,
|
expectedStatus: http.StatusNotFound,
|
||||||
expectedBody: false,
|
expectedBody: false,
|
||||||
},
|
},
|
||||||
@ -249,7 +256,7 @@ func TestRoutesHandlers(t *testing.T) {
|
|||||||
name: "PUT Not Found Peer",
|
name: "PUT Not Found Peer",
|
||||||
requestType: http.MethodPut,
|
requestType: http.MethodPut,
|
||||||
requestPath: "/api/routes/" + existingRouteID,
|
requestPath: "/api/routes/" + existingRouteID,
|
||||||
requestBody: bytes.NewBufferString(fmt.Sprintf("{\"Description\":\"Post\",\"Network\":\"192.168.0.0/16\",\"network_id\":\"awesomeNet\",\"Peer\":\"%s\"}", notFoundPeerID)),
|
requestBody: bytes.NewBufferString(fmt.Sprintf("{\"Description\":\"Post\",\"Network\":\"192.168.0.0/16\",\"network_id\":\"awesomeNet\",\"Peer\":\"%s\",\"groups\":[\"%s\"]}", notFoundPeerID, existingGroupID)),
|
||||||
expectedStatus: http.StatusNotFound,
|
expectedStatus: http.StatusNotFound,
|
||||||
expectedBody: false,
|
expectedBody: false,
|
||||||
},
|
},
|
||||||
@ -257,7 +264,7 @@ func TestRoutesHandlers(t *testing.T) {
|
|||||||
name: "PUT Invalid Network Identifier",
|
name: "PUT Invalid Network Identifier",
|
||||||
requestType: http.MethodPut,
|
requestType: http.MethodPut,
|
||||||
requestPath: "/api/routes/" + existingRouteID,
|
requestPath: "/api/routes/" + existingRouteID,
|
||||||
requestBody: bytes.NewBufferString(fmt.Sprintf("{\"Description\":\"Post\",\"Network\":\"192.168.0.0/16\",\"network_id\":\"12345678901234567890qwertyuiopqwertyuiop1\",\"Peer\":\"%s\"}", existingPeerID)),
|
requestBody: bytes.NewBufferString(fmt.Sprintf("{\"Description\":\"Post\",\"Network\":\"192.168.0.0/16\",\"network_id\":\"12345678901234567890qwertyuiopqwertyuiop1\",\"Peer\":\"%s\",\"groups\":[\"%s\"]}", existingPeerID, existingGroupID)),
|
||||||
expectedStatus: http.StatusUnprocessableEntity,
|
expectedStatus: http.StatusUnprocessableEntity,
|
||||||
expectedBody: false,
|
expectedBody: false,
|
||||||
},
|
},
|
||||||
@ -265,7 +272,7 @@ func TestRoutesHandlers(t *testing.T) {
|
|||||||
name: "PUT Invalid Network",
|
name: "PUT Invalid Network",
|
||||||
requestType: http.MethodPut,
|
requestType: http.MethodPut,
|
||||||
requestPath: "/api/routes/" + existingRouteID,
|
requestPath: "/api/routes/" + existingRouteID,
|
||||||
requestBody: bytes.NewBufferString(fmt.Sprintf("{\"Description\":\"Post\",\"Network\":\"192.168.0.0/34\",\"network_id\":\"awesomeNet\",\"Peer\":\"%s\"}", existingPeerID)),
|
requestBody: bytes.NewBufferString(fmt.Sprintf("{\"Description\":\"Post\",\"Network\":\"192.168.0.0/34\",\"network_id\":\"awesomeNet\",\"Peer\":\"%s\",\"groups\":[\"%s\"]}", existingPeerID, existingGroupID)),
|
||||||
expectedStatus: http.StatusUnprocessableEntity,
|
expectedStatus: http.StatusUnprocessableEntity,
|
||||||
expectedBody: false,
|
expectedBody: false,
|
||||||
},
|
},
|
||||||
@ -285,6 +292,7 @@ func TestRoutesHandlers(t *testing.T) {
|
|||||||
Masquerade: baseExistingRoute.Masquerade,
|
Masquerade: baseExistingRoute.Masquerade,
|
||||||
Enabled: baseExistingRoute.Enabled,
|
Enabled: baseExistingRoute.Enabled,
|
||||||
Metric: baseExistingRoute.Metric,
|
Metric: baseExistingRoute.Metric,
|
||||||
|
Groups: baseExistingRoute.Groups,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -304,6 +312,7 @@ func TestRoutesHandlers(t *testing.T) {
|
|||||||
Masquerade: baseExistingRoute.Masquerade,
|
Masquerade: baseExistingRoute.Masquerade,
|
||||||
Enabled: baseExistingRoute.Enabled,
|
Enabled: baseExistingRoute.Enabled,
|
||||||
Metric: baseExistingRoute.Metric,
|
Metric: baseExistingRoute.Metric,
|
||||||
|
Groups: baseExistingRoute.Groups,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -43,7 +43,7 @@ type MockAccountManager struct {
|
|||||||
UpdatePeerMetaFunc func(peerKey string, meta server.PeerSystemMeta) error
|
UpdatePeerMetaFunc func(peerKey string, meta server.PeerSystemMeta) error
|
||||||
UpdatePeerSSHKeyFunc func(peerKey string, sshKey string) error
|
UpdatePeerSSHKeyFunc func(peerKey string, sshKey string) error
|
||||||
UpdatePeerFunc func(accountID string, peer *server.Peer) (*server.Peer, error)
|
UpdatePeerFunc func(accountID string, peer *server.Peer) (*server.Peer, error)
|
||||||
CreateRouteFunc func(accountID string, prefix, peer, description, netID string, masquerade bool, metric int, enabled bool) (*route.Route, error)
|
CreateRouteFunc func(accountID string, prefix, peer, description, netID string, masquerade bool, metric int, groups []string, enabled bool) (*route.Route, error)
|
||||||
GetRouteFunc func(accountID, routeID, userID string) (*route.Route, error)
|
GetRouteFunc func(accountID, routeID, userID string) (*route.Route, error)
|
||||||
SaveRouteFunc func(accountID string, route *route.Route) error
|
SaveRouteFunc func(accountID string, route *route.Route) error
|
||||||
UpdateRouteFunc func(accountID string, routeID string, operations []server.RouteUpdateOperation) (*route.Route, error)
|
UpdateRouteFunc func(accountID string, routeID string, operations []server.RouteUpdateOperation) (*route.Route, error)
|
||||||
@ -325,9 +325,9 @@ func (am *MockAccountManager) UpdatePeer(accountID string, peer *server.Peer) (*
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateRoute mock implementation of CreateRoute from server.AccountManager interface
|
// CreateRoute mock implementation of CreateRoute from server.AccountManager interface
|
||||||
func (am *MockAccountManager) CreateRoute(accountID string, network, peer, description, netID string, masquerade bool, metric int, enabled bool) (*route.Route, error) {
|
func (am *MockAccountManager) CreateRoute(accountID string, network, peer, description, netID string, masquerade bool, metric int, groups []string, enabled bool) (*route.Route, error) {
|
||||||
if am.CreateRouteFunc != nil {
|
if am.CreateRouteFunc != nil {
|
||||||
return am.CreateRouteFunc(accountID, network, peer, description, netID, masquerade, metric, enabled)
|
return am.CreateRouteFunc(accountID, network, peer, description, netID, masquerade, metric, groups, enabled)
|
||||||
}
|
}
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method CreateRoute is not implemented")
|
return nil, status.Errorf(codes.Unimplemented, "method CreateRoute is not implemented")
|
||||||
}
|
}
|
||||||
|
@ -120,7 +120,7 @@ func (am *DefaultAccountManager) GetPeers(accountID, userID string) ([]*Peer, er
|
|||||||
|
|
||||||
// fetch all the peers that have access to the user's peers
|
// fetch all the peers that have access to the user's peers
|
||||||
for _, peer := range peers {
|
for _, peer := range peers {
|
||||||
aclPeers := am.getPeersByACL(account, peer.Key)
|
aclPeers := account.getPeersByACL(peer.Key)
|
||||||
for _, p := range aclPeers {
|
for _, p := range aclPeers {
|
||||||
peersMap[p.Key] = p
|
peersMap[p.Key] = p
|
||||||
}
|
}
|
||||||
@ -293,8 +293,8 @@ func (am *DefaultAccountManager) GetNetworkMap(peerPubKey string) (*NetworkMap,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
aclPeers := am.getPeersByACL(account, peerPubKey)
|
aclPeers := account.getPeersByACL(peerPubKey)
|
||||||
routesUpdate := account.GetPeersRoutes(append(aclPeers, account.Peers[peerPubKey]))
|
routesUpdate := account.getRoutesToSync(peerPubKey, aclPeers)
|
||||||
|
|
||||||
var zones []nbdns.CustomZone
|
var zones []nbdns.CustomZone
|
||||||
peersCustomZone := getPeersCustomZone(account, am.dnsDomain)
|
peersCustomZone := getPeersCustomZone(account, am.dnsDomain)
|
||||||
@ -515,9 +515,9 @@ func (am *DefaultAccountManager) UpdatePeerMeta(peerPubKey string, meta PeerSyst
|
|||||||
}
|
}
|
||||||
|
|
||||||
// getPeersByACL returns all peers that given peer has access to.
|
// getPeersByACL returns all peers that given peer has access to.
|
||||||
func (am *DefaultAccountManager) getPeersByACL(account *Account, peerPubKey string) []*Peer {
|
func (a *Account) getPeersByACL(peerPubKey string) []*Peer {
|
||||||
var peers []*Peer
|
var peers []*Peer
|
||||||
srcRules, dstRules := account.GetPeerRules(peerPubKey)
|
srcRules, dstRules := a.GetPeerRules(peerPubKey)
|
||||||
|
|
||||||
groups := map[string]*Group{}
|
groups := map[string]*Group{}
|
||||||
for _, r := range srcRules {
|
for _, r := range srcRules {
|
||||||
@ -526,7 +526,7 @@ func (am *DefaultAccountManager) getPeersByACL(account *Account, peerPubKey stri
|
|||||||
}
|
}
|
||||||
if r.Flow == TrafficFlowBidirect {
|
if r.Flow == TrafficFlowBidirect {
|
||||||
for _, gid := range r.Destination {
|
for _, gid := range r.Destination {
|
||||||
if group, ok := account.Groups[gid]; ok {
|
if group, ok := a.Groups[gid]; ok {
|
||||||
groups[gid] = group
|
groups[gid] = group
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -539,7 +539,7 @@ func (am *DefaultAccountManager) getPeersByACL(account *Account, peerPubKey stri
|
|||||||
}
|
}
|
||||||
if r.Flow == TrafficFlowBidirect {
|
if r.Flow == TrafficFlowBidirect {
|
||||||
for _, gid := range r.Source {
|
for _, gid := range r.Source {
|
||||||
if group, ok := account.Groups[gid]; ok {
|
if group, ok := a.Groups[gid]; ok {
|
||||||
groups[gid] = group
|
groups[gid] = group
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -549,13 +549,13 @@ func (am *DefaultAccountManager) getPeersByACL(account *Account, peerPubKey stri
|
|||||||
peersSet := make(map[string]struct{})
|
peersSet := make(map[string]struct{})
|
||||||
for _, g := range groups {
|
for _, g := range groups {
|
||||||
for _, pid := range g.Peers {
|
for _, pid := range g.Peers {
|
||||||
peer, ok := account.Peers[pid]
|
peer, ok := a.Peers[pid]
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Warnf(
|
log.Warnf(
|
||||||
"peer %s found in group %s but doesn't belong to account %s",
|
"peer %s found in group %s but doesn't belong to account %s",
|
||||||
pid,
|
pid,
|
||||||
g.ID,
|
g.ID,
|
||||||
account.Id,
|
a.Id,
|
||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,8 @@ const (
|
|||||||
UpdateRouteEnabled
|
UpdateRouteEnabled
|
||||||
// UpdateRouteNetworkIdentifier indicates a route net ID update operation
|
// UpdateRouteNetworkIdentifier indicates a route net ID update operation
|
||||||
UpdateRouteNetworkIdentifier
|
UpdateRouteNetworkIdentifier
|
||||||
|
// UpdateRouteGroups indicates a group list update operation
|
||||||
|
UpdateRouteGroups
|
||||||
)
|
)
|
||||||
|
|
||||||
// RouteUpdateOperationType operation type
|
// RouteUpdateOperationType operation type
|
||||||
@ -47,6 +49,8 @@ func (t RouteUpdateOperationType) String() string {
|
|||||||
return "UpdateRouteEnabled"
|
return "UpdateRouteEnabled"
|
||||||
case UpdateRouteNetworkIdentifier:
|
case UpdateRouteNetworkIdentifier:
|
||||||
return "UpdateRouteNetworkIdentifier"
|
return "UpdateRouteNetworkIdentifier"
|
||||||
|
case UpdateRouteGroups:
|
||||||
|
return "UpdateRouteGroups"
|
||||||
default:
|
default:
|
||||||
return "InvalidOperation"
|
return "InvalidOperation"
|
||||||
}
|
}
|
||||||
@ -114,7 +118,7 @@ func (am *DefaultAccountManager) checkPrefixPeerExists(accountID, peer string, p
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateRoute creates and saves a new route
|
// CreateRoute creates and saves a new route
|
||||||
func (am *DefaultAccountManager) CreateRoute(accountID string, network, peer, description, netID string, masquerade bool, metric int, enabled bool) (*route.Route, error) {
|
func (am *DefaultAccountManager) CreateRoute(accountID string, network, peer, description, netID string, masquerade bool, metric int, groups []string, enabled bool) (*route.Route, error) {
|
||||||
unlock := am.Store.AcquireAccountLock(accountID)
|
unlock := am.Store.AcquireAccountLock(accountID)
|
||||||
defer unlock()
|
defer unlock()
|
||||||
|
|
||||||
@ -148,6 +152,11 @@ func (am *DefaultAccountManager) CreateRoute(accountID string, network, peer, de
|
|||||||
return nil, status.Errorf(status.InvalidArgument, "identifier should be between 1 and %d", route.MaxNetIDChar)
|
return nil, status.Errorf(status.InvalidArgument, "identifier should be between 1 and %d", route.MaxNetIDChar)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = validateGroups(groups, account.Groups)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
newRoute.Peer = peer
|
newRoute.Peer = peer
|
||||||
newRoute.ID = xid.New().String()
|
newRoute.ID = xid.New().String()
|
||||||
newRoute.Network = newPrefix
|
newRoute.Network = newPrefix
|
||||||
@ -157,6 +166,7 @@ func (am *DefaultAccountManager) CreateRoute(accountID string, network, peer, de
|
|||||||
newRoute.Masquerade = masquerade
|
newRoute.Masquerade = masquerade
|
||||||
newRoute.Metric = metric
|
newRoute.Metric = metric
|
||||||
newRoute.Enabled = enabled
|
newRoute.Enabled = enabled
|
||||||
|
newRoute.Groups = groups
|
||||||
|
|
||||||
if account.Routes == nil {
|
if account.Routes == nil {
|
||||||
account.Routes = make(map[string]*route.Route)
|
account.Routes = make(map[string]*route.Route)
|
||||||
@ -210,6 +220,11 @@ func (am *DefaultAccountManager) SaveRoute(accountID string, routeToSave *route.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = validateGroups(routeToSave.Groups, account.Groups)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
account.Routes[routeToSave.ID] = routeToSave
|
account.Routes[routeToSave.ID] = routeToSave
|
||||||
|
|
||||||
account.Network.IncSerial()
|
account.Network.IncSerial()
|
||||||
@ -300,6 +315,12 @@ func (am *DefaultAccountManager) UpdateRoute(accountID, routeID string, operatio
|
|||||||
return nil, status.Errorf(status.InvalidArgument, "failed to parse enabled %s, not boolean", operation.Values[0])
|
return nil, status.Errorf(status.InvalidArgument, "failed to parse enabled %s, not boolean", operation.Values[0])
|
||||||
}
|
}
|
||||||
newRoute.Enabled = enabled
|
newRoute.Enabled = enabled
|
||||||
|
case UpdateRouteGroups:
|
||||||
|
err = validateGroups(operation.Values, account.Groups)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
newRoute.Groups = operation.Values
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,8 +8,13 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
const peer1Key = "BhRPtynAAYRDy08+q4HTMsos8fs4plTP4NOSh7C1ry8="
|
const (
|
||||||
const peer2Key = "/yF0+vCfv+mRR5k0dca0TrGdO/oiNeAI58gToZm5NyI="
|
peer1Key = "BhRPtynAAYRDy08+q4HTMsos8fs4plTP4NOSh7C1ry8="
|
||||||
|
peer2Key = "/yF0+vCfv+mRR5k0dca0TrGdO/oiNeAI58gToZm5NyI="
|
||||||
|
routeGroup1 = "routeGroup1"
|
||||||
|
routeGroup2 = "routeGroup2"
|
||||||
|
routeInvalidGroup1 = "routeInvalidGroup1"
|
||||||
|
)
|
||||||
|
|
||||||
func TestCreateRoute(t *testing.T) {
|
func TestCreateRoute(t *testing.T) {
|
||||||
|
|
||||||
@ -21,6 +26,7 @@ func TestCreateRoute(t *testing.T) {
|
|||||||
masquerade bool
|
masquerade bool
|
||||||
metric int
|
metric int
|
||||||
enabled bool
|
enabled bool
|
||||||
|
groups []string
|
||||||
}
|
}
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
@ -40,6 +46,7 @@ func TestCreateRoute(t *testing.T) {
|
|||||||
masquerade: false,
|
masquerade: false,
|
||||||
metric: 9999,
|
metric: 9999,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
groups: []string{routeGroup1},
|
||||||
},
|
},
|
||||||
errFunc: require.NoError,
|
errFunc: require.NoError,
|
||||||
shouldCreate: true,
|
shouldCreate: true,
|
||||||
@ -52,10 +59,11 @@ func TestCreateRoute(t *testing.T) {
|
|||||||
Masquerade: false,
|
Masquerade: false,
|
||||||
Metric: 9999,
|
Metric: 9999,
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
|
Groups: []string{routeGroup1},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Bad Prefix",
|
name: "Bad Prefix Should Fail",
|
||||||
inputArgs: input{
|
inputArgs: input{
|
||||||
network: "192.168.0.0/34",
|
network: "192.168.0.0/34",
|
||||||
netID: "happy",
|
netID: "happy",
|
||||||
@ -64,12 +72,13 @@ func TestCreateRoute(t *testing.T) {
|
|||||||
masquerade: false,
|
masquerade: false,
|
||||||
metric: 9999,
|
metric: 9999,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
groups: []string{routeGroup1},
|
||||||
},
|
},
|
||||||
errFunc: require.Error,
|
errFunc: require.Error,
|
||||||
shouldCreate: false,
|
shouldCreate: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Bad Peer",
|
name: "Bad Peer Should Fail",
|
||||||
inputArgs: input{
|
inputArgs: input{
|
||||||
network: "192.168.0.0/16",
|
network: "192.168.0.0/16",
|
||||||
netID: "happy",
|
netID: "happy",
|
||||||
@ -78,12 +87,13 @@ func TestCreateRoute(t *testing.T) {
|
|||||||
masquerade: false,
|
masquerade: false,
|
||||||
metric: 9999,
|
metric: 9999,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
groups: []string{routeGroup1},
|
||||||
},
|
},
|
||||||
errFunc: require.Error,
|
errFunc: require.Error,
|
||||||
shouldCreate: false,
|
shouldCreate: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Empty Peer",
|
name: "Empty Peer Should Create",
|
||||||
inputArgs: input{
|
inputArgs: input{
|
||||||
network: "192.168.0.0/16",
|
network: "192.168.0.0/16",
|
||||||
netID: "happy",
|
netID: "happy",
|
||||||
@ -92,6 +102,7 @@ func TestCreateRoute(t *testing.T) {
|
|||||||
masquerade: false,
|
masquerade: false,
|
||||||
metric: 9999,
|
metric: 9999,
|
||||||
enabled: false,
|
enabled: false,
|
||||||
|
groups: []string{routeGroup1},
|
||||||
},
|
},
|
||||||
errFunc: require.NoError,
|
errFunc: require.NoError,
|
||||||
shouldCreate: true,
|
shouldCreate: true,
|
||||||
@ -104,10 +115,11 @@ func TestCreateRoute(t *testing.T) {
|
|||||||
Masquerade: false,
|
Masquerade: false,
|
||||||
Metric: 9999,
|
Metric: 9999,
|
||||||
Enabled: false,
|
Enabled: false,
|
||||||
|
Groups: []string{routeGroup1},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Large Metric",
|
name: "Large Metric Should Fail",
|
||||||
inputArgs: input{
|
inputArgs: input{
|
||||||
network: "192.168.0.0/16",
|
network: "192.168.0.0/16",
|
||||||
peer: peer1Key,
|
peer: peer1Key,
|
||||||
@ -116,12 +128,13 @@ func TestCreateRoute(t *testing.T) {
|
|||||||
masquerade: false,
|
masquerade: false,
|
||||||
metric: 99999,
|
metric: 99999,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
groups: []string{routeGroup1},
|
||||||
},
|
},
|
||||||
errFunc: require.Error,
|
errFunc: require.Error,
|
||||||
shouldCreate: false,
|
shouldCreate: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Small Metric",
|
name: "Small Metric Should Fail",
|
||||||
inputArgs: input{
|
inputArgs: input{
|
||||||
network: "192.168.0.0/16",
|
network: "192.168.0.0/16",
|
||||||
netID: "happy",
|
netID: "happy",
|
||||||
@ -130,12 +143,13 @@ func TestCreateRoute(t *testing.T) {
|
|||||||
masquerade: false,
|
masquerade: false,
|
||||||
metric: 0,
|
metric: 0,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
groups: []string{routeGroup1},
|
||||||
},
|
},
|
||||||
errFunc: require.Error,
|
errFunc: require.Error,
|
||||||
shouldCreate: false,
|
shouldCreate: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Large NetID",
|
name: "Large NetID Should Fail",
|
||||||
inputArgs: input{
|
inputArgs: input{
|
||||||
network: "192.168.0.0/16",
|
network: "192.168.0.0/16",
|
||||||
peer: peer1Key,
|
peer: peer1Key,
|
||||||
@ -144,12 +158,13 @@ func TestCreateRoute(t *testing.T) {
|
|||||||
masquerade: false,
|
masquerade: false,
|
||||||
metric: 9999,
|
metric: 9999,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
groups: []string{routeGroup1},
|
||||||
},
|
},
|
||||||
errFunc: require.Error,
|
errFunc: require.Error,
|
||||||
shouldCreate: false,
|
shouldCreate: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Small NetID",
|
name: "Small NetID Should Fail",
|
||||||
inputArgs: input{
|
inputArgs: input{
|
||||||
network: "192.168.0.0/16",
|
network: "192.168.0.0/16",
|
||||||
netID: "",
|
netID: "",
|
||||||
@ -158,6 +173,52 @@ func TestCreateRoute(t *testing.T) {
|
|||||||
masquerade: false,
|
masquerade: false,
|
||||||
metric: 9999,
|
metric: 9999,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
groups: []string{routeGroup1},
|
||||||
|
},
|
||||||
|
errFunc: require.Error,
|
||||||
|
shouldCreate: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Empty Group List Should Fail",
|
||||||
|
inputArgs: input{
|
||||||
|
network: "192.168.0.0/16",
|
||||||
|
netID: "NewId",
|
||||||
|
peer: peer1Key,
|
||||||
|
description: "",
|
||||||
|
masquerade: false,
|
||||||
|
metric: 9999,
|
||||||
|
enabled: true,
|
||||||
|
groups: []string{},
|
||||||
|
},
|
||||||
|
errFunc: require.Error,
|
||||||
|
shouldCreate: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Empty Group ID string Should Fail",
|
||||||
|
inputArgs: input{
|
||||||
|
network: "192.168.0.0/16",
|
||||||
|
netID: "NewId",
|
||||||
|
peer: peer1Key,
|
||||||
|
description: "",
|
||||||
|
masquerade: false,
|
||||||
|
metric: 9999,
|
||||||
|
enabled: true,
|
||||||
|
groups: []string{""},
|
||||||
|
},
|
||||||
|
errFunc: require.Error,
|
||||||
|
shouldCreate: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Invalid Group Should Fail",
|
||||||
|
inputArgs: input{
|
||||||
|
network: "192.168.0.0/16",
|
||||||
|
netID: "NewId",
|
||||||
|
peer: peer1Key,
|
||||||
|
description: "",
|
||||||
|
masquerade: false,
|
||||||
|
metric: 9999,
|
||||||
|
enabled: true,
|
||||||
|
groups: []string{routeInvalidGroup1},
|
||||||
},
|
},
|
||||||
errFunc: require.Error,
|
errFunc: require.Error,
|
||||||
shouldCreate: false,
|
shouldCreate: false,
|
||||||
@ -183,6 +244,7 @@ func TestCreateRoute(t *testing.T) {
|
|||||||
testCase.inputArgs.netID,
|
testCase.inputArgs.netID,
|
||||||
testCase.inputArgs.masquerade,
|
testCase.inputArgs.masquerade,
|
||||||
testCase.inputArgs.metric,
|
testCase.inputArgs.metric,
|
||||||
|
testCase.inputArgs.groups,
|
||||||
testCase.inputArgs.enabled,
|
testCase.inputArgs.enabled,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -220,6 +282,7 @@ func TestSaveRoute(t *testing.T) {
|
|||||||
newPeer *string
|
newPeer *string
|
||||||
newMetric *int
|
newMetric *int
|
||||||
newPrefix *netip.Prefix
|
newPrefix *netip.Prefix
|
||||||
|
newGroups []string
|
||||||
skipCopying bool
|
skipCopying bool
|
||||||
shouldCreate bool
|
shouldCreate bool
|
||||||
errFunc require.ErrorAssertionFunc
|
errFunc require.ErrorAssertionFunc
|
||||||
@ -237,10 +300,12 @@ func TestSaveRoute(t *testing.T) {
|
|||||||
Masquerade: false,
|
Masquerade: false,
|
||||||
Metric: 9999,
|
Metric: 9999,
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
|
Groups: []string{routeGroup1},
|
||||||
},
|
},
|
||||||
newPeer: &validPeer,
|
newPeer: &validPeer,
|
||||||
newMetric: &validMetric,
|
newMetric: &validMetric,
|
||||||
newPrefix: &validPrefix,
|
newPrefix: &validPrefix,
|
||||||
|
newGroups: []string{routeGroup2},
|
||||||
errFunc: require.NoError,
|
errFunc: require.NoError,
|
||||||
shouldCreate: true,
|
shouldCreate: true,
|
||||||
expectedRoute: &route.Route{
|
expectedRoute: &route.Route{
|
||||||
@ -253,10 +318,11 @@ func TestSaveRoute(t *testing.T) {
|
|||||||
Masquerade: false,
|
Masquerade: false,
|
||||||
Metric: validMetric,
|
Metric: validMetric,
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
|
Groups: []string{routeGroup2},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Bad Prefix",
|
name: "Bad Prefix Should Fail",
|
||||||
existingRoute: &route.Route{
|
existingRoute: &route.Route{
|
||||||
ID: "testingRoute",
|
ID: "testingRoute",
|
||||||
Network: netip.MustParsePrefix("192.168.0.0/16"),
|
Network: netip.MustParsePrefix("192.168.0.0/16"),
|
||||||
@ -267,12 +333,13 @@ func TestSaveRoute(t *testing.T) {
|
|||||||
Masquerade: false,
|
Masquerade: false,
|
||||||
Metric: 9999,
|
Metric: 9999,
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
|
Groups: []string{routeGroup1},
|
||||||
},
|
},
|
||||||
newPrefix: &invalidPrefix,
|
newPrefix: &invalidPrefix,
|
||||||
errFunc: require.Error,
|
errFunc: require.Error,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Bad Peer",
|
name: "Bad Peer Should Fail",
|
||||||
existingRoute: &route.Route{
|
existingRoute: &route.Route{
|
||||||
ID: "testingRoute",
|
ID: "testingRoute",
|
||||||
Network: netip.MustParsePrefix("192.168.0.0/16"),
|
Network: netip.MustParsePrefix("192.168.0.0/16"),
|
||||||
@ -283,12 +350,13 @@ func TestSaveRoute(t *testing.T) {
|
|||||||
Masquerade: false,
|
Masquerade: false,
|
||||||
Metric: 9999,
|
Metric: 9999,
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
|
Groups: []string{routeGroup1},
|
||||||
},
|
},
|
||||||
newPeer: &invalidPeer,
|
newPeer: &invalidPeer,
|
||||||
errFunc: require.Error,
|
errFunc: require.Error,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Invalid Metric",
|
name: "Invalid Metric Should Fail",
|
||||||
existingRoute: &route.Route{
|
existingRoute: &route.Route{
|
||||||
ID: "testingRoute",
|
ID: "testingRoute",
|
||||||
Network: netip.MustParsePrefix("192.168.0.0/16"),
|
Network: netip.MustParsePrefix("192.168.0.0/16"),
|
||||||
@ -299,12 +367,13 @@ func TestSaveRoute(t *testing.T) {
|
|||||||
Masquerade: false,
|
Masquerade: false,
|
||||||
Metric: 9999,
|
Metric: 9999,
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
|
Groups: []string{routeGroup1},
|
||||||
},
|
},
|
||||||
newMetric: &invalidMetric,
|
newMetric: &invalidMetric,
|
||||||
errFunc: require.Error,
|
errFunc: require.Error,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Invalid NetID",
|
name: "Invalid NetID Should Fail",
|
||||||
existingRoute: &route.Route{
|
existingRoute: &route.Route{
|
||||||
ID: "testingRoute",
|
ID: "testingRoute",
|
||||||
Network: netip.MustParsePrefix("192.168.0.0/16"),
|
Network: netip.MustParsePrefix("192.168.0.0/16"),
|
||||||
@ -315,12 +384,13 @@ func TestSaveRoute(t *testing.T) {
|
|||||||
Masquerade: false,
|
Masquerade: false,
|
||||||
Metric: 9999,
|
Metric: 9999,
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
|
Groups: []string{routeGroup1},
|
||||||
},
|
},
|
||||||
newMetric: &invalidMetric,
|
newMetric: &invalidMetric,
|
||||||
errFunc: require.Error,
|
errFunc: require.Error,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Nil Route",
|
name: "Nil Route Should Fail",
|
||||||
existingRoute: &route.Route{
|
existingRoute: &route.Route{
|
||||||
ID: "testingRoute",
|
ID: "testingRoute",
|
||||||
Network: netip.MustParsePrefix("192.168.0.0/16"),
|
Network: netip.MustParsePrefix("192.168.0.0/16"),
|
||||||
@ -331,10 +401,62 @@ func TestSaveRoute(t *testing.T) {
|
|||||||
Masquerade: false,
|
Masquerade: false,
|
||||||
Metric: 9999,
|
Metric: 9999,
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
|
Groups: []string{routeGroup1},
|
||||||
},
|
},
|
||||||
skipCopying: true,
|
skipCopying: true,
|
||||||
errFunc: require.Error,
|
errFunc: require.Error,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Empty Group List Should Fail",
|
||||||
|
existingRoute: &route.Route{
|
||||||
|
ID: "testingRoute",
|
||||||
|
Network: netip.MustParsePrefix("192.168.0.0/16"),
|
||||||
|
NetID: validNetID,
|
||||||
|
NetworkType: route.IPv4Network,
|
||||||
|
Peer: peer1Key,
|
||||||
|
Description: "super",
|
||||||
|
Masquerade: false,
|
||||||
|
Metric: 9999,
|
||||||
|
Enabled: true,
|
||||||
|
Groups: []string{routeGroup1},
|
||||||
|
},
|
||||||
|
newGroups: []string{},
|
||||||
|
errFunc: require.Error,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Empty Group ID String Should Fail",
|
||||||
|
existingRoute: &route.Route{
|
||||||
|
ID: "testingRoute",
|
||||||
|
Network: netip.MustParsePrefix("192.168.0.0/16"),
|
||||||
|
NetID: validNetID,
|
||||||
|
NetworkType: route.IPv4Network,
|
||||||
|
Peer: peer1Key,
|
||||||
|
Description: "super",
|
||||||
|
Masquerade: false,
|
||||||
|
Metric: 9999,
|
||||||
|
Enabled: true,
|
||||||
|
Groups: []string{routeGroup1},
|
||||||
|
},
|
||||||
|
newGroups: []string{""},
|
||||||
|
errFunc: require.Error,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Invalid Group Should Fail",
|
||||||
|
existingRoute: &route.Route{
|
||||||
|
ID: "testingRoute",
|
||||||
|
Network: netip.MustParsePrefix("192.168.0.0/16"),
|
||||||
|
NetID: validNetID,
|
||||||
|
NetworkType: route.IPv4Network,
|
||||||
|
Peer: peer1Key,
|
||||||
|
Description: "super",
|
||||||
|
Masquerade: false,
|
||||||
|
Metric: 9999,
|
||||||
|
Enabled: true,
|
||||||
|
Groups: []string{routeGroup1},
|
||||||
|
},
|
||||||
|
newGroups: []string{routeInvalidGroup1},
|
||||||
|
errFunc: require.Error,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, testCase := range testCases {
|
for _, testCase := range testCases {
|
||||||
t.Run(testCase.name, func(t *testing.T) {
|
t.Run(testCase.name, func(t *testing.T) {
|
||||||
@ -370,6 +492,10 @@ func TestSaveRoute(t *testing.T) {
|
|||||||
if testCase.newPrefix != nil {
|
if testCase.newPrefix != nil {
|
||||||
routeToSave.Network = *testCase.newPrefix
|
routeToSave.Network = *testCase.newPrefix
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if testCase.newGroups != nil {
|
||||||
|
routeToSave.Groups = testCase.newGroups
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = am.SaveRoute(account.Id, routeToSave)
|
err = am.SaveRoute(account.Id, routeToSave)
|
||||||
@ -409,6 +535,7 @@ func TestUpdateRoute(t *testing.T) {
|
|||||||
Masquerade: false,
|
Masquerade: false,
|
||||||
Metric: 9999,
|
Metric: 9999,
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
|
Groups: []string{routeGroup1},
|
||||||
}
|
}
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
@ -423,7 +550,7 @@ func TestUpdateRoute(t *testing.T) {
|
|||||||
name: "Happy Path Single OPS",
|
name: "Happy Path Single OPS",
|
||||||
existingRoute: existingRoute,
|
existingRoute: existingRoute,
|
||||||
operations: []RouteUpdateOperation{
|
operations: []RouteUpdateOperation{
|
||||||
RouteUpdateOperation{
|
{
|
||||||
Type: UpdateRoutePeer,
|
Type: UpdateRoutePeer,
|
||||||
Values: []string{peer2Key},
|
Values: []string{peer2Key},
|
||||||
},
|
},
|
||||||
@ -440,40 +567,45 @@ func TestUpdateRoute(t *testing.T) {
|
|||||||
Masquerade: false,
|
Masquerade: false,
|
||||||
Metric: 9999,
|
Metric: 9999,
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
|
Groups: []string{routeGroup1},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Happy Path Multiple OPS",
|
name: "Happy Path Multiple OPS",
|
||||||
existingRoute: existingRoute,
|
existingRoute: existingRoute,
|
||||||
operations: []RouteUpdateOperation{
|
operations: []RouteUpdateOperation{
|
||||||
RouteUpdateOperation{
|
{
|
||||||
Type: UpdateRouteDescription,
|
Type: UpdateRouteDescription,
|
||||||
Values: []string{"great"},
|
Values: []string{"great"},
|
||||||
},
|
},
|
||||||
RouteUpdateOperation{
|
{
|
||||||
Type: UpdateRouteNetwork,
|
Type: UpdateRouteNetwork,
|
||||||
Values: []string{"192.168.0.0/24"},
|
Values: []string{"192.168.0.0/24"},
|
||||||
},
|
},
|
||||||
RouteUpdateOperation{
|
{
|
||||||
Type: UpdateRoutePeer,
|
Type: UpdateRoutePeer,
|
||||||
Values: []string{peer2Key},
|
Values: []string{peer2Key},
|
||||||
},
|
},
|
||||||
RouteUpdateOperation{
|
{
|
||||||
Type: UpdateRouteMetric,
|
Type: UpdateRouteMetric,
|
||||||
Values: []string{"3030"},
|
Values: []string{"3030"},
|
||||||
},
|
},
|
||||||
RouteUpdateOperation{
|
{
|
||||||
Type: UpdateRouteMasquerade,
|
Type: UpdateRouteMasquerade,
|
||||||
Values: []string{"true"},
|
Values: []string{"true"},
|
||||||
},
|
},
|
||||||
RouteUpdateOperation{
|
{
|
||||||
Type: UpdateRouteEnabled,
|
Type: UpdateRouteEnabled,
|
||||||
Values: []string{"false"},
|
Values: []string{"false"},
|
||||||
},
|
},
|
||||||
RouteUpdateOperation{
|
{
|
||||||
Type: UpdateRouteNetworkIdentifier,
|
Type: UpdateRouteNetworkIdentifier,
|
||||||
Values: []string{"megaRoute"},
|
Values: []string{"megaRoute"},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Type: UpdateRouteGroups,
|
||||||
|
Values: []string{routeGroup2},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
errFunc: require.NoError,
|
errFunc: require.NoError,
|
||||||
shouldCreate: true,
|
shouldCreate: true,
|
||||||
@ -487,23 +619,24 @@ func TestUpdateRoute(t *testing.T) {
|
|||||||
Masquerade: true,
|
Masquerade: true,
|
||||||
Metric: 3030,
|
Metric: 3030,
|
||||||
Enabled: false,
|
Enabled: false,
|
||||||
|
Groups: []string{routeGroup2},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Empty Values",
|
name: "Empty Values Should Fail",
|
||||||
existingRoute: existingRoute,
|
existingRoute: existingRoute,
|
||||||
operations: []RouteUpdateOperation{
|
operations: []RouteUpdateOperation{
|
||||||
RouteUpdateOperation{
|
{
|
||||||
Type: UpdateRoutePeer,
|
Type: UpdateRoutePeer,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
errFunc: require.Error,
|
errFunc: require.Error,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Multiple Values",
|
name: "Multiple Values Should Fail",
|
||||||
existingRoute: existingRoute,
|
existingRoute: existingRoute,
|
||||||
operations: []RouteUpdateOperation{
|
operations: []RouteUpdateOperation{
|
||||||
RouteUpdateOperation{
|
{
|
||||||
Type: UpdateRoutePeer,
|
Type: UpdateRoutePeer,
|
||||||
Values: []string{peer2Key, peer1Key},
|
Values: []string{peer2Key, peer1Key},
|
||||||
},
|
},
|
||||||
@ -511,10 +644,10 @@ func TestUpdateRoute(t *testing.T) {
|
|||||||
errFunc: require.Error,
|
errFunc: require.Error,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Bad Prefix",
|
name: "Bad Prefix Should Fail",
|
||||||
existingRoute: existingRoute,
|
existingRoute: existingRoute,
|
||||||
operations: []RouteUpdateOperation{
|
operations: []RouteUpdateOperation{
|
||||||
RouteUpdateOperation{
|
{
|
||||||
Type: UpdateRouteNetwork,
|
Type: UpdateRouteNetwork,
|
||||||
Values: []string{"192.168.0.0/34"},
|
Values: []string{"192.168.0.0/34"},
|
||||||
},
|
},
|
||||||
@ -522,10 +655,10 @@ func TestUpdateRoute(t *testing.T) {
|
|||||||
errFunc: require.Error,
|
errFunc: require.Error,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Bad Peer",
|
name: "Bad Peer Should Fail",
|
||||||
existingRoute: existingRoute,
|
existingRoute: existingRoute,
|
||||||
operations: []RouteUpdateOperation{
|
operations: []RouteUpdateOperation{
|
||||||
RouteUpdateOperation{
|
{
|
||||||
Type: UpdateRoutePeer,
|
Type: UpdateRoutePeer,
|
||||||
Values: []string{"non existing Peer"},
|
Values: []string{"non existing Peer"},
|
||||||
},
|
},
|
||||||
@ -536,7 +669,7 @@ func TestUpdateRoute(t *testing.T) {
|
|||||||
name: "Empty Peer",
|
name: "Empty Peer",
|
||||||
existingRoute: existingRoute,
|
existingRoute: existingRoute,
|
||||||
operations: []RouteUpdateOperation{
|
operations: []RouteUpdateOperation{
|
||||||
RouteUpdateOperation{
|
{
|
||||||
Type: UpdateRoutePeer,
|
Type: UpdateRoutePeer,
|
||||||
Values: []string{""},
|
Values: []string{""},
|
||||||
},
|
},
|
||||||
@ -553,13 +686,14 @@ func TestUpdateRoute(t *testing.T) {
|
|||||||
Masquerade: false,
|
Masquerade: false,
|
||||||
Metric: 9999,
|
Metric: 9999,
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
|
Groups: []string{routeGroup1},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Large Network ID",
|
name: "Large Network ID Should Fail",
|
||||||
existingRoute: existingRoute,
|
existingRoute: existingRoute,
|
||||||
operations: []RouteUpdateOperation{
|
operations: []RouteUpdateOperation{
|
||||||
RouteUpdateOperation{
|
{
|
||||||
Type: UpdateRouteNetworkIdentifier,
|
Type: UpdateRouteNetworkIdentifier,
|
||||||
Values: []string{"12345678901234567890qwertyuiopqwertyuiop1"},
|
Values: []string{"12345678901234567890qwertyuiopqwertyuiop1"},
|
||||||
},
|
},
|
||||||
@ -567,10 +701,10 @@ func TestUpdateRoute(t *testing.T) {
|
|||||||
errFunc: require.Error,
|
errFunc: require.Error,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Empty Network ID",
|
name: "Empty Network ID Should Fail",
|
||||||
existingRoute: existingRoute,
|
existingRoute: existingRoute,
|
||||||
operations: []RouteUpdateOperation{
|
operations: []RouteUpdateOperation{
|
||||||
RouteUpdateOperation{
|
{
|
||||||
Type: UpdateRouteNetworkIdentifier,
|
Type: UpdateRouteNetworkIdentifier,
|
||||||
Values: []string{""},
|
Values: []string{""},
|
||||||
},
|
},
|
||||||
@ -578,10 +712,10 @@ func TestUpdateRoute(t *testing.T) {
|
|||||||
errFunc: require.Error,
|
errFunc: require.Error,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Invalid Metric",
|
name: "Invalid Metric Should Fail",
|
||||||
existingRoute: existingRoute,
|
existingRoute: existingRoute,
|
||||||
operations: []RouteUpdateOperation{
|
operations: []RouteUpdateOperation{
|
||||||
RouteUpdateOperation{
|
{
|
||||||
Type: UpdateRouteMetric,
|
Type: UpdateRouteMetric,
|
||||||
Values: []string{"999999"},
|
Values: []string{"999999"},
|
||||||
},
|
},
|
||||||
@ -589,16 +723,27 @@ func TestUpdateRoute(t *testing.T) {
|
|||||||
errFunc: require.Error,
|
errFunc: require.Error,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Invalid Boolean",
|
name: "Invalid Boolean Should Fail",
|
||||||
existingRoute: existingRoute,
|
existingRoute: existingRoute,
|
||||||
operations: []RouteUpdateOperation{
|
operations: []RouteUpdateOperation{
|
||||||
RouteUpdateOperation{
|
{
|
||||||
Type: UpdateRouteMasquerade,
|
Type: UpdateRouteMasquerade,
|
||||||
Values: []string{"yes"},
|
Values: []string{"yes"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
errFunc: require.Error,
|
errFunc: require.Error,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Invalid Group Should Fail",
|
||||||
|
existingRoute: existingRoute,
|
||||||
|
operations: []RouteUpdateOperation{
|
||||||
|
{
|
||||||
|
Type: UpdateRouteGroups,
|
||||||
|
Values: []string{routeInvalidGroup1},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
errFunc: require.Error,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, testCase := range testCases {
|
for _, testCase := range testCases {
|
||||||
t.Run(testCase.name, func(t *testing.T) {
|
t.Run(testCase.name, func(t *testing.T) {
|
||||||
@ -697,6 +842,7 @@ func TestGetNetworkMap_RouteSync(t *testing.T) {
|
|||||||
Masquerade: false,
|
Masquerade: false,
|
||||||
Metric: 9999,
|
Metric: 9999,
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
|
Groups: []string{routeGroup1},
|
||||||
}
|
}
|
||||||
|
|
||||||
am, err := createRouterManager(t)
|
am, err := createRouterManager(t)
|
||||||
@ -714,7 +860,7 @@ func TestGetNetworkMap_RouteSync(t *testing.T) {
|
|||||||
require.Len(t, newAccountRoutes.Routes, 0, "new accounts should have no routes")
|
require.Len(t, newAccountRoutes.Routes, 0, "new accounts should have no routes")
|
||||||
|
|
||||||
createdRoute, err := am.CreateRoute(account.Id, baseRoute.Network.String(), baseRoute.Peer,
|
createdRoute, err := am.CreateRoute(account.Id, baseRoute.Network.String(), baseRoute.Peer,
|
||||||
baseRoute.Description, baseRoute.NetID, baseRoute.Masquerade, baseRoute.Metric, false)
|
baseRoute.Description, baseRoute.NetID, baseRoute.Masquerade, baseRoute.Metric, baseRoute.Groups, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
noDisabledRoutes, err := am.GetNetworkMap(peer1Key)
|
noDisabledRoutes, err := am.GetNetworkMap(peer1Key)
|
||||||
@ -734,7 +880,14 @@ func TestGetNetworkMap_RouteSync(t *testing.T) {
|
|||||||
|
|
||||||
peer2Routes, err := am.GetNetworkMap(peer2Key)
|
peer2Routes, err := am.GetNetworkMap(peer2Key)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Len(t, peer2Routes.Routes, 1, "we should receive one route for peer2")
|
require.Len(t, peer2Routes.Routes, 0, "no routes for peers not in the distribution group")
|
||||||
|
|
||||||
|
err = am.GroupAddPeer(account.Id, routeGroup1, peer2Key)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
peer2Routes, err = am.GetNetworkMap(peer2Key)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Len(t, peer2Routes.Routes, 1, "we should receive one route")
|
||||||
require.True(t, peer1Routes.Routes[0].IsEqual(peer2Routes.Routes[0]), "routes should be the same for peers in the same group")
|
require.True(t, peer1Routes.Routes[0].IsEqual(peer2Routes.Routes[0]), "routes should be the same for peers in the same group")
|
||||||
|
|
||||||
newGroup := &Group{
|
newGroup := &Group{
|
||||||
@ -844,6 +997,26 @@ func initTestRouteAccount(t *testing.T, am *DefaultAccountManager) (*Account, er
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
newGroup := &Group{
|
||||||
|
ID: routeGroup1,
|
||||||
|
Name: routeGroup1,
|
||||||
|
Peers: []string{peer1Key},
|
||||||
|
}
|
||||||
|
err = am.SaveGroup(accountID, newGroup)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
newGroup = &Group{
|
||||||
|
ID: routeGroup2,
|
||||||
|
Name: routeGroup2,
|
||||||
|
Peers: []string{peer1Key},
|
||||||
|
}
|
||||||
|
|
||||||
|
err = am.SaveGroup(accountID, newGroup)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return am.Store.GetAccount(account.Id)
|
return am.Store.GetAccount(account.Id)
|
||||||
}
|
}
|
||||||
|
@ -73,6 +73,7 @@ type Route struct {
|
|||||||
Masquerade bool
|
Masquerade bool
|
||||||
Metric int
|
Metric int
|
||||||
Enabled bool
|
Enabled bool
|
||||||
|
Groups []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy copies a route object
|
// Copy copies a route object
|
||||||
@ -87,6 +88,7 @@ func (r *Route) Copy() *Route {
|
|||||||
Metric: r.Metric,
|
Metric: r.Metric,
|
||||||
Masquerade: r.Masquerade,
|
Masquerade: r.Masquerade,
|
||||||
Enabled: r.Enabled,
|
Enabled: r.Enabled,
|
||||||
|
Groups: r.Groups,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,7 +102,8 @@ func (r *Route) IsEqual(other *Route) bool {
|
|||||||
other.Peer == r.Peer &&
|
other.Peer == r.Peer &&
|
||||||
other.Metric == r.Metric &&
|
other.Metric == r.Metric &&
|
||||||
other.Masquerade == r.Masquerade &&
|
other.Masquerade == r.Masquerade &&
|
||||||
other.Enabled == r.Enabled
|
other.Enabled == r.Enabled &&
|
||||||
|
compareGroupsList(r.Groups, other.Groups)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseNetwork Parses a network prefix string and returns a netip.Prefix object and if is invalid, IPv4 or IPv6
|
// ParseNetwork Parses a network prefix string and returns a netip.Prefix object and if is invalid, IPv4 or IPv6
|
||||||
@ -122,3 +125,23 @@ func ParseNetwork(networkString string) (NetworkType, netip.Prefix, error) {
|
|||||||
|
|
||||||
return IPv4Network, masked, nil
|
return IPv4Network, masked, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func compareGroupsList(list, other []string) bool {
|
||||||
|
if len(list) != len(other) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for _, id := range list {
|
||||||
|
match := false
|
||||||
|
for _, otherID := range other {
|
||||||
|
if id == otherID {
|
||||||
|
match = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !match {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user