github.com/alibaba/ilogtail/pkg@v0.0.0-20250526110833-c53b480d046c/helper/k8smeta/k8s_meta_link_test.go (about) 1 package k8smeta 2 3 import ( 4 "testing" 5 6 "github.com/stretchr/testify/assert" 7 app "k8s.io/api/apps/v1" 8 batch "k8s.io/api/batch/v1" 9 corev1 "k8s.io/api/core/v1" 10 networking "k8s.io/api/networking/v1" 11 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 12 ) 13 14 func TestGetPodNodeLink(t *testing.T) { 15 podCache := newK8sMetaCache(make(chan struct{}), POD) 16 nodeCache := newK8sMetaCache(make(chan struct{}), NODE) 17 nodeCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 18 EventType: "add", 19 Object: &ObjectWrapper{ 20 Raw: &corev1.Node{ 21 ObjectMeta: metav1.ObjectMeta{ 22 Name: "node1", 23 }, 24 }, 25 }, 26 }) 27 nodeCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 28 EventType: "add", 29 Object: &ObjectWrapper{ 30 Raw: &corev1.Node{ 31 ObjectMeta: metav1.ObjectMeta{ 32 Name: "node2", 33 }, 34 }, 35 }, 36 }) 37 pod1 := generateMockPod("1") 38 pod1.Raw.(*corev1.Pod).Spec.NodeName = "node1" 39 pod2 := generateMockPod("2") 40 pod2.Raw.(*corev1.Pod).Spec.NodeName = "node2" 41 podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 42 EventType: "add", 43 Object: pod1, 44 }) 45 podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 46 EventType: "add", 47 Object: pod2, 48 }) 49 linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{ 50 POD: podCache, 51 NODE: nodeCache, 52 }) 53 podList := []*K8sMetaEvent{ 54 { 55 EventType: "update", 56 Object: podCache.metaStore.Items["default/pod1"], 57 }, 58 { 59 EventType: "update", 60 Object: podCache.metaStore.Items["default/pod2"], 61 }, 62 } 63 results := linkGenerator.getPodNodeLink(podList) 64 assert.Equal(t, 2, len(results)) 65 assert.Equal(t, "node1", results[0].Object.Raw.(*PodNode).Node.Name) 66 assert.Equal(t, "node2", results[1].Object.Raw.(*PodNode).Node.Name) 67 } 68 69 func TestGetPodDeploymentLink(t *testing.T) { 70 podCache := newK8sMetaCache(make(chan struct{}), POD) 71 replicasetCache := newK8sMetaCache(make(chan struct{}), REPLICASET) 72 deploymentCache := newK8sMetaCache(make(chan struct{}), DEPLOYMENT) 73 deploymentCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 74 EventType: "add", 75 Object: &ObjectWrapper{ 76 Raw: &app.Deployment{ 77 ObjectMeta: metav1.ObjectMeta{ 78 Name: "deployment1", 79 Namespace: "default", 80 }, 81 }, 82 }, 83 }) 84 deploymentCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 85 EventType: "add", 86 Object: &ObjectWrapper{ 87 Raw: &app.Deployment{ 88 ObjectMeta: metav1.ObjectMeta{ 89 Name: "deployment2", 90 Namespace: "default", 91 }, 92 }, 93 }, 94 }) 95 replicasetCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 96 EventType: "add", 97 Object: &ObjectWrapper{ 98 Raw: &app.ReplicaSet{ 99 ObjectMeta: metav1.ObjectMeta{ 100 Name: "replicaset1", 101 Namespace: "default", 102 OwnerReferences: []metav1.OwnerReference{ 103 { 104 Kind: "Deployment", 105 Name: "deployment1", 106 }, 107 }, 108 }, 109 Spec: app.ReplicaSetSpec{ 110 Selector: &metav1.LabelSelector{ 111 MatchLabels: map[string]string{ 112 "app": "test", 113 }, 114 }, 115 }, 116 }, 117 }, 118 }) 119 replicasetCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 120 EventType: "add", 121 Object: &ObjectWrapper{ 122 Raw: &app.ReplicaSet{ 123 ObjectMeta: metav1.ObjectMeta{ 124 Name: "replicaset2", 125 Namespace: "default", 126 OwnerReferences: []metav1.OwnerReference{ 127 { 128 Kind: "Deployment", 129 Name: "deployment2", 130 }, 131 }, 132 }, 133 Spec: app.ReplicaSetSpec{ 134 Selector: &metav1.LabelSelector{ 135 MatchLabels: map[string]string{ 136 "app": "test2", 137 }, 138 }, 139 }, 140 }, 141 }, 142 }) 143 pod1 := generateMockPod("1") 144 pod1.Raw.(*corev1.Pod).OwnerReferences = []metav1.OwnerReference{ 145 { 146 Kind: "ReplicaSet", 147 Name: "replicaset1", 148 }, 149 } 150 pod2 := generateMockPod("2") 151 pod2.Raw.(*corev1.Pod).OwnerReferences = []metav1.OwnerReference{ 152 { 153 Kind: "ReplicaSet", 154 Name: "replicaset2", 155 }, 156 } 157 podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 158 EventType: "add", 159 Object: pod1, 160 }) 161 podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 162 EventType: "add", 163 Object: pod2, 164 }) 165 linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{ 166 POD: podCache, 167 REPLICASET: replicasetCache, 168 DEPLOYMENT: deploymentCache, 169 }) 170 podList := []*K8sMetaEvent{ 171 { 172 EventType: "update", 173 Object: podCache.metaStore.Items["default/pod1"], 174 }, 175 { 176 EventType: "update", 177 Object: podCache.metaStore.Items["default/pod2"], 178 }, 179 } 180 results := linkGenerator.getPodDeploymentLink(podList) 181 assert.Equal(t, 2, len(results)) 182 assert.Equal(t, "deployment1", results[0].Object.Raw.(*PodDeployment).Deployment.Name) 183 assert.Equal(t, "deployment2", results[1].Object.Raw.(*PodDeployment).Deployment.Name) 184 } 185 186 func TestGetReplicaSetDeploymentLink(t *testing.T) { 187 replicasetCache := newK8sMetaCache(make(chan struct{}), REPLICASET) 188 deploymentCache := newK8sMetaCache(make(chan struct{}), DEPLOYMENT) 189 deploymentCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 190 EventType: "add", 191 Object: &ObjectWrapper{ 192 Raw: &app.Deployment{ 193 ObjectMeta: metav1.ObjectMeta{ 194 Name: "deployment1", 195 Namespace: "default", 196 }, 197 }, 198 }, 199 }) 200 deploymentCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 201 EventType: "add", 202 Object: &ObjectWrapper{ 203 Raw: &app.Deployment{ 204 ObjectMeta: metav1.ObjectMeta{ 205 Name: "deployment2", 206 Namespace: "default", 207 }, 208 }, 209 }, 210 }) 211 replicasetCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 212 EventType: "add", 213 Object: &ObjectWrapper{ 214 Raw: &app.ReplicaSet{ 215 ObjectMeta: metav1.ObjectMeta{ 216 Name: "replicaset1", 217 Namespace: "default", 218 OwnerReferences: []metav1.OwnerReference{ 219 { 220 Kind: "Deployment", 221 Name: "deployment1", 222 }, 223 }, 224 }, 225 Spec: app.ReplicaSetSpec{ 226 Selector: &metav1.LabelSelector{ 227 MatchLabels: map[string]string{ 228 "app": "test", 229 }, 230 }, 231 }, 232 }, 233 }, 234 }) 235 replicasetCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 236 EventType: "add", 237 Object: &ObjectWrapper{ 238 Raw: &app.ReplicaSet{ 239 ObjectMeta: metav1.ObjectMeta{ 240 Name: "replicaset2", 241 Namespace: "default", 242 OwnerReferences: []metav1.OwnerReference{ 243 { 244 Kind: "Deployment", 245 Name: "deployment2", 246 }, 247 }, 248 }, 249 Spec: app.ReplicaSetSpec{ 250 Selector: &metav1.LabelSelector{ 251 MatchLabels: map[string]string{ 252 "app": "test2", 253 }, 254 }, 255 }, 256 }, 257 }, 258 }) 259 linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{ 260 REPLICASET: replicasetCache, 261 DEPLOYMENT: deploymentCache, 262 }) 263 replicasetList := []*K8sMetaEvent{ 264 { 265 EventType: "update", 266 Object: replicasetCache.metaStore.Items["default/replicaset1"], 267 }, 268 { 269 EventType: "update", 270 Object: replicasetCache.metaStore.Items["default/replicaset2"], 271 }, 272 } 273 results := linkGenerator.getReplicaSetDeploymentLink(replicasetList) 274 assert.Equal(t, 2, len(results)) 275 assert.Equal(t, "deployment1", results[0].Object.Raw.(*ReplicaSetDeployment).Deployment.Name) 276 assert.Equal(t, "deployment2", results[1].Object.Raw.(*ReplicaSetDeployment).Deployment.Name) 277 } 278 279 func TestGetPodReplicaSetLink(t *testing.T) { 280 podCache := newK8sMetaCache(make(chan struct{}), POD) 281 replicasetCache := newK8sMetaCache(make(chan struct{}), REPLICASET) 282 replicasetCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 283 EventType: "add", 284 Object: &ObjectWrapper{ 285 Raw: &app.ReplicaSet{ 286 ObjectMeta: metav1.ObjectMeta{ 287 Name: "replicaset1", 288 Namespace: "default", 289 }, 290 Spec: app.ReplicaSetSpec{ 291 Selector: &metav1.LabelSelector{ 292 MatchLabels: map[string]string{ 293 "app": "test", 294 }, 295 }, 296 }, 297 }, 298 }, 299 }) 300 replicasetCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 301 EventType: "add", 302 Object: &ObjectWrapper{ 303 Raw: &app.ReplicaSet{ 304 ObjectMeta: metav1.ObjectMeta{ 305 Name: "replicaset2", 306 Namespace: "default", 307 }, 308 Spec: app.ReplicaSetSpec{ 309 Selector: &metav1.LabelSelector{ 310 MatchLabels: map[string]string{ 311 "app": "test2", 312 }, 313 }, 314 }, 315 }, 316 }, 317 }) 318 pod1 := generateMockPod("1") 319 pod1.Raw.(*corev1.Pod).OwnerReferences = []metav1.OwnerReference{ 320 { 321 Kind: "ReplicaSet", 322 Name: "replicaset1", 323 }, 324 } 325 pod2 := generateMockPod("2") 326 pod2.Raw.(*corev1.Pod).OwnerReferences = []metav1.OwnerReference{ 327 { 328 Kind: "ReplicaSet", 329 Name: "replicaset2", 330 }, 331 } 332 podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 333 EventType: "add", 334 Object: pod1, 335 }) 336 podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 337 EventType: "add", 338 Object: pod2, 339 }) 340 linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{ 341 POD: podCache, 342 REPLICASET: replicasetCache, 343 }) 344 podList := []*K8sMetaEvent{ 345 { 346 EventType: "update", 347 Object: podCache.metaStore.Items["default/pod1"], 348 }, 349 { 350 EventType: "update", 351 Object: podCache.metaStore.Items["default/pod2"], 352 }, 353 } 354 results := linkGenerator.getPodReplicaSetLink(podList) 355 assert.Equal(t, 2, len(results)) 356 assert.Equal(t, "replicaset1", results[0].Object.Raw.(*PodReplicaSet).ReplicaSet.Name) 357 assert.Equal(t, "replicaset2", results[1].Object.Raw.(*PodReplicaSet).ReplicaSet.Name) 358 } 359 360 func TestGetPodDaemonSetLink(t *testing.T) { 361 podCache := newK8sMetaCache(make(chan struct{}), POD) 362 daemonsetCache := newK8sMetaCache(make(chan struct{}), DAEMONSET) 363 daemonsetCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 364 EventType: "add", 365 Object: &ObjectWrapper{ 366 Raw: &app.DaemonSet{ 367 ObjectMeta: metav1.ObjectMeta{ 368 Name: "daemonset1", 369 Namespace: "default", 370 }, 371 }, 372 }, 373 }) 374 daemonsetCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 375 EventType: "add", 376 Object: &ObjectWrapper{ 377 Raw: &app.DaemonSet{ 378 ObjectMeta: metav1.ObjectMeta{ 379 Name: "daemonset2", 380 Namespace: "default", 381 }, 382 }, 383 }, 384 }) 385 pod1 := generateMockPod("1") 386 pod1.Raw.(*corev1.Pod).OwnerReferences = []metav1.OwnerReference{ 387 { 388 Kind: "DaemonSet", 389 Name: "daemonset1", 390 }, 391 } 392 pod2 := generateMockPod("2") 393 pod2.Raw.(*corev1.Pod).OwnerReferences = []metav1.OwnerReference{ 394 { 395 Kind: "DaemonSet", 396 Name: "daemonset2", 397 }, 398 } 399 podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 400 EventType: "add", 401 Object: pod1, 402 }) 403 podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 404 EventType: "add", 405 Object: pod2, 406 }) 407 linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{ 408 POD: podCache, 409 DAEMONSET: daemonsetCache, 410 }) 411 podList := []*K8sMetaEvent{ 412 { 413 EventType: "update", 414 Object: podCache.metaStore.Items["default/pod1"], 415 }, 416 { 417 EventType: "update", 418 Object: podCache.metaStore.Items["default/pod2"], 419 }, 420 } 421 results := linkGenerator.getPodDaemonSetLink(podList) 422 assert.Equal(t, 2, len(results)) 423 assert.Equal(t, "daemonset1", results[0].Object.Raw.(*PodDaemonSet).DaemonSet.Name) 424 assert.Equal(t, "daemonset2", results[1].Object.Raw.(*PodDaemonSet).DaemonSet.Name) 425 } 426 427 func TestGetPodStatefulSetLink(t *testing.T) { 428 podCache := newK8sMetaCache(make(chan struct{}), POD) 429 statefulsetCache := newK8sMetaCache(make(chan struct{}), STATEFULSET) 430 statefulsetCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 431 EventType: "add", 432 Object: &ObjectWrapper{ 433 Raw: &app.StatefulSet{ 434 ObjectMeta: metav1.ObjectMeta{ 435 Name: "statefulset1", 436 Namespace: "default", 437 }, 438 }, 439 }, 440 }) 441 statefulsetCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 442 EventType: "add", 443 Object: &ObjectWrapper{ 444 Raw: &app.StatefulSet{ 445 ObjectMeta: metav1.ObjectMeta{ 446 Name: "statefulset2", 447 Namespace: "default", 448 }, 449 }, 450 }, 451 }) 452 pod1 := generateMockPod("1") 453 pod1.Raw.(*corev1.Pod).OwnerReferences = []metav1.OwnerReference{ 454 { 455 Kind: "StatefulSet", 456 Name: "statefulset1", 457 }, 458 } 459 pod2 := generateMockPod("2") 460 pod2.Raw.(*corev1.Pod).OwnerReferences = []metav1.OwnerReference{ 461 { 462 Kind: "StatefulSet", 463 Name: "statefulset2", 464 }, 465 } 466 podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 467 EventType: "add", 468 Object: pod1, 469 }) 470 podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 471 EventType: "add", 472 Object: pod2, 473 }) 474 linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{ 475 POD: podCache, 476 STATEFULSET: statefulsetCache, 477 }) 478 podList := []*K8sMetaEvent{ 479 { 480 EventType: "update", 481 Object: podCache.metaStore.Items["default/pod1"], 482 }, 483 { 484 EventType: "update", 485 Object: podCache.metaStore.Items["default/pod2"], 486 }, 487 } 488 results := linkGenerator.getPodStatefulSetLink(podList) 489 assert.Equal(t, 2, len(results)) 490 assert.Equal(t, "statefulset1", results[0].Object.Raw.(*PodStatefulSet).StatefulSet.Name) 491 assert.Equal(t, "statefulset2", results[1].Object.Raw.(*PodStatefulSet).StatefulSet.Name) 492 } 493 494 func TestGetPodJobLink(t *testing.T) { 495 podCache := newK8sMetaCache(make(chan struct{}), POD) 496 jobCache := newK8sMetaCache(make(chan struct{}), JOB) 497 jobCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 498 EventType: "add", 499 Object: &ObjectWrapper{ 500 Raw: &batch.Job{ 501 ObjectMeta: metav1.ObjectMeta{ 502 Name: "job1", 503 Namespace: "default", 504 }, 505 }, 506 }, 507 }) 508 jobCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 509 EventType: "add", 510 Object: &ObjectWrapper{ 511 Raw: &batch.Job{ 512 ObjectMeta: metav1.ObjectMeta{ 513 Name: "job2", 514 Namespace: "default", 515 }, 516 }, 517 }, 518 }) 519 pod1 := generateMockPod("1") 520 pod1.Raw.(*corev1.Pod).OwnerReferences = []metav1.OwnerReference{ 521 { 522 Kind: "Job", 523 Name: "job1", 524 }, 525 } 526 pod2 := generateMockPod("2") 527 pod2.Raw.(*corev1.Pod).OwnerReferences = []metav1.OwnerReference{ 528 { 529 Kind: "Job", 530 Name: "job2", 531 }, 532 } 533 podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 534 EventType: "add", 535 Object: pod1, 536 }) 537 podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 538 EventType: "add", 539 Object: pod2, 540 }) 541 linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{ 542 POD: podCache, 543 JOB: jobCache, 544 }) 545 podList := []*K8sMetaEvent{ 546 { 547 EventType: "update", 548 Object: podCache.metaStore.Items["default/pod1"], 549 }, 550 { 551 EventType: "update", 552 Object: podCache.metaStore.Items["default/pod2"], 553 }, 554 } 555 results := linkGenerator.getPodJobLink(podList) 556 assert.Equal(t, 2, len(results)) 557 assert.Equal(t, "job1", results[0].Object.Raw.(*PodJob).Job.Name) 558 assert.Equal(t, "job2", results[1].Object.Raw.(*PodJob).Job.Name) 559 } 560 561 func TestGetJobCronJobLink(t *testing.T) { 562 jobCache := newK8sMetaCache(make(chan struct{}), JOB) 563 cronJobCache := newK8sMetaCache(make(chan struct{}), CRONJOB) 564 cronJobCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 565 EventType: "add", 566 Object: &ObjectWrapper{ 567 Raw: &batch.CronJob{ 568 ObjectMeta: metav1.ObjectMeta{ 569 Name: "cronjob1", 570 Namespace: "default", 571 }, 572 }, 573 }, 574 }) 575 cronJobCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 576 EventType: "add", 577 Object: &ObjectWrapper{ 578 Raw: &batch.CronJob{ 579 ObjectMeta: metav1.ObjectMeta{ 580 Name: "cronjob2", 581 Namespace: "default", 582 }, 583 }, 584 }, 585 }) 586 job1 := &ObjectWrapper{ 587 Raw: &batch.Job{ 588 ObjectMeta: metav1.ObjectMeta{ 589 Name: "job1", 590 Namespace: "default", 591 }, 592 }, 593 } 594 job1.Raw.(*batch.Job).OwnerReferences = []metav1.OwnerReference{ 595 { 596 Kind: "CronJob", 597 Name: "cronjob1", 598 }, 599 } 600 job2 := &ObjectWrapper{ 601 Raw: &batch.Job{ 602 ObjectMeta: metav1.ObjectMeta{ 603 Name: "job2", 604 Namespace: "default", 605 }, 606 }, 607 } 608 job2.Raw.(*batch.Job).OwnerReferences = []metav1.OwnerReference{ 609 { 610 Kind: "CronJob", 611 Name: "cronjob2", 612 }, 613 } 614 jobCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 615 EventType: "add", 616 Object: job1, 617 }) 618 jobCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 619 EventType: "add", 620 Object: job2, 621 }) 622 linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{ 623 JOB: jobCache, 624 CRONJOB: cronJobCache, 625 }) 626 jobList := []*K8sMetaEvent{ 627 { 628 EventType: "update", 629 Object: jobCache.metaStore.Items["default/job1"], 630 }, 631 { 632 EventType: "update", 633 Object: jobCache.metaStore.Items["default/job2"], 634 }, 635 } 636 results := linkGenerator.getJobCronJobLink(jobList) 637 assert.Equal(t, 2, len(results)) 638 assert.Equal(t, "cronjob1", results[0].Object.Raw.(*JobCronJob).CronJob.Name) 639 assert.Equal(t, "cronjob2", results[1].Object.Raw.(*JobCronJob).CronJob.Name) 640 } 641 642 func TestGetPodPVCLink(t *testing.T) { 643 podCache := newK8sMetaCache(make(chan struct{}), POD) 644 pvcCache := newK8sMetaCache(make(chan struct{}), PERSISTENTVOLUMECLAIM) 645 pvcCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 646 EventType: "add", 647 Object: &ObjectWrapper{ 648 Raw: &corev1.PersistentVolumeClaim{ 649 ObjectMeta: metav1.ObjectMeta{ 650 Name: "pvc1", 651 Namespace: "default", 652 }, 653 }, 654 }, 655 }) 656 pvcCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 657 EventType: "add", 658 Object: &ObjectWrapper{ 659 Raw: &corev1.PersistentVolumeClaim{ 660 ObjectMeta: metav1.ObjectMeta{ 661 Name: "pvc2", 662 Namespace: "default", 663 }, 664 }, 665 }, 666 }) 667 pod1 := generateMockPod("1") 668 pod1.Raw.(*corev1.Pod).Spec.Volumes = []corev1.Volume{ 669 { 670 Name: "volume1", 671 VolumeSource: corev1.VolumeSource{ 672 PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ 673 ClaimName: "pvc1", 674 }, 675 }, 676 }, 677 } 678 pod2 := generateMockPod("2") 679 pod2.Raw.(*corev1.Pod).Spec.Volumes = []corev1.Volume{ 680 { 681 Name: "volume2", 682 VolumeSource: corev1.VolumeSource{ 683 PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ 684 ClaimName: "pvc2", 685 }, 686 }, 687 }, 688 } 689 podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 690 EventType: "add", 691 Object: pod1, 692 }) 693 podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 694 EventType: "add", 695 Object: pod2, 696 }) 697 linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{ 698 POD: podCache, 699 PERSISTENTVOLUMECLAIM: pvcCache, 700 }) 701 podList := []*K8sMetaEvent{ 702 { 703 EventType: "update", 704 Object: podCache.metaStore.Items["default/pod1"], 705 }, 706 { 707 EventType: "update", 708 Object: podCache.metaStore.Items["default/pod2"], 709 }, 710 } 711 results := linkGenerator.getPodPVCLink(podList) 712 assert.Equal(t, 2, len(results)) 713 assert.Equal(t, "pvc1", results[0].Object.Raw.(*PodPersistentVolumeClaim).PersistentVolumeClaim.Name) 714 assert.Equal(t, "pvc2", results[1].Object.Raw.(*PodPersistentVolumeClaim).PersistentVolumeClaim.Name) 715 } 716 717 func TestGetPodConfigMapLink(t *testing.T) { 718 podCache := newK8sMetaCache(make(chan struct{}), POD) 719 configMapCache := newK8sMetaCache(make(chan struct{}), CONFIGMAP) 720 configMapCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 721 EventType: "add", 722 Object: &ObjectWrapper{ 723 Raw: &corev1.ConfigMap{ 724 ObjectMeta: metav1.ObjectMeta{ 725 Name: "configmap1", 726 Namespace: "default", 727 }, 728 }, 729 }, 730 }) 731 configMapCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 732 EventType: "add", 733 Object: &ObjectWrapper{ 734 Raw: &corev1.ConfigMap{ 735 ObjectMeta: metav1.ObjectMeta{ 736 Name: "configmap2", 737 Namespace: "default", 738 }, 739 }, 740 }, 741 }) 742 pod1 := generateMockPod("1") 743 pod1.Raw.(*corev1.Pod).Spec.Volumes = []corev1.Volume{ 744 { 745 Name: "volume1", 746 VolumeSource: corev1.VolumeSource{ 747 ConfigMap: &corev1.ConfigMapVolumeSource{ 748 LocalObjectReference: corev1.LocalObjectReference{ 749 Name: "configmap1", 750 }, 751 }, 752 }, 753 }, 754 } 755 pod2 := generateMockPod("2") 756 pod2.Raw.(*corev1.Pod).Spec.Volumes = []corev1.Volume{ 757 { 758 Name: "volume2", 759 VolumeSource: corev1.VolumeSource{ 760 ConfigMap: &corev1.ConfigMapVolumeSource{ 761 LocalObjectReference: corev1.LocalObjectReference{ 762 Name: "configmap2", 763 }, 764 }, 765 }, 766 }, 767 } 768 podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 769 EventType: "add", 770 Object: pod1, 771 }) 772 podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 773 EventType: "add", 774 Object: pod2, 775 }) 776 linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{ 777 POD: podCache, 778 CONFIGMAP: configMapCache, 779 }) 780 podList := []*K8sMetaEvent{ 781 { 782 EventType: "update", 783 Object: podCache.metaStore.Items["default/pod1"], 784 }, 785 { 786 EventType: "update", 787 Object: podCache.metaStore.Items["default/pod2"], 788 }, 789 } 790 results := linkGenerator.getPodConfigMapLink(podList) 791 assert.Equal(t, 2, len(results)) 792 assert.Equal(t, "configmap1", results[0].Object.Raw.(*PodConfigMap).ConfigMap.Name) 793 assert.Equal(t, "configmap2", results[1].Object.Raw.(*PodConfigMap).ConfigMap.Name) 794 } 795 796 func TestGetPodServiceLink(t *testing.T) { 797 podCache := newK8sMetaCache(make(chan struct{}), POD) 798 serviceCache := newK8sMetaCache(make(chan struct{}), SERVICE) 799 serviceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 800 EventType: "add", 801 Object: &ObjectWrapper{ 802 Raw: &corev1.Service{ 803 ObjectMeta: metav1.ObjectMeta{ 804 Name: "service1", 805 Namespace: "default", 806 }, 807 Spec: corev1.ServiceSpec{ 808 Selector: map[string]string{ 809 "app": "test", 810 }, 811 }, 812 }, 813 }, 814 }) 815 serviceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 816 EventType: "add", 817 Object: &ObjectWrapper{ 818 Raw: &corev1.Service{ 819 ObjectMeta: metav1.ObjectMeta{ 820 Name: "service2", 821 Namespace: "default", 822 }, 823 Spec: corev1.ServiceSpec{ 824 Selector: map[string]string{ 825 "app": "test2", 826 }, 827 }, 828 }, 829 }, 830 }) 831 pod1 := generateMockPod("1") 832 pod1.Raw.(*corev1.Pod).Labels = map[string]string{ 833 "app": "test", 834 } 835 pod2 := generateMockPod("2") 836 pod2.Raw.(*corev1.Pod).Labels = map[string]string{ 837 "app": "test2", 838 } 839 podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 840 EventType: "add", 841 Object: pod1, 842 }) 843 podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 844 EventType: "add", 845 Object: pod2, 846 }) 847 linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{ 848 POD: podCache, 849 SERVICE: serviceCache, 850 }) 851 podList := []*K8sMetaEvent{ 852 { 853 EventType: "update", 854 Object: podCache.metaStore.Items["default/pod1"], 855 }, 856 { 857 EventType: "update", 858 Object: podCache.metaStore.Items["default/pod2"], 859 }, 860 } 861 results := linkGenerator.getPodServiceLink(podList) 862 assert.Equal(t, 2, len(results)) 863 assert.Equal(t, "service1", results[0].Object.Raw.(*PodService).Service.Name) 864 assert.Equal(t, "service2", results[1].Object.Raw.(*PodService).Service.Name) 865 } 866 867 func TestGetPodContainerLink(t *testing.T) { 868 podCache := newK8sMetaCache(make(chan struct{}), POD) 869 podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 870 EventType: "add", 871 Object: generateMockPod("1"), 872 }) 873 podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 874 EventType: "add", 875 Object: generateMockPod("2"), 876 }) 877 linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{ 878 POD: podCache, 879 }) 880 podList := []*K8sMetaEvent{ 881 { 882 EventType: "update", 883 Object: podCache.metaStore.Items["default/pod1"], 884 }, 885 { 886 EventType: "update", 887 Object: podCache.metaStore.Items["default/pod2"], 888 }, 889 } 890 results := linkGenerator.getPodContainerLink(podList) 891 assert.Equal(t, 2, len(results)) 892 assert.Equal(t, "test1", results[0].Object.Raw.(*PodContainer).Container.Name) 893 assert.Equal(t, "test2", results[1].Object.Raw.(*PodContainer).Container.Name) 894 } 895 896 func TestGetIngressServiceLink(t *testing.T) { 897 ingressCache := newK8sMetaCache(make(chan struct{}), INGRESS) 898 serviceCache := newK8sMetaCache(make(chan struct{}), SERVICE) 899 serviceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 900 EventType: "add", 901 Object: &ObjectWrapper{ 902 Raw: &corev1.Service{ 903 ObjectMeta: metav1.ObjectMeta{ 904 Name: "service1", 905 Namespace: "default", 906 }, 907 Spec: corev1.ServiceSpec{ 908 Selector: map[string]string{ 909 "app": "test", 910 }, 911 }, 912 }, 913 }, 914 }) 915 serviceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 916 EventType: "add", 917 Object: &ObjectWrapper{ 918 Raw: &corev1.Service{ 919 ObjectMeta: metav1.ObjectMeta{ 920 Name: "service2", 921 Namespace: "default", 922 }, 923 Spec: corev1.ServiceSpec{ 924 Selector: map[string]string{ 925 "app": "test2", 926 }, 927 }, 928 }, 929 }, 930 }) 931 ingressCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 932 EventType: "add", 933 Object: &ObjectWrapper{ 934 Raw: &networking.Ingress{ 935 ObjectMeta: metav1.ObjectMeta{ 936 Name: "ingress1", 937 Namespace: "default", 938 }, 939 Spec: networking.IngressSpec{ 940 Rules: []networking.IngressRule{ 941 { 942 IngressRuleValue: networking.IngressRuleValue{ 943 HTTP: &networking.HTTPIngressRuleValue{ 944 Paths: []networking.HTTPIngressPath{ 945 { 946 Backend: networking.IngressBackend{ 947 Service: &networking.IngressServiceBackend{ 948 Name: "service1", 949 }, 950 }, 951 }, 952 }, 953 }, 954 }, 955 }, 956 }, 957 }, 958 }, 959 }, 960 }) 961 ingressCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 962 EventType: "add", 963 Object: &ObjectWrapper{ 964 Raw: &networking.Ingress{ 965 ObjectMeta: metav1.ObjectMeta{ 966 Name: "ingress2", 967 Namespace: "default", 968 }, 969 Spec: networking.IngressSpec{ 970 Rules: []networking.IngressRule{ 971 { 972 IngressRuleValue: networking.IngressRuleValue{ 973 HTTP: &networking.HTTPIngressRuleValue{ 974 Paths: []networking.HTTPIngressPath{ 975 { 976 Backend: networking.IngressBackend{ 977 Service: &networking.IngressServiceBackend{ 978 Name: "service2", 979 }, 980 }, 981 }, 982 }, 983 }, 984 }, 985 }, 986 }, 987 }, 988 }, 989 }, 990 }) 991 linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{ 992 INGRESS: ingressCache, 993 SERVICE: serviceCache, 994 }) 995 ingressList := []*K8sMetaEvent{ 996 { 997 EventType: "update", 998 Object: ingressCache.metaStore.Items["default/ingress1"], 999 }, 1000 { 1001 EventType: "update", 1002 Object: ingressCache.metaStore.Items["default/ingress2"], 1003 }, 1004 } 1005 results := linkGenerator.getIngressServiceLink(ingressList) 1006 assert.Equal(t, 2, len(results)) 1007 assert.Equal(t, "service1", results[0].Object.Raw.(*IngressService).Service.Name) 1008 assert.Equal(t, "service2", results[1].Object.Raw.(*IngressService).Service.Name) 1009 } 1010 1011 func TestGetPodNamespaceLink(t *testing.T) { 1012 podCache := newK8sMetaCache(make(chan struct{}), POD) 1013 namespaceCache := newK8sMetaCache(make(chan struct{}), NAMESPACE) 1014 namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1015 EventType: "add", 1016 Object: generateMockNamespace("default"), 1017 }) 1018 namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1019 EventType: "add", 1020 Object: generateMockNamespace("kube-system"), 1021 }) 1022 pod1 := generateMockPod("1") 1023 pod1.Raw.(*corev1.Pod).Namespace = "default" 1024 pod2 := generateMockPod("2") 1025 pod2.Raw.(*corev1.Pod).Namespace = "kube-system" 1026 pod3 := generateMockPod("3") 1027 pod3.Raw.(*corev1.Pod).Namespace = "kube-system" 1028 podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1029 EventType: "add", 1030 Object: pod1, 1031 }) 1032 podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1033 EventType: "add", 1034 Object: pod2, 1035 }) 1036 podCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1037 EventType: "add", 1038 Object: pod3, 1039 }) 1040 linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{ 1041 POD: podCache, 1042 NAMESPACE: namespaceCache, 1043 }) 1044 podList := []*K8sMetaEvent{ 1045 { 1046 EventType: "update", 1047 Object: podCache.metaStore.Items["default/pod1"], 1048 }, 1049 { 1050 EventType: "update", 1051 Object: podCache.metaStore.Items["kube-system/pod2"], 1052 }, 1053 { 1054 EventType: "update", 1055 Object: podCache.metaStore.Items["kube-system/pod3"], 1056 }, 1057 } 1058 results := linkGenerator.getPodNamespaceLink(podList) 1059 assert.Equal(t, 3, len(results)) 1060 assert.Equal(t, "default", results[0].Object.Raw.(*PodNamespace).Namespace.Name) 1061 assert.Equal(t, "pod1", results[0].Object.Raw.(*PodNamespace).Pod.Name) 1062 assert.Equal(t, "kube-system", results[1].Object.Raw.(*PodNamespace).Namespace.Name) 1063 assert.Equal(t, "pod2", results[1].Object.Raw.(*PodNamespace).Pod.Name) 1064 assert.Equal(t, "kube-system", results[2].Object.Raw.(*PodNamespace).Namespace.Name) 1065 assert.Equal(t, "pod3", results[2].Object.Raw.(*PodNamespace).Pod.Name) 1066 assert.Equal(t, POD_NAMESPACE, results[0].Object.ResourceType) 1067 } 1068 1069 func TestGetServiceNamespaceLink(t *testing.T) { 1070 serviceCache := newK8sMetaCache(make(chan struct{}), SERVICE) 1071 namespaceCache := newK8sMetaCache(make(chan struct{}), NAMESPACE) 1072 namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1073 EventType: "add", 1074 Object: generateMockNamespace("default"), 1075 }) 1076 namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1077 EventType: "add", 1078 Object: generateMockNamespace("kube-system"), 1079 }) 1080 service1 := &ObjectWrapper{ 1081 Raw: &corev1.Service{ 1082 ObjectMeta: metav1.ObjectMeta{ 1083 Name: "service1", 1084 Namespace: "default", 1085 }, 1086 Spec: corev1.ServiceSpec{ 1087 Selector: map[string]string{ 1088 "app": "test", 1089 }, 1090 }, 1091 }, 1092 } 1093 service2 := &ObjectWrapper{ 1094 Raw: &corev1.Service{ 1095 ObjectMeta: metav1.ObjectMeta{ 1096 Name: "service2", 1097 Namespace: "kube-system", 1098 }, 1099 Spec: corev1.ServiceSpec{ 1100 Selector: map[string]string{ 1101 "app": "test", 1102 }, 1103 }, 1104 }, 1105 } 1106 serviceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1107 EventType: "add", 1108 Object: service1, 1109 }) 1110 serviceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1111 EventType: "add", 1112 Object: service2, 1113 }) 1114 1115 serviceList := []*K8sMetaEvent{ 1116 { 1117 EventType: "update", 1118 Object: service1, 1119 }, 1120 { 1121 EventType: "update", 1122 Object: service2, 1123 }, 1124 } 1125 linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{ 1126 SERVICE: serviceCache, 1127 NAMESPACE: namespaceCache, 1128 }) 1129 1130 results := linkGenerator.getServiceNamespaceLink(serviceList) 1131 assert.Equal(t, 2, len(results)) 1132 assert.Equal(t, "default", results[0].Object.Raw.(*ServiceNamespace).Namespace.Name) 1133 assert.Equal(t, "service1", results[0].Object.Raw.(*ServiceNamespace).Service.Name) 1134 assert.Equal(t, "kube-system", results[1].Object.Raw.(*ServiceNamespace).Namespace.Name) 1135 assert.Equal(t, "service2", results[1].Object.Raw.(*ServiceNamespace).Service.Name) 1136 assert.Equal(t, SERVICE_NAMESPACE, results[0].Object.ResourceType) 1137 1138 } 1139 1140 func TestGetDeploymentNamespaceLink(t *testing.T) { 1141 deploymentCache := newK8sMetaCache(make(chan struct{}), DEPLOYMENT) 1142 namespaceCache := newK8sMetaCache(make(chan struct{}), NAMESPACE) 1143 namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1144 EventType: "add", 1145 Object: generateMockNamespace("default"), 1146 }) 1147 namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1148 EventType: "add", 1149 Object: generateMockNamespace("kube-system"), 1150 }) 1151 deployment1 := &ObjectWrapper{ 1152 Raw: &app.Deployment{ 1153 ObjectMeta: metav1.ObjectMeta{ 1154 Name: "deployment1", 1155 Namespace: "default", 1156 }, 1157 }, 1158 } 1159 deployment2 := &ObjectWrapper{ 1160 Raw: &app.Deployment{ 1161 ObjectMeta: metav1.ObjectMeta{ 1162 Name: "deployment2", 1163 Namespace: "kube-system", 1164 }, 1165 }, 1166 } 1167 deploymentCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1168 EventType: "add", 1169 Object: deployment1, 1170 }) 1171 deploymentCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1172 EventType: "add", 1173 Object: deployment2, 1174 }) 1175 1176 deploymentList := []*K8sMetaEvent{ 1177 { 1178 EventType: "update", 1179 Object: deployment1, 1180 }, 1181 { 1182 EventType: "update", 1183 Object: deployment2, 1184 }, 1185 } 1186 linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{ 1187 DEPLOYMENT: deploymentCache, 1188 NAMESPACE: namespaceCache, 1189 }) 1190 1191 results := linkGenerator.getDeploymentNamespaceLink(deploymentList) 1192 assert.Equal(t, 2, len(results)) 1193 assert.Equal(t, "default", results[0].Object.Raw.(*DeploymentNamespace).Namespace.Name) 1194 assert.Equal(t, "deployment1", results[0].Object.Raw.(*DeploymentNamespace).Deployment.Name) 1195 assert.Equal(t, "kube-system", results[1].Object.Raw.(*DeploymentNamespace).Namespace.Name) 1196 assert.Equal(t, "deployment2", results[1].Object.Raw.(*DeploymentNamespace).Deployment.Name) 1197 assert.Equal(t, DEPLOYMENT_NAMESPACE, results[0].Object.ResourceType) 1198 1199 } 1200 1201 func TestGetDaemonSetNamespaceLink(t *testing.T) { 1202 daemonSetCache := newK8sMetaCache(make(chan struct{}), DAEMONSET) 1203 namespaceCache := newK8sMetaCache(make(chan struct{}), NAMESPACE) 1204 namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1205 EventType: "add", 1206 Object: generateMockNamespace("default"), 1207 }) 1208 namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1209 EventType: "add", 1210 Object: generateMockNamespace("kube-system"), 1211 }) 1212 daemonset1 := &ObjectWrapper{ 1213 Raw: &app.DaemonSet{ 1214 ObjectMeta: metav1.ObjectMeta{ 1215 Name: "daemonset1", 1216 Namespace: "default", 1217 }, 1218 }, 1219 } 1220 daemonset2 := &ObjectWrapper{ 1221 Raw: &app.DaemonSet{ 1222 ObjectMeta: metav1.ObjectMeta{ 1223 Name: "daemonset2", 1224 Namespace: "kube-system", 1225 }, 1226 }, 1227 } 1228 daemonSetCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1229 EventType: "add", 1230 Object: daemonset1, 1231 }) 1232 daemonSetCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1233 EventType: "add", 1234 Object: daemonset2, 1235 }) 1236 1237 daemonsetList := []*K8sMetaEvent{ 1238 { 1239 EventType: "update", 1240 Object: daemonset1, 1241 }, 1242 { 1243 EventType: "update", 1244 Object: daemonset2, 1245 }, 1246 } 1247 linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{ 1248 DAEMONSET: daemonSetCache, 1249 NAMESPACE: namespaceCache, 1250 }) 1251 1252 results := linkGenerator.getDaemonSetNamespaceLink(daemonsetList) 1253 assert.Equal(t, 2, len(results)) 1254 assert.Equal(t, "default", results[0].Object.Raw.(*DaemonSetNamespace).Namespace.Name) 1255 assert.Equal(t, "daemonset1", results[0].Object.Raw.(*DaemonSetNamespace).DaemonSet.Name) 1256 assert.Equal(t, "kube-system", results[1].Object.Raw.(*DaemonSetNamespace).Namespace.Name) 1257 assert.Equal(t, "daemonset2", results[1].Object.Raw.(*DaemonSetNamespace).DaemonSet.Name) 1258 assert.Equal(t, DAEMONSET_NAMESPACE, results[0].Object.ResourceType) 1259 } 1260 1261 func TestGetStatefulSetNamespaceLink(t *testing.T) { 1262 statefulSetCache := newK8sMetaCache(make(chan struct{}), STATEFULSET) 1263 namespaceCache := newK8sMetaCache(make(chan struct{}), NAMESPACE) 1264 namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1265 EventType: "add", 1266 Object: generateMockNamespace("default"), 1267 }) 1268 namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1269 EventType: "add", 1270 Object: generateMockNamespace("kube-system"), 1271 }) 1272 statefulSet1 := &ObjectWrapper{ 1273 Raw: &app.StatefulSet{ 1274 ObjectMeta: metav1.ObjectMeta{ 1275 Name: "statefulSet1", 1276 Namespace: "default", 1277 }, 1278 }, 1279 } 1280 statefulSet2 := &ObjectWrapper{ 1281 Raw: &app.StatefulSet{ 1282 ObjectMeta: metav1.ObjectMeta{ 1283 Name: "statefulSet2", 1284 Namespace: "kube-system", 1285 }, 1286 }, 1287 } 1288 statefulSetCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1289 EventType: "add", 1290 Object: statefulSet1, 1291 }) 1292 statefulSetCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1293 EventType: "add", 1294 Object: statefulSet2, 1295 }) 1296 1297 statefulSetList := []*K8sMetaEvent{ 1298 { 1299 EventType: "update", 1300 Object: statefulSet1, 1301 }, 1302 { 1303 EventType: "update", 1304 Object: statefulSet2, 1305 }, 1306 } 1307 linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{ 1308 DAEMONSET: statefulSetCache, 1309 NAMESPACE: namespaceCache, 1310 }) 1311 1312 results := linkGenerator.getStatefulsetNamespaceLink(statefulSetList) 1313 assert.Equal(t, 2, len(results)) 1314 assert.Equal(t, "default", results[0].Object.Raw.(*StatefulSetNamespace).Namespace.Name) 1315 assert.Equal(t, "statefulSet1", results[0].Object.Raw.(*StatefulSetNamespace).StatefulSet.Name) 1316 assert.Equal(t, "kube-system", results[1].Object.Raw.(*StatefulSetNamespace).Namespace.Name) 1317 assert.Equal(t, "statefulSet2", results[1].Object.Raw.(*StatefulSetNamespace).StatefulSet.Name) 1318 assert.Equal(t, STATEFULSET_NAMESPACE, results[0].Object.ResourceType) 1319 } 1320 1321 func TestGetConfigMapNamespaceLink(t *testing.T) { 1322 configmapCache := newK8sMetaCache(make(chan struct{}), CONFIGMAP) 1323 namespaceCache := newK8sMetaCache(make(chan struct{}), NAMESPACE) 1324 namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1325 EventType: "add", 1326 Object: generateMockNamespace("default"), 1327 }) 1328 namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1329 EventType: "add", 1330 Object: generateMockNamespace("kube-system"), 1331 }) 1332 configmap1 := &ObjectWrapper{ 1333 Raw: &corev1.ConfigMap{ 1334 ObjectMeta: metav1.ObjectMeta{ 1335 Name: "configmap1", 1336 Namespace: "default", 1337 }, 1338 }, 1339 } 1340 configmap2 := &ObjectWrapper{ 1341 Raw: &corev1.ConfigMap{ 1342 ObjectMeta: metav1.ObjectMeta{ 1343 Name: "configmap2", 1344 Namespace: "kube-system", 1345 }, 1346 }, 1347 } 1348 configmapCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1349 EventType: "add", 1350 Object: configmap1, 1351 }) 1352 configmapCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1353 EventType: "add", 1354 Object: configmap2, 1355 }) 1356 1357 configmapList := []*K8sMetaEvent{ 1358 { 1359 EventType: "update", 1360 Object: configmap1, 1361 }, 1362 { 1363 EventType: "update", 1364 Object: configmap2, 1365 }, 1366 } 1367 linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{ 1368 CONFIGMAP: configmapCache, 1369 NAMESPACE: namespaceCache, 1370 }) 1371 1372 results := linkGenerator.getConfigMapNamesapceLink(configmapList) 1373 assert.Equal(t, 2, len(results)) 1374 assert.Equal(t, "default", results[0].Object.Raw.(*ConfigMapNamespace).Namespace.Name) 1375 assert.Equal(t, "configmap1", results[0].Object.Raw.(*ConfigMapNamespace).ConfigMap.Name) 1376 assert.Equal(t, "kube-system", results[1].Object.Raw.(*ConfigMapNamespace).Namespace.Name) 1377 assert.Equal(t, "configmap2", results[1].Object.Raw.(*ConfigMapNamespace).ConfigMap.Name) 1378 assert.Equal(t, CONFIGMAP_NAMESPACE, results[0].Object.ResourceType) 1379 } 1380 1381 func TestGetJobNamespaceLink(t *testing.T) { 1382 jobCache := newK8sMetaCache(make(chan struct{}), JOB) 1383 namespaceCache := newK8sMetaCache(make(chan struct{}), NAMESPACE) 1384 namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1385 EventType: "add", 1386 Object: generateMockNamespace("default"), 1387 }) 1388 namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1389 EventType: "add", 1390 Object: generateMockNamespace("kube-system"), 1391 }) 1392 job1 := &ObjectWrapper{ 1393 Raw: &batch.Job{ 1394 ObjectMeta: metav1.ObjectMeta{ 1395 Name: "job1", 1396 Namespace: "default", 1397 }, 1398 }, 1399 } 1400 job2 := &ObjectWrapper{ 1401 Raw: &batch.Job{ 1402 ObjectMeta: metav1.ObjectMeta{ 1403 Name: "job2", 1404 Namespace: "kube-system", 1405 }, 1406 }, 1407 } 1408 jobCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1409 EventType: "add", 1410 Object: job1, 1411 }) 1412 jobCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1413 EventType: "add", 1414 Object: job2, 1415 }) 1416 1417 jobList := []*K8sMetaEvent{ 1418 { 1419 EventType: "update", 1420 Object: job1, 1421 }, 1422 { 1423 EventType: "update", 1424 Object: job2, 1425 }, 1426 } 1427 linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{ 1428 JOB: jobCache, 1429 NAMESPACE: namespaceCache, 1430 }) 1431 1432 results := linkGenerator.getJobNamesapceLink(jobList) 1433 assert.Equal(t, 2, len(results)) 1434 assert.Equal(t, "default", results[0].Object.Raw.(*JobNamespace).Namespace.Name) 1435 assert.Equal(t, "job1", results[0].Object.Raw.(*JobNamespace).Job.Name) 1436 assert.Equal(t, "kube-system", results[1].Object.Raw.(*JobNamespace).Namespace.Name) 1437 assert.Equal(t, "job2", results[1].Object.Raw.(*JobNamespace).Job.Name) 1438 assert.Equal(t, JOB_NAMESPACE, results[0].Object.ResourceType) 1439 } 1440 1441 func TestGetCronJobNamespaceLink(t *testing.T) { 1442 cronjobCache := newK8sMetaCache(make(chan struct{}), CRONJOB) 1443 namespaceCache := newK8sMetaCache(make(chan struct{}), NAMESPACE) 1444 namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1445 EventType: "add", 1446 Object: generateMockNamespace("default"), 1447 }) 1448 namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1449 EventType: "add", 1450 Object: generateMockNamespace("kube-system"), 1451 }) 1452 cronjob1 := &ObjectWrapper{ 1453 Raw: &batch.CronJob{ 1454 ObjectMeta: metav1.ObjectMeta{ 1455 Name: "cronjob1", 1456 Namespace: "default", 1457 }, 1458 }, 1459 } 1460 cronjob2 := &ObjectWrapper{ 1461 Raw: &batch.CronJob{ 1462 ObjectMeta: metav1.ObjectMeta{ 1463 Name: "cronjob2", 1464 Namespace: "kube-system", 1465 }, 1466 }, 1467 } 1468 cronjobCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1469 EventType: "add", 1470 Object: cronjob1, 1471 }) 1472 cronjobCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1473 EventType: "add", 1474 Object: cronjob2, 1475 }) 1476 1477 jobList := []*K8sMetaEvent{ 1478 { 1479 EventType: "update", 1480 Object: cronjob1, 1481 }, 1482 { 1483 EventType: "update", 1484 Object: cronjob2, 1485 }, 1486 } 1487 linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{ 1488 CRONJOB: cronjobCache, 1489 NAMESPACE: namespaceCache, 1490 }) 1491 1492 results := linkGenerator.getCronJobNamesapceLink(jobList) 1493 assert.Equal(t, 2, len(results)) 1494 assert.Equal(t, "default", results[0].Object.Raw.(*CronJobNamespace).Namespace.Name) 1495 assert.Equal(t, "cronjob1", results[0].Object.Raw.(*CronJobNamespace).CronJob.Name) 1496 assert.Equal(t, "kube-system", results[1].Object.Raw.(*CronJobNamespace).Namespace.Name) 1497 assert.Equal(t, "cronjob2", results[1].Object.Raw.(*CronJobNamespace).CronJob.Name) 1498 assert.Equal(t, CRONJOB_NAMESPACE, results[0].Object.ResourceType) 1499 } 1500 1501 func TestGetPVCNamespaceLink(t *testing.T) { 1502 pvcCache := newK8sMetaCache(make(chan struct{}), PERSISTENTVOLUME) 1503 namespaceCache := newK8sMetaCache(make(chan struct{}), NAMESPACE) 1504 namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1505 EventType: "add", 1506 Object: generateMockNamespace("default"), 1507 }) 1508 namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1509 EventType: "add", 1510 Object: generateMockNamespace("kube-system"), 1511 }) 1512 pvc1 := &ObjectWrapper{ 1513 Raw: &corev1.PersistentVolumeClaim{ 1514 ObjectMeta: metav1.ObjectMeta{ 1515 Name: "pvc1", 1516 Namespace: "default", 1517 }, 1518 }, 1519 } 1520 pvc2 := &ObjectWrapper{ 1521 Raw: &corev1.PersistentVolumeClaim{ 1522 ObjectMeta: metav1.ObjectMeta{ 1523 Name: "pvc2", 1524 Namespace: "kube-system", 1525 }, 1526 }, 1527 } 1528 pvcCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1529 EventType: "add", 1530 Object: pvc1, 1531 }) 1532 pvcCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1533 EventType: "add", 1534 Object: pvc2, 1535 }) 1536 1537 jobList := []*K8sMetaEvent{ 1538 { 1539 EventType: "update", 1540 Object: pvc1, 1541 }, 1542 { 1543 EventType: "update", 1544 Object: pvc2, 1545 }, 1546 } 1547 linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{ 1548 PERSISTENTVOLUMECLAIM: pvcCache, 1549 NAMESPACE: namespaceCache, 1550 }) 1551 1552 results := linkGenerator.getPVCNamesapceLink(jobList) 1553 assert.Equal(t, 2, len(results)) 1554 assert.Equal(t, "default", results[0].Object.Raw.(*PersistentVolumeClaimNamespace).Namespace.Name) 1555 assert.Equal(t, "pvc1", results[0].Object.Raw.(*PersistentVolumeClaimNamespace).PersistentVolumeClaim.Name) 1556 assert.Equal(t, "kube-system", results[1].Object.Raw.(*PersistentVolumeClaimNamespace).Namespace.Name) 1557 assert.Equal(t, "pvc2", results[1].Object.Raw.(*PersistentVolumeClaimNamespace).PersistentVolumeClaim.Name) 1558 assert.Equal(t, PERSISTENTVOLUMECLAIM_NAMESPACE, results[0].Object.ResourceType) 1559 } 1560 1561 func TestGetIngressNamespaceLink(t *testing.T) { 1562 ingressCache := newK8sMetaCache(make(chan struct{}), INGRESS) 1563 namespaceCache := newK8sMetaCache(make(chan struct{}), NAMESPACE) 1564 namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1565 EventType: "add", 1566 Object: generateMockNamespace("default"), 1567 }) 1568 namespaceCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1569 EventType: "add", 1570 Object: generateMockNamespace("kube-system"), 1571 }) 1572 ingress1 := &ObjectWrapper{ 1573 Raw: &networking.Ingress{ 1574 ObjectMeta: metav1.ObjectMeta{ 1575 Name: "ingress1", 1576 Namespace: "default", 1577 }, 1578 }, 1579 } 1580 ingress2 := &ObjectWrapper{ 1581 Raw: &networking.Ingress{ 1582 ObjectMeta: metav1.ObjectMeta{ 1583 Name: "ingress2", 1584 Namespace: "kube-system", 1585 }, 1586 }, 1587 } 1588 ingressCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1589 EventType: "add", 1590 Object: ingress1, 1591 }) 1592 ingressCache.metaStore.handleAddOrUpdateEvent(&K8sMetaEvent{ 1593 EventType: "add", 1594 Object: ingress2, 1595 }) 1596 1597 jobList := []*K8sMetaEvent{ 1598 { 1599 EventType: "update", 1600 Object: ingress1, 1601 }, 1602 { 1603 EventType: "update", 1604 Object: ingress2, 1605 }, 1606 } 1607 linkGenerator := NewK8sMetaLinkGenerator(map[string]MetaCache{ 1608 INGRESS: ingressCache, 1609 NAMESPACE: namespaceCache, 1610 }) 1611 1612 results := linkGenerator.getIngressNamesapceLink(jobList) 1613 assert.Equal(t, 2, len(results)) 1614 assert.Equal(t, "default", results[0].Object.Raw.(*IngressNamespace).Namespace.Name) 1615 assert.Equal(t, "ingress1", results[0].Object.Raw.(*IngressNamespace).Ingress.Name) 1616 assert.Equal(t, "kube-system", results[1].Object.Raw.(*IngressNamespace).Namespace.Name) 1617 assert.Equal(t, "ingress2", results[1].Object.Raw.(*IngressNamespace).Ingress.Name) 1618 assert.Equal(t, INGRESS_NAMESPACE, results[0].Object.ResourceType) 1619 } 1620 1621 func generateMockNamespace(namespaceName string) *ObjectWrapper { 1622 return &ObjectWrapper{ 1623 Raw: &corev1.Namespace{ 1624 ObjectMeta: metav1.ObjectMeta{ 1625 Name: namespaceName, 1626 Namespace: "", // namesapce itself without namesapce 1627 }, 1628 }, 1629 } 1630 } 1631 1632 func generateMockPod(index string) *ObjectWrapper { 1633 return &ObjectWrapper{ 1634 Raw: &corev1.Pod{ 1635 ObjectMeta: metav1.ObjectMeta{ 1636 Name: "pod" + index, 1637 Namespace: "default", 1638 }, 1639 Spec: corev1.PodSpec{ 1640 Containers: []corev1.Container{ 1641 { 1642 Name: "test" + index, 1643 Image: "test" + index, 1644 }, 1645 }, 1646 }, 1647 }, 1648 } 1649 }