Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend network route with access control groups #2027

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion management/server/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ type AccountManager interface {
DeletePolicy(accountID, policyID, userID string) error
ListPolicies(accountID, userID string) ([]*Policy, error)
GetRoute(accountID string, routeID route.ID, userID string) (*route.Route, error)
CreateRoute(accountID, prefix, peerID string, peerGroupIDs []string, description string, netID route.NetID, masquerade bool, metric int, groups []string, enabled bool, userID string) (*route.Route, error)
CreateRoute(accountID, prefix, peerID string, peerGroupIDs []string, description string, netID route.NetID, masquerade bool, metric int, groups []string, accessControlGroupIDs []string, enabled bool, userID string) (*route.Route, error)
SaveRoute(accountID, userID string, route *route.Route) error
DeleteRoute(accountID string, routeID route.ID, userID string) error
ListRoutes(accountID, userID string) ([]*route.Route, error)
Expand Down
7 changes: 4 additions & 3 deletions management/server/account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1576,9 +1576,10 @@ func TestAccount_Copy(t *testing.T) {
},
Routes: map[route.ID]*route.Route{
"route1": {
ID: "route1",
PeerGroups: []string{},
Groups: []string{"group1"},
ID: "route1",
PeerGroups: []string{},
Groups: []string{"group1"},
AccessControlGroups: []string{},
},
},
NameServerGroups: map[string]*nbdns.NameServerGroup{
Expand Down
6 changes: 6 additions & 0 deletions management/server/http/api/openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1014,6 +1014,12 @@ components:
items:
type: string
example: "chacdk86lnnboviihd70"
access_control_groups:
description: Access control group identifier associated with route.
type: array
items:
type: string
example: "chacbco6lnnbn6cg5s91"
required:
- id
- description
Expand Down
6 changes: 6 additions & 0 deletions management/server/http/api/types.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 14 additions & 2 deletions management/server/http/routes_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,16 @@ func (h *RoutesHandler) CreateRoute(w http.ResponseWriter, r *http.Request) {
peerId = *req.Peer
}

peerGroupIds := []string{}
var peerGroupIds []string
if req.PeerGroups != nil {
peerGroupIds = *req.PeerGroups
}

var accessControlGroupIds []string
if req.AccessControlGroups != nil {
accessControlGroupIds = *req.AccessControlGroups
}

if (peerId != "" && len(peerGroupIds) > 0) || (peerId == "" && len(peerGroupIds) == 0) {
util.WriteError(status.Errorf(status.InvalidArgument, "only one peer or peer_groups should be provided"), w)
return
Expand All @@ -107,7 +112,7 @@ func (h *RoutesHandler) CreateRoute(w http.ResponseWriter, r *http.Request) {

newRoute, err := h.accountManager.CreateRoute(
account.Id, newPrefix.String(), peerId, peerGroupIds,
req.Description, route.NetID(req.NetworkId), req.Masquerade, req.Metric, req.Groups, req.Enabled, user.Id,
req.Description, route.NetID(req.NetworkId), req.Masquerade, req.Metric, req.Groups, accessControlGroupIds, req.Enabled, user.Id,
)
if err != nil {
util.WriteError(err, w)
Expand Down Expand Up @@ -204,6 +209,10 @@ func (h *RoutesHandler) UpdateRoute(w http.ResponseWriter, r *http.Request) {
newRoute.PeerGroups = *req.PeerGroups
}

if req.AccessControlGroups != nil {
newRoute.AccessControlGroups = *req.AccessControlGroups
}

err = h.accountManager.SaveRoute(account.Id, user.Id, newRoute)
if err != nil {
util.WriteError(err, w)
Expand Down Expand Up @@ -280,5 +289,8 @@ func toRouteResponse(serverRoute *route.Route) *api.Route {
if len(serverRoute.PeerGroups) > 0 {
route.PeerGroups = &serverRoute.PeerGroups
}
if len(serverRoute.AccessControlGroups) > 0 {
route.AccessControlGroups = &serverRoute.AccessControlGroups
}
return route
}
64 changes: 53 additions & 11 deletions management/server/http/routes_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func initRoutesTestData() *RoutesHandler {
}
return nil, status.Errorf(status.NotFound, "route with ID %s not found", routeID)
},
CreateRouteFunc: func(accountID, network, peerID string, peerGroups []string, description string, netID route.NetID, masquerade bool, metric int, groups []string, enabled bool, _ string) (*route.Route, error) {
CreateRouteFunc: func(accountID, network, peerID string, peerGroups []string, description string, netID route.NetID, masquerade bool, metric int, groups []string, accessControlGroups []string, enabled bool, _ string) (*route.Route, error) {
if peerID == notFoundPeerID {
return nil, status.Errorf(status.InvalidArgument, "peer with ID %s not found", peerID)
}
Expand All @@ -102,16 +102,17 @@ func initRoutesTestData() *RoutesHandler {
}
networkType, p, _ := route.ParseNetwork(network)
return &route.Route{
ID: existingRouteID,
NetID: netID,
Peer: peerID,
PeerGroups: peerGroups,
Network: p,
NetworkType: networkType,
Description: description,
Masquerade: masquerade,
Enabled: enabled,
Groups: groups,
ID: existingRouteID,
NetID: netID,
Peer: peerID,
PeerGroups: peerGroups,
Network: p,
NetworkType: networkType,
Description: description,
Masquerade: masquerade,
Enabled: enabled,
Groups: groups,
AccessControlGroups: accessControlGroups,
}, nil
},
SaveRouteFunc: func(_, _ string, r *route.Route) error {
Expand Down Expand Up @@ -210,6 +211,27 @@ func TestRoutesHandlers(t *testing.T) {
Groups: []string{existingGroupID},
},
},
{
name: "POST OK With Access Control Groups",
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\",\"groups\":[\"%s\"],\"access_control_groups\":[\"%s\"]}", existingPeerID, existingGroupID, existingGroupID))),
expectedStatus: http.StatusOK,
expectedBody: true,
expectedRoute: &api.Route{
Id: existingRouteID,
Description: "Post",
NetworkId: "awesomeNet",
Network: "192.168.0.0/16",
Peer: &existingPeerID,
NetworkType: route.IPv4NetworkString,
Masquerade: false,
Enabled: false,
Groups: []string{existingGroupID},
AccessControlGroups: &[]string{existingGroupID},
},
},
{
name: "POST Non Linux Peer",
requestType: http.MethodPost,
Expand Down Expand Up @@ -279,6 +301,26 @@ func TestRoutesHandlers(t *testing.T) {
Groups: []string{existingGroupID},
},
},
{
name: "PUT OK With Access Control Groups",
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\",\"groups\":[\"%s\"],\"access_control_groups\":[\"%s\"]}}", existingPeerID, existingGroupID, existingGroupID)),
expectedStatus: http.StatusOK,
expectedBody: true,
expectedRoute: &api.Route{
Id: existingRouteID,
Description: "Post",
NetworkId: "awesomeNet",
Network: "192.168.0.0/16",
Peer: &existingPeerID,
NetworkType: route.IPv4NetworkString,
Masquerade: false,
Enabled: false,
Groups: []string{existingGroupID},
AccessControlGroups: &[]string{existingGroupID},
},
},
{
name: "PUT OK when peer_groups provided",
requestType: http.MethodPut,
Expand Down
6 changes: 3 additions & 3 deletions management/server/mock_server/account_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ type MockAccountManager struct {
UpdatePeerMetaFunc func(peerID string, meta nbpeer.PeerSystemMeta) error
UpdatePeerSSHKeyFunc func(peerID string, sshKey string) error
UpdatePeerFunc func(accountID, userID string, peer *nbpeer.Peer) (*nbpeer.Peer, error)
CreateRouteFunc func(accountID, prefix, peer string, peerGroups []string, description string, netID route.NetID, masquerade bool, metric int, groups []string, enabled bool, userID string) (*route.Route, error)
CreateRouteFunc func(accountID, prefix, peer string, peerGroups []string, description string, netID route.NetID, masquerade bool, metric int, groups []string, accessControlGroups []string, enabled bool, userID string) (*route.Route, error)
GetRouteFunc func(accountID string, routeID route.ID, userID string) (*route.Route, error)
SaveRouteFunc func(accountID string, userID string, route *route.Route) error
DeleteRouteFunc func(accountID string, routeID route.ID, userID string) error
Expand Down Expand Up @@ -412,9 +412,9 @@ func (am *MockAccountManager) UpdatePeer(accountID, userID string, peer *nbpeer.
}

// CreateRoute mock implementation of CreateRoute from server.AccountManager interface
func (am *MockAccountManager) CreateRoute(accountID, prefix, peerID string, peerGroupIDs []string, description string, netID route.NetID, masquerade bool, metric int, groups []string, enabled bool, userID string) (*route.Route, error) {
func (am *MockAccountManager) CreateRoute(accountID, prefix, peerID string, peerGroupIDs []string, description string, netID route.NetID, masquerade bool, metric int, groups []string, accessControlGroups []string, enabled bool, userID string) (*route.Route, error) {
if am.CreateRouteFunc != nil {
return am.CreateRouteFunc(accountID, prefix, peerID, peerGroupIDs, description, netID, masquerade, metric, groups, enabled, userID)
return am.CreateRouteFunc(accountID, prefix, peerID, peerGroupIDs, description, netID, masquerade, metric, groups, accessControlGroups, enabled, userID)
}
return nil, status.Errorf(codes.Unimplemented, "method CreateRoute is not implemented")
}
Expand Down
17 changes: 16 additions & 1 deletion management/server/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ func (am *DefaultAccountManager) checkRoutePrefixExistsForPeers(account *Account
}

// CreateRoute creates and saves a new route
func (am *DefaultAccountManager) CreateRoute(accountID, network, peerID string, peerGroupIDs []string, description string, netID route.NetID, masquerade bool, metric int, groups []string, enabled bool, userID string) (*route.Route, error) {
func (am *DefaultAccountManager) CreateRoute(accountID, network, peerID string, peerGroupIDs []string, description string, netID route.NetID, masquerade bool, metric int, groups []string, accessControlGroupIDs []string, enabled bool, userID string) (*route.Route, error) {
unlock := am.Store.AcquireAccountWriteLock(accountID)
defer unlock()

Expand Down Expand Up @@ -145,6 +145,13 @@ func (am *DefaultAccountManager) CreateRoute(accountID, network, peerID string,
}
}

if len(accessControlGroupIDs) > 0 {
err = validateGroups(accessControlGroupIDs, account.Groups)
if err != nil {
return nil, err
}
}

err = am.checkRoutePrefixExistsForPeers(account, peerID, newRoute.ID, peerGroupIDs, newPrefix)
if err != nil {
return nil, err
Expand Down Expand Up @@ -173,6 +180,7 @@ func (am *DefaultAccountManager) CreateRoute(accountID, network, peerID string,
newRoute.Metric = metric
newRoute.Enabled = enabled
newRoute.Groups = groups
newRoute.AccessControlGroups = accessControlGroupIDs

if account.Routes == nil {
account.Routes = make(map[route.ID]*route.Route)
Expand Down Expand Up @@ -229,6 +237,13 @@ func (am *DefaultAccountManager) SaveRoute(accountID, userID string, routeToSave
}
}

if len(routeToSave.AccessControlGroups) > 0 {
err = validateGroups(routeToSave.AccessControlGroups, account.Groups)
if err != nil {
return err
}
}

err = am.checkRoutePrefixExistsForPeers(account, routeToSave.Peer, routeToSave.ID, routeToSave.Copy().PeerGroups, routeToSave.Network)
if err != nil {
return err
Expand Down
Loading
Loading