44package mirrors
55
66import (
7+ "fmt"
78 "testing"
89
910 . "github.com/onsi/ginkgo/v2"
1011 "github.com/onsi/gomega"
1112 "github.com/stretchr/testify/assert"
13+ "github.com/stretchr/testify/require"
1214 corev1 "k8s.io/api/core/v1"
1315 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
16+ "k8s.io/apimachinery/pkg/runtime"
17+ utilruntime "k8s.io/apimachinery/pkg/util/runtime"
1418 "k8s.io/apiserver/pkg/storage/names"
19+ clientgoscheme "k8s.io/client-go/kubernetes/scheme"
20+ clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
1521 runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1"
1622
1723 "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/api/v1alpha1"
@@ -32,6 +38,10 @@ func TestMirrorsPatch(t *testing.T) {
3238}
3339
3440var _ = Describe ("Generate Global mirror patches" , func () {
41+ clientScheme := runtime .NewScheme ()
42+ utilruntime .Must (clientgoscheme .AddToScheme (clientScheme ))
43+ utilruntime .Must (clusterv1 .AddToScheme (clientScheme ))
44+
3545 patchGenerator := func () mutation.GeneratePatches {
3646 // Always initialize the testEnv variable in the closure.
3747 // This will allow ginkgo to initialize testEnv variable during test execution time.
@@ -40,7 +50,7 @@ var _ = Describe("Generate Global mirror patches", func() {
4050 // that are written by the tests.
4151 // Test cases writes credentials secret that the mutator handler reads.
4252 // Using direct client will enable reading it immediately.
43- client , err := testEnv .GetK8sClient ( )
53+ client , err := testEnv .GetK8sClientWithScheme ( clientScheme )
4454 gomega .Expect (err ).To (gomega .BeNil ())
4555 return mutation .NewMetaGeneratePatchesHandler ("" , client , NewPatch (client )).(mutation.GeneratePatches )
4656 }
@@ -330,11 +340,69 @@ var _ = Describe("Generate Global mirror patches", func() {
330340 },
331341 },
332342 },
343+ {
344+ Name : "files added in KubeadmControlPlaneTemplate for registry addon" ,
345+ Vars : []runtimehooksv1.Variable {
346+ capitest .VariableWithValue (
347+ v1alpha1 .ClusterConfigVariableName ,
348+ v1alpha1.RegistryAddon {},
349+ []string {"addons" , v1alpha1 .RegistryAddonVariableName }... ,
350+ ),
351+ },
352+ RequestItem : request .NewKubeadmControlPlaneTemplateRequestItem ("" ),
353+ ExpectedPatchMatchers : []capitest.JSONPatchMatcher {
354+ {
355+ Operation : "add" ,
356+ Path : "/spec/template/spec/kubeadmConfigSpec/files" ,
357+ ValueMatcher : gomega .HaveExactElements (
358+ gomega .HaveKeyWithValue (
359+ "path" , "/etc/containerd/certs.d/_default/hosts.toml" ,
360+ ),
361+ gomega .HaveKeyWithValue (
362+ "path" , "/etc/caren/containerd/patches/registry-config.toml" ,
363+ ),
364+ ),
365+ },
366+ },
367+ },
368+ {
369+ Name : "files added in KubeadmConfigTemplate for registry addon" ,
370+ Vars : []runtimehooksv1.Variable {
371+ capitest .VariableWithValue (
372+ v1alpha1 .ClusterConfigVariableName ,
373+ v1alpha1.RegistryAddon {},
374+ []string {"addons" , v1alpha1 .RegistryAddonVariableName }... ,
375+ ),
376+ capitest .VariableWithValue (
377+ "builtin" ,
378+ map [string ]any {
379+ "machineDeployment" : map [string ]any {
380+ "class" : names .SimpleNameGenerator .GenerateName ("worker-" ),
381+ },
382+ },
383+ ),
384+ },
385+ RequestItem : request .NewKubeadmConfigTemplateRequestItem ("" ),
386+ ExpectedPatchMatchers : []capitest.JSONPatchMatcher {
387+ {
388+ Operation : "add" ,
389+ Path : "/spec/template/spec/files" ,
390+ ValueMatcher : gomega .HaveExactElements (
391+ gomega .HaveKeyWithValue (
392+ "path" , "/etc/containerd/certs.d/_default/hosts.toml" ,
393+ ),
394+ gomega .HaveKeyWithValue (
395+ "path" , "/etc/caren/containerd/patches/registry-config.toml" ,
396+ ),
397+ ),
398+ },
399+ },
400+ },
333401 }
334402
335403 // Create credentials secret before each test
336404 BeforeEach (func (ctx SpecContext ) {
337- client , err := helpers .TestEnv .GetK8sClient ( )
405+ client , err := helpers .TestEnv .GetK8sClientWithScheme ( clientScheme )
338406 gomega .Expect (err ).To (gomega .BeNil ())
339407 gomega .Expect (client .Create (
340408 ctx ,
@@ -344,11 +412,28 @@ var _ = Describe("Generate Global mirror patches", func() {
344412 ctx ,
345413 newMirrorSecretWithoutCA (validMirrorNoCASecretName , request .Namespace ),
346414 )).To (gomega .BeNil ())
415+
416+ gomega .Expect (client .Create (
417+ ctx ,
418+ & clusterv1.Cluster {
419+ ObjectMeta : metav1.ObjectMeta {
420+ Name : request .ClusterName ,
421+ Namespace : request .Namespace ,
422+ },
423+ Spec : clusterv1.ClusterSpec {
424+ ClusterNetwork : & clusterv1.ClusterNetwork {
425+ Services : & clusterv1.NetworkRanges {
426+ CIDRBlocks : []string {"192.168.0.1/16" },
427+ },
428+ },
429+ },
430+ },
431+ )).To (gomega .BeNil ())
347432 })
348433
349434 // Delete credentials secret after each test
350435 AfterEach (func (ctx SpecContext ) {
351- client , err := helpers .TestEnv .GetK8sClient ( )
436+ client , err := helpers .TestEnv .GetK8sClientWithScheme ( clientScheme )
352437 gomega .Expect (err ).To (gomega .BeNil ())
353438 gomega .Expect (client .Delete (
354439 ctx ,
@@ -358,6 +443,16 @@ var _ = Describe("Generate Global mirror patches", func() {
358443 ctx ,
359444 newMirrorSecretWithoutCA (validMirrorNoCASecretName , request .Namespace ),
360445 )).To (gomega .BeNil ())
446+
447+ gomega .Expect (client .Delete (
448+ ctx ,
449+ & clusterv1.Cluster {
450+ ObjectMeta : metav1.ObjectMeta {
451+ Name : request .ClusterName ,
452+ Namespace : request .Namespace ,
453+ },
454+ },
455+ )).To (gomega .BeNil ())
361456 })
362457
363458 // create test node for each case
@@ -406,6 +501,67 @@ func newMirrorSecretWithoutCA(name, namespace string) *corev1.Secret {
406501 }
407502}
408503
504+ func Test_containerdConfigFromRegistryAddon (t * testing.T ) {
505+ t .Parallel ()
506+ tests := []struct {
507+ name string
508+ cluster * clusterv1.Cluster
509+ want containerdConfig
510+ wantErr error
511+ }{
512+ {
513+ name : "valid input" ,
514+ cluster : & clusterv1.Cluster {
515+ ObjectMeta : metav1.ObjectMeta {
516+ Name : request .ClusterName ,
517+ Namespace : request .Namespace ,
518+ },
519+ Spec : clusterv1.ClusterSpec {
520+ ClusterNetwork : & clusterv1.ClusterNetwork {
521+ Services : & clusterv1.NetworkRanges {
522+ CIDRBlocks : []string {"192.168.0.1/16" },
523+ },
524+ },
525+ },
526+ },
527+ want : containerdConfig {
528+ URL : "http://192.168.0.20" ,
529+ Mirror : true ,
530+ },
531+ },
532+ {
533+ name : "missing Services CIDR" ,
534+ cluster : & clusterv1.Cluster {
535+ ObjectMeta : metav1.ObjectMeta {
536+ Name : request .ClusterName ,
537+ Namespace : request .Namespace ,
538+ },
539+ Spec : clusterv1.ClusterSpec {
540+ ClusterNetwork : & clusterv1.ClusterNetwork {},
541+ },
542+ },
543+ wantErr : fmt .Errorf (
544+ "error getting service IP for the registry addon: " +
545+ "error getting a service IP for a cluster: " +
546+ "unexpected empty service Subnets" ,
547+ ),
548+ },
549+ }
550+ for idx := range tests {
551+ tt := tests [idx ]
552+ t .Run (tt .name , func (t * testing.T ) {
553+ t .Parallel ()
554+ got , err := containerdConfigFromRegistryAddon (tt .cluster )
555+ if tt .wantErr != nil {
556+ require .EqualError (t , err , tt .wantErr .Error ())
557+ } else {
558+ require .NoError (t , err )
559+ }
560+ assert .Equal (t , tt .want , got )
561+ })
562+ }
563+ }
564+
409565func Test_needContainerdConfiguration (t * testing.T ) {
410566 t .Parallel ()
411567 tests := []struct {
0 commit comments