github.com/ironcore-dev/gardener-extension-provider-ironcore@v0.3.2-0.20240314231816-8336447fb9a0/pkg/controller/controlplane/suite_test.go (about) 1 // SPDX-FileCopyrightText: 2022 SAP SE or an SAP affiliate company and IronCore contributors 2 // SPDX-License-Identifier: Apache-2.0 3 4 package controlplane 5 6 import ( 7 "context" 8 "encoding/json" 9 "path/filepath" 10 "testing" 11 "time" 12 13 "github.com/gardener/gardener/pkg/apis/core/v1beta1" 14 extensionsv1alpha1 "github.com/gardener/gardener/pkg/apis/extensions/v1alpha1" 15 "github.com/ironcore-dev/controller-utils/buildutils" 16 "github.com/ironcore-dev/controller-utils/modutils" 17 storagev1alpha1 "github.com/ironcore-dev/ironcore/api/storage/v1alpha1" 18 utilsenvtest "github.com/ironcore-dev/ironcore/utils/envtest" 19 "github.com/ironcore-dev/ironcore/utils/envtest/apiserver" 20 . "github.com/onsi/ginkgo/v2" 21 . "github.com/onsi/gomega" 22 corev1 "k8s.io/api/core/v1" 23 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 24 "k8s.io/apimachinery/pkg/runtime" 25 "k8s.io/apimachinery/pkg/runtime/serializer" 26 "k8s.io/client-go/kubernetes/scheme" 27 "k8s.io/client-go/rest" 28 "k8s.io/utils/ptr" 29 "sigs.k8s.io/controller-runtime/pkg/client" 30 "sigs.k8s.io/controller-runtime/pkg/envtest" 31 "sigs.k8s.io/controller-runtime/pkg/envtest/komega" 32 logf "sigs.k8s.io/controller-runtime/pkg/log" 33 "sigs.k8s.io/controller-runtime/pkg/log/zap" 34 "sigs.k8s.io/controller-runtime/pkg/manager" 35 metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" 36 "sigs.k8s.io/controller-runtime/pkg/webhook" 37 38 ironcoreextensionv1alpha1 "github.com/ironcore-dev/gardener-extension-provider-ironcore/pkg/apis/ironcore/v1alpha1" 39 ) 40 41 const ( 42 pollingInterval = 50 * time.Millisecond 43 eventuallyTimeout = 10 * time.Second 44 consistentlyDuration = 1 * time.Second 45 apiServiceTimeout = 5 * time.Minute 46 ) 47 48 var ( 49 testEnv *envtest.Environment 50 testEnvExt *utilsenvtest.EnvironmentExtensions 51 cfg *rest.Config 52 k8sClient client.Client 53 ) 54 55 func TestAPIs(t *testing.T) { 56 SetDefaultConsistentlyPollingInterval(pollingInterval) 57 SetDefaultEventuallyPollingInterval(pollingInterval) 58 SetDefaultEventuallyTimeout(eventuallyTimeout) 59 SetDefaultConsistentlyDuration(consistentlyDuration) 60 61 RegisterFailHandler(Fail) 62 RunSpecs(t, "Infrastructure Controller Suite") 63 } 64 65 var _ = BeforeSuite(func() { 66 logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) 67 68 var err error 69 70 By("bootstrapping test environment") 71 testEnv = &envtest.Environment{ 72 CRDDirectoryPaths: []string{ 73 filepath.Join("..", "..", "..", "example", "20-crd-resources.gardener.cloud_managedresources.yaml"), 74 filepath.Join("..", "..", "..", "example", "20-crd-extensions.gardener.cloud_clusters.yaml"), 75 filepath.Join("..", "..", "..", "example", "20-crd-extensions.gardener.cloud_infrastructures.yaml"), 76 filepath.Join("..", "..", "..", "example", "20-crd-extensions.gardener.cloud_controlplanes.yaml"), 77 }, 78 ErrorIfCRDPathMissing: true, 79 } 80 81 testEnvExt = &utilsenvtest.EnvironmentExtensions{ 82 APIServiceDirectoryPaths: []string{ 83 modutils.Dir("github.com/ironcore-dev/ironcore", "config", "apiserver", "apiservice", "bases"), 84 }, 85 ErrorIfAPIServicePathIsMissing: true, 86 } 87 88 cfg, err = utilsenvtest.StartWithExtensions(testEnv, testEnvExt) 89 Expect(err).NotTo(HaveOccurred()) 90 Expect(cfg).NotTo(BeNil()) 91 DeferCleanup(utilsenvtest.StopWithExtensions, testEnv, testEnvExt) 92 93 Expect(extensionsv1alpha1.AddToScheme(scheme.Scheme)).To(Succeed()) 94 Expect(ironcoreextensionv1alpha1.AddToScheme(scheme.Scheme)).To(Succeed()) 95 Expect(corev1.AddToScheme(scheme.Scheme)).To(Succeed()) 96 Expect(storagev1alpha1.AddToScheme(scheme.Scheme)).To(Succeed()) 97 98 // Init package-level k8sClient 99 k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) 100 Expect(err).NotTo(HaveOccurred()) 101 Expect(k8sClient).NotTo(BeNil()) 102 103 komega.SetClient(k8sClient) 104 105 apiSrv, err := apiserver.New(cfg, apiserver.Options{ 106 MainPath: "github.com/ironcore-dev/ironcore/cmd/ironcore-apiserver", 107 BuildOptions: []buildutils.BuildOption{buildutils.ModModeMod}, 108 ETCDServers: []string{testEnv.ControlPlane.Etcd.URL.String()}, 109 Host: testEnvExt.APIServiceInstallOptions.LocalServingHost, 110 Port: testEnvExt.APIServiceInstallOptions.LocalServingPort, 111 CertDir: testEnvExt.APIServiceInstallOptions.LocalServingCertDir, 112 }) 113 Expect(err).NotTo(HaveOccurred()) 114 115 Expect(apiSrv.Start()).To(Succeed()) 116 DeferCleanup(apiSrv.Stop) 117 118 err = utilsenvtest.WaitUntilAPIServicesReadyWithTimeout(apiServiceTimeout, testEnvExt, k8sClient, scheme.Scheme) 119 Expect(err).NotTo(HaveOccurred()) 120 }) 121 122 func SetupTest() (*corev1.Namespace, *valuesProvider, *extensionsv1alpha1.Cluster) { 123 var ( 124 namespace = &corev1.Namespace{} 125 cluster = &extensionsv1alpha1.Cluster{} 126 vp = &valuesProvider{} 127 ) 128 129 BeforeEach(func(ctx SpecContext) { 130 var mgrCtx context.Context 131 mgrCtx, cancel := context.WithCancel(context.Background()) 132 DeferCleanup(cancel) 133 134 *namespace = corev1.Namespace{ 135 ObjectMeta: metav1.ObjectMeta{ 136 GenerateName: "testns-", 137 }, 138 } 139 Expect(k8sClient.Create(ctx, namespace)).To(Succeed(), "failed to create test namespace") 140 DeferCleanup(k8sClient.Delete, namespace) 141 142 shoot := v1beta1.Shoot{ 143 ObjectMeta: metav1.ObjectMeta{ 144 Namespace: namespace.Name, 145 Name: "foo", 146 }, 147 Spec: v1beta1.ShootSpec{ 148 Kubernetes: v1beta1.Kubernetes{ 149 Version: "1.26.0", 150 }, 151 Region: "foo", 152 Provider: v1beta1.Provider{ 153 Workers: []v1beta1.Worker{ 154 {Name: "foo"}, 155 {Name: "bar"}, 156 }, 157 }, 158 Networking: &v1beta1.Networking{ 159 Nodes: ptr.To[string]("10.0.0.0/24"), 160 }, 161 }, 162 } 163 shootJson, err := json.Marshal(shoot) 164 Expect(err).NotTo(HaveOccurred()) 165 166 *cluster = extensionsv1alpha1.Cluster{ 167 ObjectMeta: metav1.ObjectMeta{ 168 Name: namespace.Name, 169 }, 170 Spec: extensionsv1alpha1.ClusterSpec{ 171 CloudProfile: runtime.RawExtension{Raw: []byte("{}")}, 172 Seed: runtime.RawExtension{Raw: []byte("{}")}, 173 Shoot: runtime.RawExtension{Raw: shootJson}, 174 }, 175 } 176 Expect(k8sClient.Create(ctx, cluster)).Should(Succeed()) 177 DeferCleanup(k8sClient.Delete, cluster) 178 179 mgr, err := manager.New(cfg, manager.Options{ 180 Scheme: scheme.Scheme, 181 Metrics: metricsserver.Options{BindAddress: "0"}, 182 WebhookServer: &webhook.DefaultServer{Options: webhook.Options{ 183 CertDir: testEnv.WebhookInstallOptions.LocalServingCertDir, 184 }}, 185 }) 186 Expect(err).NotTo(HaveOccurred()) 187 188 secret := &corev1.Secret{ 189 ObjectMeta: metav1.ObjectMeta{ 190 Namespace: namespace.Name, 191 Name: "my-infra-creds", 192 }, 193 Data: map[string][]byte{ 194 "namespace": []byte(namespace.Name), 195 "token": []byte("foo"), 196 }, 197 } 198 Expect(k8sClient.Create(ctx, secret)).To(Succeed()) 199 200 user, err := testEnv.AddUser(envtest.User{ 201 Name: "dummy", 202 Groups: []string{"system:authenticated", "system:masters"}, 203 }, cfg) 204 Expect(err).NotTo(HaveOccurred()) 205 206 kubeconfig, err := user.KubeConfig() 207 Expect(err).NotTo(HaveOccurred()) 208 209 By("creating a test cloudprovider secret") 210 cloudproviderSecret := &corev1.Secret{ 211 ObjectMeta: metav1.ObjectMeta{ 212 Namespace: namespace.Name, 213 Name: "cloudprovider", 214 }, 215 Data: map[string][]byte{ 216 "namespace": []byte(namespace.Name), 217 "token": []byte("foo"), 218 "kubeconfig": kubeconfig, 219 }, 220 } 221 Expect(k8sClient.Create(ctx, cloudproviderSecret)).To(Succeed()) 222 DeferCleanup(k8sClient.Delete, cloudproviderSecret) 223 224 Expect(AddToManagerWithOptions(mgrCtx, mgr, AddOptions{ 225 IgnoreOperationAnnotation: true, 226 })).NotTo(HaveOccurred()) 227 228 *vp = valuesProvider{ 229 client: mgr.GetClient(), 230 decoder: serializer.NewCodecFactory(mgr.GetScheme(), serializer.EnableStrict).UniversalDecoder(), 231 } 232 233 go func() { 234 defer GinkgoRecover() 235 Expect(mgr.Start(mgrCtx)).To(Succeed(), "failed to start manager") 236 }() 237 }) 238 239 return namespace, vp, cluster 240 }