From f2a585e950928ecae5fa69637f7b947f13e6f457 Mon Sep 17 00:00:00 2001 From: Denis Tingaikin Date: Mon, 2 Oct 2023 13:32:15 +0300 Subject: [PATCH] do not choose endpoints that doesn't match with the network service (#1516) Signed-off-by: Denis Tingaikin --- .../common/discover/server_test.go | 98 +++++++++++++++++++ pkg/tools/matchutils/utils.go | 7 +- 2 files changed, 103 insertions(+), 2 deletions(-) diff --git a/pkg/networkservice/common/discover/server_test.go b/pkg/networkservice/common/discover/server_test.go index 4d3055121..9095544f9 100644 --- a/pkg/networkservice/common/discover/server_test.go +++ b/pkg/networkservice/common/discover/server_test.go @@ -1,5 +1,7 @@ // Copyright (c) 2020-2022 Doc.ai and/or its affiliates. // +// Copyright (c) 2023 Cisco and/or its affiliates. +// // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -36,6 +38,7 @@ import ( registryadapters "github.com/networkservicemesh/sdk/pkg/registry/core/adapters" registrynext "github.com/networkservicemesh/sdk/pkg/registry/core/next" "github.com/networkservicemesh/sdk/pkg/tools/clienturlctx" + "github.com/networkservicemesh/sdk/pkg/tools/matchutils" ) const ( @@ -543,3 +546,98 @@ func TestDiscoverCandidatesServer_NoEndpointOnClose(t *testing.T) { require.True(t, closed) } + +func Test_Discover_Scale_FromZero_vL3(t *testing.T) { + var ns = ®istry.NetworkService{ + Name: "ns-1", + Payload: "IP", + Matches: []*registry.Match{ + { + Fallthrough: true, + Routes: []*registry.Destination{ + { + DestinationSelector: map[string]string{ + "app": "nse-vl3-vpp", + "nodeName": "{{.nodeName}}", + }, + }, + }, + }, + { + Fallthrough: true, + SourceSelector: map[string]string{ + "capability": "vl3", + }, + Routes: []*registry.Destination{ + { + DestinationSelector: map[string]string{ + "capability": "vl3", + }, + }, + }, + }, + { + Fallthrough: true, + Routes: []*registry.Destination{ + { + DestinationSelector: map[string]string{ + "app": "nse-autoscaler", + }, + }, + }, + }, + }, + } + + var nseA = ®istry.NetworkServiceEndpoint{ + Name: "nse-A", + NetworkServiceLabels: map[string]*registry.NetworkServiceLabels{ + "ns-1": {Labels: map[string]string{ + "capability": "vl3", + "nodeName": "node-1", + "app": "nse-vl3-vpp", + }}, + }, + } + + var nseB = ®istry.NetworkServiceEndpoint{ + Name: "nse-B", + NetworkServiceLabels: map[string]*registry.NetworkServiceLabels{ + "ns-1": {Labels: map[string]string{ + "capability": "vl3", + "nodeName": "node-2", + "app": "nse-vl3-vpp", + }}, + }, + } + + var nseC = ®istry.NetworkServiceEndpoint{ + Name: "nse-C", + NetworkServiceLabels: map[string]*registry.NetworkServiceLabels{ + "ns-1": {Labels: map[string]string{ + "app": "nse-autoscaler", + }}, + }, + } + + var nseD = ®istry.NetworkServiceEndpoint{ + Name: "nse-D", + NetworkServiceLabels: map[string]*registry.NetworkServiceLabels{ + "ns-1": {Labels: map[string]string{ + "app": "unknown", + }}, + }, + } + + require.Empty(t, matchutils.MatchEndpoint(map[string]string{}, ns, nseD), "there are no matches for nse-D") + require.Empty(t, matchutils.MatchEndpoint(map[string]string{"app": "nse-autoscaler"}, ns, nseD), "there are no matches for nse-D") + + require.Equal(t, []*registry.NetworkServiceEndpoint{nseC}, matchutils.MatchEndpoint(map[string]string{}, ns, nseC, nseD), "by match №3") + require.Equal(t, []*registry.NetworkServiceEndpoint{nseC}, matchutils.MatchEndpoint(map[string]string{"app": "nse-autoscaler"}, ns, nseC, nseD), "by match №3") + + require.Equal(t, []*registry.NetworkServiceEndpoint{nseB}, matchutils.MatchEndpoint(map[string]string{"app": "nse-vl3-vpp", "nodeName": "node-2"}, ns, nseC, nseA, nseB, nseD), "by match №1") + require.Equal(t, []*registry.NetworkServiceEndpoint{nseA}, matchutils.MatchEndpoint(map[string]string{"app": "nse-vl3-vpp", "nodeName": "node-1"}, ns, nseC, nseA, nseD, nseB), "by match №1") + + require.Equal(t, []*registry.NetworkServiceEndpoint{nseA}, matchutils.MatchEndpoint(map[string]string{"capability": "vl3", "app": "nse-vl3-vpp", "nodeName": "node-2"}, ns, nseC, nseA, nseD), "by match №2") + require.Equal(t, []*registry.NetworkServiceEndpoint{nseB}, matchutils.MatchEndpoint(map[string]string{"capability": "vl3", "app": "nse-vl3-vpp", "nodeName": "node-1"}, ns, nseC, nseD, nseB), "by match №2") +} diff --git a/pkg/tools/matchutils/utils.go b/pkg/tools/matchutils/utils.go index 335a77d60..45fb5ebbc 100644 --- a/pkg/tools/matchutils/utils.go +++ b/pkg/tools/matchutils/utils.go @@ -34,6 +34,9 @@ import ( // MatchEndpoint filters input nses by network service configuration. // Returns the same nses list if no matches are declared in the network service. func MatchEndpoint(nsLabels map[string]string, ns *registry.NetworkService, nses ...*registry.NetworkServiceEndpoint) []*registry.NetworkServiceEndpoint { + if len(ns.Matches) == 0 { + return nses + } for _, match := range ns.GetMatches() { // All match source selector labels should be present in the requested labels map if !IsSubset(nsLabels, match.GetSourceSelector(), nsLabels) { @@ -60,13 +63,13 @@ func MatchEndpoint(nsLabels map[string]string, ns *registry.NetworkService, nses } if match.GetMetadata() != nil && len(match.Routes) == 0 && len(nseCandidates) == 0 { - break + return nses } return nseCandidates } - return nses + return nil } // MatchNetworkServices returns true if two network services are matched