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

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

View File

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

View File

@ -70,7 +70,7 @@ type AccountManager interface {
DeleteRule(accountId, ruleID string) error DeleteRule(accountId, ruleID string) error
ListRules(accountId string) ([]*Rule, error) ListRules(accountId string) ([]*Rule, error)
GetRoute(accountID, routeID string) (*route.Route, 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 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

View File

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

View File

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

View File

@ -44,8 +44,9 @@ const (
RoutePatchOperationPathEnabled RoutePatchOperationPath = "enabled" RoutePatchOperationPathEnabled RoutePatchOperationPath = "enabled"
RoutePatchOperationPathMasquerade RoutePatchOperationPath = "masquerade" RoutePatchOperationPathMasquerade RoutePatchOperationPath = "masquerade"
RoutePatchOperationPathMetric RoutePatchOperationPath = "metric" RoutePatchOperationPathMetric RoutePatchOperationPath = "metric"
RoutePatchOperationPathNetwork RoutePatchOperationPath = "network"
RoutePatchOperationPathNetworkId RoutePatchOperationPath = "network_id"
RoutePatchOperationPathPeer RoutePatchOperationPath = "peer" RoutePatchOperationPathPeer RoutePatchOperationPath = "peer"
RoutePatchOperationPathPrefix RoutePatchOperationPath = "prefix"
) )
// Defines values for RulePatchOperationOp. // Defines values for RulePatchOperationOp.
@ -184,14 +185,17 @@ type Route struct {
// Route metric number. Lowest number has higher priority // Route metric number. Lowest number has higher priority
Metric int `json:"metric"` 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 Identifier associated with route
Peer string `json:"peer"` 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. // RoutePatchOperation defines model for RoutePatchOperation.
@ -226,11 +230,14 @@ type RouteRequest struct {
// Route metric number. Lowest number has higher priority // Route metric number. Lowest number has higher priority
Metric int `json:"metric"` 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 Identifier associated with route
Peer string `json:"peer"` Peer string `json:"peer"`
// Prefix or network range in CIDR format
Prefix string `json:"prefix"`
} }
// Rule defines model for Rule. // Rule defines model for Rule.

View File

@ -12,6 +12,7 @@ import (
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/status" "google.golang.org/grpc/status"
"net/http" "net/http"
"unicode/utf8"
) )
// Routes is the routes handler of the account // 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 peerKey = peer.Key
} }
_, newPrefix, err := route.ParsePrefix(req.Prefix) _, newPrefix, err := route.ParseNetwork(req.Network)
if err != nil { 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 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 { if err != nil {
log.Error(err) log.Error(err)
http.Redirect(w, r, "/", http.StatusInternalServerError) http.Redirect(w, r, "/", http.StatusInternalServerError)
@ -123,9 +129,9 @@ func (h *Routes) UpdateRouteHandler(w http.ResponseWriter, r *http.Request) {
return return
} }
prefixType, newPrefix, err := route.ParsePrefix(req.Prefix) prefixType, newPrefix, err := route.ParseNetwork(req.Network)
if err != nil { 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 return
} }
@ -140,10 +146,16 @@ func (h *Routes) UpdateRouteHandler(w http.ResponseWriter, r *http.Request) {
peerKey = peer.Key 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{ newRoute := &route.Route{
ID: routeID, ID: routeID,
Prefix: newPrefix, Network: newPrefix,
PrefixType: prefixType, NetID: req.NetworkId,
NetworkType: prefixType,
Masquerade: req.Masquerade, Masquerade: req.Masquerade,
Peer: peerKey, Peer: peerKey,
Metric: req.Metric, Metric: req.Metric,
@ -200,14 +212,14 @@ func (h *Routes) PatchRouteHandler(w http.ResponseWriter, r *http.Request) {
for _, patch := range req { for _, patch := range req {
switch patch.Path { switch patch.Path {
case api.RoutePatchOperationPathPrefix: case api.RoutePatchOperationPathNetwork:
if patch.Op != api.RoutePatchOperationOpReplace { 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) http.StatusBadRequest)
return return
} }
operations = append(operations, server.RouteUpdateOperation{ operations = append(operations, server.RouteUpdateOperation{
Type: server.UpdateRoutePrefix, Type: server.UpdateRouteNetwork,
Values: patch.Value, Values: patch.Value,
}) })
case api.RoutePatchOperationPathDescription: case api.RoutePatchOperationPathDescription:
@ -220,6 +232,16 @@ func (h *Routes) PatchRouteHandler(w http.ResponseWriter, r *http.Request) {
Type: server.UpdateRouteDescription, Type: server.UpdateRouteDescription,
Values: patch.Value, 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: case api.RoutePatchOperationPathPeer:
if patch.Op != api.RoutePatchOperationOpReplace { if patch.Op != api.RoutePatchOperationOpReplace {
http.Error(w, fmt.Sprintf("Peer field only accepts replace operation, got %s", patch.Op), 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{ return &api.Route{
Id: serverRoute.ID, Id: serverRoute.ID,
Description: serverRoute.Description, Description: serverRoute.Description,
NetworkId: serverRoute.NetID,
Enabled: serverRoute.Enabled, Enabled: serverRoute.Enabled,
Peer: peerIP, Peer: peerIP,
Prefix: serverRoute.Prefix.String(), Network: serverRoute.Network.String(),
PrefixType: serverRoute.PrefixType.String(), NetworkType: serverRoute.NetworkType.String(),
Masquerade: serverRoute.Masquerade, Masquerade: serverRoute.Masquerade,
Metric: serverRoute.Metric, Metric: serverRoute.Metric,
} }

View File

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

View File

@ -45,7 +45,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 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) GetRouteFunc func(accountID, routeID 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)
@ -369,9 +369,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, 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 { 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") return nil, status.Errorf(codes.Unimplemented, "method CreateRoute is not implemented")
} }

View File

@ -9,13 +9,14 @@ import (
"google.golang.org/grpc/status" "google.golang.org/grpc/status"
"net/netip" "net/netip"
"strconv" "strconv"
"unicode/utf8"
) )
const ( const (
// UpdateRouteDescription indicates a route description update operation // UpdateRouteDescription indicates a route description update operation
UpdateRouteDescription RouteUpdateOperationType = iota UpdateRouteDescription RouteUpdateOperationType = iota
// UpdateRoutePrefix indicates a route IP update operation // UpdateRouteNetwork indicates a route IP update operation
UpdateRoutePrefix UpdateRouteNetwork
// UpdateRoutePeer indicates a route peer update operation // UpdateRoutePeer indicates a route peer update operation
UpdateRoutePeer UpdateRoutePeer
// UpdateRouteMetric indicates a route metric update operation // UpdateRouteMetric indicates a route metric update operation
@ -24,6 +25,8 @@ const (
UpdateRouteMasquerade UpdateRouteMasquerade
// UpdateRouteEnabled indicates a route enabled update operation // UpdateRouteEnabled indicates a route enabled update operation
UpdateRouteEnabled UpdateRouteEnabled
// UpdateRouteNetworkIdentifier indicates a route net ID update operation
UpdateRouteNetworkIdentifier
) )
// RouteUpdateOperationType operation type // RouteUpdateOperationType operation type
@ -33,8 +36,8 @@ func (t RouteUpdateOperationType) String() string {
switch t { switch t {
case UpdateRouteDescription: case UpdateRouteDescription:
return "UpdateRouteDescription" return "UpdateRouteDescription"
case UpdateRoutePrefix: case UpdateRouteNetwork:
return "UpdateRoutePrefix" return "UpdateRouteNetwork"
case UpdateRoutePeer: case UpdateRoutePeer:
return "UpdateRoutePeer" return "UpdateRoutePeer"
case UpdateRouteMetric: case UpdateRouteMetric:
@ -43,6 +46,8 @@ func (t RouteUpdateOperationType) String() string {
return "UpdateRouteMasquerade" return "UpdateRouteMasquerade"
case UpdateRouteEnabled: case UpdateRouteEnabled:
return "UpdateRouteEnabled" return "UpdateRouteEnabled"
case UpdateRouteNetworkIdentifier:
return "UpdateRouteNetworkIdentifier"
default: default:
return "InvalidOperation" 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) 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 { func (am *DefaultAccountManager) checkPrefixPeerExists(accountID, peer string, prefix netip.Prefix) error {
routesWithPrefix, err := am.Store.GetRoutesByPrefix(accountID, prefix) 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 // 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() am.mux.Lock()
defer am.mux.Unlock() defer am.mux.Unlock()
@ -101,9 +106,9 @@ func (am *DefaultAccountManager) CreateRoute(accountID string, prefix, peer, des
} }
var newRoute route.Route var newRoute route.Route
prefixType, newPrefix, err := route.ParsePrefix(prefix) prefixType, newPrefix, err := route.ParseNetwork(network)
if err != nil { 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) err = am.checkPrefixPeerExists(accountID, peer, newPrefix)
if err != nil { 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) 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.Peer = peer
newRoute.ID = xid.New().String() newRoute.ID = xid.New().String()
newRoute.Prefix = newPrefix newRoute.Network = newPrefix
newRoute.PrefixType = prefixType newRoute.NetworkType = prefixType
newRoute.Description = description newRoute.Description = description
newRoute.NetID = netID
newRoute.Masquerade = masquerade newRoute.Masquerade = masquerade
newRoute.Metric = metric newRoute.Metric = metric
newRoute.Enabled = enabled newRoute.Enabled = enabled
@ -158,14 +168,18 @@ func (am *DefaultAccountManager) SaveRoute(accountID string, routeToSave *route.
return status.Errorf(codes.InvalidArgument, "route provided is nil") return status.Errorf(codes.InvalidArgument, "route provided is nil")
} }
if !routeToSave.Prefix.IsValid() { if !routeToSave.Network.IsValid() {
return status.Errorf(codes.InvalidArgument, "invalid Prefix %s", routeToSave.Prefix.String()) return status.Errorf(codes.InvalidArgument, "invalid Prefix %s", routeToSave.Network.String())
} }
if routeToSave.Metric < route.MinMetric || routeToSave.Metric > route.MaxMetric { 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) 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) account, err := am.Store.GetAccount(accountID)
if err != nil { if err != nil {
return status.Errorf(codes.NotFound, "account not found") return status.Errorf(codes.NotFound, "account not found")
@ -214,8 +228,13 @@ func (am *DefaultAccountManager) UpdateRoute(accountID, routeID string, operatio
switch operation.Type { switch operation.Type {
case UpdateRouteDescription: case UpdateRouteDescription:
newRoute.Description = operation.Values[0] newRoute.Description = operation.Values[0]
case UpdateRoutePrefix: case UpdateRouteNetworkIdentifier:
prefixType, prefix, err := route.ParsePrefix(operation.Values[0]) 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 { if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "failed to parse IP %s", operation.Values[0]) 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 { if err != nil {
return nil, err return nil, err
} }
newRoute.Prefix = prefix newRoute.Network = prefix
newRoute.PrefixType = prefixType newRoute.NetworkType = prefixType
case UpdateRoutePeer: case UpdateRoutePeer:
if operation.Values[0] != "" { if operation.Values[0] != "" {
_, peerExist := account.Peers[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 { if err != nil {
return nil, err return nil, err
} }
@ -321,8 +340,9 @@ func (am *DefaultAccountManager) ListRoutes(accountID string) ([]*route.Route, e
func toProtocolRoute(route *route.Route) *proto.Route { func toProtocolRoute(route *route.Route) *proto.Route {
return &proto.Route{ return &proto.Route{
ID: route.ID, ID: route.ID,
Prefix: route.Prefix.String(), NetID: route.NetID,
PrefixType: int64(route.PrefixType), Network: route.Network.String(),
NetworkType: int64(route.NetworkType),
Peer: route.Peer, Peer: route.Peer,
Metric: int64(route.Metric), Metric: int64(route.Metric),
Masquerade: route.Masquerade, Masquerade: route.Masquerade,

View File

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

View File

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