| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033 |
- // +build kube
- /*
- Copyright 2020 Docker Compose CLI authors
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- package kubernetes
- import (
- "fmt"
- "os"
- "runtime"
- "testing"
- "github.com/compose-spec/compose-go/loader"
- "github.com/compose-spec/compose-go/types"
- "github.com/stretchr/testify/assert"
- apiv1 "k8s.io/api/core/v1"
- "k8s.io/apimachinery/pkg/api/resource"
- )
- func loadYAML(yaml string) (*types.Project, error) {
- dict, err := loader.ParseYAML([]byte(yaml))
- if err != nil {
- return nil, err
- }
- workingDir, err := os.Getwd()
- if err != nil {
- panic(err)
- }
- configs := []types.ConfigFile{
- {
- Filename: "test-compose.yaml",
- Config: dict,
- },
- }
- config := types.ConfigDetails{
- WorkingDir: workingDir,
- ConfigFiles: configs,
- Environment: nil,
- }
- return loader.Load(config)
- }
- func podTemplate(t *testing.T, yaml string) apiv1.PodTemplateSpec {
- res, err := podTemplateWithError(yaml)
- assert.NoError(t, err)
- return res
- }
- func podTemplateWithError(yaml string) (apiv1.PodTemplateSpec, error) {
- model, err := loadYAML(yaml)
- if err != nil {
- return apiv1.PodTemplateSpec{}, err
- }
- return toPodTemplate(model, model.Services[0], nil)
- }
- func TestToPodWithDockerSocket(t *testing.T) {
- if runtime.GOOS == "windows" {
- t.Skip("on windows, source path validation is broken (and actually, source validation for windows workload is broken too). Skip it for now, as we don't support it yet")
- return
- }
- podTemplate := podTemplate(t, `
- version: "3"
- services:
- redis:
- image: "redis:alpine"
- volumes:
- - "/var/run/docker.sock:/var/run/docker.sock"
- `)
- expectedVolume := apiv1.Volume{
- Name: "mount-0",
- VolumeSource: apiv1.VolumeSource{
- HostPath: &apiv1.HostPathVolumeSource{
- Path: "/var/run",
- },
- },
- }
- expectedMount := apiv1.VolumeMount{
- Name: "mount-0",
- MountPath: "/var/run/docker.sock",
- SubPath: "docker.sock",
- }
- assert.Len(t, podTemplate.Spec.Volumes, 1)
- assert.Len(t, podTemplate.Spec.Containers[0].VolumeMounts, 1)
- assert.Equal(t, expectedVolume, podTemplate.Spec.Volumes[0])
- assert.Equal(t, expectedMount, podTemplate.Spec.Containers[0].VolumeMounts[0])
- }
- func TestToPodWithFunkyCommand(t *testing.T) {
- podTemplate := podTemplate(t, `
- version: "3"
- services:
- redis:
- image: basi/node-exporter
- command: ["-collector.procfs", "/host/proc", "-collector.sysfs", "/host/sys"]
- `)
- expectedArgs := []string{
- `-collector.procfs`,
- `/host/proc`, // ?
- `-collector.sysfs`,
- `/host/sys`, // ?
- }
- assert.Equal(t, expectedArgs, podTemplate.Spec.Containers[0].Args)
- }
- /* FIXME
- func TestToPodWithGlobalVolume(t *testing.T) {
- podTemplate := podTemplate(t, `
- version: "3"
- services:
- db:
- image: "postgres:9.4"
- volumes:
- - dbdata:/var/lib/postgresql/data
- volumes:
- dbdata:
- `)
- expectedMount := apiv1.VolumeMount{
- Name: "dbdata",
- MountPath: "/var/lib/postgresql/data",
- }
- assert.Len(t, podTemplate.Spec.Volumes, 0)
- assert.Len(t, podTemplate.Spec.Containers[0].VolumeMounts, 1)
- assert.Equal(t, expectedMount, podTemplate.Spec.Containers[0].VolumeMounts[0])
- }
- */
- func TestToPodWithResources(t *testing.T) {
- podTemplate := podTemplate(t, `
- version: "3"
- services:
- db:
- image: "postgres:9.4"
- deploy:
- resources:
- limits:
- cpus: "0.001"
- memory: 50Mb
- reservations:
- cpus: "0.0001"
- memory: 20Mb
- `)
- expectedResourceRequirements := apiv1.ResourceRequirements{
- Limits: map[apiv1.ResourceName]resource.Quantity{
- apiv1.ResourceCPU: resource.MustParse("0.001"),
- apiv1.ResourceMemory: resource.MustParse(fmt.Sprintf("%d", 50*1024*1024)),
- },
- Requests: map[apiv1.ResourceName]resource.Quantity{
- apiv1.ResourceCPU: resource.MustParse("0.0001"),
- apiv1.ResourceMemory: resource.MustParse(fmt.Sprintf("%d", 20*1024*1024)),
- },
- }
- assert.Equal(t, expectedResourceRequirements, podTemplate.Spec.Containers[0].Resources)
- }
- func TestToPodWithCapabilities(t *testing.T) {
- podTemplate := podTemplate(t, `
- version: "3"
- services:
- redis:
- image: "redis:alpine"
- cap_add:
- - ALL
- cap_drop:
- - NET_ADMIN
- - SYS_ADMIN
- `)
- expectedSecurityContext := &apiv1.SecurityContext{
- Capabilities: &apiv1.Capabilities{
- Add: []apiv1.Capability{"ALL"},
- Drop: []apiv1.Capability{"NET_ADMIN", "SYS_ADMIN"},
- },
- }
- assert.Equal(t, expectedSecurityContext, podTemplate.Spec.Containers[0].SecurityContext)
- }
- func TestToPodWithReadOnly(t *testing.T) {
- podTemplate := podTemplate(t, `
- version: "3"
- services:
- redis:
- image: "redis:alpine"
- read_only: true
- `)
- yes := true
- expectedSecurityContext := &apiv1.SecurityContext{
- ReadOnlyRootFilesystem: &yes,
- }
- assert.Equal(t, expectedSecurityContext, podTemplate.Spec.Containers[0].SecurityContext)
- }
- func TestToPodWithPrivileged(t *testing.T) {
- podTemplate := podTemplate(t, `
- version: "3"
- services:
- redis:
- image: "redis:alpine"
- privileged: true
- `)
- yes := true
- expectedSecurityContext := &apiv1.SecurityContext{
- Privileged: &yes,
- }
- assert.Equal(t, expectedSecurityContext, podTemplate.Spec.Containers[0].SecurityContext)
- }
- func TestToPodWithEnvNilShouldErrorOut(t *testing.T) {
- _, err := podTemplateWithError(`
- version: "3"
- services:
- redis:
- image: "redis:alpine"
- environment:
- - SESSION_SECRET
- `)
- assert.Error(t, err)
- }
- func TestToPodWithEnv(t *testing.T) {
- podTemplate := podTemplate(t, `
- version: "3"
- services:
- redis:
- image: "redis:alpine"
- environment:
- - RACK_ENV=development
- - SHOW=true
- `)
- expectedEnv := []apiv1.EnvVar{
- {
- Name: "RACK_ENV",
- Value: "development",
- },
- {
- Name: "SHOW",
- Value: "true",
- },
- }
- assert.Equal(t, expectedEnv, podTemplate.Spec.Containers[0].Env)
- }
- func TestToPodWithVolume(t *testing.T) {
- if runtime.GOOS == "windows" {
- t.Skip("on windows, source path validation is broken (and actually, source validation for windows workload is broken too). Skip it for now, as we don't support it yet")
- return
- }
- podTemplate := podTemplate(t, `
- version: "3"
- services:
- nginx:
- image: nginx
- volumes:
- - /ignore:/ignore
- - /opt/data:/var/lib/mysql:ro
- `)
- assert.Len(t, podTemplate.Spec.Volumes, 2)
- assert.Len(t, podTemplate.Spec.Containers[0].VolumeMounts, 2)
- }
- /* FIXME
- func TestToPodWithRelativeVolumes(t *testing.T) {
- if runtime.GOOS == "windows" {
- t.Skip("on windows, source path validation is broken (and actually, source validation for windows workload is broken too). Skip it for now, as we don't support it yet")
- return
- }
- _, err := podTemplateWithError(`
- version: "3"
- services:
- nginx:
- image: nginx
- volumes:
- - ./fail:/ignore
- `)
- assert.Error(t, err)
- }
- */
- func TestToPodWithHealthCheck(t *testing.T) {
- podTemplate := podTemplate(t, `
- version: "3"
- services:
- nginx:
- image: nginx
- healthcheck:
- test: ["CMD", "curl", "-f", "http://localhost"]
- interval: 90s
- timeout: 10s
- retries: 3
- `)
- expectedLivenessProbe := &apiv1.Probe{
- TimeoutSeconds: 10,
- PeriodSeconds: 90,
- FailureThreshold: 3,
- Handler: apiv1.Handler{
- Exec: &apiv1.ExecAction{
- Command: []string{"curl", "-f", "http://localhost"},
- },
- },
- }
- assert.Equal(t, expectedLivenessProbe, podTemplate.Spec.Containers[0].LivenessProbe)
- }
- func TestToPodWithShellHealthCheck(t *testing.T) {
- podTemplate := podTemplate(t, `
- version: "3"
- services:
- nginx:
- image: nginx
- healthcheck:
- test: ["CMD-SHELL", "curl -f http://localhost"]
- `)
- expectedLivenessProbe := &apiv1.Probe{
- TimeoutSeconds: 1,
- PeriodSeconds: 1,
- FailureThreshold: 3,
- Handler: apiv1.Handler{
- Exec: &apiv1.ExecAction{
- Command: []string{"sh", "-c", "curl -f http://localhost"},
- },
- },
- }
- assert.Equal(t, expectedLivenessProbe, podTemplate.Spec.Containers[0].LivenessProbe)
- }
- /* FIXME
- func TestToPodWithTargetlessExternalSecret(t *testing.T) {
- podTemplate := podTemplate(t, `
- version: "3"
- services:
- nginx:
- image: nginx
- secrets:
- - my_secret
- `)
- expectedVolume := apiv1.Volume{
- Name: "secret-0",
- VolumeSource: apiv1.VolumeSource{
- Secret: &apiv1.SecretVolumeSource{
- SecretName: "my_secret",
- Items: []apiv1.KeyToPath{
- {
- Key: "file", // TODO: This is the key we assume external secrets use
- Path: "secret-0",
- },
- },
- },
- },
- }
- expectedMount := apiv1.VolumeMount{
- Name: "secret-0",
- ReadOnly: true,
- MountPath: "/run/secrets/my_secret",
- SubPath: "secret-0",
- }
- assert.Len(t, podTemplate.Spec.Volumes, 1)
- assert.Len(t, podTemplate.Spec.Containers[0].VolumeMounts, 1)
- assert.Equal(t, expectedVolume, podTemplate.Spec.Volumes[0])
- assert.Equal(t, expectedMount, podTemplate.Spec.Containers[0].VolumeMounts[0])
- }
- */
- /* FIXME
- func TestToPodWithExternalSecret(t *testing.T) {
- podTemplate := podTemplate(t, `
- version: "3"
- services:
- nginx:
- image: nginx
- secrets:
- - source: my_secret
- target: nginx_secret
- `)
- expectedVolume := apiv1.Volume{
- Name: "secret-0",
- VolumeSource: apiv1.VolumeSource{
- Secret: &apiv1.SecretVolumeSource{
- SecretName: "my_secret",
- Items: []apiv1.KeyToPath{
- {
- Key: "file", // TODO: This is the key we assume external secrets use
- Path: "secret-0",
- },
- },
- },
- },
- }
- expectedMount := apiv1.VolumeMount{
- Name: "secret-0",
- ReadOnly: true,
- MountPath: "/run/secrets/nginx_secret",
- SubPath: "secret-0",
- }
- assert.Len(t, podTemplate.Spec.Volumes, 1)
- assert.Len(t, podTemplate.Spec.Containers[0].VolumeMounts, 1)
- assert.Equal(t, expectedVolume, podTemplate.Spec.Volumes[0])
- assert.Equal(t, expectedMount, podTemplate.Spec.Containers[0].VolumeMounts[0])
- }
- */
- /* FIXME
- func TestToPodWithFileBasedSecret(t *testing.T) {
- podTemplate := podTemplate(t, `
- version: "3"
- services:
- nginx:
- image: nginx
- secrets:
- - source: my_secret
- secrets:
- my_secret:
- file: ./secret.txt
- `)
- expectedVolume := apiv1.Volume{
- Name: "secret-0",
- VolumeSource: apiv1.VolumeSource{
- Secret: &apiv1.SecretVolumeSource{
- SecretName: "my_secret",
- Items: []apiv1.KeyToPath{
- {
- Key: "secret.txt",
- Path: "secret-0",
- },
- },
- },
- },
- }
- expectedMount := apiv1.VolumeMount{
- Name: "secret-0",
- ReadOnly: true,
- MountPath: "/run/secrets/my_secret",
- SubPath: "secret-0",
- }
- assert.Len(t, podTemplate.Spec.Volumes, 1)
- assert.Len(t, podTemplate.Spec.Containers[0].VolumeMounts, 1)
- assert.Equal(t, expectedVolume, podTemplate.Spec.Volumes[0])
- assert.Equal(t, expectedMount, podTemplate.Spec.Containers[0].VolumeMounts[0])
- }
- */
- /* FIXME
- func TestToPodWithTwoFileBasedSecrets(t *testing.T) {
- podTemplate := podTemplate(t, `
- version: "3"
- services:
- nginx:
- image: nginx
- secrets:
- - source: my_secret1
- - source: my_secret2
- target: secret2
- secrets:
- my_secret1:
- file: ./secret1.txt
- my_secret2:
- file: ./secret2.txt
- `)
- expectedVolumes := []apiv1.Volume{
- {
- Name: "secret-0",
- VolumeSource: apiv1.VolumeSource{
- Secret: &apiv1.SecretVolumeSource{
- SecretName: "my_secret1",
- Items: []apiv1.KeyToPath{
- {
- Key: "secret1.txt",
- Path: "secret-0",
- },
- },
- },
- },
- },
- {
- Name: "secret-1",
- VolumeSource: apiv1.VolumeSource{
- Secret: &apiv1.SecretVolumeSource{
- SecretName: "my_secret2",
- Items: []apiv1.KeyToPath{
- {
- Key: "secret2.txt",
- Path: "secret-1",
- },
- },
- },
- },
- },
- }
- expectedMounts := []apiv1.VolumeMount{
- {
- Name: "secret-0",
- ReadOnly: true,
- MountPath: "/run/secrets/my_secret1",
- SubPath: "secret-0",
- },
- {
- Name: "secret-1",
- ReadOnly: true,
- MountPath: "/run/secrets/secret2",
- SubPath: "secret-1",
- },
- }
- assert.Equal(t, expectedVolumes, podTemplate.Spec.Volumes)
- assert.Equal(t, expectedMounts, podTemplate.Spec.Containers[0].VolumeMounts)
- }
- */
- func TestToPodWithTerminationGracePeriod(t *testing.T) {
- podTemplate := podTemplate(t, `
- version: "3"
- services:
- redis:
- image: "redis:alpine"
- stop_grace_period: 100s
- `)
- expected := int64(100)
- assert.Equal(t, &expected, podTemplate.Spec.TerminationGracePeriodSeconds)
- }
- func TestToPodWithTmpfs(t *testing.T) {
- podTemplate := podTemplate(t, `
- version: "3"
- services:
- redis:
- image: "redis:alpine"
- tmpfs:
- - /tmp
- `)
- expectedVolume := apiv1.Volume{
- Name: "tmp-0",
- VolumeSource: apiv1.VolumeSource{
- EmptyDir: &apiv1.EmptyDirVolumeSource{
- Medium: "Memory",
- },
- },
- }
- expectedMount := apiv1.VolumeMount{
- Name: "tmp-0",
- MountPath: "/tmp",
- }
- assert.Len(t, podTemplate.Spec.Volumes, 1)
- assert.Len(t, podTemplate.Spec.Containers[0].VolumeMounts, 1)
- assert.Equal(t, expectedVolume, podTemplate.Spec.Volumes[0])
- assert.Equal(t, expectedMount, podTemplate.Spec.Containers[0].VolumeMounts[0])
- }
- func TestToPodWithNumericalUser(t *testing.T) {
- podTemplate := podTemplate(t, `
- version: "3"
- services:
- redis:
- image: "redis:alpine"
- user: "1000"
- `)
- userID := int64(1000)
- expectedSecurityContext := &apiv1.SecurityContext{
- RunAsUser: &userID,
- }
- assert.Equal(t, expectedSecurityContext, podTemplate.Spec.Containers[0].SecurityContext)
- }
- func TestToPodWithGitVolume(t *testing.T) {
- podTemplate := podTemplate(t, `
- version: "3"
- services:
- redis:
- image: "redis:alpine"
- volumes:
- - source: "[email protected]:moby/moby.git"
- target: /sources
- type: git
- `)
- expectedVolume := apiv1.Volume{
- Name: "mount-0",
- VolumeSource: apiv1.VolumeSource{
- GitRepo: &apiv1.GitRepoVolumeSource{
- Repository: "[email protected]:moby/moby.git",
- },
- },
- }
- expectedMount := apiv1.VolumeMount{
- Name: "mount-0",
- ReadOnly: false,
- MountPath: "/sources",
- }
- assert.Len(t, podTemplate.Spec.Volumes, 1)
- assert.Len(t, podTemplate.Spec.Containers[0].VolumeMounts, 1)
- assert.Equal(t, expectedVolume, podTemplate.Spec.Volumes[0])
- assert.Equal(t, expectedMount, podTemplate.Spec.Containers[0].VolumeMounts[0])
- }
- /* FIXME
- func TestToPodWithFileBasedConfig(t *testing.T) {
- podTemplate := podTemplate(t, `
- version: "3"
- services:
- redis:
- image: "redis:alpine"
- configs:
- - source: my_config
- target: /usr/share/nginx/html/index.html
- uid: "103"
- gid: "103"
- mode: 0440
- configs:
- my_config:
- file: ./file.html
- `)
- mode := int32(0440)
- expectedVolume := apiv1.Volume{
- Name: "config-0",
- VolumeSource: apiv1.VolumeSource{
- ConfigMap: &apiv1.ConfigMapVolumeSource{
- LocalObjectReference: apiv1.LocalObjectReference{
- Name: "my_config",
- },
- Items: []apiv1.KeyToPath{
- {
- Key: "file.html",
- Path: "config-0",
- Mode: &mode,
- },
- },
- },
- },
- }
- expectedMount := apiv1.VolumeMount{
- Name: "config-0",
- ReadOnly: true,
- MountPath: "/usr/share/nginx/html/index.html",
- SubPath: "config-0",
- }
- assert.Len(t, podTemplate.Spec.Volumes, 1)
- assert.Len(t, podTemplate.Spec.Containers[0].VolumeMounts, 1)
- assert.Equal(t, expectedVolume, podTemplate.Spec.Volumes[0])
- assert.Equal(t, expectedMount, podTemplate.Spec.Containers[0].VolumeMounts[0])
- }
- */
- /* FIXME
- func TestToPodWithTargetlessFileBasedConfig(t *testing.T) {
- podTemplate := podTemplate(t, `
- version: "3"
- services:
- redis:
- image: "redis:alpine"
- configs:
- - my_config
- configs:
- my_config:
- file: ./file.html
- `)
- expectedVolume := apiv1.Volume{
- Name: "config-0",
- VolumeSource: apiv1.VolumeSource{
- ConfigMap: &apiv1.ConfigMapVolumeSource{
- LocalObjectReference: apiv1.LocalObjectReference{
- Name: "myconfig",
- },
- Items: []apiv1.KeyToPath{
- {
- Key: "file.html",
- Path: "config-0",
- },
- },
- },
- },
- }
- expectedMount := apiv1.VolumeMount{
- Name: "config-0",
- ReadOnly: true,
- MountPath: "/myconfig",
- SubPath: "config-0",
- }
- assert.Len(t, podTemplate.Spec.Volumes, 1)
- assert.Len(t, podTemplate.Spec.Containers[0].VolumeMounts, 1)
- assert.Equal(t, expectedVolume, podTemplate.Spec.Volumes[0])
- assert.Equal(t, expectedMount, podTemplate.Spec.Containers[0].VolumeMounts[0])
- }
- */
- func TestToPodWithExternalConfig(t *testing.T) {
- podTemplate := podTemplate(t, `
- version: "3"
- services:
- redis:
- image: "redis:alpine"
- configs:
- - source: my_config
- target: /usr/share/nginx/html/index.html
- uid: "103"
- gid: "103"
- mode: 0440
- configs:
- my_config:
- external: true
- `)
- mode := int32(0440)
- expectedVolume := apiv1.Volume{
- Name: "config-0",
- VolumeSource: apiv1.VolumeSource{
- ConfigMap: &apiv1.ConfigMapVolumeSource{
- LocalObjectReference: apiv1.LocalObjectReference{
- Name: "my_config",
- },
- Items: []apiv1.KeyToPath{
- {
- Key: "file", // TODO: This is the key we assume external config use
- Path: "config-0",
- Mode: &mode,
- },
- },
- },
- },
- }
- expectedMount := apiv1.VolumeMount{
- Name: "config-0",
- ReadOnly: true,
- MountPath: "/usr/share/nginx/html/index.html",
- SubPath: "config-0",
- }
- assert.Len(t, podTemplate.Spec.Volumes, 1)
- assert.Len(t, podTemplate.Spec.Containers[0].VolumeMounts, 1)
- assert.Equal(t, expectedVolume, podTemplate.Spec.Volumes[0])
- assert.Equal(t, expectedMount, podTemplate.Spec.Containers[0].VolumeMounts[0])
- }
- /* FIXME
- func TestToPodWithTwoConfigsSameMountPoint(t *testing.T) {
- podTemplate := podTemplate(t, `
- version: "3"
- services:
- nginx:
- image: nginx
- configs:
- - source: first
- target: /data/first.json
- mode: "0440"
- - source: second
- target: /data/second.json
- mode: "0550"
- configs:
- first:
- file: ./file1
- secondv:
- file: ./file2
- `)
- mode0440 := int32(0440)
- mode0550 := int32(0550)
- expectedVolumes := []apiv1.Volume{
- {
- Name: "config-0",
- VolumeSource: apiv1.VolumeSource{
- ConfigMap: &apiv1.ConfigMapVolumeSource{
- LocalObjectReference: apiv1.LocalObjectReference{
- Name: "first",
- },
- Items: []apiv1.KeyToPath{
- {
- Key: "file1",
- Path: "config-0",
- Mode: &mode0440,
- },
- },
- },
- },
- },
- {
- Name: "config-1",
- VolumeSource: apiv1.VolumeSource{
- ConfigMap: &apiv1.ConfigMapVolumeSource{
- LocalObjectReference: apiv1.LocalObjectReference{
- Name: "second",
- },
- Items: []apiv1.KeyToPath{
- {
- Key: "file2",
- Path: "config-1",
- Mode: &mode0550,
- },
- },
- },
- },
- },
- }
- expectedMounts := []apiv1.VolumeMount{
- {
- Name: "config-0",
- ReadOnly: true,
- MountPath: "/data/first.json",
- SubPath: "config-0",
- },
- {
- Name: "config-1",
- ReadOnly: true,
- MountPath: "/data/second.json",
- SubPath: "config-1",
- },
- }
- assert.Equal(t, expectedVolumes, podTemplate.Spec.Volumes)
- assert.Equal(t, expectedMounts, podTemplate.Spec.Containers[0].VolumeMounts)
- }
- */
- func TestToPodWithTwoExternalConfigsSameMountPoint(t *testing.T) {
- podTemplate := podTemplate(t, `
- version: "3"
- services:
- nginx:
- image: nginx
- configs:
- - source: first
- target: /data/first.json
- - source: second
- target: /data/second.json
- configs:
- first:
- file: ./file1
- second:
- file: ./file2
- `)
- expectedVolumes := []apiv1.Volume{
- {
- Name: "config-0",
- VolumeSource: apiv1.VolumeSource{
- ConfigMap: &apiv1.ConfigMapVolumeSource{
- LocalObjectReference: apiv1.LocalObjectReference{
- Name: "first",
- },
- Items: []apiv1.KeyToPath{
- {
- Key: "file",
- Path: "config-0",
- },
- },
- },
- },
- },
- {
- Name: "config-1",
- VolumeSource: apiv1.VolumeSource{
- ConfigMap: &apiv1.ConfigMapVolumeSource{
- LocalObjectReference: apiv1.LocalObjectReference{
- Name: "second",
- },
- Items: []apiv1.KeyToPath{
- {
- Key: "file",
- Path: "config-1",
- },
- },
- },
- },
- },
- }
- expectedMounts := []apiv1.VolumeMount{
- {
- Name: "config-0",
- ReadOnly: true,
- MountPath: "/data/first.json",
- SubPath: "config-0",
- },
- {
- Name: "config-1",
- ReadOnly: true,
- MountPath: "/data/second.json",
- SubPath: "config-1",
- },
- }
- assert.Equal(t, expectedVolumes, podTemplate.Spec.Volumes)
- assert.Equal(t, expectedMounts, podTemplate.Spec.Containers[0].VolumeMounts)
- }
- /* FIXME
- func TestToPodWithPullSecret(t *testing.T) {
- podTemplateWithSecret := podTemplate(t, `
- version: "3"
- services:
- nginx:
- image: nginx
- x-kubernetes.pull-secret: test-pull-secret
- `)
- assert.Equal(t, 1, len(podTemplateWithSecret.Spec.ImagePullSecrets))
- assert.Equal(t, "test-pull-secret", podTemplateWithSecret.Spec.ImagePullSecrets[0].Name)
- podTemplateNoSecret := podTemplate(t, `
- version: "3"
- services:
- nginx:
- image: nginx
- `)
- assert.Nil(t, podTemplateNoSecret.Spec.ImagePullSecrets)
- }
- */
- /* FIXME
- func TestToPodWithPullPolicy(t *testing.T) {
- cases := []struct {
- name string
- stack string
- expectedPolicy apiv1.PullPolicy
- expectedError string
- }{
- {
- name: "specific tag",
- stack: `
- version: "3"
- services:
- nginx:
- image: nginx:specific
- `,
- expectedPolicy: apiv1.PullIfNotPresent,
- },
- {
- name: "latest tag",
- stack: `
- version: "3"
- services:
- nginx:
- image: nginx:latest
- `,
- expectedPolicy: apiv1.PullAlways,
- },
- {
- name: "explicit policy",
- stack: `
- version: "3"
- services:
- nginx:
- image: nginx:specific
- x-kubernetes.pull-policy: Never
- `,
- expectedPolicy: apiv1.PullNever,
- },
- {
- name: "invalid policy",
- stack: `
- version: "3"
- services:
- nginx:
- image: nginx:specific
- x-kubernetes.pull-policy: Invalid
- `,
- expectedError: `invalid pull policy "Invalid", must be "Always", "IfNotPresent" or "Never"`,
- },
- }
- for _, c := range cases {
- t.Run(c.name, func(t *testing.T) {
- pod, err := podTemplateWithError(c.stack)
- if c.expectedError != "" {
- assert.EqualError(t, err, c.expectedError)
- } else {
- assert.NoError(t, err)
- assert.Equal(t, pod.Spec.Containers[0].ImagePullPolicy, c.expectedPolicy)
- }
- })
- }
- }
- */
|