From 1c4046f415de9bf867b694376dafad4a7e761daa Mon Sep 17 00:00:00 2001 From: shreddedbacon Date: Sat, 12 Oct 2024 20:45:26 +1100 Subject: [PATCH] fix: lagoon.persistent.name override checks --- cmd/template_lagoonservices_test.go | 33 +++++ internal/generator/buildvalues.go | 1 + internal/generator/generator.go | 6 + internal/generator/services.go | 74 +++++------ internal/generator/services_test.go | 64 +++++++-- internal/generator/volumes.go | 22 ++++ internal/generator/volumes_test.go | 122 ++++++++++++++++++ internal/templating/services/templates_pvc.go | 10 +- .../templating/services/templates_pvc_test.go | 65 ++++++---- .../docker-compose.persistent-name-2.yml | 30 +++++ .../basic/docker-compose.persistent-name.yml | 16 +++ .../basic/lagoon.persistent-name-2.yml | 10 ++ .../testdata/basic/lagoon.persistent-name.yml | 10 ++ .../deployment-basic.yaml | 93 +++++++++++++ .../test-basic-persistent-name/pvc-basic.yaml | 30 +++++ .../service-basic.yaml | 35 +++++ .../deployment-basic.yaml | 93 +++++++++++++ .../deployment-basic2.yaml | 93 +++++++++++++ .../pvc-basic.yaml | 30 +++++ .../service-basic.yaml | 35 +++++ .../service-basic2.yaml | 35 +++++ 21 files changed, 825 insertions(+), 82 deletions(-) create mode 100644 internal/generator/volumes_test.go create mode 100644 internal/testdata/basic/docker-compose.persistent-name-2.yml create mode 100644 internal/testdata/basic/docker-compose.persistent-name.yml create mode 100644 internal/testdata/basic/lagoon.persistent-name-2.yml create mode 100644 internal/testdata/basic/lagoon.persistent-name.yml create mode 100644 internal/testdata/basic/service-templates/test-basic-persistent-name/deployment-basic.yaml create mode 100644 internal/testdata/basic/service-templates/test-basic-persistent-name/pvc-basic.yaml create mode 100644 internal/testdata/basic/service-templates/test-basic-persistent-name/service-basic.yaml create mode 100644 internal/testdata/basic/service-templates/test-basic-persistent-names/deployment-basic.yaml create mode 100644 internal/testdata/basic/service-templates/test-basic-persistent-names/deployment-basic2.yaml create mode 100644 internal/testdata/basic/service-templates/test-basic-persistent-names/pvc-basic.yaml create mode 100644 internal/testdata/basic/service-templates/test-basic-persistent-names/service-basic.yaml create mode 100644 internal/testdata/basic/service-templates/test-basic-persistent-names/service-basic2.yaml diff --git a/cmd/template_lagoonservices_test.go b/cmd/template_lagoonservices_test.go index 786d3eb0..d1ce645a 100644 --- a/cmd/template_lagoonservices_test.go +++ b/cmd/template_lagoonservices_test.go @@ -480,6 +480,39 @@ func TestTemplateLagoonServices(t *testing.T) { templatePath: "testoutput", want: "internal/testdata/basic/service-templates/test-basic-spot-affinity", }, + { + name: "test-basic-persistent-name", + description: "tests a basic deployment with a persistent name", + args: testdata.GetSeedData( + testdata.TestData{ + ProjectName: "example-project", + EnvironmentName: "main", + Branch: "main", + LagoonYAML: "internal/testdata/basic/lagoon.persistent-name.yml", + ImageReferences: map[string]string{ + "basic": "harbor.example/example-project/main/basic@sha256:b2001babafaa8128fe89aa8fd11832cade59931d14c3de5b3ca32e2a010fbaa8", + }, + }, true), + templatePath: "testoutput", + want: "internal/testdata/basic/service-templates/test-basic-persistent-name", + }, + { + name: "test-basic-persistent-names", + description: "tests a basic deployment with two services with persistent name", + args: testdata.GetSeedData( + testdata.TestData{ + ProjectName: "example-project", + EnvironmentName: "main", + Branch: "main", + LagoonYAML: "internal/testdata/basic/lagoon.persistent-name-2.yml", + ImageReferences: map[string]string{ + "basic": "harbor.example/example-project/main/basic@sha256:b2001babafaa8128fe89aa8fd11832cade59931d14c3de5b3ca32e2a010fbaa8", + "basic2": "harbor.example/example-project/main/basic2@sha256:b2001babafaa8128fe89aa8fd11832cade59931d14c3de5b3ca32e2a010fbaa8", + }, + }, true), + templatePath: "testoutput", + want: "internal/testdata/basic/service-templates/test-basic-persistent-names", + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/internal/generator/buildvalues.go b/internal/generator/buildvalues.go index bc1a20c9..697cbd64 100644 --- a/internal/generator/buildvalues.go +++ b/internal/generator/buildvalues.go @@ -199,6 +199,7 @@ type ServiceValues struct { IsDBaaS bool `json:"isDBaaS"` IsSingle bool `json:"isSingle"` AdditionalVolumes []ServiceVolume `json:"additonalVolumes,omitempty"` + CreateDefaultVolume bool `json:"createDefaultVolume"` } type ImageBuild struct { diff --git a/internal/generator/generator.go b/internal/generator/generator.go index cfa0cbcf..7b1225b9 100644 --- a/internal/generator/generator.go +++ b/internal/generator/generator.go @@ -419,6 +419,12 @@ func NewGenerator( return nil, err } + // strip out duplicate default volumes + err = flagDefaultVolumeCreation(&buildValues) + if err != nil { + return nil, err + } + if imageCacheBuildArgsJSON != "" { err = json.Unmarshal([]byte(imageCacheBuildArgsJSON), &buildValues.ImageCacheBuildArguments) if err != nil { diff --git a/internal/generator/services.go b/internal/generator/services.go index f3e8908e..c1d46dd0 100644 --- a/internal/generator/services.go +++ b/internal/generator/services.go @@ -249,43 +249,6 @@ func composeToServiceValues( lagoonOverrideName = composeService } - // check if the service has any persistent labels, this is the path that the volume will be mounted to - servicePersistentPath := lagoon.CheckDockerComposeLagoonLabel(composeServiceValues.Labels, "lagoon.persistent") - if servicePersistentPath == "" { - // if there is no persistent path, check if the service type has a default path - if val, ok := servicetypes.ServiceTypes[lagoonType]; ok { - servicePersistentPath = val.Volumes.PersistentVolumePath - // check if the service type provides or consumes a default persistent volume - if (val.ProvidesPersistentVolume || val.ConsumesPersistentVolume) && servicePersistentPath == "" { - return nil, fmt.Errorf("label lagoon.persistent not defined for service %s, no valid mount path was found", composeService) - } - } - } - servicePersistentName := lagoon.CheckDockerComposeLagoonLabel(composeServiceValues.Labels, "lagoon.persistent.name") - if servicePersistentName == "" && servicePersistentPath != "" { - // if there is a persistent path defined, then set the persistent name to be the compose service if no persistent name is provided - // persistent name is used by joined services like nginx/php or cli or worker pods to mount another service volume - servicePersistentName = lagoonOverrideName - } - servicePersistentSize := lagoon.CheckDockerComposeLagoonLabel(composeServiceValues.Labels, "lagoon.persistent.size") - if servicePersistentSize == "" { - // if there is no persistent size, check if the service type has a default size allocated - if val, ok := servicetypes.ServiceTypes[lagoonType]; ok { - servicePersistentSize = val.Volumes.PersistentVolumeSize - // check if the service type provides persistent volume, and that a size was detected - if val.ProvidesPersistentVolume && servicePersistentSize == "" { - return nil, fmt.Errorf("label lagoon.persistent.size not defined for service %s, no valid size was found", composeService) - } - } - } - if servicePersistentSize != "" { - // check the provided size is a valid resource size for kubernetes - _, err := ValidateResourceSize(servicePersistentSize) - if err != nil { - return nil, fmt.Errorf("provided persistent volume size for %s is not valid: %v", servicePersistentName, err) - } - } - baseimage := lagoon.CheckDockerComposeLagoonLabel(composeServiceValues.Labels, "lagoon.base.image") if baseimage != "" { // First, let's ensure that the structure of the base image is valid @@ -381,6 +344,43 @@ func composeToServiceValues( } } + // check if the service has any persistent labels, this is the path that the volume will be mounted to + servicePersistentPath := lagoon.CheckDockerComposeLagoonLabel(composeServiceValues.Labels, "lagoon.persistent") + if servicePersistentPath == "" { + // if there is no persistent path, check if the service type has a default path + if val, ok := servicetypes.ServiceTypes[lagoonType]; ok { + servicePersistentPath = val.Volumes.PersistentVolumePath + // check if the service type provides or consumes a default persistent volume + if (val.ProvidesPersistentVolume || val.ConsumesPersistentVolume) && servicePersistentPath == "" { + return nil, fmt.Errorf("label lagoon.persistent not defined for service %s, no valid mount path was found", composeService) + } + } + } + servicePersistentName := lagoon.CheckDockerComposeLagoonLabel(composeServiceValues.Labels, "lagoon.persistent.name") + if servicePersistentName == "" && servicePersistentPath != "" { + // if there is a persistent path defined, then set the persistent name to be the compose service if no persistent name is provided + // persistent name is used by joined services like nginx/php or cli or worker pods to mount another service volume + servicePersistentName = lagoonOverrideName + } + servicePersistentSize := lagoon.CheckDockerComposeLagoonLabel(composeServiceValues.Labels, "lagoon.persistent.size") + if servicePersistentSize == "" { + // if there is no persistent size, check if the service type has a default size allocated + if val, ok := servicetypes.ServiceTypes[lagoonType]; ok { + servicePersistentSize = val.Volumes.PersistentVolumeSize + // check if the service type provides persistent volume, and that a size was detected + if val.ProvidesPersistentVolume && servicePersistentSize == "" { + return nil, fmt.Errorf("label lagoon.persistent.size not defined for service %s, no valid size was found", composeService) + } + } + } + if servicePersistentSize != "" { + // check the provided size is a valid resource size for kubernetes + _, err := ValidateResourceSize(servicePersistentSize) + if err != nil { + return nil, fmt.Errorf("provided persistent volume size for %s is not valid: %v", servicePersistentName, err) + } + } + // calculate if this service needs any additional volumes attached from the calculated build volumes // additional volumes can only be attached to certain serviceVolumes, err := calculateServiceVolumes(buildValues, lagoonType, servicePersistentName, composeServiceValues.Labels) diff --git a/internal/generator/services_test.go b/internal/generator/services_test.go index 94d84323..2cd53e3a 100644 --- a/internal/generator/services_test.go +++ b/internal/generator/services_test.go @@ -6,6 +6,7 @@ import ( "testing" "time" + "github.com/andreyvit/diff" composetypes "github.com/compose-spec/compose-go/types" "github.com/uselagoon/build-deploy-tool/internal/dbaasclient" "github.com/uselagoon/build-deploy-tool/internal/helpers" @@ -19,10 +20,11 @@ func Test_composeToServiceValues(t *testing.T) { composeServiceValues composetypes.ServiceConfig } tests := []struct { - name string - args args - want *ServiceValues - wantErr bool + name string + description string + args args + want *ServiceValues + wantErr bool }{ { name: "test1", @@ -201,7 +203,9 @@ func Test_composeToServiceValues(t *testing.T) { wantErr: true, }, { - name: "test4 - variable servicetypes type override", + name: "test-variable-servicetypes-type-override", + description: `this test should fail to change the nginx service from nginx-php to nginx-php-persistent + this is because there is no lagoon.persistent labels on the dockercompose service to suit this change`, args: args{ buildValues: &BuildValues{ Namespace: "example-project-main", @@ -231,10 +235,46 @@ func Test_composeToServiceValues(t *testing.T) { }, }, }, + want: nil, + wantErr: true, + }, + { + name: "test-variable-servicetypes-type-override-b", + description: `this test should pasee and change the nginx service from nginx to basic + this is because there is nothing really special between these two services besides the port`, + args: args{ + buildValues: &BuildValues{ + Namespace: "example-project-main", + Project: "example-project", + ImageRegistry: "harbor.example", + Environment: "main", + Branch: "main", + BuildType: "branch", + ServiceTypeOverrides: &lagoon.EnvironmentVariable{ + Name: "LAGOON_SERVICE_TYPES", + Value: "nginx:basic,mariadb:mariadb-dbaas", + }, + LagoonYAML: lagoon.YAML{ + Environments: lagoon.Environments{ + "main": lagoon.Environment{}, + }, + }, + }, + composeService: "nginx", + composeServiceValues: composetypes.ServiceConfig{ + Labels: composetypes.Labels{ + "lagoon.type": "nginx", + }, + Build: &composetypes.BuildConfig{ + Context: ".", + Dockerfile: "../testdata/basic/docker/basic.dockerfile", + }, + }, + }, want: &ServiceValues{ Name: "nginx", OverrideName: "nginx", - Type: "nginx-php-persistent", + Type: "basic", AutogeneratedRoutesEnabled: true, AutogeneratedRoutesTLSAcme: true, InPodCronjobs: []lagoon.Cronjob{}, @@ -245,7 +285,6 @@ func Test_composeToServiceValues(t *testing.T) { DockerFile: "../testdata/basic/docker/basic.dockerfile", BuildImage: "harbor.example/example-project/main/nginx:latest", }, - BackupsEnabled: true, }, }, { @@ -558,6 +597,9 @@ func Test_composeToServiceValues(t *testing.T) { Type: "mariadb-single", AutogeneratedRoutesEnabled: false, AutogeneratedRoutesTLSAcme: false, + PersistentVolumePath: "/var/lib/mysql", + PersistentVolumeName: "mariadb", + PersistentVolumeSize: "5Gi", DBaaSEnvironment: "development2", InPodCronjobs: []lagoon.Cronjob{}, NativeCronjobs: []lagoon.Cronjob{}, @@ -1252,10 +1294,10 @@ func Test_composeToServiceValues(t *testing.T) { t.Errorf("composeToServiceValues() error = %v, wantErr %v", err, tt.wantErr) return } - lValues, _ := json.Marshal(got) - wValues, _ := json.Marshal(tt.want) - if !reflect.DeepEqual(string(lValues), string(wValues)) { - t.Errorf("composeToServiceValues() = %v, want %v", string(lValues), string(wValues)) + f1, _ := json.MarshalIndent(got, "", " ") + r1, _ := json.MarshalIndent(tt.want, "", " ") + if !reflect.DeepEqual(f1, r1) { + t.Errorf("composeToServiceValues() = \n%v", diff.LineDiff(string(r1), string(f1))) } }) } diff --git a/internal/generator/volumes.go b/internal/generator/volumes.go index 00740d15..3b852c8d 100644 --- a/internal/generator/volumes.go +++ b/internal/generator/volumes.go @@ -124,3 +124,25 @@ func calculateServiceVolumes(buildValues *BuildValues, lagoonType, servicePersis return serviceVolumes, nil } + +// flagDefaultVolumeCreation checks services for duplicate default volumes and flags only the ones that need to be created +// this will ensure that a service type that provides a volume will create that volume +// even if the `lagoon.persistent.name` is different to the default name being the service name +// due to the way labels in docker-compose can be added to services for lagoon, this allows multiple types to mount one shared volume by name +// from one main service, across multiple services by using the `lagoon.persistent.name` value +func flagDefaultVolumeCreation( + buildValues *BuildValues, +) error { + vols := make(map[string]bool) + for idx, service := range buildValues.Services { + if sType, ok := servicetypes.ServiceTypes[service.Type]; ok && service.PersistentVolumeName != "" { + if _, ok := vols[service.PersistentVolumeName]; !ok && sType.ProvidesPersistentVolume { + // this volume is the one to be created by the first service that provides a persistent volume + service.CreateDefaultVolume = true + vols[service.PersistentVolumeName] = true + buildValues.Services[idx] = service + } + } + } + return nil +} diff --git a/internal/generator/volumes_test.go b/internal/generator/volumes_test.go new file mode 100644 index 00000000..645caef8 --- /dev/null +++ b/internal/generator/volumes_test.go @@ -0,0 +1,122 @@ +package generator + +import ( + "encoding/json" + "reflect" + "testing" + + "github.com/andreyvit/diff" + "github.com/uselagoon/build-deploy-tool/internal/lagoon" +) + +func Test_flagDefaultVolumeCreation(t *testing.T) { + type args struct { + } + tests := []struct { + name string + buildValues *BuildValues + want []ServiceValues + wantErr bool + }{ + { + name: "test1", + buildValues: &BuildValues{ + Services: []ServiceValues{ + { + Name: "nginx", + OverrideName: "nginx", + Type: "nginx-php-persistent", + AutogeneratedRoutesEnabled: true, + AutogeneratedRoutesTLSAcme: true, + InPodCronjobs: []lagoon.Cronjob{}, + NativeCronjobs: []lagoon.Cronjob{}, + PersistentVolumeSize: "5Gi", + ImageBuild: &ImageBuild{ + TemporaryImage: "example-project-main-nginx", + Context: ".", + DockerFile: "../testdata/basic/docker/basic.dockerfile", + BuildImage: "harbor.example/example-project/main/nginx:latest", + }, + PersistentVolumeName: "nginx", + PersistentVolumePath: "/app/docroot/sites/default/files/", + BackupsEnabled: true, + }, + }, + }, + want: []ServiceValues{ + { + Name: "nginx", + OverrideName: "nginx", + Type: "nginx-php-persistent", + AutogeneratedRoutesEnabled: true, + AutogeneratedRoutesTLSAcme: true, + InPodCronjobs: []lagoon.Cronjob{}, + NativeCronjobs: []lagoon.Cronjob{}, + PersistentVolumeSize: "5Gi", + ImageBuild: &ImageBuild{ + TemporaryImage: "example-project-main-nginx", + Context: ".", + DockerFile: "../testdata/basic/docker/basic.dockerfile", + BuildImage: "harbor.example/example-project/main/nginx:latest", + }, + PersistentVolumeName: "nginx", + PersistentVolumePath: "/app/docroot/sites/default/files/", + BackupsEnabled: true, + CreateDefaultVolume: true, + }, + }, + }, + { + name: "test2", + buildValues: &BuildValues{ + Services: []ServiceValues{ + { + Name: "basic", + OverrideName: "basic", + Type: "basic-persistent", + PersistentVolumeSize: "5Gi", + PersistentVolumeName: "basic-data", + PersistentVolumePath: "/basic-data/", + }, + { + Name: "basic2", + OverrideName: "basic2", + Type: "basic-persistent", + PersistentVolumeName: "basic-data", + PersistentVolumePath: "/basic-data/", + }, + }, + }, + want: []ServiceValues{ + { + Name: "basic", + OverrideName: "basic", + Type: "basic-persistent", + PersistentVolumeSize: "5Gi", + PersistentVolumeName: "basic-data", + PersistentVolumePath: "/basic-data/", + CreateDefaultVolume: true, + }, + { + Name: "basic2", + OverrideName: "basic2", + Type: "basic-persistent", + PersistentVolumeName: "basic-data", + PersistentVolumePath: "/basic-data/", + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := flagDefaultVolumeCreation(tt.buildValues); (err != nil) != tt.wantErr { + t.Errorf("flagDefaultVolumeCreation() error = %v, wantErr %v", err, tt.wantErr) + } + f1, _ := json.MarshalIndent(tt.buildValues.Services, "", " ") + r1, _ := json.MarshalIndent(tt.want, "", " ") + if !reflect.DeepEqual(f1, r1) { + t.Errorf("flagDefaultVolumeCreation() = \n%v", diff.LineDiff(string(r1), string(f1))) + } + }) + } +} diff --git a/internal/templating/services/templates_pvc.go b/internal/templating/services/templates_pvc.go index 7f0da966..c8a9e772 100644 --- a/internal/templating/services/templates_pvc.go +++ b/internal/templating/services/templates_pvc.go @@ -51,7 +51,7 @@ func GeneratePVCTemplate( // iterate over them and generate any kubernetes services for _, serviceValues := range checkedServices { if val, ok := servicetypes.ServiceTypes[serviceValues.Type]; ok { - if val.Volumes.PersistentVolumeSize != "" { + if serviceValues.CreateDefaultVolume { pvc, err := generateDefaultPVC(buildValues, serviceValues, val, labels, annotations) if err != nil { return nil, err @@ -92,14 +92,6 @@ func generateDefaultPVC(buildValues generator.BuildValues, val servicetypes.ServiceType, labels, annotations map[string]string, ) (*corev1.PersistentVolumeClaim, error) { - if serviceValues.PersistentVolumeName != "" { - if serviceValues.PersistentVolumeName != serviceValues.OverrideName { - // this service base volume is not needed because it is created by a different service - // lagoon legacy templates allowed due to a funny templating issue, for multiple "basic" types to mount one volume - // from one main service, across multiple services of the same type - return nil, nil - } - } serviceTypeValues := &servicetypes.ServiceType{} helpers.DeepCopy(val, serviceTypeValues) persistentVolumeSize := serviceTypeValues.Volumes.PersistentVolumeSize diff --git a/internal/templating/services/templates_pvc_test.go b/internal/templating/services/templates_pvc_test.go index e92731e4..57482da7 100644 --- a/internal/templating/services/templates_pvc_test.go +++ b/internal/templating/services/templates_pvc_test.go @@ -47,17 +47,21 @@ func TestGeneratePVCTemplate(t *testing.T) { ServicePort: 8080, }, { - Name: "myservice-persist", - OverrideName: "myservice-persist", - Type: "basic-persistent", - DBaaSEnvironment: "development", + Name: "myservice-persist", + OverrideName: "myservice-persist", + Type: "basic-persistent", + DBaaSEnvironment: "development", + PersistentVolumeSize: "5Gi", + CreateDefaultVolume: true, }, { - Name: "myservice-persist-po", - OverrideName: "myservice-persist-po", - Type: "basic-persistent", - DBaaSEnvironment: "development", - ServicePort: 8080, + Name: "myservice-persist-po", + OverrideName: "myservice-persist-po", + Type: "basic-persistent", + DBaaSEnvironment: "development", + ServicePort: 8080, + PersistentVolumeSize: "5Gi", + CreateDefaultVolume: true, }, { Name: "myservice-persist-po", @@ -66,6 +70,7 @@ func TestGeneratePVCTemplate(t *testing.T) { DBaaSEnvironment: "development", ServicePort: 8080, PersistentVolumeSize: "100Gi", + CreateDefaultVolume: true, }, }, }, @@ -116,10 +121,12 @@ func TestGeneratePVCTemplate(t *testing.T) { Branch: "environment-name", Services: []generator.ServiceValues{ { - Name: "myservice", - OverrideName: "myservice", - Type: "elasticsearch", - DBaaSEnvironment: "development", + Name: "myservice", + OverrideName: "myservice", + Type: "elasticsearch", + DBaaSEnvironment: "development", + PersistentVolumeSize: "5Gi", + CreateDefaultVolume: true, }, { Name: "myservice-size", @@ -127,6 +134,7 @@ func TestGeneratePVCTemplate(t *testing.T) { Type: "elasticsearch", DBaaSEnvironment: "development", PersistentVolumeSize: "100Gi", + CreateDefaultVolume: true, }, }, }, @@ -147,10 +155,12 @@ func TestGeneratePVCTemplate(t *testing.T) { Branch: "environment-name", Services: []generator.ServiceValues{ { - Name: "myservice", - OverrideName: "myservice", - Type: "opensearch", - DBaaSEnvironment: "development", + Name: "myservice", + OverrideName: "myservice", + Type: "opensearch", + DBaaSEnvironment: "development", + PersistentVolumeSize: "5Gi", + CreateDefaultVolume: true, }, { Name: "myservice-size", @@ -158,6 +168,7 @@ func TestGeneratePVCTemplate(t *testing.T) { Type: "opensearch", DBaaSEnvironment: "development", PersistentVolumeSize: "100Gi", + CreateDefaultVolume: true, }, }, }, @@ -178,10 +189,12 @@ func TestGeneratePVCTemplate(t *testing.T) { Branch: "environment-name", Services: []generator.ServiceValues{ { - Name: "myservice", - OverrideName: "myservice", - Type: "postgres-single", - DBaaSEnvironment: "development", + Name: "myservice", + OverrideName: "myservice", + Type: "postgres-single", + DBaaSEnvironment: "development", + PersistentVolumeSize: "5Gi", + CreateDefaultVolume: true, }, }, }, @@ -203,10 +216,12 @@ func TestGeneratePVCTemplate(t *testing.T) { RWX2RWO: true, Services: []generator.ServiceValues{ { - Name: "myservice-persist", - OverrideName: "myservice-persist", - Type: "basic-persistent", - DBaaSEnvironment: "development", + Name: "myservice-persist", + OverrideName: "myservice-persist", + Type: "basic-persistent", + DBaaSEnvironment: "development", + PersistentVolumeSize: "5Gi", + CreateDefaultVolume: true, }, }, }, diff --git a/internal/testdata/basic/docker-compose.persistent-name-2.yml b/internal/testdata/basic/docker-compose.persistent-name-2.yml new file mode 100644 index 00000000..bc854122 --- /dev/null +++ b/internal/testdata/basic/docker-compose.persistent-name-2.yml @@ -0,0 +1,30 @@ +version: '2' +services: + basic: + build: + context: internal/testdata/basic/docker + dockerfile: basic.dockerfile + labels: + lagoon.service.port: 5672 + lagoon.service.usecomposeports: true + lagoon.autogeneratedroute: false + lagoon.type: basic-persistent + lagoon.persistent: /var/lib/basic + lagoon.persistent.name: basic-data + ports: + - '5672' + - '15672:15672' + basic2: + build: + context: internal/testdata/basic/docker + dockerfile: basic.dockerfile + labels: + lagoon.service.port: 5672 + lagoon.service.usecomposeports: true + lagoon.autogeneratedroute: false + lagoon.type: basic-persistent + lagoon.persistent: /var/lib/basic + lagoon.persistent.name: basic-data + ports: + - '5672' + - '15672:15672' diff --git a/internal/testdata/basic/docker-compose.persistent-name.yml b/internal/testdata/basic/docker-compose.persistent-name.yml new file mode 100644 index 00000000..e315f840 --- /dev/null +++ b/internal/testdata/basic/docker-compose.persistent-name.yml @@ -0,0 +1,16 @@ +version: '2' +services: + basic: + build: + context: internal/testdata/basic/docker + dockerfile: basic.dockerfile + labels: + lagoon.service.port: 5672 + lagoon.service.usecomposeports: true + lagoon.autogeneratedroute: false + lagoon.type: basic-persistent + lagoon.persistent: /var/lib/basic + lagoon.persistent.name: basic-data + ports: + - '5672' + - '15672:15672' diff --git a/internal/testdata/basic/lagoon.persistent-name-2.yml b/internal/testdata/basic/lagoon.persistent-name-2.yml new file mode 100644 index 00000000..e7ffa8c7 --- /dev/null +++ b/internal/testdata/basic/lagoon.persistent-name-2.yml @@ -0,0 +1,10 @@ +docker-compose-yaml: internal/testdata/basic/docker-compose.persistent-name-2.yml + +environment_variables: + git_sha: "true" + +environments: + main: + routes: + - node: + - example.com diff --git a/internal/testdata/basic/lagoon.persistent-name.yml b/internal/testdata/basic/lagoon.persistent-name.yml new file mode 100644 index 00000000..b857e962 --- /dev/null +++ b/internal/testdata/basic/lagoon.persistent-name.yml @@ -0,0 +1,10 @@ +docker-compose-yaml: internal/testdata/basic/docker-compose.persistent-name.yml + +environment_variables: + git_sha: "true" + +environments: + main: + routes: + - node: + - example.com diff --git a/internal/testdata/basic/service-templates/test-basic-persistent-name/deployment-basic.yaml b/internal/testdata/basic/service-templates/test-basic-persistent-name/deployment-basic.yaml new file mode 100644 index 00000000..23ded318 --- /dev/null +++ b/internal/testdata/basic/service-templates/test-basic-persistent-name/deployment-basic.yaml @@ -0,0 +1,93 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + lagoon.sh/branch: main + lagoon.sh/version: v2.7.x + creationTimestamp: null + labels: + app.kubernetes.io/instance: basic + app.kubernetes.io/managed-by: build-deploy-tool + app.kubernetes.io/name: basic-persistent + lagoon.sh/buildType: branch + lagoon.sh/environment: main + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + lagoon.sh/service: basic + lagoon.sh/service-type: basic-persistent + lagoon.sh/template: basic-persistent-0.1.0 + name: basic +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: basic + app.kubernetes.io/name: basic-persistent + strategy: {} + template: + metadata: + annotations: + lagoon.sh/branch: main + lagoon.sh/configMapSha: abcdefg1234567890 + lagoon.sh/version: v2.7.x + creationTimestamp: null + labels: + app.kubernetes.io/instance: basic + app.kubernetes.io/managed-by: build-deploy-tool + app.kubernetes.io/name: basic-persistent + lagoon.sh/buildType: branch + lagoon.sh/environment: main + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + lagoon.sh/service: basic + lagoon.sh/service-type: basic-persistent + lagoon.sh/template: basic-persistent-0.1.0 + spec: + containers: + - env: + - name: LAGOON_GIT_SHA + value: abcdefg123456 + - name: CRONJOBS + - name: SERVICE_NAME + value: basic + envFrom: + - configMapRef: + name: lagoon-env + image: harbor.example/example-project/main/basic@sha256:b2001babafaa8128fe89aa8fd11832cade59931d14c3de5b3ca32e2a010fbaa8 + imagePullPolicy: Always + livenessProbe: + initialDelaySeconds: 60 + tcpSocket: + port: 5672 + timeoutSeconds: 10 + name: basic + ports: + - containerPort: 5672 + name: tcp-5672 + protocol: TCP + - containerPort: 15672 + name: tcp-15672 + protocol: TCP + readinessProbe: + initialDelaySeconds: 1 + tcpSocket: + port: 5672 + timeoutSeconds: 1 + resources: + requests: + cpu: 10m + memory: 10Mi + securityContext: {} + volumeMounts: + - mountPath: /var/lib/basic + name: basic-data + enableServiceLinks: false + imagePullSecrets: + - name: lagoon-internal-registry-secret + priorityClassName: lagoon-priority-production + volumes: + - name: basic-data + persistentVolumeClaim: + claimName: basic-data +status: {} diff --git a/internal/testdata/basic/service-templates/test-basic-persistent-name/pvc-basic.yaml b/internal/testdata/basic/service-templates/test-basic-persistent-name/pvc-basic.yaml new file mode 100644 index 00000000..08fff6a4 --- /dev/null +++ b/internal/testdata/basic/service-templates/test-basic-persistent-name/pvc-basic.yaml @@ -0,0 +1,30 @@ +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + annotations: + k8up.io/backup: "true" + k8up.syn.tools/backup: "true" + lagoon.sh/branch: main + lagoon.sh/version: v2.7.x + creationTimestamp: null + labels: + app.kubernetes.io/instance: basic + app.kubernetes.io/managed-by: build-deploy-tool + app.kubernetes.io/name: basic-persistent + lagoon.sh/buildType: branch + lagoon.sh/environment: main + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + lagoon.sh/service: basic + lagoon.sh/service-type: basic-persistent + lagoon.sh/template: basic-persistent-0.1.0 + name: basic +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: 5Gi + storageClassName: bulk +status: {} diff --git a/internal/testdata/basic/service-templates/test-basic-persistent-name/service-basic.yaml b/internal/testdata/basic/service-templates/test-basic-persistent-name/service-basic.yaml new file mode 100644 index 00000000..2dba6161 --- /dev/null +++ b/internal/testdata/basic/service-templates/test-basic-persistent-name/service-basic.yaml @@ -0,0 +1,35 @@ +--- +apiVersion: v1 +kind: Service +metadata: + annotations: + lagoon.sh/branch: main + lagoon.sh/version: v2.7.x + creationTimestamp: null + labels: + app.kubernetes.io/instance: basic + app.kubernetes.io/managed-by: build-deploy-tool + app.kubernetes.io/name: basic-persistent + lagoon.sh/buildType: branch + lagoon.sh/environment: main + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + lagoon.sh/service: basic + lagoon.sh/service-type: basic-persistent + lagoon.sh/template: basic-persistent-0.1.0 + name: basic +spec: + ports: + - name: tcp-5672 + port: 5672 + protocol: TCP + targetPort: tcp-5672 + - name: tcp-15672 + port: 15672 + protocol: TCP + targetPort: tcp-15672 + selector: + app.kubernetes.io/instance: basic + app.kubernetes.io/name: basic-persistent +status: + loadBalancer: {} diff --git a/internal/testdata/basic/service-templates/test-basic-persistent-names/deployment-basic.yaml b/internal/testdata/basic/service-templates/test-basic-persistent-names/deployment-basic.yaml new file mode 100644 index 00000000..23ded318 --- /dev/null +++ b/internal/testdata/basic/service-templates/test-basic-persistent-names/deployment-basic.yaml @@ -0,0 +1,93 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + lagoon.sh/branch: main + lagoon.sh/version: v2.7.x + creationTimestamp: null + labels: + app.kubernetes.io/instance: basic + app.kubernetes.io/managed-by: build-deploy-tool + app.kubernetes.io/name: basic-persistent + lagoon.sh/buildType: branch + lagoon.sh/environment: main + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + lagoon.sh/service: basic + lagoon.sh/service-type: basic-persistent + lagoon.sh/template: basic-persistent-0.1.0 + name: basic +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: basic + app.kubernetes.io/name: basic-persistent + strategy: {} + template: + metadata: + annotations: + lagoon.sh/branch: main + lagoon.sh/configMapSha: abcdefg1234567890 + lagoon.sh/version: v2.7.x + creationTimestamp: null + labels: + app.kubernetes.io/instance: basic + app.kubernetes.io/managed-by: build-deploy-tool + app.kubernetes.io/name: basic-persistent + lagoon.sh/buildType: branch + lagoon.sh/environment: main + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + lagoon.sh/service: basic + lagoon.sh/service-type: basic-persistent + lagoon.sh/template: basic-persistent-0.1.0 + spec: + containers: + - env: + - name: LAGOON_GIT_SHA + value: abcdefg123456 + - name: CRONJOBS + - name: SERVICE_NAME + value: basic + envFrom: + - configMapRef: + name: lagoon-env + image: harbor.example/example-project/main/basic@sha256:b2001babafaa8128fe89aa8fd11832cade59931d14c3de5b3ca32e2a010fbaa8 + imagePullPolicy: Always + livenessProbe: + initialDelaySeconds: 60 + tcpSocket: + port: 5672 + timeoutSeconds: 10 + name: basic + ports: + - containerPort: 5672 + name: tcp-5672 + protocol: TCP + - containerPort: 15672 + name: tcp-15672 + protocol: TCP + readinessProbe: + initialDelaySeconds: 1 + tcpSocket: + port: 5672 + timeoutSeconds: 1 + resources: + requests: + cpu: 10m + memory: 10Mi + securityContext: {} + volumeMounts: + - mountPath: /var/lib/basic + name: basic-data + enableServiceLinks: false + imagePullSecrets: + - name: lagoon-internal-registry-secret + priorityClassName: lagoon-priority-production + volumes: + - name: basic-data + persistentVolumeClaim: + claimName: basic-data +status: {} diff --git a/internal/testdata/basic/service-templates/test-basic-persistent-names/deployment-basic2.yaml b/internal/testdata/basic/service-templates/test-basic-persistent-names/deployment-basic2.yaml new file mode 100644 index 00000000..2cbc166a --- /dev/null +++ b/internal/testdata/basic/service-templates/test-basic-persistent-names/deployment-basic2.yaml @@ -0,0 +1,93 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + lagoon.sh/branch: main + lagoon.sh/version: v2.7.x + creationTimestamp: null + labels: + app.kubernetes.io/instance: basic2 + app.kubernetes.io/managed-by: build-deploy-tool + app.kubernetes.io/name: basic-persistent + lagoon.sh/buildType: branch + lagoon.sh/environment: main + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + lagoon.sh/service: basic2 + lagoon.sh/service-type: basic-persistent + lagoon.sh/template: basic-persistent-0.1.0 + name: basic2 +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: basic2 + app.kubernetes.io/name: basic-persistent + strategy: {} + template: + metadata: + annotations: + lagoon.sh/branch: main + lagoon.sh/configMapSha: abcdefg1234567890 + lagoon.sh/version: v2.7.x + creationTimestamp: null + labels: + app.kubernetes.io/instance: basic2 + app.kubernetes.io/managed-by: build-deploy-tool + app.kubernetes.io/name: basic-persistent + lagoon.sh/buildType: branch + lagoon.sh/environment: main + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + lagoon.sh/service: basic2 + lagoon.sh/service-type: basic-persistent + lagoon.sh/template: basic-persistent-0.1.0 + spec: + containers: + - env: + - name: LAGOON_GIT_SHA + value: abcdefg123456 + - name: CRONJOBS + - name: SERVICE_NAME + value: basic2 + envFrom: + - configMapRef: + name: lagoon-env + image: harbor.example/example-project/main/basic2@sha256:b2001babafaa8128fe89aa8fd11832cade59931d14c3de5b3ca32e2a010fbaa8 + imagePullPolicy: Always + livenessProbe: + initialDelaySeconds: 60 + tcpSocket: + port: 5672 + timeoutSeconds: 10 + name: basic + ports: + - containerPort: 5672 + name: tcp-5672 + protocol: TCP + - containerPort: 15672 + name: tcp-15672 + protocol: TCP + readinessProbe: + initialDelaySeconds: 1 + tcpSocket: + port: 5672 + timeoutSeconds: 1 + resources: + requests: + cpu: 10m + memory: 10Mi + securityContext: {} + volumeMounts: + - mountPath: /var/lib/basic + name: basic-data + enableServiceLinks: false + imagePullSecrets: + - name: lagoon-internal-registry-secret + priorityClassName: lagoon-priority-production + volumes: + - name: basic-data + persistentVolumeClaim: + claimName: basic-data +status: {} diff --git a/internal/testdata/basic/service-templates/test-basic-persistent-names/pvc-basic.yaml b/internal/testdata/basic/service-templates/test-basic-persistent-names/pvc-basic.yaml new file mode 100644 index 00000000..08fff6a4 --- /dev/null +++ b/internal/testdata/basic/service-templates/test-basic-persistent-names/pvc-basic.yaml @@ -0,0 +1,30 @@ +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + annotations: + k8up.io/backup: "true" + k8up.syn.tools/backup: "true" + lagoon.sh/branch: main + lagoon.sh/version: v2.7.x + creationTimestamp: null + labels: + app.kubernetes.io/instance: basic + app.kubernetes.io/managed-by: build-deploy-tool + app.kubernetes.io/name: basic-persistent + lagoon.sh/buildType: branch + lagoon.sh/environment: main + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + lagoon.sh/service: basic + lagoon.sh/service-type: basic-persistent + lagoon.sh/template: basic-persistent-0.1.0 + name: basic +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: 5Gi + storageClassName: bulk +status: {} diff --git a/internal/testdata/basic/service-templates/test-basic-persistent-names/service-basic.yaml b/internal/testdata/basic/service-templates/test-basic-persistent-names/service-basic.yaml new file mode 100644 index 00000000..2dba6161 --- /dev/null +++ b/internal/testdata/basic/service-templates/test-basic-persistent-names/service-basic.yaml @@ -0,0 +1,35 @@ +--- +apiVersion: v1 +kind: Service +metadata: + annotations: + lagoon.sh/branch: main + lagoon.sh/version: v2.7.x + creationTimestamp: null + labels: + app.kubernetes.io/instance: basic + app.kubernetes.io/managed-by: build-deploy-tool + app.kubernetes.io/name: basic-persistent + lagoon.sh/buildType: branch + lagoon.sh/environment: main + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + lagoon.sh/service: basic + lagoon.sh/service-type: basic-persistent + lagoon.sh/template: basic-persistent-0.1.0 + name: basic +spec: + ports: + - name: tcp-5672 + port: 5672 + protocol: TCP + targetPort: tcp-5672 + - name: tcp-15672 + port: 15672 + protocol: TCP + targetPort: tcp-15672 + selector: + app.kubernetes.io/instance: basic + app.kubernetes.io/name: basic-persistent +status: + loadBalancer: {} diff --git a/internal/testdata/basic/service-templates/test-basic-persistent-names/service-basic2.yaml b/internal/testdata/basic/service-templates/test-basic-persistent-names/service-basic2.yaml new file mode 100644 index 00000000..507d2768 --- /dev/null +++ b/internal/testdata/basic/service-templates/test-basic-persistent-names/service-basic2.yaml @@ -0,0 +1,35 @@ +--- +apiVersion: v1 +kind: Service +metadata: + annotations: + lagoon.sh/branch: main + lagoon.sh/version: v2.7.x + creationTimestamp: null + labels: + app.kubernetes.io/instance: basic2 + app.kubernetes.io/managed-by: build-deploy-tool + app.kubernetes.io/name: basic-persistent + lagoon.sh/buildType: branch + lagoon.sh/environment: main + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + lagoon.sh/service: basic2 + lagoon.sh/service-type: basic-persistent + lagoon.sh/template: basic-persistent-0.1.0 + name: basic2 +spec: + ports: + - name: tcp-5672 + port: 5672 + protocol: TCP + targetPort: tcp-5672 + - name: tcp-15672 + port: 15672 + protocol: TCP + targetPort: tcp-15672 + selector: + app.kubernetes.io/instance: basic2 + app.kubernetes.io/name: basic-persistent +status: + loadBalancer: {}