github.com/cilium/cilium@v1.16.2/pkg/policy/api/ingress_test.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package api 5 6 import ( 7 "context" 8 "testing" 9 10 "fmt" 11 12 "github.com/stretchr/testify/require" 13 "k8s.io/apimachinery/pkg/util/intstr" 14 15 slim_metav1 "github.com/cilium/cilium/pkg/k8s/slim/k8s/apis/meta/v1" 16 ) 17 18 func TestIngressRequiresDerivativeRuleWithoutToGroups(t *testing.T) { 19 ig := IngressRule{} 20 require.Equal(t, false, ig.RequiresDerivative()) 21 } 22 23 func TestRequiresDerivativeRuleWithFromGroups(t *testing.T) { 24 ig := IngressRule{} 25 ig.FromGroups = []Groups{ 26 GetGroupsRule(), 27 } 28 require.Equal(t, true, ig.RequiresDerivative()) 29 } 30 31 func TestCreateDerivativeRuleWithoutFromGroups(t *testing.T) { 32 ig := &IngressRule{ 33 IngressCommonRule: IngressCommonRule{ 34 FromEndpoints: []EndpointSelector{ 35 { 36 LabelSelector: &slim_metav1.LabelSelector{MatchLabels: map[string]string{ 37 "test": "true", 38 }, 39 }, 40 }, 41 }, 42 }, 43 } 44 newRule, err := ig.CreateDerivative(context.TODO()) 45 require.EqualValues(t, newRule, ig) 46 require.Nil(t, err) 47 } 48 49 func TestCreateDerivativeRuleWithFromGroups(t *testing.T) { 50 cb := GetCallBackWithRule("192.168.1.1") 51 RegisterToGroupsProvider(AWSProvider, cb) 52 53 ig := &IngressRule{ 54 IngressCommonRule: IngressCommonRule{ 55 FromGroups: []Groups{ 56 GetGroupsRule(), 57 }, 58 }, 59 } 60 61 // Checking that the derivative rule is working correctly 62 require.Equal(t, true, ig.RequiresDerivative()) 63 64 newRule, err := ig.CreateDerivative(context.TODO()) 65 require.Nil(t, err) 66 require.Equal(t, 0, len(newRule.FromGroups)) 67 require.Equal(t, 1, len(newRule.FromCIDRSet)) 68 } 69 70 func TestIsLabelBasedIngress(t *testing.T) { 71 setUpSuite(t) 72 73 type args struct { 74 eg *IngressRule 75 } 76 type wanted struct { 77 isLabelBased bool 78 } 79 80 tests := []struct { 81 name string 82 setupArgs func() args 83 setupWanted func() wanted 84 }{ 85 { 86 name: "label-based-rule", 87 setupArgs: func() args { 88 return args{ 89 eg: &IngressRule{ 90 IngressCommonRule: IngressCommonRule{ 91 FromEndpoints: []EndpointSelector{ 92 { 93 LabelSelector: &slim_metav1.LabelSelector{MatchLabels: map[string]string{ 94 "test": "true", 95 }, 96 }, 97 }, 98 }, 99 }, 100 }, 101 } 102 }, 103 setupWanted: func() wanted { 104 return wanted{ 105 isLabelBased: true, 106 } 107 }, 108 }, 109 { 110 name: "cidr-based-rule", 111 setupArgs: func() args { 112 return args{ 113 &IngressRule{ 114 IngressCommonRule: IngressCommonRule{ 115 FromCIDR: CIDRSlice{"192.0.0.0/3"}, 116 }, 117 }, 118 } 119 }, 120 setupWanted: func() wanted { 121 return wanted{ 122 isLabelBased: true, 123 } 124 }, 125 }, 126 { 127 name: "cidrset-based-rule", 128 setupArgs: func() args { 129 return args{ 130 &IngressRule{ 131 IngressCommonRule: IngressCommonRule{ 132 FromCIDRSet: CIDRRuleSlice{ 133 { 134 Cidr: "192.0.0.0/3", 135 }, 136 }, 137 }, 138 }, 139 } 140 }, 141 setupWanted: func() wanted { 142 return wanted{ 143 isLabelBased: true, 144 } 145 }, 146 }, 147 { 148 name: "rule-with-requirements", 149 setupArgs: func() args { 150 return args{ 151 &IngressRule{ 152 IngressCommonRule: IngressCommonRule{ 153 FromRequires: []EndpointSelector{ 154 { 155 LabelSelector: &slim_metav1.LabelSelector{MatchLabels: map[string]string{ 156 "test": "true", 157 }, 158 }, 159 }, 160 }, 161 }, 162 }, 163 } 164 }, 165 setupWanted: func() wanted { 166 return wanted{ 167 isLabelBased: false, 168 } 169 }, 170 }, 171 { 172 name: "rule-with-entities", 173 setupArgs: func() args { 174 return args{ 175 &IngressRule{ 176 IngressCommonRule: IngressCommonRule{ 177 FromEntities: EntitySlice{ 178 EntityHost, 179 }, 180 }, 181 }, 182 } 183 }, 184 setupWanted: func() wanted { 185 return wanted{ 186 isLabelBased: true, 187 } 188 }, 189 }, 190 { 191 name: "rule-with-no-l3-specification", 192 setupArgs: func() args { 193 return args{ 194 &IngressRule{ 195 ToPorts: []PortRule{ 196 { 197 Ports: []PortProtocol{ 198 { 199 Port: "80", 200 Protocol: ProtoTCP, 201 }, 202 }, 203 }, 204 }, 205 }, 206 } 207 }, 208 setupWanted: func() wanted { 209 return wanted{ 210 isLabelBased: true, 211 } 212 }, 213 }, 214 { 215 name: "rule-with-named-port", 216 setupArgs: func() args { 217 return args{ 218 &IngressRule{ 219 ToPorts: []PortRule{ 220 { 221 Ports: []PortProtocol{ 222 { 223 Port: "port-80", 224 Protocol: ProtoTCP, 225 }, 226 }, 227 }, 228 }, 229 }, 230 } 231 }, 232 setupWanted: func() wanted { 233 return wanted{ 234 isLabelBased: true, 235 } 236 }, 237 }, 238 { 239 name: "rule-with-icmp", 240 setupArgs: func() args { 241 icmpType := intstr.FromInt(8) 242 return args{ 243 &IngressRule{ 244 ICMPs: ICMPRules{ 245 { 246 Fields: []ICMPField{ 247 { 248 Type: &icmpType, 249 }, 250 }, 251 }, 252 }, 253 }, 254 } 255 }, 256 setupWanted: func() wanted { 257 return wanted{ 258 isLabelBased: true, 259 } 260 }, 261 }, 262 { 263 name: "rule-with-icmp6", 264 setupArgs: func() args { 265 icmpType := intstr.FromInt(128) 266 return args{ 267 &IngressRule{ 268 ICMPs: ICMPRules{ 269 { 270 Fields: []ICMPField{ 271 { 272 Family: IPv6Family, 273 Type: &icmpType, 274 }, 275 }, 276 }, 277 }, 278 }, 279 } 280 }, 281 setupWanted: func() wanted { 282 return wanted{ 283 isLabelBased: true, 284 } 285 }, 286 }, 287 } 288 289 for _, tt := range tests { 290 args := tt.setupArgs() 291 want := tt.setupWanted() 292 require.Equal(t, nil, args.eg.sanitize(), fmt.Sprintf("Test name: %q", tt.name)) 293 isLabelBased := args.eg.AllowsWildcarding() 294 require.EqualValues(t, want.isLabelBased, isLabelBased, fmt.Sprintf("Test name: %q", tt.name)) 295 } 296 } 297 298 func TestIngressCommonRuleDeepEqual(t *testing.T) { 299 testCases := []struct { 300 name string 301 in, other *IngressCommonRule 302 expected bool 303 }{ 304 { 305 name: "All fields are nil in both", 306 in: &IngressCommonRule{}, 307 other: &IngressCommonRule{}, 308 expected: true, 309 }, 310 { 311 name: "All fields are empty in both", 312 in: &IngressCommonRule{ 313 FromEndpoints: []EndpointSelector{}, 314 FromCIDR: []CIDR{}, 315 FromCIDRSet: []CIDRRule{}, 316 FromEntities: []Entity{}, 317 }, 318 other: &IngressCommonRule{ 319 FromEndpoints: []EndpointSelector{}, 320 FromCIDR: []CIDR{}, 321 FromCIDRSet: []CIDRRule{}, 322 FromEntities: []Entity{}, 323 }, 324 expected: true, 325 }, 326 { 327 name: "FromEndpoints is nil in left operand", 328 in: &IngressCommonRule{ 329 FromEndpoints: nil, 330 }, 331 other: &IngressCommonRule{ 332 FromEndpoints: []EndpointSelector{}, 333 }, 334 expected: false, 335 }, 336 { 337 name: "FromEndpoints is empty in left operand", 338 in: &IngressCommonRule{ 339 FromEndpoints: []EndpointSelector{}, 340 }, 341 other: &IngressCommonRule{ 342 FromEndpoints: nil, 343 }, 344 expected: false, 345 }, 346 { 347 name: "FromCIDR is nil in left operand", 348 in: &IngressCommonRule{ 349 FromCIDR: nil, 350 }, 351 other: &IngressCommonRule{ 352 FromCIDR: []CIDR{}, 353 }, 354 expected: false, 355 }, 356 { 357 name: "FromCIDR is empty in left operand", 358 in: &IngressCommonRule{ 359 FromCIDR: []CIDR{}, 360 }, 361 other: &IngressCommonRule{ 362 FromCIDR: nil, 363 }, 364 expected: false, 365 }, 366 { 367 name: "FromCIDRSet is nil in left operand", 368 in: &IngressCommonRule{ 369 FromCIDRSet: nil, 370 }, 371 other: &IngressCommonRule{ 372 FromCIDRSet: []CIDRRule{}, 373 }, 374 expected: false, 375 }, 376 { 377 name: "FromCIDRSet is empty in left operand", 378 in: &IngressCommonRule{ 379 FromCIDRSet: []CIDRRule{}, 380 }, 381 other: &IngressCommonRule{ 382 FromCIDRSet: nil, 383 }, 384 expected: false, 385 }, 386 { 387 name: "FromEntities is nil in left operand", 388 in: &IngressCommonRule{ 389 FromEntities: nil, 390 }, 391 other: &IngressCommonRule{ 392 FromEntities: []Entity{}, 393 }, 394 expected: false, 395 }, 396 { 397 name: "FromEntities is empty in left operand", 398 in: &IngressCommonRule{ 399 FromEntities: []Entity{}, 400 }, 401 other: &IngressCommonRule{ 402 FromEntities: nil, 403 }, 404 expected: false, 405 }, 406 } 407 for _, tc := range testCases { 408 t.Run(tc.name, func(t *testing.T) { 409 require.Equal(t, tc.expected, tc.in.DeepEqual(tc.other)) 410 }) 411 } 412 }