github.com/cilium/cilium@v1.16.2/operator/identitygc/gc_test.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package identitygc 5 6 import ( 7 "context" 8 "fmt" 9 "testing" 10 "time" 11 12 "github.com/cilium/hive/cell" 13 "github.com/cilium/hive/hivetest" 14 "go.uber.org/goleak" 15 corev1 "k8s.io/api/core/v1" 16 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 17 18 authIdentity "github.com/cilium/cilium/operator/auth/identity" 19 "github.com/cilium/cilium/operator/auth/spire" 20 "github.com/cilium/cilium/operator/k8s" 21 cmtypes "github.com/cilium/cilium/pkg/clustermesh/types" 22 "github.com/cilium/cilium/pkg/hive" 23 v2 "github.com/cilium/cilium/pkg/k8s/apis/cilium.io/v2" 24 k8sClient "github.com/cilium/cilium/pkg/k8s/client" 25 "github.com/cilium/cilium/pkg/metrics" 26 "github.com/cilium/cilium/pkg/option" 27 ) 28 29 func TestIdentitiesGC(t *testing.T) { 30 defer goleak.VerifyNone( 31 t, 32 // To ignore goroutine started from sigs.k8s.io/controller-runtime/pkg/log.go 33 // init function 34 goleak.IgnoreTopFunction("time.Sleep"), 35 ) 36 37 var clientset k8sClient.Clientset 38 var authIdentityClient authIdentity.Provider 39 40 hive := hive.New( 41 cell.Config(cmtypes.DefaultClusterInfo), 42 metrics.Metric(NewMetrics), 43 44 // provide a fake clientset 45 k8sClient.FakeClientCell, 46 // provide a fake spire client 47 spire.FakeCellClient, 48 // provide resources 49 k8s.ResourcesCell, 50 51 // provide identities gc test configuration 52 cell.Provide(func() Config { 53 return Config{ 54 Interval: 50 * time.Millisecond, 55 HeartbeatTimeout: 50 * time.Millisecond, 56 57 RateInterval: time.Minute, 58 RateLimit: 2500, 59 } 60 }), 61 cell.Provide(func() SharedConfig { 62 return SharedConfig{ 63 IdentityAllocationMode: option.IdentityAllocationModeCRD, 64 } 65 }), 66 67 // initial setup for the test 68 cell.Invoke(func(c k8sClient.Clientset, authClient authIdentity.Provider) error { 69 clientset = c 70 authIdentityClient = authClient 71 if err := setupK8sNodes(clientset); err != nil { 72 return err 73 } 74 if err := setupCiliumIdentities(clientset); err != nil { 75 return err 76 } 77 if err := setupCiliumEndpoint(clientset); err != nil { 78 return err 79 } 80 if err := setupAuthIdentities(authIdentityClient); err != nil { 81 return err 82 } 83 84 return nil 85 }), 86 87 cell.Invoke(registerGC), 88 ) 89 90 ctx, cancel := context.WithCancel(context.Background()) 91 defer cancel() 92 93 tlog := hivetest.Logger(t) 94 if err := hive.Start(tlog, ctx); err != nil { 95 t.Fatalf("failed to start: %s", err) 96 } 97 98 var ( 99 identities *v2.CiliumIdentityList 100 err error 101 ) 102 for retry := 0; retry < 10; retry++ { 103 identities, err = clientset.CiliumV2().CiliumIdentities().List( 104 ctx, 105 metav1.ListOptions{ 106 LabelSelector: metav1.FormatLabelSelector( 107 &metav1.LabelSelector{ 108 MatchLabels: map[string]string{ 109 "test": "identities-gc", 110 }, 111 }, 112 ), 113 }, 114 ) 115 if err == nil && len(identities.Items) == 1 { 116 break 117 } 118 time.Sleep(50 * time.Millisecond) 119 } 120 if err != nil { 121 t.Fatalf("unable to list Cilium identities: %s", err) 122 } 123 if len(identities.Items) != 1 { 124 t.Fatalf("expected 1 Cilium identity, got %d", len(identities.Items)) 125 } 126 if identities.Items[0].Name != "99999" { 127 t.Fatalf("expected Cilium identity \"99999\", got %q", identities.Items[0].Name) 128 } 129 130 authIdentities, err := authIdentityClient.List(ctx) 131 if err != nil { 132 t.Fatalf("unable to list Cilium Auth identities: %s", err) 133 } 134 135 if len(authIdentities) != 1 { 136 t.Fatalf("expected 1 Cilium Auth identity, got %d", len(authIdentities)) 137 } 138 139 if authIdentities[0] != "99999" { 140 t.Fatalf("expected Cilium Auth identity \"99999\", got %q", authIdentities[0]) 141 } 142 143 if err := hive.Stop(tlog, ctx); err != nil { 144 t.Fatalf("failed to stop: %s", err) 145 } 146 } 147 148 func setupK8sNodes(clientset k8sClient.Clientset) error { 149 nodes := []*corev1.Node{ 150 { 151 TypeMeta: metav1.TypeMeta{ 152 APIVersion: "v1", 153 Kind: "Node", 154 }, 155 ObjectMeta: metav1.ObjectMeta{ 156 Name: "node-control-plane", 157 Labels: map[string]string{"kubernetes.io/hostname": "node-control-plane"}, 158 }, 159 }, 160 { 161 TypeMeta: metav1.TypeMeta{ 162 APIVersion: "v1", 163 Kind: "Node", 164 }, 165 ObjectMeta: metav1.ObjectMeta{ 166 Name: "node-worker", 167 Labels: map[string]string{"kubernetes.io/hostname": "node-worker"}, 168 }, 169 }, 170 } 171 for _, node := range nodes { 172 if _, err := clientset.CoreV1().Nodes(). 173 Create(context.Background(), node, metav1.CreateOptions{}); err != nil { 174 return fmt.Errorf("failed to create node %v: %w", node, err) 175 } 176 } 177 return nil 178 } 179 180 func setupCiliumIdentities(clientset k8sClient.Clientset) error { 181 identities := []*v2.CiliumIdentity{ 182 { 183 TypeMeta: metav1.TypeMeta{ 184 APIVersion: "cilium.io/v2", 185 Kind: "CiliumIdentity", 186 }, 187 ObjectMeta: metav1.ObjectMeta{ 188 Name: "88888", 189 Labels: map[string]string{ 190 "test": "identities-gc", 191 }, 192 }, 193 }, 194 { 195 TypeMeta: metav1.TypeMeta{ 196 APIVersion: "cilium.io/v2", 197 Kind: "CiliumIdentity", 198 }, 199 ObjectMeta: metav1.ObjectMeta{ 200 Name: "99999", 201 Labels: map[string]string{ 202 "test": "identities-gc", 203 }, 204 }, 205 }, 206 } 207 for _, identity := range identities { 208 if _, err := clientset.CiliumV2().CiliumIdentities(). 209 Create(context.Background(), identity, metav1.CreateOptions{}); err != nil { 210 return fmt.Errorf("failed to create identity %v: %w", identity, err) 211 } 212 } 213 return nil 214 } 215 216 func setupAuthIdentities(client authIdentity.Provider) error { 217 if err := client.Upsert(context.Background(), "88888"); err != nil { 218 return err 219 } 220 if err := client.Upsert(context.Background(), "99999"); err != nil { 221 return err 222 } 223 return nil 224 } 225 226 func setupCiliumEndpoint(clientset k8sClient.Clientset) error { 227 endpoint := &v2.CiliumEndpoint{ 228 ObjectMeta: metav1.ObjectMeta{ 229 Name: "test-endpoint", 230 }, 231 Status: v2.EndpointStatus{ 232 Identity: &v2.EndpointIdentity{ 233 ID: 99999, 234 }, 235 }, 236 } 237 if _, err := clientset.CiliumV2().CiliumEndpoints(""). 238 Create(context.Background(), endpoint, metav1.CreateOptions{}); err != nil { 239 return fmt.Errorf("failed to create endpoint %v: %w", endpoint, err) 240 } 241 return nil 242 }