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:
Maycon Santos
2022-12-06 10:11:57 +01:00
committed by GitHub
parent d1b7c23b19
commit a387e3cfc2
16 changed files with 386 additions and 101 deletions

View File

@@ -379,6 +379,11 @@ components:
masquerade:
description: Indicate if peer should masquerade traffic to this route's prefix
type: boolean
groups:
description: Route group tag groups
type: array
items:
type: string
required:
- id
- description
@@ -388,6 +393,7 @@ components:
- network
- metric
- masquerade
- groups
Route:
allOf:
- type: object
@@ -410,7 +416,7 @@ components:
path:
description: Route field to update in form /<field>
type: string
enum: [ "network","network_id","description","enabled","peer","metric","masquerade" ]
enum: [ "network","network_id","description","enabled","peer","metric","masquerade", "groups" ]
required:
- path
Nameserver:

View File

@@ -65,6 +65,7 @@ const (
const (
RoutePatchOperationPathDescription RoutePatchOperationPath = "description"
RoutePatchOperationPathEnabled RoutePatchOperationPath = "enabled"
RoutePatchOperationPathGroups RoutePatchOperationPath = "groups"
RoutePatchOperationPathMasquerade RoutePatchOperationPath = "masquerade"
RoutePatchOperationPathMetric RoutePatchOperationPath = "metric"
RoutePatchOperationPathNetwork RoutePatchOperationPath = "network"
@@ -296,6 +297,9 @@ type Route struct {
// Enabled Route status
Enabled bool `json:"enabled"`
// Groups Route group tag groups
Groups []string `json:"groups"`
// Id Route Id
Id string `json:"id"`
@@ -344,6 +348,9 @@ type RouteRequest struct {
// Enabled Route status
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 bool `json:"masquerade"`

View File

@@ -89,7 +89,7 @@ func (h *Routes) CreateRouteHandler(w http.ResponseWriter, r *http.Request) {
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 {
util.WriteError(err, w)
return
@@ -162,6 +162,7 @@ func (h *Routes) UpdateRouteHandler(w http.ResponseWriter, r *http.Request) {
Metric: req.Metric,
Description: req.Description,
Enabled: req.Enabled,
Groups: req.Groups,
}
err = h.accountManager.SaveRoute(account.Id, newRoute)
@@ -298,6 +299,16 @@ func (h *Routes) PatchRouteHandler(w http.ResponseWriter, r *http.Request) {
Type: server.UpdateRouteEnabled,
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:
util.WriteError(status.Errorf(status.InvalidArgument, "invalid patch path"), w)
return
@@ -383,5 +394,6 @@ func toRouteResponse(account *server.Account, serverRoute *route.Route) *api.Rou
NetworkType: serverRoute.NetworkType.String(),
Masquerade: serverRoute.Masquerade,
Metric: serverRoute.Metric,
Groups: serverRoute.Groups,
}
}

View File

@@ -28,6 +28,7 @@ const (
notFoundPeerID = "100.64.0.200"
existingPeerKey = "existingPeerKey"
testAccountID = "test_id"
existingGroupID = "testGroup"
)
var baseExistingRoute = &route.Route{
@@ -39,6 +40,7 @@ var baseExistingRoute = &route.Route{
Metric: 9999,
Masquerade: false,
Enabled: true,
Groups: []string{existingGroupID},
}
var testingAccount = &server.Account{
@@ -64,7 +66,7 @@ func initRoutesTestData() *Routes {
}
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)
return &route.Route{
ID: existingRouteID,
@@ -75,6 +77,7 @@ func initRoutesTestData() *Routes {
Description: description,
Masquerade: masquerade,
Enabled: enabled,
Groups: groups,
}, nil
},
SaveRouteFunc: func(_ string, _ *route.Route) error {
@@ -116,6 +119,8 @@ func initRoutesTestData() *Routes {
routeToUpdate.Masquerade, _ = strconv.ParseBool(operation.Values[0])
case server.UpdateRouteEnabled:
routeToUpdate.Enabled, _ = strconv.ParseBool(operation.Values[0])
case server.UpdateRouteGroups:
routeToUpdate.Groups = operation.Values
default:
return nil, fmt.Errorf("no operation")
}
@@ -181,7 +186,7 @@ func TestRoutesHandlers(t *testing.T) {
requestType: http.MethodPost,
requestPath: "/api/routes",
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,
expectedBody: true,
expectedRoute: &api.Route{
@@ -193,13 +198,14 @@ func TestRoutesHandlers(t *testing.T) {
NetworkType: route.IPv4NetworkString,
Masquerade: false,
Enabled: false,
Groups: []string{existingGroupID},
},
},
{
name: "POST Not Found Peer",
requestType: http.MethodPost,
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,
expectedBody: false,
},
@@ -207,7 +213,7 @@ func TestRoutesHandlers(t *testing.T) {
name: "POST Invalid Network Identifier",
requestType: http.MethodPost,
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,
expectedBody: false,
},
@@ -215,7 +221,7 @@ func TestRoutesHandlers(t *testing.T) {
name: "POST Invalid Network",
requestType: http.MethodPost,
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,
expectedBody: false,
},
@@ -223,7 +229,7 @@ func TestRoutesHandlers(t *testing.T) {
name: "PUT OK",
requestType: http.MethodPut,
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,
expectedBody: true,
expectedRoute: &api.Route{
@@ -235,13 +241,14 @@ func TestRoutesHandlers(t *testing.T) {
NetworkType: route.IPv4NetworkString,
Masquerade: false,
Enabled: false,
Groups: []string{existingGroupID},
},
},
{
name: "PUT Not Found Route",
requestType: http.MethodPut,
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,
expectedBody: false,
},
@@ -249,7 +256,7 @@ func TestRoutesHandlers(t *testing.T) {
name: "PUT Not Found Peer",
requestType: http.MethodPut,
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,
expectedBody: false,
},
@@ -257,7 +264,7 @@ func TestRoutesHandlers(t *testing.T) {
name: "PUT Invalid Network Identifier",
requestType: http.MethodPut,
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,
expectedBody: false,
},
@@ -265,7 +272,7 @@ func TestRoutesHandlers(t *testing.T) {
name: "PUT Invalid Network",
requestType: http.MethodPut,
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,
expectedBody: false,
},
@@ -285,6 +292,7 @@ func TestRoutesHandlers(t *testing.T) {
Masquerade: baseExistingRoute.Masquerade,
Enabled: baseExistingRoute.Enabled,
Metric: baseExistingRoute.Metric,
Groups: baseExistingRoute.Groups,
},
},
{
@@ -304,6 +312,7 @@ func TestRoutesHandlers(t *testing.T) {
Masquerade: baseExistingRoute.Masquerade,
Enabled: baseExistingRoute.Enabled,
Metric: baseExistingRoute.Metric,
Groups: baseExistingRoute.Groups,
},
},
{