diff --git a/api/v2beta1/wfs_conversion.go b/api/v2beta1/wfs_conversion.go index 92d7e15..53ef2f3 100644 --- a/api/v2beta1/wfs_conversion.go +++ b/api/v2beta1/wfs_conversion.go @@ -39,26 +39,31 @@ func (src *WFS) ConvertTo(dstRaw conversion.Hub) error { dst := dstRaw.(*pdoknlv3.WFS) log.Printf("ConvertTo: Converting WFS from Spoke version v2beta1 to Hub version v3;"+ "source: %s/%s, target: %s/%s", src.Namespace, src.Name, dst.Namespace, dst.Name) + V3WFSHubFromV2(src, dst) - dst.ObjectMeta = src.ObjectMeta + return nil +} + +func V3WFSHubFromV2(src *WFS, target *pdoknlv3.WFS) { + target.ObjectMeta = src.ObjectMeta // Set LifeCycle if defined if src.Spec.Kubernetes.Lifecycle != nil && src.Spec.Kubernetes.Lifecycle.TTLInDays != nil { - dst.Spec.Lifecycle = &sharedModel.Lifecycle{ + target.Spec.Lifecycle = &sharedModel.Lifecycle{ TTLInDays: Pointer(int32(*src.Spec.Kubernetes.Lifecycle.TTLInDays)), } } if src.Spec.Kubernetes.Autoscaling != nil { - dst.Spec.HorizontalPodAutoscalerPatch = ConvertAutoscaling(*src.Spec.Kubernetes.Autoscaling) + target.Spec.HorizontalPodAutoscalerPatch = ConvertAutoscaling(*src.Spec.Kubernetes.Autoscaling) } // TODO converse src.Spec.Kubernetes.HealthCheck when we know what the implementation in v3 will be if src.Spec.Kubernetes.Resources != nil { - dst.Spec.PodSpecPatch = ConvertResources(*src.Spec.Kubernetes.Resources) + target.Spec.PodSpecPatch = ConvertResources(*src.Spec.Kubernetes.Resources) } - dst.Spec.Options = *ConvertOptionsV2ToV3(src.Spec.Options) + target.Spec.Options = *ConvertOptionsV2ToV3(src.Spec.Options) service := pdoknlv3.WFSService{ // TODO what is prefix, Geonovum subdomain? @@ -114,9 +119,7 @@ func (src *WFS) ConvertTo(dstRaw conversion.Hub) error { service.FeatureTypes = append(service.FeatureTypes, convertV2FeatureTypeToV3(featureType)) } - dst.Spec.Service = service - - return nil + target.Spec.Service = service } func convertV2FeatureTypeToV3(src FeatureType) pdoknlv3.FeatureType { diff --git a/api/v2beta1/wms_conversion.go b/api/v2beta1/wms_conversion.go index 08acd5e..e53bf94 100644 --- a/api/v2beta1/wms_conversion.go +++ b/api/v2beta1/wms_conversion.go @@ -43,12 +43,12 @@ func (src *WMS) ConvertTo(dstRaw conversion.Hub) error { dst := dstRaw.(*pdoknlv3.WMS) log.Printf("ConvertTo: Converting WMS from Spoke version v2beta1 to Hub version v3;"+ "source: %s/%s, target: %s/%s", src.Namespace, src.Name, dst.Namespace, dst.Name) - V3HubFromV2(src, dst) + V3WMSHubFromV2(src, dst) return nil } -func V3HubFromV2(src *WMS, target *pdoknlv3.WMS) { +func V3WMSHubFromV2(src *WMS, target *pdoknlv3.WMS) { dst := target dst.ObjectMeta = src.ObjectMeta @@ -324,6 +324,13 @@ func (v2Service WMSService) MapLayersToV3() pdoknlv3.Layer { Visible: smoothoperatorutils.Pointer(true), } + if v2Service.DataEPSG != "EPSG:28992" && v2Service.Extent != nil { + topLayer.BoundingBoxes = append(topLayer.BoundingBoxes, pdoknlv3.WMSBoundingBox{ + CRS: v2Service.DataEPSG, + BBox: sharedModel.ExtentToBBox(*v2Service.Extent), + }) + } + // adding the bottom layers to the middle layers they are grouped by for _, layer := range notGroupedLayers { bottomLayers := groupedLayers[*layer.Name] diff --git a/api/v2beta1/wms_conversion_test.go b/api/v2beta1/wms_conversion_test.go index d184e37..62b375b 100644 --- a/api/v2beta1/wms_conversion_test.go +++ b/api/v2beta1/wms_conversion_test.go @@ -14,7 +14,7 @@ func TestV2ToV3(t *testing.T) { err := yaml.Unmarshal([]byte(input), &v2wms) assert.NoError(t, err) var target pdoknlv3.WMS - V3HubFromV2(&v2wms, &target) + V3WMSHubFromV2(&v2wms, &target) assert.Equal(t, "NWB - Wegen WMS", target.Spec.Service.Title) a := 0 _ = a diff --git a/api/v3/wms_validation.go b/api/v3/wms_validation.go index a905a3c..57b4426 100644 --- a/api/v3/wms_validation.go +++ b/api/v3/wms_validation.go @@ -119,8 +119,7 @@ func validateWMS(wms *WMS, warnings *[]string, reasons *[]string) { layerReasons = append(layerReasons, "layer.boundingBoxes must contain a boundingBox for CRS '"+service.DataEPSG+"' when service.dataEPSG is not 'EPSG:28992'") } - //nolint:nestif - if !*layer.Visible { + if layer.Visible != nil && !*layer.Visible { if layer.Title != nil { *warnings = append(*warnings, sharedValidation.FormatValidationWarning("layer.title is not used when layer.visible=false", wms.GroupVersionKind(), wms.GetName())) } @@ -189,7 +188,7 @@ func validateWMS(wms *WMS, warnings *[]string, reasons *[]string) { } if layerType == GroupLayer || layerType == TopLayer { - if !*layer.Visible { + if layer.Visible != nil && !*layer.Visible { layerReasons = append(layerReasons, layerType+" must be visible") } if layer.Data != nil { diff --git a/internal/controller/capabilitiesgenerator/capabilities_generator_test.go b/internal/controller/capabilitiesgenerator/capabilities_generator_test.go index 92b5970..36880fb 100644 --- a/internal/controller/capabilitiesgenerator/capabilities_generator_test.go +++ b/internal/controller/capabilitiesgenerator/capabilities_generator_test.go @@ -648,7 +648,7 @@ func TestInputForWMS(t *testing.T) { err := yaml.Unmarshal([]byte(v2wmsstring), &v2wms) assert.NoError(t, err) var wms pdoknlv3.WMS - v2beta1.V3HubFromV2(&v2wms, &wms) + v2beta1.V3WMSHubFromV2(&v2wms, &wms) pdoknlv3.SetHost("http://localhost") contactPersonPrimary := smoothoperatorv1.ContactPersonPrimary{ diff --git a/internal/controller/legendgenerator/legend_generator_test.go b/internal/controller/legendgenerator/legend_generator_test.go index d30ba9c..973f3b6 100644 --- a/internal/controller/legendgenerator/legend_generator_test.go +++ b/internal/controller/legendgenerator/legend_generator_test.go @@ -15,7 +15,7 @@ func TestGetConfigMapDataNoLegendFix(t *testing.T) { err := yaml.Unmarshal([]byte(v2wmsstring), &v2wms) assert.NoError(t, err) var wms pdoknlv3.WMS - v2beta1.V3HubFromV2(&v2wms, &wms) + v2beta1.V3WMSHubFromV2(&v2wms, &wms) configMapData := GetConfigMapData(&wms) @@ -34,7 +34,7 @@ func TestGetConfigMapDataLegendFix(t *testing.T) { err := yaml.Unmarshal([]byte(v2wmsstring), &v2wms) assert.NoError(t, err) var wms pdoknlv3.WMS - v2beta1.V3HubFromV2(&v2wms, &wms) + v2beta1.V3WMSHubFromV2(&v2wms, &wms) configMapData := GetConfigMapData(&wms) diff --git a/test/e2e/admission_tester/admission_tester.go b/test/e2e/admission_tester/admission_tester.go new file mode 100644 index 0000000..1bd592b --- /dev/null +++ b/test/e2e/admission_tester/admission_tester.go @@ -0,0 +1,132 @@ +package main + +import ( + "errors" + "fmt" + "github.com/pdok/mapserver-operator/api/v2beta1" + pdoknlv3 "github.com/pdok/mapserver-operator/api/v3" + "io/fs" + "log" + "os" + "path/filepath" + "sigs.k8s.io/yaml" + "strings" +) + +func main() { + var k8sClusters string + fmt.Print("Enter k8s-cluster folder:\n") + fmt.Scanln(&k8sClusters) + if !strings.HasSuffix(k8sClusters, "/") { + k8sClusters += "/" + } + k8sClusters += "applications" + err := filepath.WalkDir(k8sClusters, func(path string, d fs.DirEntry, err error) error { + if strings.HasSuffix(path, "wms.yaml") { + checkWms(path) + } else if strings.HasSuffix(path, "wfs.yaml") { + checkWfs(path) + } + return nil + }) + if err != nil { + log.Fatalf("impossible to walk directories: %s", err) + } +} + +func checkWms(path string) { + print("Checking ") + print(path) + print("...") + fileString, err := getNormalizedFileString(path) + if err != nil { + return + } + + var v2wms v2beta1.WMS + err = yaml.Unmarshal([]byte(fileString), &v2wms) + if err != nil { + fmt.Printf("Could not unmarshall '%s' to v2wms", path) + return + } + var wms pdoknlv3.WMS + v2beta1.V3WMSHubFromV2(&v2wms, &wms) + warnings, err := wms.ValidateCreate() + if err != nil { + println("ERRORS") + println("###") + println(err.Error()) + println("###") + } else if len(warnings) > 0 { + println("WARNINGS") + } else { + println("OK") + } + +} + +func checkWfs(path string) { + print("Checking ") + print(path) + print("...") + fileString, err := getNormalizedFileString(path) + if err != nil { + return + } + + var v2wfs v2beta1.WFS + err = yaml.Unmarshal([]byte(fileString), &v2wfs) + if err != nil { + fmt.Printf("Could not unmarshall '%s' to v2wms", path) + return + } + var wfs pdoknlv3.WFS + v2beta1.V3WFSHubFromV2(&v2wfs, &wfs) + warnings, err := wfs.ValidateCreate() + if err != nil { + println("ERRORS") + println("###") + println(err.Error()) + println("###") + } else if len(warnings) > 0 { + println("WARNINGS") + } else { + println("OK") + } +} + +func getNormalizedFileString(path string) (string, error) { + fileBytes, err := os.ReadFile(path) + if err != nil { + return "", errors.New(fmt.Sprintf("Could not read file '%s', exiting", path)) + } + fileString := string(fileBytes) + fileString = strings.ReplaceAll(fileString, "${BLOBS_RESOURCES_BUCKET}", "resources") + fileString = strings.ReplaceAll(fileString, "${OWNER}", "owner") + fileString = strings.ReplaceAll(fileString, "${DATASET}", "dataset") + fileString = strings.ReplaceAll(fileString, "${SERVICE_VERSION}", "v1_0") + fileString = strings.ReplaceAll(fileString, "${THEME}", "theme") + fileString = strings.ReplaceAll(fileString, "${INCLUDES}", "includes") + fileString = strings.ReplaceAll(fileString, "${BLOBS_GEOPACKAGES_BUCKET}", "geopackages") + fileString = strings.ReplaceAll(fileString, "${BLOBS_TIFS_BUCKET}", "tifs") + fileString = strings.ReplaceAll(fileString, "${GPKG_VERSION}", "aaaa/1") + fileString = strings.ReplaceAll(fileString, "${ATOM_VERSION}", "bbbb/2") + fileString = strings.ReplaceAll(fileString, "${GPKG_VERSION_25}", "aaaa/1") + fileString = strings.ReplaceAll(fileString, "${GPKG_VERSION_50}", "aaaa/1") + fileString = strings.ReplaceAll(fileString, "${GPKG_VERSION_100}", "aaaa/1") + fileString = strings.ReplaceAll(fileString, "${GPKG_VERSION_250}", "aaaa/1") + fileString = strings.ReplaceAll(fileString, "${GPKG_VERSION_500}", "aaaa/1") + fileString = strings.ReplaceAll(fileString, "${GPKG_VERSION_1000}", "aaaa/1") + fileString = strings.ReplaceAll(fileString, "${GPKG_VERSION_1}", "aaaa/1") + fileString = strings.ReplaceAll(fileString, "${BLOBS_DOWNLOADS_BUCKET}", "downloads") + fileString = strings.ReplaceAll(fileString, "${LIMITS_EPHEMERAL_STORAGE}", "102M") + fileString = strings.ReplaceAll(fileString, "${REQUESTS_CPU}", "1001") + fileString = strings.ReplaceAll(fileString, "${REQUESTS_MEM}", "100M") + fileString = strings.ReplaceAll(fileString, "${REQUESTS_EPHEMERAL_STORAGE}", "101M") + fileString = strings.ReplaceAll(fileString, "${LIMITS_MEM}", "103M") + + if strings.Contains(fileString, "${") { + return "", errors.New(fmt.Sprintf("File '%s' still has an unreplaced variable", path)) + } + return fileString, nil +}