@@ -286,4 +286,239 @@ var _ = Describe("DevWorkspace Controller", func() {
286286 })
287287
288288 })
289+
290+ Context ("Automatic provisioning" , func () {
291+ const testURL = "test-url"
292+
293+ BeforeEach (func () {
294+ workspacecontroller .SetupHttpClientsForTesting (& http.Client {
295+ Transport : & testutil.TestRoundTripper {
296+ Data : map [string ]testutil.TestResponse {
297+ fmt .Sprintf ("%s/healthz" , testURL ): {
298+ StatusCode : http .StatusOK ,
299+ },
300+ },
301+ },
302+ })
303+ createDevWorkspace ("test-devworkspace.yaml" )
304+ })
305+
306+ AfterEach (func () {
307+ deleteDevWorkspace (devWorkspaceName )
308+ workspacecontroller .SetupHttpClientsForTesting (getBasicTestHttpClient ())
309+ })
310+
311+ It ("Mounts image pull secrets to the DevWorkspace Deployment" , func () {
312+ devworkspace := getExistingDevWorkspace ()
313+ workspaceID := devworkspace .Status .DevWorkspaceId
314+
315+ By ("Creating secrets for docker configs" )
316+ dockerCfgSecretName := "test-dockercfg"
317+ dockerCfg := generateSecret (dockerCfgSecretName , corev1 .SecretTypeDockercfg )
318+ dockerCfg .Labels [constants .DevWorkspacePullSecretLabel ] = "true"
319+ dockerCfg .Data [".dockercfg" ] = []byte ("{}" )
320+ createObject (dockerCfg )
321+ defer deleteObject (dockerCfg )
322+
323+ dockerCfgSecretJsonName := "test-dockercfg-json"
324+ dockerCfgJson := generateSecret (dockerCfgSecretJsonName , corev1 .SecretTypeDockerConfigJson )
325+ dockerCfgJson .Labels [constants .DevWorkspacePullSecretLabel ] = "true"
326+ dockerCfgJson .Data [".dockerconfigjson" ] = []byte ("{}" )
327+ createObject (dockerCfgJson )
328+ defer deleteObject (dockerCfgJson )
329+
330+ By ("Manually making Routing ready to continue" )
331+ markRoutingReady (testURL , common .DevWorkspaceRoutingName (workspaceID ))
332+
333+ deploy := & appsv1.Deployment {}
334+ deployNN := types.NamespacedName {
335+ Name : common .DeploymentName (workspaceID ),
336+ Namespace : testNamespace ,
337+ }
338+ Eventually (func () error {
339+ return k8sClient .Get (ctx , deployNN , deploy )
340+ }, timeout , interval ).Should (Succeed (), "Getting workspace deployment from cluster" )
341+
342+ Expect (deploy .Spec .Template .Spec .ImagePullSecrets ).Should (ContainElement (corev1.LocalObjectReference {Name : dockerCfgSecretName }))
343+ Expect (deploy .Spec .Template .Spec .ImagePullSecrets ).Should (ContainElement (corev1.LocalObjectReference {Name : dockerCfgSecretJsonName }))
344+ })
345+
346+ It ("Manages git credentials for DevWorkspace" , func () {
347+ devworkspace := getExistingDevWorkspace ()
348+ workspaceID := devworkspace .Status .DevWorkspaceId
349+
350+ By ("Creating a secret for git credentials" )
351+ gitCredentialsSecretName := "test-git-credentials"
352+ gitCredentials := generateSecret (gitCredentialsSecretName , corev1 .SecretTypeOpaque )
353+ gitCredentials .Labels [constants .DevWorkspaceGitCredentialLabel ] = "true"
354+ gitCredentials .Annotations [constants .DevWorkspaceMountPathAnnotation ] = "/test/path"
355+ gitCredentials .
Data [
"credentials" ]
= []
byte (
"https://username:[email protected] " )
356+
357+ createObject (gitCredentials )
358+ defer deleteObject (gitCredentials )
359+
360+ By ("Manually making Routing ready to continue" )
361+ markRoutingReady (testURL , common .DevWorkspaceRoutingName (workspaceID ))
362+
363+ deploy := & appsv1.Deployment {}
364+ deployNN := types.NamespacedName {
365+ Name : common .DeploymentName (workspaceID ),
366+ Namespace : testNamespace ,
367+ }
368+ Eventually (func () error {
369+ return k8sClient .Get (ctx , deployNN , deploy )
370+ }, timeout , interval ).Should (Succeed (), "Getting workspace deployment from cluster" )
371+
372+ modeReadOnly := int32 (0640 )
373+ gitconfigVolumeName := common .AutoMountConfigMapVolumeName ("devworkspace-gitconfig" )
374+ gitconfigVolume := corev1.Volume {
375+ Name : gitconfigVolumeName ,
376+ VolumeSource : corev1.VolumeSource {
377+ ConfigMap : & corev1.ConfigMapVolumeSource {
378+ LocalObjectReference : corev1.LocalObjectReference {Name : "devworkspace-gitconfig" },
379+ DefaultMode : & modeReadOnly ,
380+ },
381+ },
382+ }
383+ gitConfigVolumeMount := corev1.VolumeMount {
384+ Name : gitconfigVolumeName ,
385+ ReadOnly : false ,
386+ MountPath : "/etc/gitconfig" ,
387+ SubPath : "gitconfig" ,
388+ }
389+ gitCredentialsVolumeName := common .AutoMountSecretVolumeName ("devworkspace-merged-git-credentials" )
390+ gitCredentialsVolume := corev1.Volume {
391+ Name : gitCredentialsVolumeName ,
392+ VolumeSource : corev1.VolumeSource {
393+ Secret : & corev1.SecretVolumeSource {
394+ SecretName : "devworkspace-merged-git-credentials" ,
395+ DefaultMode : & modeReadOnly ,
396+ },
397+ },
398+ }
399+ gitCredentialsVolumeMount := corev1.VolumeMount {
400+ Name : gitCredentialsVolumeName ,
401+ ReadOnly : true ,
402+ MountPath : "/test/path/credentials" ,
403+ SubPath : "credentials" ,
404+ }
405+
406+ volumes := deploy .Spec .Template .Spec .Volumes
407+ Expect (volumes ).Should (ContainElements (gitconfigVolume , gitCredentialsVolume ), "Git credentials should be mounted as volumes in Deployment" )
408+ for _ , container := range deploy .Spec .Template .Spec .Containers {
409+ Expect (container .VolumeMounts ).Should (ContainElements (gitConfigVolumeMount , gitCredentialsVolumeMount ))
410+ }
411+ })
412+
413+ It ("Automounts secrets and configmaps volumes" , func () {
414+ devworkspace := getExistingDevWorkspace ()
415+ workspaceID := devworkspace .Status .DevWorkspaceId
416+
417+ By ("Creating a automount secrets and configmaps" )
418+ fileCM := generateConfigMap ("file-cm" )
419+ fileCM .Labels [constants .DevWorkspaceMountLabel ] = "true"
420+ fileCM .Annotations [constants .DevWorkspaceMountPathAnnotation ] = "/file/cm"
421+ createObject (fileCM )
422+ defer deleteObject (fileCM )
423+
424+ subpathCM := generateConfigMap ("subpath-cm" )
425+ subpathCM .Labels [constants .DevWorkspaceMountLabel ] = "true"
426+ subpathCM .Annotations [constants .DevWorkspaceMountPathAnnotation ] = "/subpath/cm"
427+ subpathCM .Annotations [constants .DevWorkspaceMountAsAnnotation ] = "subpath"
428+ subpathCM .Data ["testdata1" ] = "testValue"
429+ subpathCM .Data ["testdata2" ] = "testValue"
430+ createObject (subpathCM )
431+ defer deleteObject (subpathCM )
432+
433+ fileSecret := generateSecret ("file-secret" , corev1 .SecretTypeOpaque )
434+ fileSecret .Labels [constants .DevWorkspaceMountLabel ] = "true"
435+ fileSecret .Annotations [constants .DevWorkspaceMountPathAnnotation ] = "/file/secret"
436+ createObject (fileSecret )
437+ defer deleteObject (fileSecret )
438+
439+ subpathSecret := generateSecret ("subpath-secret" , corev1 .SecretTypeOpaque )
440+ subpathSecret .Labels [constants .DevWorkspaceMountLabel ] = "true"
441+ subpathSecret .Annotations [constants .DevWorkspaceMountPathAnnotation ] = "/subpath/secret"
442+ subpathSecret .Annotations [constants .DevWorkspaceMountAsAnnotation ] = "subpath"
443+ subpathSecret .Data ["testsecret" ] = []byte ("testValue" )
444+ createObject (subpathSecret )
445+ defer deleteObject (subpathSecret )
446+
447+ By ("Manually making Routing ready to continue" )
448+ markRoutingReady (testURL , common .DevWorkspaceRoutingName (workspaceID ))
449+
450+ deploy := & appsv1.Deployment {}
451+ deployNN := types.NamespacedName {
452+ Name : common .DeploymentName (workspaceID ),
453+ Namespace : testNamespace ,
454+ }
455+ Eventually (func () error {
456+ return k8sClient .Get (ctx , deployNN , deploy )
457+ }, timeout , interval ).Should (Succeed (), "Getting workspace deployment from cluster" )
458+
459+ expectedAutomountVolumes := []corev1.Volume {
460+ volumeFromConfigMap (fileCM ),
461+ volumeFromConfigMap (subpathCM ),
462+ volumeFromSecret (fileSecret ),
463+ volumeFromSecret (subpathSecret ),
464+ }
465+ Expect (deploy .Spec .Template .Spec .Volumes ).Should (ContainElements (expectedAutomountVolumes ), "Automount volumes should be added to deployment" )
466+ expectedAutomountVolumeMounts := []corev1.VolumeMount {
467+ volumeMountFromConfigMap (fileCM , "/file/cm" , "" ),
468+ volumeMountFromConfigMap (subpathCM , "/subpath/cm" , "testdata1" ),
469+ volumeMountFromConfigMap (subpathCM , "/subpath/cm" , "testdata2" ),
470+ volumeMountFromSecret (fileSecret , "/file/secret" , "" ),
471+ volumeMountFromSecret (subpathSecret , "/subpath/secret" , "testsecret" ),
472+ }
473+ for _ , container := range deploy .Spec .Template .Spec .Containers {
474+ Expect (container .VolumeMounts ).Should (ContainElements (expectedAutomountVolumeMounts ), "Automount volumeMounts should be added to all containers" )
475+ }
476+ })
477+
478+ It ("Automounts secrets and configmaps env vars" , func () {
479+ devworkspace := getExistingDevWorkspace ()
480+ workspaceID := devworkspace .Status .DevWorkspaceId
481+
482+ By ("Creating a automount secrets and configmaps" )
483+ cm := generateConfigMap ("env-cm" )
484+ cm .Labels [constants .DevWorkspaceMountLabel ] = "true"
485+ cm .Annotations [constants .DevWorkspaceMountAsAnnotation ] = "env"
486+ createObject (cm )
487+ defer deleteObject (cm )
488+
489+ secret := generateSecret ("env-secret" , corev1 .SecretTypeOpaque )
490+ secret .Labels [constants .DevWorkspaceMountLabel ] = "true"
491+ secret .Annotations [constants .DevWorkspaceMountAsAnnotation ] = "env"
492+ createObject (secret )
493+ defer deleteObject (secret )
494+
495+ By ("Manually making Routing ready to continue" )
496+ markRoutingReady (testURL , common .DevWorkspaceRoutingName (workspaceID ))
497+ deploy := & appsv1.Deployment {}
498+ deployNN := types.NamespacedName {
499+ Name : common .DeploymentName (workspaceID ),
500+ Namespace : testNamespace ,
501+ }
502+ Eventually (func () error {
503+ return k8sClient .Get (ctx , deployNN , deploy )
504+ }, timeout , interval ).Should (Succeed (), "Getting workspace deployment from cluster" )
505+
506+ expectedEnvFromSources := []corev1.EnvFromSource {
507+ {
508+ ConfigMapRef : & corev1.ConfigMapEnvSource {
509+ LocalObjectReference : corev1.LocalObjectReference {Name : cm .Name },
510+ },
511+ },
512+ {
513+ SecretRef : & corev1.SecretEnvSource {
514+ LocalObjectReference : corev1.LocalObjectReference {Name : secret .Name },
515+ },
516+ },
517+ }
518+ for _ , container := range deploy .Spec .Template .Spec .Containers {
519+ Expect (container .EnvFrom ).Should (ContainElements (expectedEnvFromSources ), "Automounted env sources should be added to containers" )
520+ }
521+ })
522+ })
523+
289524})
0 commit comments