Skip to content

Commit

Permalink
Add network service to MonitorScopeSelector (#178)
Browse files Browse the repository at this point in the history
Allow MonitorScopeSelector to filter connections based
on network service as well.

Signed-off-by: Lugossy Zoltan <[email protected]>
  • Loading branch information
zolug committed Dec 4, 2024
1 parent df76555 commit 5e378ca
Show file tree
Hide file tree
Showing 4 changed files with 247 additions and 28 deletions.
85 changes: 57 additions & 28 deletions pkg/api/networkservice/connection.pb.go

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

2 changes: 2 additions & 0 deletions pkg/api/networkservice/connection.proto
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright 2018 Red Hat, Inc.
// Copyright (c) 2018 Cisco and/or its affiliates.
// Copyright (c) 2024 Nordix Foundation.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -91,6 +92,7 @@ message ConnectionEvent {

message MonitorScopeSelector {
repeated PathSegment path_segments = 1;
repeated string network_services = 2;
}

service MonitorConnection {
Expand Down
28 changes: 28 additions & 0 deletions pkg/api/networkservice/connection_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
//
// Copyright (c) 2023-2024 Cisco and/or its affiliates.
//
// Copyright (c) 2024 Nordix Foundation.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -37,12 +39,38 @@ func (x *Connection) Clone() *Connection {
return proto.Clone(x).(*Connection)
}

// Iterates through the selector.NetworkServices array looking for a network service
// that matches the Connection.NetworkService. Treats an empty selector.NetworkService
// array as a wildcard - Returns true on match
func (x *Connection) matchesNetworkService(networkServices []string) bool {
if len(networkServices) == 0 {
return true
}

for _, v := range networkServices {
if v == x.GetNetworkService() {
// matched network service
return true
}
}

return false
}

// MatchesMonitorScopeSelector - Returns true of the connection matches the selector
func (x *Connection) MatchesMonitorScopeSelector(selector *MonitorScopeSelector) bool {

Check failure on line 61 in pkg/api/networkservice/connection_helpers.go

View workflow job for this annotation

GitHub Actions / golangci-lint / golangci-lint

cyclomatic complexity 16 of func `(*Connection).MatchesMonitorScopeSelector` is high (> 15) (gocyclo)
if x == nil {
return false
}
// Note: Empty selector always matches a non-nil Connection
if len(selector.GetPathSegments()) == 0 && len(selector.GetNetworkServices()) == 0 {
return true
}
// Compare network service names first
if !x.matchesNetworkService(selector.GetNetworkServices()) {
return false
}
// Empty PathSegments in selector, treat as wildcard
if len(selector.GetPathSegments()) == 0 {
return true
}
Expand Down
160 changes: 160 additions & 0 deletions pkg/api/networkservice/connection_helpers_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// Copyright (c) 2023 Cisco and/or its affiliates.
//
// Copyright (c) 2024 Nordix Foundation.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -99,3 +101,161 @@ func TestMonitorScopeSelector(t *testing.T) {
})
}
}

// nolint: funlen
func TestNetworkServiceMonitorScopeSelector(t *testing.T) {
cases := []struct {
testname string
conn *networkservice.Connection
selector *networkservice.MonitorScopeSelector
matches bool
}{
{
testname: "EmptySelector",
conn: &networkservice.Connection{
Path: &networkservice.Path{
PathSegments: []*networkservice.PathSegment{{Name: "s1", Id: "id1", Token: "t1"}, {Name: "s2", Id: "id2", Token: "t2"}},
},
NetworkService: "ns1",
},
selector: &networkservice.MonitorScopeSelector{},
matches: true,
},
{
testname: "IdenticalPathsAndNetworkService",
conn: &networkservice.Connection{
Path: &networkservice.Path{
PathSegments: []*networkservice.PathSegment{{Name: "s1", Id: "id1", Token: "t1"}, {Name: "s2", Id: "id2", Token: "t2"}},
},
NetworkService: "ns1",
},
selector: &networkservice.MonitorScopeSelector{
PathSegments: []*networkservice.PathSegment{{Name: "s1", Id: "id1", Token: "t1"}, {Name: "s2", Id: "id2", Token: "t2"}},
NetworkServices: []string{"ns1"},
},
matches: true,
},
{
testname: "IdenticalPathsAndDifferentNetworkService",
conn: &networkservice.Connection{
Path: &networkservice.Path{
PathSegments: []*networkservice.PathSegment{{Name: "s1", Id: "id1", Token: "t1"}, {Name: "s2", Id: "id2", Token: "t2"}},
},
NetworkService: "ns1",
},
selector: &networkservice.MonitorScopeSelector{
PathSegments: []*networkservice.PathSegment{{Name: "s1", Id: "id1", Token: "t1"}, {Name: "s2", Id: "id2", Token: "t2"}},
NetworkServices: []string{"ns2"},
},
matches: false,
},
{
testname: "IdenticalPathsAndMatchingNetworkServiceList",
conn: &networkservice.Connection{
Path: &networkservice.Path{
PathSegments: []*networkservice.PathSegment{{Name: "s1", Id: "id1", Token: "t1"}, {Name: "s2", Id: "id2", Token: "t2"}},
},
NetworkService: "ns1",
},
selector: &networkservice.MonitorScopeSelector{
PathSegments: []*networkservice.PathSegment{{Name: "s1", Id: "id1", Token: "t1"}, {Name: "s2", Id: "id2", Token: "t2"}},
NetworkServices: []string{"ns2", "ns1", "ns3"},
},
matches: true,
},
{
testname: "IdenticalPathsAndNonMatchingNetworkServiceList",
conn: &networkservice.Connection{
Path: &networkservice.Path{
PathSegments: []*networkservice.PathSegment{{Name: "s1", Id: "id1", Token: "t1"}, {Name: "s2", Id: "id2", Token: "t2"}},
},
NetworkService: "ns1",
},
selector: &networkservice.MonitorScopeSelector{
PathSegments: []*networkservice.PathSegment{{Name: "s1", Id: "id1", Token: "t1"}, {Name: "s2", Id: "id2", Token: "t2"}},
NetworkServices: []string{"ns2", "ns3", "ns0"},
},
matches: false,
},
{
testname: "IdenticalNetworkService",
conn: &networkservice.Connection{
Path: &networkservice.Path{
PathSegments: []*networkservice.PathSegment{{Name: "s1", Id: "id1", Token: "t1"}, {Name: "s2", Id: "id2", Token: "t2"}},
},
NetworkService: "ns1",
},
selector: &networkservice.MonitorScopeSelector{
NetworkServices: []string{"ns1"},
},
matches: true,
},
{
testname: "IdenticalNetworkServiceEmptyConnectionPath",
conn: &networkservice.Connection{
NetworkService: "ns1",
},
selector: &networkservice.MonitorScopeSelector{
NetworkServices: []string{"ns1"},
},
matches: true,
},
{
testname: "DifferentNetworkService",
conn: &networkservice.Connection{
Path: &networkservice.Path{
PathSegments: []*networkservice.PathSegment{{Name: "s1", Id: "id1", Token: "t1"}, {Name: "s2", Id: "id2", Token: "t2"}},
},
NetworkService: "ns1",
},
selector: &networkservice.MonitorScopeSelector{
NetworkServices: []string{"ns2"},
},
matches: false,
},
{
testname: "DifferentNetworkServiceEmptyConnectionPath",
conn: &networkservice.Connection{
NetworkService: "ns1",
},
selector: &networkservice.MonitorScopeSelector{
NetworkServices: []string{"ns2"},
},
matches: false,
},
{
testname: "MatchingNetworkServiceList",
conn: &networkservice.Connection{
Path: &networkservice.Path{
PathSegments: []*networkservice.PathSegment{{Name: "s1", Id: "id1", Token: "t1"}, {Name: "s2", Id: "id2", Token: "t2"}},
},
NetworkService: "ns1",
},
selector: &networkservice.MonitorScopeSelector{
NetworkServices: []string{"ns2", "ns1", "ns3"},
},
matches: true,
},
{
testname: "NonMatchingNetworkServiceList",
conn: &networkservice.Connection{
Path: &networkservice.Path{
PathSegments: []*networkservice.PathSegment{{Name: "s1", Id: "id1", Token: "t1"}, {Name: "s2", Id: "id2", Token: "t2"}},
},
NetworkService: "ns1",
},
selector: &networkservice.MonitorScopeSelector{
NetworkServices: []string{"ns2", "ns3", "ns0"},
},
matches: false,
},
}

for _, testCase := range cases {
c := testCase
t.Run(c.testname, func(t *testing.T) {

Check failure on line 256 in pkg/api/networkservice/connection_helpers_test.go

View workflow job for this annotation

GitHub Actions / golangci-lint / golangci-lint

unnecessary leading newline (whitespace)

require.Equal(t, c.conn.MatchesMonitorScopeSelector(c.selector), c.matches)
})
}
}

0 comments on commit 5e378ca

Please sign in to comment.