Add Network ID and rename Prefix to Network (#432)

Adding network ID will allow us to group

Renaming Prefix with Network
will keep things more clear and Consistent
This commit is contained in:
Maycon Santos 2022-08-22 14:10:24 +02:00 committed by GitHub
parent 762a26dcea
commit 09312b3e6d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 405 additions and 216 deletions

View File

@ -1358,12 +1358,13 @@ type Route struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`
Prefix string `protobuf:"bytes,2,opt,name=Prefix,proto3" json:"Prefix,omitempty"`
PrefixType int64 `protobuf:"varint,3,opt,name=PrefixType,proto3" json:"PrefixType,omitempty"`
Peer string `protobuf:"bytes,4,opt,name=Peer,proto3" json:"Peer,omitempty"`
Metric int64 `protobuf:"varint,5,opt,name=Metric,proto3" json:"Metric,omitempty"`
Masquerade bool `protobuf:"varint,6,opt,name=Masquerade,proto3" json:"Masquerade,omitempty"`
ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`
Network string `protobuf:"bytes,2,opt,name=Network,proto3" json:"Network,omitempty"`
NetworkType int64 `protobuf:"varint,3,opt,name=NetworkType,proto3" json:"NetworkType,omitempty"`
Peer string `protobuf:"bytes,4,opt,name=Peer,proto3" json:"Peer,omitempty"`
Metric int64 `protobuf:"varint,5,opt,name=Metric,proto3" json:"Metric,omitempty"`
Masquerade bool `protobuf:"varint,6,opt,name=Masquerade,proto3" json:"Masquerade,omitempty"`
NetID string `protobuf:"bytes,7,opt,name=NetID,proto3" json:"NetID,omitempty"`
}
func (x *Route) Reset() {
@ -1405,16 +1406,16 @@ func (x *Route) GetID() string {
return ""
}
func (x *Route) GetPrefix() string {
func (x *Route) GetNetwork() string {
if x != nil {
return x.Prefix
return x.Network
}
return ""
}
func (x *Route) GetPrefixType() int64 {
func (x *Route) GetNetworkType() int64 {
if x != nil {
return x.PrefixType
return x.NetworkType
}
return 0
}
@ -1440,6 +1441,13 @@ func (x *Route) GetMasquerade() bool {
return false
}
func (x *Route) GetNetID() string {
if x != nil {
return x.NetID
}
return ""
}
var File_management_proto protoreflect.FileDescriptor
var file_management_proto_rawDesc = []byte{
@ -1607,42 +1615,43 @@ var file_management_proto_rawDesc = []byte{
0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18,
0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x1a, 0x0a,
0x08, 0x41, 0x75, 0x64, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
0x08, 0x41, 0x75, 0x64, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x9b, 0x01, 0x0a, 0x05, 0x52, 0x6f,
0x08, 0x41, 0x75, 0x64, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x22, 0xb5, 0x01, 0x0a, 0x05, 0x52, 0x6f,
0x75, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x02, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x02, 0x20,
0x01, 0x28, 0x09, 0x52, 0x06, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x1e, 0x0a, 0x0a, 0x50,
0x72, 0x65, 0x66, 0x69, 0x78, 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52,
0x0a, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x50,
0x65, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x50, 0x65, 0x65, 0x72, 0x12,
0x16, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52,
0x06, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x1e, 0x0a, 0x0a, 0x4d, 0x61, 0x73, 0x71, 0x75,
0x65, 0x72, 0x61, 0x64, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x4d, 0x61, 0x73,
0x71, 0x75, 0x65, 0x72, 0x61, 0x64, 0x65, 0x32, 0xf7, 0x02, 0x0a, 0x11, 0x4d, 0x61, 0x6e, 0x61,
0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x45, 0x0a,
0x05, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d,
0x02, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x02,
0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, 0x20, 0x0a,
0x0b, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01,
0x28, 0x03, 0x52, 0x0b, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x12,
0x12, 0x0a, 0x04, 0x50, 0x65, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x50,
0x65, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x18, 0x05, 0x20,
0x01, 0x28, 0x03, 0x52, 0x06, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x1e, 0x0a, 0x0a, 0x4d,
0x61, 0x73, 0x71, 0x75, 0x65, 0x72, 0x61, 0x64, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52,
0x0a, 0x4d, 0x61, 0x73, 0x71, 0x75, 0x65, 0x72, 0x61, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x4e,
0x65, 0x74, 0x49, 0x44, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x4e, 0x65, 0x74, 0x49,
0x44, 0x32, 0xf7, 0x02, 0x0a, 0x11, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74,
0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x45, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x69, 0x6e,
0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e,
0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1c,
0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72,
0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x46,
0x0a, 0x04, 0x53, 0x79, 0x6e, 0x63, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d,
0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73,
0x73, 0x61, 0x67, 0x65, 0x1a, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e,
0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x04, 0x53, 0x79, 0x6e, 0x63, 0x12, 0x1c, 0x2e, 0x6d,
0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70,
0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1c, 0x2e, 0x6d, 0x61, 0x6e,
0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65,
0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x42, 0x0a, 0x0c,
0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x12, 0x11, 0x2e, 0x6d,
0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a,
0x1d, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x65, 0x72,
0x76, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
0x12, 0x33, 0x0a, 0x09, 0x69, 0x73, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x12, 0x11, 0x2e,
0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79,
0x1a, 0x11, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6d,
0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x5a, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, 0x69,
0x63, 0x65, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46,
0x6c, 0x6f, 0x77, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74,
0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x1a, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45,
0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22,
0x00, 0x42, 0x08, 0x5a, 0x06, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x33,
0x67, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x42, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72,
0x76, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x12, 0x11, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d,
0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1d, 0x2e, 0x6d, 0x61, 0x6e, 0x61,
0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4b, 0x65, 0x79,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x33, 0x0a, 0x09, 0x69, 0x73,
0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x12, 0x11, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65,
0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x11, 0x2e, 0x6d, 0x61, 0x6e,
0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12,
0x5a, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x41, 0x75, 0x74, 0x68,
0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x6c, 0x6f, 0x77, 0x12, 0x1c, 0x2e,
0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79,
0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1c, 0x2e, 0x6d, 0x61,
0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74,
0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x42, 0x08, 0x5a, 0x06, 0x2f,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (

View File

@ -235,9 +235,10 @@ message ProviderConfig {
// Route represents a route.Route object
message Route {
string ID = 1;
string Prefix = 2;
int64 PrefixType = 3;
string Network = 2;
int64 NetworkType = 3;
string Peer = 4;
int64 Metric = 5;
bool Masquerade = 6;
string NetID = 7;
}

View File

@ -70,7 +70,7 @@ type AccountManager interface {
DeleteRule(accountId, ruleID string) error
ListRules(accountId string) ([]*Rule, error)
GetRoute(accountID, routeID string) (*route.Route, error)
CreateRoute(accountID string, prefix, peer, description string, masquerade bool, metric int, enabled bool) (*route.Route, error)
CreateRoute(accountID string, prefix, peer, description, netID string, masquerade bool, metric int, enabled bool) (*route.Route, error)
SaveRoute(accountID string, route *route.Route) error
UpdateRoute(accountID string, routeID string, operations []RouteUpdateOperation) (*route.Route, error)
DeleteRoute(accountID, routeID string) error

View File

@ -134,11 +134,11 @@ func restore(file string) (*FileStore, error) {
if store.AccountPrefix2RouteIDs[account.Id] == nil {
store.AccountPrefix2RouteIDs[account.Id] = make(map[string][]string)
}
if _, ok := store.AccountPrefix2RouteIDs[account.Id][route.Prefix.String()]; !ok {
store.AccountPrefix2RouteIDs[account.Id][route.Prefix.String()] = make([]string, 0)
if _, ok := store.AccountPrefix2RouteIDs[account.Id][route.Network.String()]; !ok {
store.AccountPrefix2RouteIDs[account.Id][route.Network.String()] = make([]string, 0)
}
store.AccountPrefix2RouteIDs[account.Id][route.Prefix.String()] = append(
store.AccountPrefix2RouteIDs[account.Id][route.Prefix.String()],
store.AccountPrefix2RouteIDs[account.Id][route.Network.String()] = append(
store.AccountPrefix2RouteIDs[account.Id][route.Network.String()],
route.ID,
)
}
@ -340,11 +340,11 @@ func (s *FileStore) SaveAccount(account *Account) error {
if s.AccountPrefix2RouteIDs[account.Id] == nil {
s.AccountPrefix2RouteIDs[account.Id] = make(map[string][]string)
}
if _, ok := s.AccountPrefix2RouteIDs[account.Id][route.Prefix.String()]; !ok {
s.AccountPrefix2RouteIDs[account.Id][route.Prefix.String()] = make([]string, 0)
if _, ok := s.AccountPrefix2RouteIDs[account.Id][route.Network.String()]; !ok {
s.AccountPrefix2RouteIDs[account.Id][route.Network.String()] = make([]string, 0)
}
s.AccountPrefix2RouteIDs[account.Id][route.Prefix.String()] = append(
s.AccountPrefix2RouteIDs[account.Id][route.Prefix.String()],
s.AccountPrefix2RouteIDs[account.Id][route.Network.String()] = append(
s.AccountPrefix2RouteIDs[account.Id][route.Network.String()],
route.ID,
)
}

View File

@ -282,14 +282,19 @@ components:
description:
description: Route description
type: string
network_id:
description: Route network identifier, to group HA routes
type: string
maxLength: 40
minLength: 1
enabled:
description: Route status
type: boolean
peer:
description: Peer Identifier associated with route
type: string
prefix:
description: Prefix or network range in CIDR format
network:
description: Network range in CIDR format
type: string
metric:
description: Route metric number. Lowest number has higher priority
@ -302,9 +307,10 @@ components:
required:
- id
- description
- network_id
- enabled
- peer
- prefix
- network
- metric
- masquerade
Route:
@ -314,12 +320,12 @@ components:
id:
description: Route Id
type: string
prefix_type:
description: Prefix type indicating if it is IPv4 or IPv6
network_type:
description: Network type indicating if it is IPv4 or IPv6
type: string
required:
- id
- prefix_type
- network_type
- $ref: '#/components/schemas/RouteRequest'
RoutePatchOperation:
allOf:
@ -329,7 +335,7 @@ components:
path:
description: Route field to update in form /<field>
type: string
enum: [ "prefix","description","enabled","peer","metric","masquerade" ]
enum: [ "network","network_id","description","enabled","peer","metric","masquerade" ]
required:
- path

View File

@ -44,8 +44,9 @@ const (
RoutePatchOperationPathEnabled RoutePatchOperationPath = "enabled"
RoutePatchOperationPathMasquerade RoutePatchOperationPath = "masquerade"
RoutePatchOperationPathMetric RoutePatchOperationPath = "metric"
RoutePatchOperationPathNetwork RoutePatchOperationPath = "network"
RoutePatchOperationPathNetworkId RoutePatchOperationPath = "network_id"
RoutePatchOperationPathPeer RoutePatchOperationPath = "peer"
RoutePatchOperationPathPrefix RoutePatchOperationPath = "prefix"
)
// Defines values for RulePatchOperationOp.
@ -184,14 +185,17 @@ type Route struct {
// Route metric number. Lowest number has higher priority
Metric int `json:"metric"`
// Network range in CIDR format
Network string `json:"network"`
// Route network identifier, to group HA routes
NetworkId string `json:"network_id"`
// Network type indicating if it is IPv4 or IPv6
NetworkType string `json:"network_type"`
// Peer Identifier associated with route
Peer string `json:"peer"`
// Prefix or network range in CIDR format
Prefix string `json:"prefix"`
// Prefix type indicating if it is IPv4 or IPv6
PrefixType string `json:"prefix_type"`
}
// RoutePatchOperation defines model for RoutePatchOperation.
@ -226,11 +230,14 @@ type RouteRequest struct {
// Route metric number. Lowest number has higher priority
Metric int `json:"metric"`
// Network range in CIDR format
Network string `json:"network"`
// Route network identifier, to group HA routes
NetworkId string `json:"network_id"`
// Peer Identifier associated with route
Peer string `json:"peer"`
// Prefix or network range in CIDR format
Prefix string `json:"prefix"`
}
// Rule defines model for Rule.

View File

@ -12,6 +12,7 @@ import (
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"net/http"
"unicode/utf8"
)
// Routes is the routes handler of the account
@ -78,13 +79,18 @@ func (h *Routes) CreateRouteHandler(w http.ResponseWriter, r *http.Request) {
peerKey = peer.Key
}
_, newPrefix, err := route.ParsePrefix(req.Prefix)
_, newPrefix, err := route.ParseNetwork(req.Network)
if err != nil {
http.Error(w, fmt.Sprintf("couldn't parse update prefix %s", req.Prefix), http.StatusBadRequest)
http.Error(w, fmt.Sprintf("couldn't parse update prefix %s", req.Network), http.StatusBadRequest)
return
}
newRoute, err := h.accountManager.CreateRoute(account.Id, newPrefix.String(), peerKey, req.Description, req.Masquerade, req.Metric, req.Enabled)
if utf8.RuneCountInString(req.NetworkId) > route.MaxNetIDChar || req.NetworkId == "" {
http.Error(w, fmt.Sprintf("identifier should be between 1 and %d", route.MaxNetIDChar), http.StatusBadRequest)
return
}
newRoute, err := h.accountManager.CreateRoute(account.Id, newPrefix.String(), peerKey, req.Description, req.NetworkId, req.Masquerade, req.Metric, req.Enabled)
if err != nil {
log.Error(err)
http.Redirect(w, r, "/", http.StatusInternalServerError)
@ -123,9 +129,9 @@ func (h *Routes) UpdateRouteHandler(w http.ResponseWriter, r *http.Request) {
return
}
prefixType, newPrefix, err := route.ParsePrefix(req.Prefix)
prefixType, newPrefix, err := route.ParseNetwork(req.Network)
if err != nil {
http.Error(w, fmt.Sprintf("couldn't parse update prefix %s for route ID %s", req.Prefix, routeID), http.StatusBadRequest)
http.Error(w, fmt.Sprintf("couldn't parse update prefix %s for route ID %s", req.Network, routeID), http.StatusBadRequest)
return
}
@ -140,10 +146,16 @@ func (h *Routes) UpdateRouteHandler(w http.ResponseWriter, r *http.Request) {
peerKey = peer.Key
}
if utf8.RuneCountInString(req.NetworkId) > route.MaxNetIDChar || req.NetworkId == "" {
http.Error(w, fmt.Sprintf("identifier should be between 1 and %d", route.MaxNetIDChar), http.StatusBadRequest)
return
}
newRoute := &route.Route{
ID: routeID,
Prefix: newPrefix,
PrefixType: prefixType,
Network: newPrefix,
NetID: req.NetworkId,
NetworkType: prefixType,
Masquerade: req.Masquerade,
Peer: peerKey,
Metric: req.Metric,
@ -200,14 +212,14 @@ func (h *Routes) PatchRouteHandler(w http.ResponseWriter, r *http.Request) {
for _, patch := range req {
switch patch.Path {
case api.RoutePatchOperationPathPrefix:
case api.RoutePatchOperationPathNetwork:
if patch.Op != api.RoutePatchOperationOpReplace {
http.Error(w, fmt.Sprintf("Prefix field only accepts replace operation, got %s", patch.Op),
http.Error(w, fmt.Sprintf("Network field only accepts replace operation, got %s", patch.Op),
http.StatusBadRequest)
return
}
operations = append(operations, server.RouteUpdateOperation{
Type: server.UpdateRoutePrefix,
Type: server.UpdateRouteNetwork,
Values: patch.Value,
})
case api.RoutePatchOperationPathDescription:
@ -220,6 +232,16 @@ func (h *Routes) PatchRouteHandler(w http.ResponseWriter, r *http.Request) {
Type: server.UpdateRouteDescription,
Values: patch.Value,
})
case api.RoutePatchOperationPathNetworkId:
if patch.Op != api.RoutePatchOperationOpReplace {
http.Error(w, fmt.Sprintf("Network Identifier field only accepts replace operation, got %s", patch.Op),
http.StatusBadRequest)
return
}
operations = append(operations, server.RouteUpdateOperation{
Type: server.UpdateRouteNetworkIdentifier,
Values: patch.Value,
})
case api.RoutePatchOperationPathPeer:
if patch.Op != api.RoutePatchOperationOpReplace {
http.Error(w, fmt.Sprintf("Peer field only accepts replace operation, got %s", patch.Op),
@ -370,10 +392,11 @@ func toRouteResponse(account *server.Account, serverRoute *route.Route) *api.Rou
return &api.Route{
Id: serverRoute.ID,
Description: serverRoute.Description,
NetworkId: serverRoute.NetID,
Enabled: serverRoute.Enabled,
Peer: peerIP,
Prefix: serverRoute.Prefix.String(),
PrefixType: serverRoute.PrefixType.String(),
Network: serverRoute.Network.String(),
NetworkType: serverRoute.NetworkType.String(),
Masquerade: serverRoute.Masquerade,
Metric: serverRoute.Metric,
}

View File

@ -34,8 +34,9 @@ const (
var baseExistingRoute = &route.Route{
ID: existingRouteID,
Description: "base route",
Prefix: netip.MustParsePrefix("192.168.0.0/24"),
PrefixType: route.IPv4Prefix,
NetID: "awesomeNet",
Network: netip.MustParsePrefix("192.168.0.0/24"),
NetworkType: route.IPv4Network,
Metric: 9999,
Masquerade: false,
Enabled: true,
@ -61,13 +62,14 @@ func initRoutesTestData() *Routes {
}
return nil, status.Errorf(codes.NotFound, "route with ID %s not found", routeID)
},
CreateRouteFunc: func(accountID string, prefix, peer, description string, masquerade bool, metric int, enabled bool) (*route.Route, error) {
prefixType, p, _ := route.ParsePrefix(prefix)
CreateRouteFunc: func(accountID string, network, peer, description, netID string, masquerade bool, metric int, enabled bool) (*route.Route, error) {
networkType, p, _ := route.ParseNetwork(network)
return &route.Route{
ID: existingRouteID,
NetID: netID,
Peer: peer,
Prefix: p,
PrefixType: prefixType,
Network: p,
NetworkType: networkType,
Description: description,
Masquerade: masquerade,
Enabled: enabled,
@ -95,10 +97,12 @@ func initRoutesTestData() *Routes {
}
for _, operation := range operations {
switch operation.Type {
case server.UpdateRoutePrefix:
routeToUpdate.PrefixType, routeToUpdate.Prefix, _ = route.ParsePrefix(operation.Values[0])
case server.UpdateRouteNetwork:
routeToUpdate.NetworkType, routeToUpdate.Network, _ = route.ParseNetwork(operation.Values[0])
case server.UpdateRouteDescription:
routeToUpdate.Description = operation.Values[0]
case server.UpdateRouteNetworkIdentifier:
routeToUpdate.NetID = operation.Values[0]
case server.UpdateRoutePeer:
routeToUpdate.Peer = operation.Values[0]
case server.UpdateRouteMetric:
@ -172,15 +176,16 @@ func TestRoutesHandlers(t *testing.T) {
requestType: http.MethodPost,
requestPath: "/api/routes",
requestBody: bytes.NewBuffer(
[]byte(fmt.Sprintf("{\"Description\":\"Post\",\"Prefix\":\"192.168.0.0/16\",\"Peer\":\"%s\"}", existingPeerID))),
[]byte(fmt.Sprintf("{\"Description\":\"Post\",\"Network\":\"192.168.0.0/16\",\"network_id\":\"awesomeNet\",\"Peer\":\"%s\"}", existingPeerID))),
expectedStatus: http.StatusOK,
expectedBody: true,
expectedRoute: &api.Route{
Id: existingRouteID,
Description: "Post",
Prefix: "192.168.0.0/16",
NetworkId: "awesomeNet",
Network: "192.168.0.0/16",
Peer: existingPeerID,
PrefixType: route.IPv4PrefixString,
NetworkType: route.IPv4NetworkString,
Masquerade: false,
Enabled: false,
},
@ -189,15 +194,23 @@ func TestRoutesHandlers(t *testing.T) {
name: "POST Not Found Peer",
requestType: http.MethodPost,
requestPath: "/api/routes",
requestBody: bytes.NewBufferString(fmt.Sprintf("{\"Description\":\"Post\",\"Prefix\":\"192.168.0.0/16\",\"Peer\":\"%s\"}", notFoundPeerID)),
requestBody: bytes.NewBufferString(fmt.Sprintf("{\"Description\":\"Post\",\"Network\":\"192.168.0.0/16\",\"network_id\":\"awesomeNet\",\"Peer\":\"%s\"}", notFoundPeerID)),
expectedStatus: http.StatusUnprocessableEntity,
expectedBody: false,
},
{
name: "POST Invalid Prefix",
name: "POST Not Invalid Network Identifier",
requestType: http.MethodPost,
requestPath: "/api/routes",
requestBody: bytes.NewBufferString(fmt.Sprintf("{\"Description\":\"Post\",\"Prefix\":\"192.168.0.0/34\",\"Peer\":\"%s\"}", existingPeerID)),
requestBody: bytes.NewBufferString(fmt.Sprintf("{\"Description\":\"Post\",\"Network\":\"192.168.0.0/16\",\"network_id\":\"12345678901234567890qwertyuiopqwertyuiop1\",\"Peer\":\"%s\"}", existingPeerID)),
expectedStatus: http.StatusBadRequest,
expectedBody: false,
},
{
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)),
expectedStatus: http.StatusBadRequest,
expectedBody: false,
},
@ -205,15 +218,16 @@ func TestRoutesHandlers(t *testing.T) {
name: "PUT OK",
requestType: http.MethodPut,
requestPath: "/api/routes/" + existingRouteID,
requestBody: bytes.NewBufferString(fmt.Sprintf("{\"Description\":\"Post\",\"Prefix\":\"192.168.0.0/16\",\"Peer\":\"%s\"}", existingPeerID)),
requestBody: bytes.NewBufferString(fmt.Sprintf("{\"Description\":\"Post\",\"Network\":\"192.168.0.0/16\",\"network_id\":\"awesomeNet\",\"Peer\":\"%s\"}", existingPeerID)),
expectedStatus: http.StatusOK,
expectedBody: true,
expectedRoute: &api.Route{
Id: existingRouteID,
Description: "Post",
Prefix: "192.168.0.0/16",
NetworkId: "awesomeNet",
Network: "192.168.0.0/16",
Peer: existingPeerID,
PrefixType: route.IPv4PrefixString,
NetworkType: route.IPv4NetworkString,
Masquerade: false,
Enabled: false,
},
@ -222,7 +236,7 @@ func TestRoutesHandlers(t *testing.T) {
name: "PUT Not Found Route",
requestType: http.MethodPut,
requestPath: "/api/routes/" + notFoundRouteID,
requestBody: bytes.NewBufferString(fmt.Sprintf("{\"Description\":\"Post\",\"Prefix\":\"192.168.0.0/16\",\"Peer\":\"%s\"}", existingPeerID)),
requestBody: bytes.NewBufferString(fmt.Sprintf("{\"Description\":\"Post\",\"Network\":\"192.168.0.0/16\",\"network_id\":\"awesomeNet\",\"Peer\":\"%s\"}", existingPeerID)),
expectedStatus: http.StatusNotFound,
expectedBody: false,
},
@ -230,15 +244,23 @@ func TestRoutesHandlers(t *testing.T) {
name: "PUT Not Found Peer",
requestType: http.MethodPut,
requestPath: "/api/routes/" + existingRouteID,
requestBody: bytes.NewBufferString(fmt.Sprintf("{\"Description\":\"Post\",\"Prefix\":\"192.168.0.0/16\",\"Peer\":\"%s\"}", notFoundPeerID)),
requestBody: bytes.NewBufferString(fmt.Sprintf("{\"Description\":\"Post\",\"Network\":\"192.168.0.0/16\",\"network_id\":\"awesomeNet\",\"Peer\":\"%s\"}", notFoundPeerID)),
expectedStatus: http.StatusUnprocessableEntity,
expectedBody: false,
},
{
name: "PUT Invalid Prefix",
name: "PUT Invalid Network Identifier",
requestType: http.MethodPut,
requestPath: "/api/routes/" + existingRouteID,
requestBody: bytes.NewBufferString(fmt.Sprintf("{\"Description\":\"Post\",\"Prefix\":\"192.168.0.0/34\",\"Peer\":\"%s\"}", existingPeerID)),
requestBody: bytes.NewBufferString(fmt.Sprintf("{\"Description\":\"Post\",\"Network\":\"192.168.0.0/16\",\"network_id\":\"12345678901234567890qwertyuiopqwertyuiop1\",\"Peer\":\"%s\"}", existingPeerID)),
expectedStatus: http.StatusBadRequest,
expectedBody: false,
},
{
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)),
expectedStatus: http.StatusBadRequest,
expectedBody: false,
},
@ -252,8 +274,9 @@ func TestRoutesHandlers(t *testing.T) {
expectedRoute: &api.Route{
Id: existingRouteID,
Description: "NewDesc",
Prefix: baseExistingRoute.Prefix.String(),
PrefixType: route.IPv4PrefixString,
NetworkId: "awesomeNet",
Network: baseExistingRoute.Network.String(),
NetworkType: route.IPv4NetworkString,
Masquerade: baseExistingRoute.Masquerade,
Enabled: baseExistingRoute.Enabled,
Metric: baseExistingRoute.Metric,
@ -269,8 +292,9 @@ func TestRoutesHandlers(t *testing.T) {
expectedRoute: &api.Route{
Id: existingRouteID,
Description: "NewDesc",
Prefix: baseExistingRoute.Prefix.String(),
PrefixType: route.IPv4PrefixString,
NetworkId: "awesomeNet",
Network: baseExistingRoute.Network.String(),
NetworkType: route.IPv4NetworkString,
Peer: existingPeerID,
Masquerade: baseExistingRoute.Masquerade,
Enabled: baseExistingRoute.Enabled,
@ -289,7 +313,7 @@ func TestRoutesHandlers(t *testing.T) {
name: "PATCH Not Found Route",
requestType: http.MethodPatch,
requestPath: "/api/routes/" + notFoundRouteID,
requestBody: bytes.NewBufferString("[{\"op\":\"replace\",\"path\":\"prefix\",\"value\":[\"192.168.0.0/34\"]}]"),
requestBody: bytes.NewBufferString("[{\"op\":\"replace\",\"path\":\"network\",\"value\":[\"192.168.0.0/34\"]}]"),
expectedStatus: http.StatusNotFound,
expectedBody: false,
},

View File

@ -45,7 +45,7 @@ type MockAccountManager struct {
UpdatePeerMetaFunc func(peerKey string, meta server.PeerSystemMeta) error
UpdatePeerSSHKeyFunc func(peerKey string, sshKey string) error
UpdatePeerFunc func(accountID string, peer *server.Peer) (*server.Peer, error)
CreateRouteFunc func(accountID string, prefix, peer, description string, masquerade bool, metric int, enabled bool) (*route.Route, error)
CreateRouteFunc func(accountID string, prefix, peer, description, netID string, masquerade bool, metric int, enabled bool) (*route.Route, error)
GetRouteFunc func(accountID, routeID string) (*route.Route, error)
SaveRouteFunc func(accountID string, route *route.Route) error
UpdateRouteFunc func(accountID string, routeID string, operations []server.RouteUpdateOperation) (*route.Route, error)
@ -369,9 +369,9 @@ func (am *MockAccountManager) UpdatePeer(accountID string, peer *server.Peer) (*
}
// CreateRoute mock implementation of CreateRoute from server.AccountManager interface
func (am *MockAccountManager) CreateRoute(accountID string, prefix, peer, description 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, enabled bool) (*route.Route, error) {
if am.GetRouteFunc != nil {
return am.CreateRouteFunc(accountID, prefix, peer, description, masquerade, metric, enabled)
return am.CreateRouteFunc(accountID, network, peer, description, netID, masquerade, metric, enabled)
}
return nil, status.Errorf(codes.Unimplemented, "method CreateRoute is not implemented")
}

View File

@ -9,13 +9,14 @@ import (
"google.golang.org/grpc/status"
"net/netip"
"strconv"
"unicode/utf8"
)
const (
// UpdateRouteDescription indicates a route description update operation
UpdateRouteDescription RouteUpdateOperationType = iota
// UpdateRoutePrefix indicates a route IP update operation
UpdateRoutePrefix
// UpdateRouteNetwork indicates a route IP update operation
UpdateRouteNetwork
// UpdateRoutePeer indicates a route peer update operation
UpdateRoutePeer
// UpdateRouteMetric indicates a route metric update operation
@ -24,6 +25,8 @@ const (
UpdateRouteMasquerade
// UpdateRouteEnabled indicates a route enabled update operation
UpdateRouteEnabled
// UpdateRouteNetworkIdentifier indicates a route net ID update operation
UpdateRouteNetworkIdentifier
)
// RouteUpdateOperationType operation type
@ -33,8 +36,8 @@ func (t RouteUpdateOperationType) String() string {
switch t {
case UpdateRouteDescription:
return "UpdateRouteDescription"
case UpdateRoutePrefix:
return "UpdateRoutePrefix"
case UpdateRouteNetwork:
return "UpdateRouteNetwork"
case UpdateRoutePeer:
return "UpdateRoutePeer"
case UpdateRouteMetric:
@ -43,6 +46,8 @@ func (t RouteUpdateOperationType) String() string {
return "UpdateRouteMasquerade"
case UpdateRouteEnabled:
return "UpdateRouteEnabled"
case UpdateRouteNetworkIdentifier:
return "UpdateRouteNetworkIdentifier"
default:
return "InvalidOperation"
}
@ -72,7 +77,7 @@ func (am *DefaultAccountManager) GetRoute(accountID, routeID string) (*route.Rou
return nil, status.Errorf(codes.NotFound, "route with ID %s not found", routeID)
}
// checkPrefixPeerExists checks the combination of prefix and peer id, if it exists returns an error, otehrwise returns nil
// checkPrefixPeerExists checks the combination of prefix and peer id, if it exists returns an error, otherwise returns nil
func (am *DefaultAccountManager) checkPrefixPeerExists(accountID, peer string, prefix netip.Prefix) error {
routesWithPrefix, err := am.Store.GetRoutesByPrefix(accountID, prefix)
@ -91,7 +96,7 @@ func (am *DefaultAccountManager) checkPrefixPeerExists(accountID, peer string, p
}
// CreateRoute creates and saves a new route
func (am *DefaultAccountManager) CreateRoute(accountID string, prefix, peer, description 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, enabled bool) (*route.Route, error) {
am.mux.Lock()
defer am.mux.Unlock()
@ -101,9 +106,9 @@ func (am *DefaultAccountManager) CreateRoute(accountID string, prefix, peer, des
}
var newRoute route.Route
prefixType, newPrefix, err := route.ParsePrefix(prefix)
prefixType, newPrefix, err := route.ParseNetwork(network)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "failed to parse IP %s", prefix)
return nil, status.Errorf(codes.InvalidArgument, "failed to parse IP %s", network)
}
err = am.checkPrefixPeerExists(accountID, peer, newPrefix)
if err != nil {
@ -121,11 +126,16 @@ func (am *DefaultAccountManager) CreateRoute(accountID string, prefix, peer, des
return nil, status.Errorf(codes.InvalidArgument, "metric should be between %d and %d", route.MinMetric, route.MaxMetric)
}
if utf8.RuneCountInString(netID) > route.MaxNetIDChar || netID == "" {
return nil, status.Errorf(codes.InvalidArgument, "identifier should be between 1 and %d", route.MaxNetIDChar)
}
newRoute.Peer = peer
newRoute.ID = xid.New().String()
newRoute.Prefix = newPrefix
newRoute.PrefixType = prefixType
newRoute.Network = newPrefix
newRoute.NetworkType = prefixType
newRoute.Description = description
newRoute.NetID = netID
newRoute.Masquerade = masquerade
newRoute.Metric = metric
newRoute.Enabled = enabled
@ -158,14 +168,18 @@ func (am *DefaultAccountManager) SaveRoute(accountID string, routeToSave *route.
return status.Errorf(codes.InvalidArgument, "route provided is nil")
}
if !routeToSave.Prefix.IsValid() {
return status.Errorf(codes.InvalidArgument, "invalid Prefix %s", routeToSave.Prefix.String())
if !routeToSave.Network.IsValid() {
return status.Errorf(codes.InvalidArgument, "invalid Prefix %s", routeToSave.Network.String())
}
if routeToSave.Metric < route.MinMetric || routeToSave.Metric > route.MaxMetric {
return status.Errorf(codes.InvalidArgument, "metric should be between %d and %d", route.MinMetric, route.MaxMetric)
}
if utf8.RuneCountInString(routeToSave.NetID) > route.MaxNetIDChar || routeToSave.NetID == "" {
return status.Errorf(codes.InvalidArgument, "identifier should be between 1 and %d", route.MaxNetIDChar)
}
account, err := am.Store.GetAccount(accountID)
if err != nil {
return status.Errorf(codes.NotFound, "account not found")
@ -214,8 +228,13 @@ func (am *DefaultAccountManager) UpdateRoute(accountID, routeID string, operatio
switch operation.Type {
case UpdateRouteDescription:
newRoute.Description = operation.Values[0]
case UpdateRoutePrefix:
prefixType, prefix, err := route.ParsePrefix(operation.Values[0])
case UpdateRouteNetworkIdentifier:
if utf8.RuneCountInString(operation.Values[0]) > route.MaxNetIDChar || operation.Values[0] == "" {
return nil, status.Errorf(codes.InvalidArgument, "identifier should be between 1 and %d", route.MaxNetIDChar)
}
newRoute.NetID = operation.Values[0]
case UpdateRouteNetwork:
prefixType, prefix, err := route.ParseNetwork(operation.Values[0])
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "failed to parse IP %s", operation.Values[0])
}
@ -223,8 +242,8 @@ func (am *DefaultAccountManager) UpdateRoute(accountID, routeID string, operatio
if err != nil {
return nil, err
}
newRoute.Prefix = prefix
newRoute.PrefixType = prefixType
newRoute.Network = prefix
newRoute.NetworkType = prefixType
case UpdateRoutePeer:
if operation.Values[0] != "" {
_, peerExist := account.Peers[operation.Values[0]]
@ -233,7 +252,7 @@ func (am *DefaultAccountManager) UpdateRoute(accountID, routeID string, operatio
}
}
err = am.checkPrefixPeerExists(accountID, operation.Values[0], routeToUpdate.Prefix)
err = am.checkPrefixPeerExists(accountID, operation.Values[0], routeToUpdate.Network)
if err != nil {
return nil, err
}
@ -320,12 +339,13 @@ func (am *DefaultAccountManager) ListRoutes(accountID string) ([]*route.Route, e
func toProtocolRoute(route *route.Route) *proto.Route {
return &proto.Route{
ID: route.ID,
Prefix: route.Prefix.String(),
PrefixType: int64(route.PrefixType),
Peer: route.Peer,
Metric: int64(route.Metric),
Masquerade: route.Masquerade,
ID: route.ID,
NetID: route.NetID,
Network: route.Network.String(),
NetworkType: int64(route.NetworkType),
Peer: route.Peer,
Metric: int64(route.Metric),
Masquerade: route.Masquerade,
}
}

View File

@ -14,7 +14,8 @@ const peer2Key = "/yF0+vCfv+mRR5k0dca0TrGdO/oiNeAI58gToZm5NyI="
func TestCreateRoute(t *testing.T) {
type input struct {
prefix string
network string
netID string
peer string
description string
masquerade bool
@ -32,7 +33,8 @@ func TestCreateRoute(t *testing.T) {
{
name: "Happy Path",
inputArgs: input{
prefix: "192.168.0.0/16",
network: "192.168.0.0/16",
netID: "happy",
peer: peer1Key,
description: "super",
masquerade: false,
@ -42,8 +44,9 @@ func TestCreateRoute(t *testing.T) {
errFunc: require.NoError,
shouldCreate: true,
expectedRoute: &route.Route{
Prefix: netip.MustParsePrefix("192.168.0.0/16"),
PrefixType: route.IPv4Prefix,
Network: netip.MustParsePrefix("192.168.0.0/16"),
NetworkType: route.IPv4Network,
NetID: "happy",
Peer: peer1Key,
Description: "super",
Masquerade: false,
@ -54,7 +57,8 @@ func TestCreateRoute(t *testing.T) {
{
name: "Bad Prefix",
inputArgs: input{
prefix: "192.168.0.0/34",
network: "192.168.0.0/34",
netID: "happy",
peer: peer1Key,
description: "super",
masquerade: false,
@ -67,7 +71,8 @@ func TestCreateRoute(t *testing.T) {
{
name: "Bad Peer",
inputArgs: input{
prefix: "192.168.0.0/16",
network: "192.168.0.0/16",
netID: "happy",
peer: "notExistingPeer",
description: "super",
masquerade: false,
@ -80,7 +85,8 @@ func TestCreateRoute(t *testing.T) {
{
name: "Empty Peer",
inputArgs: input{
prefix: "192.168.0.0/16",
network: "192.168.0.0/16",
netID: "happy",
peer: "",
description: "super",
masquerade: false,
@ -90,8 +96,9 @@ func TestCreateRoute(t *testing.T) {
errFunc: require.NoError,
shouldCreate: true,
expectedRoute: &route.Route{
Prefix: netip.MustParsePrefix("192.168.0.0/16"),
PrefixType: route.IPv4Prefix,
Network: netip.MustParsePrefix("192.168.0.0/16"),
NetworkType: route.IPv4Network,
NetID: "happy",
Peer: "",
Description: "super",
Masquerade: false,
@ -102,8 +109,9 @@ func TestCreateRoute(t *testing.T) {
{
name: "Large Metric",
inputArgs: input{
prefix: "192.168.0.0/16",
network: "192.168.0.0/16",
peer: peer1Key,
netID: "happy",
description: "super",
masquerade: false,
metric: 99999,
@ -115,7 +123,8 @@ func TestCreateRoute(t *testing.T) {
{
name: "Small Metric",
inputArgs: input{
prefix: "192.168.0.0/16",
network: "192.168.0.0/16",
netID: "happy",
peer: peer1Key,
description: "super",
masquerade: false,
@ -125,6 +134,34 @@ func TestCreateRoute(t *testing.T) {
errFunc: require.Error,
shouldCreate: false,
},
{
name: "Large NetID",
inputArgs: input{
network: "192.168.0.0/16",
peer: peer1Key,
netID: "12345678901234567890qwertyuiopqwertyuiop1",
description: "super",
masquerade: false,
metric: 9999,
enabled: true,
},
errFunc: require.Error,
shouldCreate: false,
},
{
name: "Small NetID",
inputArgs: input{
network: "192.168.0.0/16",
netID: "",
peer: peer1Key,
description: "",
masquerade: false,
metric: 9999,
enabled: true,
},
errFunc: require.Error,
shouldCreate: false,
},
}
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
@ -140,9 +177,10 @@ func TestCreateRoute(t *testing.T) {
outRoute, err := am.CreateRoute(
account.Id,
testCase.inputArgs.prefix,
testCase.inputArgs.network,
testCase.inputArgs.peer,
testCase.inputArgs.description,
testCase.inputArgs.netID,
testCase.inputArgs.masquerade,
testCase.inputArgs.metric,
testCase.inputArgs.enabled,
@ -173,6 +211,8 @@ func TestSaveRoute(t *testing.T) {
invalidPrefix, _ := netip.ParsePrefix("192.168.0.0/34")
validMetric := 1000
invalidMetric := 99999
validNetID := "12345678901234567890qw"
invalidNetID := "12345678901234567890qwertyuiopqwertyuiop1"
testCases := []struct {
name string
@ -189,8 +229,9 @@ func TestSaveRoute(t *testing.T) {
name: "Happy Path",
existingRoute: &route.Route{
ID: "testingRoute",
Prefix: netip.MustParsePrefix("192.168.0.0/16"),
PrefixType: route.IPv4Prefix,
Network: netip.MustParsePrefix("192.168.0.0/16"),
NetID: validNetID,
NetworkType: route.IPv4Network,
Peer: peer1Key,
Description: "super",
Masquerade: false,
@ -204,8 +245,9 @@ func TestSaveRoute(t *testing.T) {
shouldCreate: true,
expectedRoute: &route.Route{
ID: "testingRoute",
Prefix: validPrefix,
PrefixType: route.IPv4Prefix,
Network: validPrefix,
NetID: validNetID,
NetworkType: route.IPv4Network,
Peer: validPeer,
Description: "super",
Masquerade: false,
@ -217,8 +259,9 @@ func TestSaveRoute(t *testing.T) {
name: "Bad Prefix",
existingRoute: &route.Route{
ID: "testingRoute",
Prefix: netip.MustParsePrefix("192.168.0.0/16"),
PrefixType: route.IPv4Prefix,
Network: netip.MustParsePrefix("192.168.0.0/16"),
NetID: validNetID,
NetworkType: route.IPv4Network,
Peer: peer1Key,
Description: "super",
Masquerade: false,
@ -232,8 +275,9 @@ func TestSaveRoute(t *testing.T) {
name: "Bad Peer",
existingRoute: &route.Route{
ID: "testingRoute",
Prefix: netip.MustParsePrefix("192.168.0.0/16"),
PrefixType: route.IPv4Prefix,
Network: netip.MustParsePrefix("192.168.0.0/16"),
NetID: validNetID,
NetworkType: route.IPv4Network,
Peer: peer1Key,
Description: "super",
Masquerade: false,
@ -247,8 +291,25 @@ func TestSaveRoute(t *testing.T) {
name: "Invalid Metric",
existingRoute: &route.Route{
ID: "testingRoute",
Prefix: netip.MustParsePrefix("192.168.0.0/16"),
PrefixType: route.IPv4Prefix,
Network: netip.MustParsePrefix("192.168.0.0/16"),
NetID: validNetID,
NetworkType: route.IPv4Network,
Peer: peer1Key,
Description: "super",
Masquerade: false,
Metric: 9999,
Enabled: true,
},
newMetric: &invalidMetric,
errFunc: require.Error,
},
{
name: "Invalid NetID",
existingRoute: &route.Route{
ID: "testingRoute",
Network: netip.MustParsePrefix("192.168.0.0/16"),
NetID: invalidNetID,
NetworkType: route.IPv4Network,
Peer: peer1Key,
Description: "super",
Masquerade: false,
@ -262,8 +323,9 @@ func TestSaveRoute(t *testing.T) {
name: "Nil Route",
existingRoute: &route.Route{
ID: "testingRoute",
Prefix: netip.MustParsePrefix("192.168.0.0/16"),
PrefixType: route.IPv4Prefix,
Network: netip.MustParsePrefix("192.168.0.0/16"),
NetID: validNetID,
NetworkType: route.IPv4Network,
Peer: peer1Key,
Description: "super",
Masquerade: false,
@ -306,7 +368,7 @@ func TestSaveRoute(t *testing.T) {
}
if testCase.newPrefix != nil {
routeToSave.Prefix = *testCase.newPrefix
routeToSave.Network = *testCase.newPrefix
}
}
@ -334,8 +396,9 @@ func TestUpdateRoute(t *testing.T) {
existingRoute := &route.Route{
ID: routeID,
Prefix: netip.MustParsePrefix("192.168.0.0/16"),
PrefixType: route.IPv4Prefix,
Network: netip.MustParsePrefix("192.168.0.0/16"),
NetID: "superRoute",
NetworkType: route.IPv4Network,
Peer: peer1Key,
Description: "super",
Masquerade: false,
@ -364,8 +427,9 @@ func TestUpdateRoute(t *testing.T) {
shouldCreate: true,
expectedRoute: &route.Route{
ID: routeID,
Prefix: netip.MustParsePrefix("192.168.0.0/16"),
PrefixType: route.IPv4Prefix,
Network: netip.MustParsePrefix("192.168.0.0/16"),
NetID: "superRoute",
NetworkType: route.IPv4Network,
Peer: peer2Key,
Description: "super",
Masquerade: false,
@ -382,7 +446,7 @@ func TestUpdateRoute(t *testing.T) {
Values: []string{"great"},
},
RouteUpdateOperation{
Type: UpdateRoutePrefix,
Type: UpdateRouteNetwork,
Values: []string{"192.168.0.0/24"},
},
RouteUpdateOperation{
@ -401,13 +465,18 @@ func TestUpdateRoute(t *testing.T) {
Type: UpdateRouteEnabled,
Values: []string{"false"},
},
RouteUpdateOperation{
Type: UpdateRouteNetworkIdentifier,
Values: []string{"megaRoute"},
},
},
errFunc: require.NoError,
shouldCreate: true,
expectedRoute: &route.Route{
ID: routeID,
Prefix: netip.MustParsePrefix("192.168.0.0/24"),
PrefixType: route.IPv4Prefix,
Network: netip.MustParsePrefix("192.168.0.0/24"),
NetID: "megaRoute",
NetworkType: route.IPv4Network,
Peer: peer2Key,
Description: "great",
Masquerade: true,
@ -441,7 +510,7 @@ func TestUpdateRoute(t *testing.T) {
existingRoute: existingRoute,
operations: []RouteUpdateOperation{
RouteUpdateOperation{
Type: UpdateRoutePrefix,
Type: UpdateRouteNetwork,
Values: []string{"192.168.0.0/34"},
},
},
@ -471,8 +540,9 @@ func TestUpdateRoute(t *testing.T) {
shouldCreate: true,
expectedRoute: &route.Route{
ID: routeID,
Prefix: netip.MustParsePrefix("192.168.0.0/16"),
PrefixType: route.IPv4Prefix,
Network: netip.MustParsePrefix("192.168.0.0/16"),
NetID: "superRoute",
NetworkType: route.IPv4Network,
Peer: "",
Description: "super",
Masquerade: false,
@ -480,6 +550,28 @@ func TestUpdateRoute(t *testing.T) {
Enabled: true,
},
},
{
name: "Large Network ID",
existingRoute: existingRoute,
operations: []RouteUpdateOperation{
RouteUpdateOperation{
Type: UpdateRouteNetworkIdentifier,
Values: []string{"12345678901234567890qwertyuiopqwertyuiop1"},
},
},
errFunc: require.Error,
},
{
name: "Empty Network ID",
existingRoute: existingRoute,
operations: []RouteUpdateOperation{
RouteUpdateOperation{
Type: UpdateRouteNetworkIdentifier,
Values: []string{""},
},
},
errFunc: require.Error,
},
{
name: "Invalid Metric",
existingRoute: existingRoute,
@ -544,8 +636,8 @@ func TestDeleteRoute(t *testing.T) {
testingRoute := &route.Route{
ID: "testingRoute",
Prefix: netip.MustParsePrefix("192.168.0.0/16"),
PrefixType: route.IPv4Prefix,
Network: netip.MustParsePrefix("192.168.0.0/16"),
NetworkType: route.IPv4Network,
Peer: peer1Key,
Description: "super",
Masquerade: false,
@ -592,8 +684,9 @@ func TestGetNetworkMap_RouteSync(t *testing.T) {
baseRoute := &route.Route{
ID: "testingRoute",
Prefix: netip.MustParsePrefix("192.168.0.0/16"),
PrefixType: route.IPv4Prefix,
Network: netip.MustParsePrefix("192.168.0.0/16"),
NetID: "superNet",
NetworkType: route.IPv4Network,
Peer: peer1Key,
Description: "super",
Masquerade: false,
@ -615,8 +708,8 @@ func TestGetNetworkMap_RouteSync(t *testing.T) {
require.NoError(t, err)
require.Len(t, newAccountRoutes.Routes, 0, "new accounts should have no routes")
createdRoute, err := am.CreateRoute(account.Id, baseRoute.Prefix.String(), baseRoute.Peer,
baseRoute.Description, baseRoute.Masquerade, baseRoute.Metric, false)
createdRoute, err := am.CreateRoute(account.Id, baseRoute.Network.String(), baseRoute.Peer,
baseRoute.Description, baseRoute.NetID, baseRoute.Masquerade, baseRoute.Metric, false)
require.NoError(t, err)
noDisabledRoutes, err := am.GetNetworkMap(peer1Key)

View File

@ -14,59 +14,63 @@ const (
MinMetric = 1
// MaxMetric max metric input
MaxMetric = 9999
)
const (
// InvalidPrefixString invalid prefix type string
InvalidPrefixString = "Invalid"
// IPv4PrefixString IPv4 prefix type string
IPv4PrefixString = "IPv4"
// IPv6PrefixString IPv6 prefix type string
IPv6PrefixString = "IPv6"
// MaxNetIDChar Max Network Identifier
MaxNetIDChar = 40
)
const (
// InvalidPrefix invalid prefix type
InvalidPrefix PrefixType = iota
// IPv4Prefix IPv4 prefix type
IPv4Prefix
// IPv6Prefix IPv6 prefix type
IPv6Prefix
// InvalidNetworkString invalid network type string
InvalidNetworkString = "Invalid"
// IPv4NetworkString IPv4 network type string
IPv4NetworkString = "IPv4"
// IPv6NetworkString IPv6 network type string
IPv6NetworkString = "IPv6"
)
// PrefixType route prefix type
type PrefixType int
const (
// InvalidNetwork invalid network type
InvalidNetwork NetworkType = iota
// IPv4Network IPv4 network type
IPv4Network
// IPv6Network IPv6 network type
IPv6Network
)
// NetworkType route network type
type NetworkType int
// String returns prefix type string
func (p PrefixType) String() string {
func (p NetworkType) String() string {
switch p {
case IPv4Prefix:
return IPv4PrefixString
case IPv6Prefix:
return IPv6PrefixString
case IPv4Network:
return IPv4NetworkString
case IPv6Network:
return IPv6NetworkString
default:
return InvalidPrefixString
return InvalidNetworkString
}
}
// ToPrefixType returns a prefix type
func ToPrefixType(prefix string) PrefixType {
func ToPrefixType(prefix string) NetworkType {
switch prefix {
case IPv4PrefixString:
return IPv4Prefix
case IPv6PrefixString:
return IPv6Prefix
case IPv4NetworkString:
return IPv4Network
case IPv6NetworkString:
return IPv6Network
default:
return InvalidPrefix
return InvalidNetwork
}
}
// Route represents a route
type Route struct {
Prefix netip.Prefix
ID string
Network netip.Prefix
NetID string
Description string
Peer string
PrefixType PrefixType
NetworkType NetworkType
Masquerade bool
Metric int
Enabled bool
@ -77,8 +81,9 @@ func (r *Route) Copy() *Route {
return &Route{
ID: r.ID,
Description: r.Description,
Prefix: r.Prefix,
PrefixType: r.PrefixType,
NetID: r.NetID,
Network: r.Network,
NetworkType: r.NetworkType,
Peer: r.Peer,
Metric: r.Metric,
Masquerade: r.Masquerade,
@ -90,30 +95,31 @@ func (r *Route) Copy() *Route {
func (r *Route) IsEqual(other *Route) bool {
return other.ID == r.ID &&
other.Description == r.Description &&
other.Prefix == r.Prefix &&
other.PrefixType == r.PrefixType &&
other.NetID == r.NetID &&
other.Network == r.Network &&
other.NetworkType == r.NetworkType &&
other.Peer == r.Peer &&
other.Metric == r.Metric &&
other.Masquerade == r.Masquerade &&
other.Enabled == r.Enabled
}
// ParsePrefix Parses a prefix string and returns a netip.Prefix object and if is invalid, IPv4 or IPv6
func ParsePrefix(prefixString string) (PrefixType, netip.Prefix, error) {
prefix, err := netip.ParsePrefix(prefixString)
// ParseNetwork Parses a network prefix string and returns a netip.Prefix object and if is invalid, IPv4 or IPv6
func ParseNetwork(networkString string) (NetworkType, netip.Prefix, error) {
prefix, err := netip.ParsePrefix(networkString)
if err != nil {
return InvalidPrefix, netip.Prefix{}, err
return InvalidNetwork, netip.Prefix{}, err
}
masked := prefix.Masked()
if !masked.IsValid() {
return InvalidPrefix, netip.Prefix{}, status.Errorf(codes.InvalidArgument, "invalid range %s", prefixString)
return InvalidNetwork, netip.Prefix{}, status.Errorf(codes.InvalidArgument, "invalid range %s", networkString)
}
if masked.Addr().Is6() {
return IPv6Prefix, masked, nil
return IPv6Network, masked, nil
}
return IPv4Prefix, masked, nil
return IPv4Network, masked, nil
}