github.com/rohankumardubey/cilium@v1.6.12/daemon/policy_test.go (about) 1 // Copyright 2016-2019 Authors of Cilium 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // +build !privileged_tests 16 17 package main 18 19 import ( 20 "context" 21 "fmt" 22 "os" 23 "sort" 24 "time" 25 26 "github.com/cilium/cilium/common/addressing" 27 "github.com/cilium/cilium/pkg/checker" 28 "github.com/cilium/cilium/pkg/endpoint" 29 "github.com/cilium/cilium/pkg/endpoint/regeneration" 30 "github.com/cilium/cilium/pkg/identity" 31 "github.com/cilium/cilium/pkg/identity/cache" 32 "github.com/cilium/cilium/pkg/labels" 33 "github.com/cilium/cilium/pkg/mac" 34 "github.com/cilium/cilium/pkg/policy/api" 35 "github.com/cilium/cilium/pkg/testutils" 36 37 cilium "github.com/cilium/proxy/go/cilium/api" 38 envoy_api_v2_core "github.com/cilium/proxy/go/envoy/api/v2/core" 39 envoy_api_v2_route "github.com/cilium/proxy/go/envoy/api/v2/route" 40 envoy_type_matcher "github.com/cilium/proxy/go/envoy/type/matcher" 41 42 "github.com/golang/protobuf/ptypes/wrappers" 43 44 . "gopkg.in/check.v1" 45 ) 46 47 var ( 48 QAHardAddr = mac.MAC{0x01, 0x02, 0x03, 0x04, 0x05, 0x06} 49 QAIPv6Addr, _ = addressing.NewCiliumIPv6("beef:beef:beef:beef:aaaa:aaaa:1111:1112") 50 QAIPv4Addr, _ = addressing.NewCiliumIPv4("10.11.12.13") 51 ProdHardAddr = mac.MAC{0x01, 0x07, 0x08, 0x09, 0x0a, 0x0b} 52 ProdIPv6Addr, _ = addressing.NewCiliumIPv6("cafe:cafe:cafe:cafe:aaaa:aaaa:1111:1112") 53 ProdIPv4Addr, _ = addressing.NewCiliumIPv4("10.11.12.14") 54 55 lblProd = labels.ParseLabel("Prod") 56 lblQA = labels.ParseLabel("QA") 57 lblFoo = labels.ParseLabel("foo") 58 lblBar = labels.ParseLabel("bar") 59 lblJoe = labels.ParseLabel("user=joe") 60 lblPete = labels.ParseLabel("user=pete") 61 62 testEndpointID = uint16(1) 63 64 regenerationMetadata = ®eneration.ExternalRegenerationMetadata{ 65 Reason: "test", 66 } 67 68 CNPAllowTCP80 = api.PortRule{ 69 Ports: []api.PortProtocol{ 70 {Port: "80", Protocol: api.ProtoTCP}, 71 }, 72 } 73 CNPAllowGETbar = api.PortRule{ 74 Ports: CNPAllowTCP80.Ports, 75 Rules: &api.L7Rules{ 76 HTTP: []api.PortRuleHTTP{ 77 { 78 Path: "/bar", 79 Method: "GET", 80 }, 81 }, 82 }, 83 } 84 85 PNPAllowAll = cilium.PortNetworkPolicyRule_HttpRules{ 86 HttpRules: &cilium.HttpNetworkPolicyRules{ 87 HttpRules: []*cilium.HttpNetworkPolicyRule{ 88 {}, 89 }, 90 }, 91 } 92 googleRe2 = &envoy_type_matcher.RegexMatcher_GoogleRe2{ 93 GoogleRe2: &envoy_type_matcher.RegexMatcher_GoogleRE2{ 94 MaxProgramSize: &wrappers.UInt32Value{Value: 100}, // Envoy default 95 }} 96 97 PNPAllowGETbar = cilium.PortNetworkPolicyRule_HttpRules{ 98 HttpRules: &cilium.HttpNetworkPolicyRules{ 99 HttpRules: []*cilium.HttpNetworkPolicyRule{ 100 { 101 Headers: []*envoy_api_v2_route.HeaderMatcher{ 102 { 103 Name: ":method", 104 HeaderMatchSpecifier: &envoy_api_v2_route.HeaderMatcher_SafeRegexMatch{ 105 SafeRegexMatch: &envoy_type_matcher.RegexMatcher{ 106 EngineType: googleRe2, 107 Regex: "GET", 108 }}, 109 }, 110 { 111 Name: ":path", 112 HeaderMatchSpecifier: &envoy_api_v2_route.HeaderMatcher_SafeRegexMatch{ 113 SafeRegexMatch: &envoy_type_matcher.RegexMatcher{ 114 EngineType: googleRe2, 115 Regex: "/bar", 116 }}, 117 }, 118 }, 119 }, 120 }, 121 }, 122 } 123 ) 124 125 // getXDSNetworkPolicies returns the representation of the xDS network policies 126 // as a map of IP addresses to NetworkPolicy objects 127 func (ds *DaemonSuite) getXDSNetworkPolicies(c *C, resourceNames []string) map[string]*cilium.NetworkPolicy { 128 networkPolicies, err := ds.d.l7Proxy.GetNetworkPolicies(resourceNames) 129 c.Assert(err, IsNil) 130 return networkPolicies 131 } 132 133 func prepareEndpointDirs() (cleanup func(), err error) { 134 testEPDir := fmt.Sprintf("%d", testEndpointID) 135 if err = os.Mkdir(testEPDir, 755); err != nil { 136 return func() {}, err 137 } 138 return func() { 139 os.RemoveAll(fmt.Sprintf("%s/lxc_config.h", testEPDir)) 140 time.Sleep(1 * time.Second) 141 os.RemoveAll(testEPDir) 142 os.RemoveAll(fmt.Sprintf("%s_backup", testEPDir)) 143 }, nil 144 } 145 146 func (ds *DaemonSuite) prepareEndpoint(c *C, identity *identity.Identity, qa bool) *endpoint.Endpoint { 147 e := endpoint.NewEndpointWithState(ds.d, testEndpointID, endpoint.StateWaitingForIdentity) 148 e.IfName = "dummy1" 149 if qa { 150 e.IPv6 = QAIPv6Addr 151 e.IPv4 = QAIPv4Addr 152 e.LXCMAC = QAHardAddr 153 e.SetNodeMACLocked(QAHardAddr) 154 } else { 155 e.IPv6 = ProdIPv6Addr 156 e.IPv4 = ProdIPv4Addr 157 e.LXCMAC = ProdHardAddr 158 e.SetNodeMACLocked(ProdHardAddr) 159 } 160 e.SetIdentity(identity, true) 161 162 e.UnconditionalLock() 163 ready := e.SetStateLocked(endpoint.StateWaitingToRegenerate, "test") 164 e.Unlock() 165 c.Assert(ready, Equals, true) 166 buildSuccess := <-e.Regenerate(regenerationMetadata) 167 c.Assert(buildSuccess, Equals, true) 168 169 return e 170 } 171 172 func (ds *DaemonSuite) regenerateEndpoint(c *C, e *endpoint.Endpoint) { 173 e.UnconditionalLock() 174 ready := e.SetStateLocked(endpoint.StateWaitingToRegenerate, "test") 175 e.Unlock() 176 c.Assert(ready, Equals, true) 177 buildSuccess := <-e.Regenerate(regenerationMetadata) 178 c.Assert(buildSuccess, Equals, true) 179 } 180 181 func (ds *DaemonSuite) TestUpdateConsumerMap(c *C) { 182 rules := api.Rules{ 183 { 184 EndpointSelector: api.NewESFromLabels(lblBar), 185 Ingress: []api.IngressRule{ 186 { 187 FromEndpoints: []api.EndpointSelector{ 188 api.NewESFromLabels(lblJoe), 189 api.NewESFromLabels(lblPete), 190 api.NewESFromLabels(lblFoo), 191 }, 192 }, 193 { 194 FromEndpoints: []api.EndpointSelector{ 195 api.NewESFromLabels(lblFoo), 196 }, 197 ToPorts: []api.PortRule{ 198 // Allow Port 80 GET /bar 199 CNPAllowGETbar, 200 }, 201 }, 202 }, 203 }, 204 { 205 EndpointSelector: api.NewESFromLabels(lblQA), 206 Ingress: []api.IngressRule{ 207 { 208 FromRequires: []api.EndpointSelector{ 209 api.NewESFromLabels(lblQA), 210 }, 211 }, 212 }, 213 }, 214 { 215 EndpointSelector: api.NewESFromLabels(lblProd), 216 Ingress: []api.IngressRule{ 217 { 218 FromRequires: []api.EndpointSelector{ 219 api.NewESFromLabels(lblProd), 220 }, 221 }, 222 }, 223 }, 224 } 225 226 ds.d.l7Proxy.RemoveAllNetworkPolicies() 227 228 _, err3 := ds.d.PolicyAdd(rules, nil) 229 c.Assert(err3, Equals, nil) 230 231 // Prepare the identities necessary for testing 232 qaBarLbls := labels.Labels{lblBar.Key: lblBar, lblQA.Key: lblQA} 233 qaBarSecLblsCtx, _, err := cache.AllocateIdentity(context.Background(), ds.d, qaBarLbls) 234 c.Assert(err, Equals, nil) 235 defer cache.Release(context.Background(), ds.d, qaBarSecLblsCtx) 236 prodBarLbls := labels.Labels{lblBar.Key: lblBar, lblProd.Key: lblProd} 237 prodBarSecLblsCtx, _, err := cache.AllocateIdentity(context.Background(), ds.d, prodBarLbls) 238 c.Assert(err, Equals, nil) 239 defer cache.Release(context.Background(), ds.d, prodBarSecLblsCtx) 240 qaFooLbls := labels.Labels{lblFoo.Key: lblFoo, lblQA.Key: lblQA} 241 qaFooSecLblsCtx, _, err := cache.AllocateIdentity(context.Background(), ds.d, qaFooLbls) 242 c.Assert(err, Equals, nil) 243 defer cache.Release(context.Background(), ds.d, qaFooSecLblsCtx) 244 prodFooLbls := labels.Labels{lblFoo.Key: lblFoo, lblProd.Key: lblProd} 245 prodFooSecLblsCtx, _, err := cache.AllocateIdentity(context.Background(), ds.d, prodFooLbls) 246 c.Assert(err, Equals, nil) 247 defer cache.Release(context.Background(), ds.d, prodFooSecLblsCtx) 248 prodFooJoeLbls := labels.Labels{lblFoo.Key: lblFoo, lblProd.Key: lblProd, lblJoe.Key: lblJoe} 249 prodFooJoeSecLblsCtx, _, err := cache.AllocateIdentity(context.Background(), ds.d, prodFooJoeLbls) 250 c.Assert(err, Equals, nil) 251 defer cache.Release(context.Background(), ds.d, prodFooJoeSecLblsCtx) 252 253 // Prepare endpoints 254 cleanup, err2 := prepareEndpointDirs() 255 c.Assert(err2, Equals, nil) 256 defer cleanup() 257 258 e := ds.prepareEndpoint(c, qaBarSecLblsCtx, true) 259 c.Assert(e.Allows(qaBarSecLblsCtx.ID), Equals, false) 260 c.Assert(e.Allows(prodBarSecLblsCtx.ID), Equals, false) 261 c.Assert(e.Allows(qaFooSecLblsCtx.ID), Equals, true) 262 c.Assert(e.Allows(prodFooSecLblsCtx.ID), Equals, false) 263 264 e = ds.prepareEndpoint(c, prodBarSecLblsCtx, false) 265 c.Assert(e.Allows(0), Equals, false) 266 c.Assert(e.Allows(qaBarSecLblsCtx.ID), Equals, false) 267 c.Assert(e.Allows(prodBarSecLblsCtx.ID), Equals, false) 268 c.Assert(e.Allows(qaFooSecLblsCtx.ID), Equals, false) 269 c.Assert(e.Allows(prodFooSecLblsCtx.ID), Equals, true) 270 c.Assert(e.Allows(prodFooJoeSecLblsCtx.ID), Equals, true) 271 272 // Check that both policies have been updated in the xDS cache for the L7 273 // proxies. 274 networkPolicies := ds.getXDSNetworkPolicies(c, nil) 275 c.Assert(networkPolicies, HasLen, 4) 276 277 qaBarNetworkPolicy := networkPolicies[QAIPv4Addr.String()] 278 c.Assert(qaBarNetworkPolicy, Not(IsNil)) 279 expectedRemotePolicies := []uint64{ 280 uint64(qaFooSecLblsCtx.ID), 281 // The prodFoo* identities are allowed by FromEndpoints but rejected by 282 // FromRequires, so they are not included in the remote policies: 283 // uint64(prodFooSecLblsCtx.ID), 284 // uint64(prodFooJoeSecLblsCtx.ID), 285 } 286 sort.Slice(expectedRemotePolicies, func(i, j int) bool { 287 return expectedRemotePolicies[i] < expectedRemotePolicies[j] 288 }) 289 expectedNetworkPolicy := &cilium.NetworkPolicy{ 290 Name: QAIPv4Addr.String(), 291 Policy: uint64(qaBarSecLblsCtx.ID), 292 ConntrackMapName: "global", 293 IngressPerPortPolicies: []*cilium.PortNetworkPolicy{ 294 { 295 Port: 80, 296 Protocol: envoy_api_v2_core.SocketAddress_TCP, 297 Rules: []*cilium.PortNetworkPolicyRule{ 298 { 299 RemotePolicies: expectedRemotePolicies, 300 L7: &PNPAllowAll, 301 }, 302 //{ 303 // RemotePolicies: expectedRemotePolicies, 304 // L7: &PNPAllowGETbar, 305 //}, 306 }, 307 }, 308 }, 309 EgressPerPortPolicies: []*cilium.PortNetworkPolicy{ // Allow-all policy. 310 {Protocol: envoy_api_v2_core.SocketAddress_TCP}, 311 {Protocol: envoy_api_v2_core.SocketAddress_UDP}, 312 }, 313 } 314 c.Assert(qaBarNetworkPolicy, checker.Equals, expectedNetworkPolicy) 315 316 prodBarNetworkPolicy := networkPolicies[ProdIPv4Addr.String()] 317 c.Assert(prodBarNetworkPolicy, Not(IsNil)) 318 expectedRemotePolicies = []uint64{ 319 // The qaFoo identity is allowed by FromEndpoints but rejected by 320 // FromRequires, so it is not included in the remote policies: 321 // uint64(qaFooSecLblsCtx.ID), 322 uint64(prodFooSecLblsCtx.ID), 323 uint64(prodFooJoeSecLblsCtx.ID), 324 } 325 sort.Slice(expectedRemotePolicies, func(i, j int) bool { 326 return expectedRemotePolicies[i] < expectedRemotePolicies[j] 327 }) 328 expectedRemotePolicies2 := []uint64{ 329 uint64(prodFooJoeSecLblsCtx.ID), 330 } 331 sort.Slice(expectedRemotePolicies2, func(i, j int) bool { 332 return expectedRemotePolicies2[i] < expectedRemotePolicies2[j] 333 }) 334 335 expectedNetworkPolicy = &cilium.NetworkPolicy{ 336 Name: ProdIPv4Addr.String(), 337 Policy: uint64(prodBarSecLblsCtx.ID), 338 ConntrackMapName: "global", 339 IngressPerPortPolicies: []*cilium.PortNetworkPolicy{ 340 { 341 Port: 80, 342 Protocol: envoy_api_v2_core.SocketAddress_TCP, 343 Rules: []*cilium.PortNetworkPolicyRule{ 344 { 345 RemotePolicies: expectedRemotePolicies2, 346 L7: &PNPAllowAll, 347 }, 348 { 349 RemotePolicies: expectedRemotePolicies, 350 L7: &PNPAllowAll, 351 }, 352 //{ 353 // RemotePolicies: expectedRemotePolicies, 354 // L7: &PNPAllowGETbar, 355 //}, 356 }, 357 }, 358 }, 359 EgressPerPortPolicies: []*cilium.PortNetworkPolicy{ // Allow-all policy. 360 {Protocol: envoy_api_v2_core.SocketAddress_TCP}, 361 {Protocol: envoy_api_v2_core.SocketAddress_UDP}, 362 }, 363 } 364 c.Assert(prodBarNetworkPolicy, checker.Equals, expectedNetworkPolicy) 365 } 366 367 func (ds *DaemonSuite) TestL4_L7_Shadowing(c *C) { 368 // Prepare the identities necessary for testing 369 qaBarLbls := labels.Labels{lblBar.Key: lblBar, lblQA.Key: lblQA} 370 qaBarSecLblsCtx, _, err := cache.AllocateIdentity(context.Background(), ds.d, qaBarLbls) 371 c.Assert(err, Equals, nil) 372 defer cache.Release(context.Background(), ds.d, qaBarSecLblsCtx) 373 qaFooLbls := labels.Labels{lblFoo.Key: lblFoo, lblQA.Key: lblQA} 374 qaFooSecLblsCtx, _, err := cache.AllocateIdentity(context.Background(), ds.d, qaFooLbls) 375 c.Assert(err, Equals, nil) 376 defer cache.Release(context.Background(), ds.d, qaFooSecLblsCtx) 377 378 rules := api.Rules{ 379 { 380 EndpointSelector: api.NewESFromLabels(lblBar), 381 Ingress: []api.IngressRule{ 382 { 383 ToPorts: []api.PortRule{ 384 // Allow all on port 80 (no proxy) 385 CNPAllowTCP80, 386 }, 387 }, 388 { 389 FromEndpoints: []api.EndpointSelector{ 390 api.NewESFromLabels(lblFoo), 391 }, 392 ToPorts: []api.PortRule{ 393 // Allow Port 80 GET /bar 394 CNPAllowGETbar, 395 }, 396 }, 397 }, 398 }, 399 } 400 401 ds.d.l7Proxy.RemoveAllNetworkPolicies() 402 403 _, err = ds.d.PolicyAdd(rules, nil) 404 c.Assert(err, Equals, nil) 405 406 // Prepare endpoints 407 cleanup, err := prepareEndpointDirs() 408 c.Assert(err, Equals, nil) 409 defer cleanup() 410 411 e := ds.prepareEndpoint(c, qaBarSecLblsCtx, true) 412 c.Assert(e.Allows(qaBarSecLblsCtx.ID), Equals, false) 413 c.Assert(e.Allows(qaFooSecLblsCtx.ID), Equals, false) 414 415 // Check that both policies have been updated in the xDS cache for the L7 416 // proxies. 417 networkPolicies := ds.getXDSNetworkPolicies(c, nil) 418 c.Assert(networkPolicies, HasLen, 2) 419 420 qaBarNetworkPolicy := networkPolicies[QAIPv4Addr.String()] 421 expectedNetworkPolicy := &cilium.NetworkPolicy{ 422 Name: QAIPv4Addr.String(), 423 Policy: uint64(qaBarSecLblsCtx.ID), 424 ConntrackMapName: "global", 425 IngressPerPortPolicies: []*cilium.PortNetworkPolicy{ 426 { 427 Port: 80, 428 Protocol: envoy_api_v2_core.SocketAddress_TCP, 429 Rules: []*cilium.PortNetworkPolicyRule{ 430 { 431 RemotePolicies: nil, 432 L7: &PNPAllowAll, 433 }, 434 { 435 RemotePolicies: []uint64{uint64(qaFooSecLblsCtx.ID)}, 436 L7: &PNPAllowGETbar, 437 }, 438 }, 439 }, 440 }, 441 EgressPerPortPolicies: []*cilium.PortNetworkPolicy{ // Allow-all policy. 442 {Protocol: envoy_api_v2_core.SocketAddress_TCP}, 443 {Protocol: envoy_api_v2_core.SocketAddress_UDP}, 444 }, 445 } 446 c.Assert(qaBarNetworkPolicy, checker.Equals, expectedNetworkPolicy) 447 } 448 449 func (ds *DaemonSuite) TestReplacePolicy(c *C) { 450 lbls := labels.ParseLabelArray("foo", "bar") 451 rules := api.Rules{ 452 { 453 Labels: lbls, 454 EndpointSelector: api.NewESFromLabels(lblBar), 455 Egress: []api.EgressRule{{ToCIDR: []api.CIDR{"1.1.1.1/32", "2.2.2.0/24"}}}, 456 }, 457 { 458 Labels: lbls, 459 EndpointSelector: api.NewESFromLabels(lblBar), 460 }, 461 } 462 463 _, err := ds.d.PolicyAdd(rules, nil) 464 c.Assert(err, IsNil) 465 ds.d.policy.Mutex.RLock() 466 c.Assert(len(ds.d.policy.SearchRLocked(lbls)), Equals, 2) 467 ds.d.policy.Mutex.RUnlock() 468 rules[0].Egress = []api.EgressRule{{ToCIDR: []api.CIDR{"1.1.1.1/32", "2.2.2.2/32"}}} 469 _, err = ds.d.PolicyAdd(rules, &AddOptions{Replace: true}) 470 471 c.Assert(err, IsNil) 472 ds.d.policy.Mutex.RLock() 473 c.Assert(len(ds.d.policy.SearchRLocked(lbls)), Equals, 2) 474 ds.d.policy.Mutex.RUnlock() 475 476 // Updating of prefix lengths may complete *after* PolicyAdd returns. Add a 477 // wait for prefix lengths to be correct after timeout to ensure that we 478 // do not assert before the releasing of CIDRs has been performed. 479 testutils.WaitUntil(func() bool { 480 _, s4 := ds.d.prefixLengths.ToBPFData() 481 sort.Ints(s4) 482 if len(s4) != 2 { 483 c.Logf("IPv4 Prefix lengths incorrect (expected [0, 32]). This may be because CIDRs were not released on replace. %+v", s4) 484 return false 485 } 486 for i, v := range []int{0, 32} { 487 if s4[i] != v { 488 c.Logf("Unexpected IPv4 Prefix length. This may be because CIDRs were not released on replace. %+v", s4) 489 return false 490 } 491 } 492 return true 493 }, time.Second*5) 494 } 495 496 func (ds *DaemonSuite) TestRemovePolicy(c *C) { 497 qaBarLbls := labels.Labels{lblBar.Key: lblBar, lblQA.Key: lblQA} 498 qaBarSecLblsCtx, _, err := cache.AllocateIdentity(context.Background(), ds.d, qaBarLbls) 499 c.Assert(err, Equals, nil) 500 defer cache.Release(context.Background(), ds.d, qaBarSecLblsCtx) 501 502 rules := api.Rules{ 503 { 504 EndpointSelector: api.NewESFromLabels(lblBar), 505 Ingress: []api.IngressRule{ 506 { 507 FromEndpoints: []api.EndpointSelector{ 508 api.NewESFromLabels(lblJoe), 509 api.NewESFromLabels(lblPete), 510 api.NewESFromLabels(lblFoo), 511 }, 512 }, 513 { 514 FromEndpoints: []api.EndpointSelector{ 515 api.NewESFromLabels(lblFoo), 516 }, 517 ToPorts: []api.PortRule{ 518 // Allow Port 80 GET /bar 519 CNPAllowGETbar, 520 }, 521 }, 522 }, 523 }, 524 { 525 EndpointSelector: api.NewESFromLabels(lblQA), 526 Ingress: []api.IngressRule{ 527 { 528 FromRequires: []api.EndpointSelector{ 529 api.NewESFromLabels(lblQA), 530 }, 531 }, 532 }, 533 }, 534 { 535 EndpointSelector: api.NewESFromLabels(lblProd), 536 Ingress: []api.IngressRule{ 537 { 538 FromRequires: []api.EndpointSelector{ 539 api.NewESFromLabels(lblProd), 540 }, 541 }, 542 }, 543 }, 544 } 545 546 ds.d.l7Proxy.RemoveAllNetworkPolicies() 547 548 _, err3 := ds.d.PolicyAdd(rules, nil) 549 c.Assert(err3, Equals, nil) 550 551 cleanup, err2 := prepareEndpointDirs() 552 c.Assert(err2, Equals, nil) 553 defer cleanup() 554 555 // Create the endpoint and generate its policy. 556 e := ds.prepareEndpoint(c, qaBarSecLblsCtx, true) 557 558 // Check that the policy has been updated in the xDS cache for the L7 559 // proxies. 560 networkPolicies := ds.getXDSNetworkPolicies(c, nil) 561 c.Assert(networkPolicies, HasLen, 2) 562 qaBarNetworkPolicy := networkPolicies[QAIPv4Addr.String()] 563 c.Assert(qaBarNetworkPolicy, Not(IsNil)) 564 565 // Delete the endpoint. 566 e.UnconditionalLock() 567 e.LeaveLocked(nil, endpoint.DeleteConfig{}) 568 e.Unlock() 569 570 // Check that the policy has been removed from the xDS cache. 571 networkPolicies = ds.getXDSNetworkPolicies(c, nil) 572 c.Assert(networkPolicies, HasLen, 0) 573 } 574 575 func (ds *DaemonSuite) TestIncrementalPolicy(c *C) { 576 qaBarLbls := labels.Labels{lblBar.Key: lblBar, lblQA.Key: lblQA} 577 qaBarSecLblsCtx, _, err := cache.AllocateIdentity(context.Background(), ds.d, qaBarLbls) 578 c.Assert(err, Equals, nil) 579 defer cache.Release(context.Background(), ds.d, qaBarSecLblsCtx) 580 581 rules := api.Rules{ 582 { 583 EndpointSelector: api.NewESFromLabels(lblBar), 584 Ingress: []api.IngressRule{ 585 { 586 FromEndpoints: []api.EndpointSelector{ 587 api.NewESFromLabels(lblJoe), 588 api.NewESFromLabels(lblPete), 589 api.NewESFromLabels(lblFoo), 590 }, 591 }, 592 { 593 FromEndpoints: []api.EndpointSelector{ 594 api.NewESFromLabels(lblFoo), 595 }, 596 ToPorts: []api.PortRule{ 597 // Allow Port 80 GET /bar 598 CNPAllowGETbar, 599 }, 600 }, 601 }, 602 }, 603 { 604 EndpointSelector: api.NewESFromLabels(lblQA), 605 Ingress: []api.IngressRule{ 606 { 607 FromRequires: []api.EndpointSelector{ 608 api.NewESFromLabels(lblQA), 609 }, 610 }, 611 }, 612 }, 613 { 614 EndpointSelector: api.NewESFromLabels(lblProd), 615 Ingress: []api.IngressRule{ 616 { 617 FromRequires: []api.EndpointSelector{ 618 api.NewESFromLabels(lblProd), 619 }, 620 }, 621 }, 622 }, 623 } 624 625 ds.d.l7Proxy.RemoveAllNetworkPolicies() 626 627 _, err3 := ds.d.PolicyAdd(rules, nil) 628 c.Assert(err3, Equals, nil) 629 630 cleanup, err2 := prepareEndpointDirs() 631 c.Assert(err2, Equals, nil) 632 defer cleanup() 633 634 // Create the endpoint and generate its policy. 635 e := ds.prepareEndpoint(c, qaBarSecLblsCtx, true) 636 637 // Check that the policy has been updated in the xDS cache for the L7 638 // proxies. 639 networkPolicies := ds.getXDSNetworkPolicies(c, nil) 640 c.Assert(networkPolicies, HasLen, 2) 641 qaBarNetworkPolicy := networkPolicies[QAIPv4Addr.String()] 642 c.Assert(qaBarNetworkPolicy, Not(IsNil)) 643 644 c.Assert(qaBarNetworkPolicy.IngressPerPortPolicies, HasLen, 0) 645 646 // Allocate identities needed for this test 647 qaFooLbls := labels.Labels{lblFoo.Key: lblFoo, lblQA.Key: lblQA} 648 qaFooID, _, err := cache.AllocateIdentity(context.Background(), ds.d, qaFooLbls) 649 c.Assert(err, Equals, nil) 650 defer cache.Release(context.Background(), ds.d, qaFooID) 651 652 // Regenerate endpoint 653 ds.regenerateEndpoint(c, e) 654 655 // Check that the policy has been updated in the xDS cache for the L7 656 // proxies. 657 networkPolicies = ds.getXDSNetworkPolicies(c, nil) 658 c.Assert(networkPolicies, HasLen, 2) 659 qaBarNetworkPolicy = networkPolicies[QAIPv4Addr.String()] 660 c.Assert(qaBarNetworkPolicy, Not(IsNil)) 661 662 c.Assert(qaBarNetworkPolicy.IngressPerPortPolicies, HasLen, 1) 663 c.Assert(qaBarNetworkPolicy.IngressPerPortPolicies[0].Rules, HasLen, 1) 664 c.Assert(qaBarNetworkPolicy.IngressPerPortPolicies[0].Rules[0].RemotePolicies, HasLen, 1) 665 c.Assert(qaBarNetworkPolicy.IngressPerPortPolicies[0].Rules[0].RemotePolicies[0], Equals, uint64(qaFooID.ID)) 666 667 // Delete the endpoint. 668 e.UnconditionalLock() 669 e.LeaveLocked(nil, endpoint.DeleteConfig{}) 670 e.Unlock() 671 672 // Check that the policy has been removed from the xDS cache. 673 networkPolicies = ds.getXDSNetworkPolicies(c, nil) 674 c.Assert(networkPolicies, HasLen, 0) 675 }