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 }