| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005 |
- // +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) (*loader.Config, error) {
- dict, err := loader.ParseYAML([]byte(yaml))
- if err != nil {
- return nil, err
- }
- workingDir, err := os.Getwd()
- if err != nil {
- panic(err)
- }
- configs := []types.ConfigFiles{}
- config := types.ConfigDetails{
- WorkingDir: workingDir,
- ConfigFiles: configs,
- Environment: utils.Environment(),
- }
- model, err := loader.Load(config)
- return model
- }
- 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.Services[0], nil, model)
- }
- 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)
- }
- func TestToPodWithGlobalVolume(t *testing.T) {
- podTemplate := podTemplate(t, `
- version: "3"
- services:
- db:
- image: "postgres:9.4"
- volumes:
- - dbdata:/var/lib/postgresql/data
- `)
- 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)
- }
- func /*FIXME Test*/ ToPodWithRelativeVolumes(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)
- }
- 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])
- }
- 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])
- }
- func /*FIXME Test*/ ToPodWithFileBasedSecret(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])
- }
- func /*FIXME Test*/ ToPodWithTwoFileBasedSecrets(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])
- }
- func /*FIXME Test*/ ToPodWithFileBasedConfig(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])
- }
- func /*FIXME Test*/ ToPodWithTargetlessFileBasedConfig(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])
- }
- func /*FIXME Test*/ ToPodWithTwoConfigsSameMountPoint(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)
- }
- func /*FIXME Test*/ ToPodWithPullSecret(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)
- }
- func /*FIXME Test*/ ToPodWithPullPolicy(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)
- }
- })
- }
- }
|