15
15
package main
16
16
17
17
import (
18
+ "fmt"
18
19
"log"
19
20
"os"
20
21
"strings"
22
+ "sync"
21
23
"time"
22
24
23
25
. "github.com/onsi/ginkgo"
@@ -29,6 +31,12 @@ import (
29
31
"github.com/projectcalico/libcalico-go/lib/ipip"
30
32
"github.com/projectcalico/libcalico-go/lib/net"
31
33
"github.com/projectcalico/libcalico-go/lib/testutils"
34
+ "k8s.io/client-go/tools/clientcmd"
35
+
36
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
37
+ "k8s.io/client-go/kubernetes"
38
+ "k8s.io/client-go/pkg/api/v1"
39
+ clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
32
40
)
33
41
34
42
var exitCode int
@@ -454,3 +462,82 @@ var _ = Describe("UT for Node IP assignment and conflict checking.", func() {
454
462
Entry ("Test with \" IP6\" env var set to IP and BGP spec populated with different IP" , makeNode ("192.168.1.10/24" , "2001:db8:85a3:8d3:1319:8a2e:370:7348/32" ), []EnvItem {{"IP" , "192.168.1.10/24" }, {"IP6" , "2001:db8:85a3:8d3:1319:8a2e:370:7349/32" }}, true ),
455
463
)
456
464
})
465
+
466
+ var _ = Describe ("FV tests against K8s API server." , func () {
467
+ It ("should not throw an error when multiple Nodes configure the same global CRD value." , func () {
468
+ // How many Nodes we want to "create".
469
+ numNodes := 10
470
+
471
+ // Create a K8s client.
472
+ configOverrides := & clientcmd.ConfigOverrides {
473
+ ClusterInfo : clientcmdapi.Cluster {
474
+ Server : "http://127.0.0.1:8080" ,
475
+ InsecureSkipTLSVerify : true ,
476
+ },
477
+ }
478
+
479
+ kcfg , err := clientcmd .NewNonInteractiveDeferredLoadingClientConfig (& clientcmd.ClientConfigLoadingRules {}, configOverrides ).ClientConfig ()
480
+ if err != nil {
481
+ Fail (fmt .Sprintf ("Failed to create K8s config: %v" , err ))
482
+ }
483
+
484
+ cs , err := kubernetes .NewForConfig (kcfg )
485
+ if err != nil {
486
+ Fail (fmt .Sprintf ("Could not create K8s client: %v" , err ))
487
+ }
488
+
489
+ // Create Calico client with k8s backend.
490
+ cfg := api .NewCalicoAPIConfig ()
491
+ cfg .Spec = api.CalicoAPIConfigSpec {
492
+ DatastoreType : api .Kubernetes ,
493
+ KubeConfig : api.KubeConfig {
494
+ K8sAPIEndpoint : "http://127.0.0.1:8080" ,
495
+ K8sInsecureSkipTLSVerify : true ,
496
+ },
497
+ }
498
+
499
+ c := testutils .CreateClient (* cfg )
500
+
501
+ // Create some Nodes using K8s client, Calico client does not support Node creation for KDD.
502
+ kNodes := []* v1.Node {}
503
+ for i := 0 ; i < numNodes ; i ++ {
504
+ n := & v1.Node {
505
+ ObjectMeta : metav1.ObjectMeta {
506
+ Name : fmt .Sprintf ("raceNode%02d" , i + 1 ),
507
+ },
508
+ }
509
+ kNodes = append (kNodes , n )
510
+ cs .Nodes ().Create (n )
511
+ }
512
+
513
+ // Pull above Nodes using Calico client.
514
+ nodes , err := c .Nodes ().List (api.NodeMetadata {})
515
+ if err != nil {
516
+ Fail (fmt .Sprintf ("Could not retrieve Nodes %v" , err ))
517
+ }
518
+
519
+ // Run ensureDefaultConfig against each of the Nodes using goroutines to simulate multiple Nodes coming online.
520
+ var wg sync.WaitGroup
521
+ errors := []error {}
522
+ for _ , node := range nodes .Items {
523
+ wg .Add (1 )
524
+ go func () {
525
+ defer wg .Done ()
526
+ err = ensureDefaultConfig (cfg , c , & node )
527
+ if err != nil {
528
+ errors = append (errors , err )
529
+ }
530
+ }()
531
+ }
532
+
533
+ wg .Wait ()
534
+
535
+ // Verify all runs complete without error.
536
+ Expect (len (errors )).To (Equal (0 ))
537
+
538
+ // Clean up our Nodes.
539
+ for _ , node := range nodes .Items {
540
+ cs .Nodes ().Delete (node .Metadata .Name , & metav1.DeleteOptions {})
541
+ }
542
+ })
543
+ })
0 commit comments