github.com/cilium/cilium@v1.16.2/pkg/hubble/filters/nodename_test.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Hubble
     3  
     4  package filters
     5  
     6  import (
     7  	"context"
     8  	"testing"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/require"
    12  
    13  	flowpb "github.com/cilium/cilium/api/v1/flow"
    14  	v1 "github.com/cilium/cilium/pkg/hubble/api/v1"
    15  	"github.com/cilium/cilium/pkg/monitor/api"
    16  )
    17  
    18  func TestNodeFilter(t *testing.T) {
    19  	tests := []struct {
    20  		name            string
    21  		nodeName        []string
    22  		wantErr         bool
    23  		wantErrContains string
    24  		want            map[string]bool
    25  	}{
    26  		{
    27  			name: "no_filter",
    28  			want: map[string]bool{
    29  				"default/k8s1": true,
    30  				"k8s1":         true,
    31  				"":             true, // with no filter, even empty node names match
    32  			},
    33  		},
    34  		{
    35  			name:     "everything",
    36  			nodeName: []string{"/"},
    37  			want: map[string]bool{
    38  				"default/k8s1": true,
    39  				"k8s1":         true,
    40  				"":             false, // with a filter, empty node names never match
    41  			},
    42  		},
    43  		{
    44  			name:     "literal_cluster_pattern",
    45  			nodeName: []string{"cluster-name/"},
    46  			want: map[string]bool{
    47  				"cluster-name/k8s1": true,
    48  				"cluster-name/k8s2": true,
    49  				"default/k8s1":      false,
    50  				"k8s1":              false,
    51  			},
    52  		},
    53  		{
    54  			name:     "literal_node_pattern",
    55  			nodeName: []string{"k8s1"},
    56  			want: map[string]bool{
    57  				"default/k8s1": true,
    58  				"default/k8s2": false,
    59  				"k8s1":         true,
    60  			},
    61  		},
    62  		{
    63  			name:     "literal_node_patterns",
    64  			nodeName: []string{"k8s1", "runtime1"},
    65  			want: map[string]bool{
    66  				"default/k8s1":     true,
    67  				"default/k8s2":     false,
    68  				"default/runtime1": true,
    69  				"k8s1":             true,
    70  			},
    71  		},
    72  		{
    73  			name:     "node_wildcard_pattern",
    74  			nodeName: []string{"k8s*"},
    75  			want: map[string]bool{
    76  				"default/k8s1":     true,
    77  				"default/runtime1": false,
    78  				"k8s1":             true,
    79  			},
    80  		},
    81  		{
    82  			name:     "cluster_wildcard_pattern",
    83  			nodeName: []string{"cluster-*/k8s1"},
    84  			want: map[string]bool{
    85  				"cluster-1/k8s1": true,
    86  				"cluster-1/k8s2": false,
    87  				"default/k8s1":   false,
    88  				"k8s1":           false,
    89  			},
    90  		},
    91  		{
    92  			name:     "cluster_pattern_and_node_wildcard_pattern",
    93  			nodeName: []string{"cluster-name/*.com"},
    94  			want: map[string]bool{
    95  				"cluster-name/foo.com":     true,
    96  				"cluster-name/foo.bar.com": true,
    97  				"cluster-name/foo.com.org": false,
    98  				"default/foo.com":          false,
    99  				"k8s1":                     false,
   100  			},
   101  		},
   102  		{
   103  			name:            "invalid_empty_pattern",
   104  			nodeName:        []string{""},
   105  			wantErr:         true,
   106  			wantErrContains: "empty pattern",
   107  		},
   108  		{
   109  			name:            "invalid_cluster_pattern",
   110  			nodeName:        []string{"cluster|name/"},
   111  			wantErr:         true,
   112  			wantErrContains: "invalid rune in pattern",
   113  		},
   114  		{
   115  			name:            "invalid_node_pattern",
   116  			nodeName:        []string{"cluster-name/node|name"},
   117  			wantErr:         true,
   118  			wantErrContains: "invalid rune in pattern",
   119  		},
   120  		{
   121  			name:            "too_many_slashes",
   122  			nodeName:        []string{"cluster-name/node-name/more"},
   123  			wantErr:         true,
   124  			wantErrContains: "too many slashes in pattern",
   125  		},
   126  	}
   127  	for _, tt := range tests {
   128  		t.Run(tt.name, func(t *testing.T) {
   129  			ff := []*flowpb.FlowFilter{
   130  				{
   131  					EventType: []*flowpb.EventTypeFilter{
   132  						{
   133  							Type: api.MessageTypeAccessLog,
   134  						},
   135  					},
   136  					NodeName: tt.nodeName,
   137  				},
   138  			}
   139  			fl, err := BuildFilterList(context.Background(), ff, []OnBuildFilter{&NodeNameFilter{}})
   140  			if tt.wantErr {
   141  				require.Error(t, err)
   142  				assert.Contains(t, err.Error(), tt.wantErrContains)
   143  				return
   144  			}
   145  
   146  			for nodeName, want := range tt.want {
   147  				ev := &v1.Event{
   148  					Event: &flowpb.Flow{
   149  						EventType: &flowpb.CiliumEventType{
   150  							Type: api.MessageTypeAccessLog,
   151  						},
   152  						NodeName: nodeName,
   153  					},
   154  				}
   155  				assert.Equal(t, want, fl.MatchOne(ev), nodeName)
   156  			}
   157  		})
   158  	}
   159  }