diff --git a/api/v2beta1/shared_conversion.go b/api/v2beta1/shared_conversion.go index abcadd3..091ef6f 100644 --- a/api/v2beta1/shared_conversion.go +++ b/api/v2beta1/shared_conversion.go @@ -75,7 +75,7 @@ func ConvertAutoscaling(src Autoscaling) *pdoknlv3.HorizontalPodAutoscalerPatch return &pdoknlv3.HorizontalPodAutoscalerPatch{ MinReplicas: minReplicas, - MaxReplicas: maxReplicas, + MaxReplicas: &maxReplicas, Metrics: metrics, } } @@ -221,8 +221,10 @@ func NewV2KubernetesObject(lifecycle *smoothoperatormodel.Lifecycle, podSpecPatc kub.Resources = &podSpecPatch.Containers[0].Resources if scalingSpec != nil { - kub.Autoscaling = &Autoscaling{ - MaxReplicas: smoothoperatorutils.Pointer(int(scalingSpec.MaxReplicas)), + kub.Autoscaling = &Autoscaling{} + + if scalingSpec.MaxReplicas != nil { + kub.Autoscaling.MaxReplicas = smoothoperatorutils.Pointer(int(*scalingSpec.MaxReplicas)) } if scalingSpec.MinReplicas != nil { diff --git a/api/v2beta1/wfs_conversion.go b/api/v2beta1/wfs_conversion.go index bccbb8e..2a394a3 100644 --- a/api/v2beta1/wfs_conversion.go +++ b/api/v2beta1/wfs_conversion.go @@ -26,6 +26,7 @@ package v2beta1 import ( "log" + "strconv" pdoknlv3 "github.com/pdok/mapserver-operator/api/v3" smoothoperatormodel "github.com/pdok/smooth-operator/model" @@ -43,7 +44,7 @@ func (src *WFS) ConvertTo(dstRaw conversion.Hub) error { return src.ToV3(dst) } -//nolint:gosec +//nolint:gosec,funlen,cyclop func (src *WFS) ToV3(dst *pdoknlv3.WFS) error { dst.ObjectMeta = src.ObjectMeta @@ -76,6 +77,20 @@ func (src *WFS) ToV3(dst *pdoknlv3.WFS) error { return err } + accessConstraints, err := url.Parse("https://creativecommons.org/publicdomain/zero/1.0/deed.nl") + if err != nil { + return err + } + if src.Spec.Service.AccessConstraints != nil { + accessConstraints, err = url.Parse(*src.Spec.Service.AccessConstraints) + if err != nil { + return err + } + } + + if err != nil { + return err + } service := pdoknlv3.WFSService{ Prefix: src.Spec.General.Dataset, URL: *url, @@ -84,7 +99,7 @@ func (src *WFS) ToV3(dst *pdoknlv3.WFS) error { Abstract: src.Spec.Service.Abstract, Keywords: src.Spec.Service.Keywords, Fees: nil, - AccessConstraints: src.Spec.Service.AccessConstraints, + AccessConstraints: smoothoperatormodel.URL{URL: accessConstraints}, DefaultCrs: src.Spec.Service.DataEPSG, OtherCrs: []string{ "EPSG::25831", @@ -95,10 +110,17 @@ func (src *WFS) ToV3(dst *pdoknlv3.WFS) error { "EPSG::4258", "EPSG::4326", }, - CountDefault: src.Spec.Service.Maxfeatures, FeatureTypes: make([]pdoknlv3.FeatureType, 0), } + if src.Spec.Service.Maxfeatures != nil { + maxFeatures, err := strconv.Atoi(*src.Spec.Service.Maxfeatures) + if err != nil { + return err + } + service.CountDefault = &maxFeatures + } + if src.Spec.Service.Mapfile != nil { service.Mapfile = &pdoknlv3.Mapfile{ ConfigMapKeyRef: src.Spec.Service.Mapfile.ConfigMapKeyRef, @@ -148,7 +170,7 @@ func convertV2FeatureTypeToV3(src FeatureType) pdoknlv3.FeatureType { Title: src.Title, Abstract: src.Abstract, Keywords: src.Keywords, - DatasetMetadataURL: pdoknlv3.MetadataURL{ + DatasetMetadataURL: &pdoknlv3.MetadataURL{ CSW: &pdoknlv3.Metadata{ MetadataIdentifier: src.DatasetMetadataIdentifier, }, @@ -190,19 +212,24 @@ func (dst *WFS) ConvertFrom(srcRaw conversion.Hub) error { } } + accessConstraints := src.Spec.Service.AccessConstraints.String() + service := WFSService{ Title: src.Spec.Service.Title, Abstract: src.Spec.Service.Abstract, Keywords: src.Spec.Service.Keywords, - AccessConstraints: src.Spec.Service.AccessConstraints, + AccessConstraints: &accessConstraints, DataEPSG: src.Spec.Service.DefaultCrs, - Maxfeatures: src.Spec.Service.CountDefault, Authority: Authority{ Name: "", URL: "", }, } + if src.Spec.Service.CountDefault != nil { + service.Maxfeatures = smoothoperatorutils.Pointer(strconv.Itoa(*src.Spec.Service.CountDefault)) + } + if src.Spec.Service.Bbox != nil { service.Extent = smoothoperatorutils.Pointer(src.Spec.Service.Bbox.DefaultCRS.ToExtent()) } else { diff --git a/api/v3/shared_types.go b/api/v3/shared_types.go index 56bcf97..df725ae 100644 --- a/api/v3/shared_types.go +++ b/api/v3/shared_types.go @@ -25,7 +25,7 @@ const ( // This way we don't have to specify the scaleTargetRef field in the CRD. type HorizontalPodAutoscalerPatch struct { MinReplicas *int32 `json:"minReplicas,omitempty"` - MaxReplicas int32 `json:"maxReplicas"` + MaxReplicas *int32 `json:"maxReplicas,omitempty"` Metrics []autoscalingv2.MetricSpec `json:"metrics,omitempty"` Behavior *autoscalingv2.HorizontalPodAutoscalerBehavior `json:"behavior,omitempty"` } @@ -167,7 +167,7 @@ type Data struct { // +kubebuilder:validation:Type=object type Gpkg struct { // Blobkey identifies the location/bucket of the .gpkg file - // +kubebuilder:validation:Pattern=`\.gpkg$` + // +kubebuilder:validation:Pattern:=^.+\/.+\/.+\.gpkg$ // +kubebuilder:validation:MinLength:=1 BlobKey string `json:"blobKey"` diff --git a/api/v3/shared_validation.go b/api/v3/shared_validation.go index e63cb01..6c240bd 100644 --- a/api/v3/shared_validation.go +++ b/api/v3/shared_validation.go @@ -1,7 +1,10 @@ package v3 import ( + "fmt" + sharedValidation "github.com/pdok/smooth-operator/pkg/validation" + v1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/util/validation/field" @@ -34,3 +37,41 @@ func ValidateUpdate[W WMSWFS](newW, oldW W, validate func(W, *[]string, *field.E newW.GroupKind(), newW.GetName(), allErrs) } + +func ValidateHorizontalPodAutoscalerPatch(patch HorizontalPodAutoscalerPatch, allErrs *field.ErrorList) { + path := field.NewPath("spec").Child("horizontalPodAutoscaler") + // TODO: replace hardcoded defaults with dynamic defaults from cli options or ownerInfo + var minReplicas, maxReplicas int32 = 2, 32 + if patch.MinReplicas != nil { + minReplicas = *patch.MinReplicas + } + if patch.MaxReplicas != nil { + maxReplicas = *patch.MaxReplicas + } + + if maxReplicas < minReplicas { + replicas := fmt.Sprintf("minReplicas: %d, maxReplicas: %d", minReplicas, maxReplicas) + + *allErrs = append(*allErrs, field.Invalid(path, replicas, "maxReplicas cannot be less than minReplicas")) + } + +} + +func ValidateEphemeralStorage(podSpecPatch v1.PodSpec, allErrs *field.ErrorList) { + path := field.NewPath("spec"). + Child("podSpecPatch"). + Child("containers"). + Key("mapserver"). + Child("resources"). + Child("limits"). + Child(v1.ResourceEphemeralStorage.String()) + storageSet := false + for _, container := range podSpecPatch.Containers { + if container.Name == "mapserver" { + _, storageSet = container.Resources.Limits[v1.ResourceEphemeralStorage] + } + } + if !storageSet { + *allErrs = append(*allErrs, field.Required(path, "")) + } +} diff --git a/api/v3/wfs_types.go b/api/v3/wfs_types.go index f502c67..dae9b82 100644 --- a/api/v3/wfs_types.go +++ b/api/v3/wfs_types.go @@ -118,6 +118,7 @@ type WFSService struct { // Keywords for capabilities // +kubebuilder:validation:MinItems:=1 + // +kubebuilder:validation:items:MinLength:=1 Keywords []string `json:"keywords"` // Optional Fees @@ -125,10 +126,8 @@ type WFSService struct { Fees *string `json:"fees,omitempty"` // AccessConstraints URL - // +kubebuilder:validation:Pattern:="https?://" // +kubebuilder:default="https://creativecommons.org/publicdomain/zero/1.0/deed.nl" - // +kubebuilder:validation:MinLength:=1 - AccessConstraints *string `json:"accessConstraints,omitempty"` + AccessConstraints smoothoperatormodel.URL `json:"accessConstraints,omitempty"` // Default CRS (DataEPSG) // +kubebuilder:validation:Pattern:="^EPSG:(28992|25831|25832|3034|3035|3857|4258|4326)$" @@ -143,8 +142,8 @@ type WFSService struct { Bbox *Bbox `json:"bbox,omitempty"` // CountDefault -> wfs_maxfeatures in mapfile - // +kubebuilder:validation:MinLength:=1 - CountDefault *string `json:"countDefault,omitempty"` + // +kubebuilder:validation:Minimum:=1 + CountDefault *int `json:"countDefault,omitempty"` // FeatureTypes configurations // +kubebuilder:validation:MinItems:=1 @@ -164,6 +163,8 @@ func (s WFSService) KeywordsIncludingInspireKeyword() []string { // HealthCheck is the struct with all fields to configure custom healthchecks type HealthCheckWFS struct { // +kubebuilder:validation:MinLength:=1 + // +kubebuilder:validation:XValidation:rule="self.contains('Service=WFS')",message="a valid healthcheck contains 'Service=WFS'" + // +kubebuilder:validation:XValidation:rule="self.contains('Request=')",message="a valid healthcheck contains 'Request='" Querystring string `json:"querystring"` // +kubebuilder:validation:Pattern=(image/png|text/xml|text/html) Mimetype string `json:"mimetype"` @@ -192,11 +193,12 @@ type FeatureType struct { // Keywords of the feature // +kubebuilder:validation:MinItems:=1 + // +kubebuilder:validation:items:MinLength:=1 Keywords []string `json:"keywords"` // Metadata URL // +kubebuilder:validation:Type=object - DatasetMetadataURL MetadataURL `json:"datasetMetadataUrl"` + DatasetMetadataURL *MetadataURL `json:"datasetMetadataUrl,omitempty"` // Optional feature bbox // +kubebuilder:validation:Optional diff --git a/api/v3/wfs_validation.go b/api/v3/wfs_validation.go index 5d13f11..d951d84 100644 --- a/api/v3/wfs_validation.go +++ b/api/v3/wfs_validation.go @@ -3,8 +3,6 @@ package v3 import ( "strings" - corev1 "k8s.io/api/core/v1" - sharedValidation "github.com/pdok/smooth-operator/pkg/validation" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -58,25 +56,10 @@ func ValidateWFS(wfs *WFS, warnings *[]string, allErrs *field.ErrorList) { sharedValidation.AddWarning(warnings, *path.Child("bbox"), "is not used when service.mapfile is configured", wfs.GroupVersionKind(), wfs.GetName()) } + if wfs.Spec.HorizontalPodAutoscalerPatch != nil { + ValidateHorizontalPodAutoscalerPatch(*wfs.Spec.HorizontalPodAutoscalerPatch, allErrs) + } + podSpecPatch := wfs.Spec.PodSpecPatch ValidateEphemeralStorage(podSpecPatch, allErrs) } - -func ValidateEphemeralStorage(podSpecPatch corev1.PodSpec, allErrs *field.ErrorList) { - path := field.NewPath("spec"). - Child("podSpecPatch"). - Child("containers"). - Key("mapserver"). - Child("resources"). - Child("limits"). - Child(corev1.ResourceEphemeralStorage.String()) - storageSet := false - for _, container := range podSpecPatch.Containers { - if container.Name == "mapserver" { - _, storageSet = container.Resources.Limits[corev1.ResourceEphemeralStorage] - } - } - if !storageSet { - *allErrs = append(*allErrs, field.Required(path, "")) - } -} diff --git a/api/v3/wms_types.go b/api/v3/wms_types.go index a4f8b3c..b83dfcc 100644 --- a/api/v3/wms_types.go +++ b/api/v3/wms_types.go @@ -90,6 +90,7 @@ type WMSService struct { // Keywords of the service // +kubebuilder:validation:MinItems:=1 + // +kubebuilder:validation:items:MinLength:=1 Keywords []string `json:"keywords"` // Reference to a CR of Kind OwnerInfo diff --git a/api/v3/wms_validation.go b/api/v3/wms_validation.go index 861c03d..a2d42f9 100644 --- a/api/v3/wms_validation.go +++ b/api/v3/wms_validation.go @@ -291,6 +291,10 @@ func ValidateWMS(wms *WMS, warnings *[]string, allErrs *field.ErrorList) { )) } + if wms.Spec.HorizontalPodAutoscalerPatch != nil { + ValidateHorizontalPodAutoscalerPatch(*wms.Spec.HorizontalPodAutoscalerPatch, allErrs) + } + podSpecPatch := wms.Spec.PodSpecPatch ValidateEphemeralStorage(podSpecPatch, allErrs) } diff --git a/api/v3/zz_generated.deepcopy.go b/api/v3/zz_generated.deepcopy.go index decf3c5..c46f1b8 100644 --- a/api/v3/zz_generated.deepcopy.go +++ b/api/v3/zz_generated.deepcopy.go @@ -200,7 +200,11 @@ func (in *FeatureType) DeepCopyInto(out *FeatureType) { *out = make([]string, len(*in)) copy(*out, *in) } - in.DatasetMetadataURL.DeepCopyInto(&out.DatasetMetadataURL) + if in.DatasetMetadataURL != nil { + in, out := &in.DatasetMetadataURL, &out.DatasetMetadataURL + *out = new(MetadataURL) + (*in).DeepCopyInto(*out) + } if in.Bbox != nil { in, out := &in.Bbox, &out.Bbox *out = new(FeatureBbox) @@ -294,6 +298,11 @@ func (in *HorizontalPodAutoscalerPatch) DeepCopyInto(out *HorizontalPodAutoscale *out = new(int32) **out = **in } + if in.MaxReplicas != nil { + in, out := &in.MaxReplicas, &out.MaxReplicas + *out = new(int32) + **out = **in + } if in.Metrics != nil { in, out := &in.Metrics, &out.Metrics *out = make([]v2.MetricSpec, len(*in)) @@ -691,11 +700,7 @@ func (in *WFSService) DeepCopyInto(out *WFSService) { *out = new(string) **out = **in } - if in.AccessConstraints != nil { - in, out := &in.AccessConstraints, &out.AccessConstraints - *out = new(string) - **out = **in - } + in.AccessConstraints.DeepCopyInto(&out.AccessConstraints) if in.OtherCrs != nil { in, out := &in.OtherCrs, &out.OtherCrs *out = make([]string, len(*in)) @@ -708,7 +713,7 @@ func (in *WFSService) DeepCopyInto(out *WFSService) { } if in.CountDefault != nil { in, out := &in.CountDefault, &out.CountDefault - *out = new(string) + *out = new(int) **out = **in } if in.FeatureTypes != nil { diff --git a/config/crd/bases/pdok.nl_wfs.yaml b/config/crd/bases/pdok.nl_wfs.yaml index 6670b55..f89d7c7 100644 --- a/config/crd/bases/pdok.nl_wfs.yaml +++ b/config/crd/bases/pdok.nl_wfs.yaml @@ -466,6 +466,11 @@ spec: querystring: minLength: 1 type: string + x-kubernetes-validations: + - message: a valid healthcheck contains 'Service=WFS' + rule: self.contains('Service=WFS') + - message: a valid healthcheck contains 'Request=' + rule: self.contains('Request=') required: - mimetype - querystring @@ -1058,8 +1063,6 @@ spec: minReplicas: format: int32 type: integer - required: - - maxReplicas type: object lifecycle: description: Optional lifecycle settings @@ -1132,8 +1135,7 @@ spec: accessConstraints: default: https://creativecommons.org/publicdomain/zero/1.0/deed.nl description: AccessConstraints URL - minLength: 1 - pattern: https?:// + pattern: ^https?://.+/.+ type: string bbox: description: Service bounding box @@ -1168,8 +1170,8 @@ spec: type: object countDefault: description: CountDefault -> wfs_maxfeatures in mapfile - minLength: 1 - type: string + minimum: 1 + type: integer defaultCrs: description: Default CRS (DataEPSG) minLength: 1 @@ -1252,7 +1254,7 @@ spec: description: Blobkey identifies the location/bucket of the .gpkg file minLength: 1 - pattern: \.gpkg$ + pattern: ^.+\/.+\/.+\.gpkg$ type: string columns: description: Columns to visualize for this table @@ -1405,6 +1407,7 @@ spec: keywords: description: Keywords of the feature items: + minLength: 1 type: string minItems: 1 type: array @@ -1419,7 +1422,6 @@ spec: required: - abstract - data - - datasetMetadataUrl - keywords - name - title @@ -1487,6 +1489,7 @@ spec: keywords: description: Keywords for capabilities items: + minLength: 1 type: string minItems: 1 type: array diff --git a/config/crd/bases/pdok.nl_wms.yaml b/config/crd/bases/pdok.nl_wms.yaml index 5eadab7..bb36e92 100644 --- a/config/crd/bases/pdok.nl_wms.yaml +++ b/config/crd/bases/pdok.nl_wms.yaml @@ -1084,8 +1084,6 @@ spec: minReplicas: format: int32 type: integer - required: - - maxReplicas type: object lifecycle: description: Optional lifecycle settings @@ -1213,6 +1211,7 @@ spec: keywords: description: Keywords of the service items: + minLength: 1 type: string minItems: 1 type: array @@ -1280,7 +1279,7 @@ spec: blobKey: description: Blobkey identifies the location/bucket of the .gpkg file minLength: 1 - pattern: \.gpkg$ + pattern: ^.+\/.+\/.+\.gpkg$ type: string columns: description: Columns to visualize for this table @@ -1488,7 +1487,7 @@ spec: blobKey: description: Blobkey identifies the location/bucket of the .gpkg file minLength: 1 - pattern: \.gpkg$ + pattern: ^.+\/.+\/.+\.gpkg$ type: string columns: description: Columns to visualize for this table @@ -1696,7 +1695,7 @@ spec: blobKey: description: Blobkey identifies the location/bucket of the .gpkg file minLength: 1 - pattern: \.gpkg$ + pattern: ^.+\/.+\/.+\.gpkg$ type: string columns: description: Columns to visualize for this table diff --git a/config/samples/v3_wfs.yaml b/config/samples/v3_wfs.yaml index 8119da5..eca4c69 100644 --- a/config/samples/v3_wfs.yaml +++ b/config/samples/v3_wfs.yaml @@ -1,92 +1,42 @@ apiVersion: pdok.nl/v3 kind: WFS metadata: + name: sample labels: - app.kubernetes.io/name: mapserver-operator - app.kubernetes.io/managed-by: kustomize - dataset: dataset - dataset-owner: eigenaar - service-type: wfs - service-version: 1.0.0 - name: sample-v3 + sample: sample spec: - lifecycle: - ttlInDays: 21 podSpecPatch: containers: - name: mapserver resources: limits: - memory: 12M ephemeral-storage: 2G - horizontalPodAutoscalerPatch: - scaleTargetRef: - apiVersion: apps/v1 - kind: Deployment - name: wfs-sample-v3 - maxReplicas: 5 - minReplicas: 2 - metrics: - - type: "Resource" - resource: - name: cpu - target: - type: Utilization - averageUtilization: 60 - options: - automaticCasing: true - prefetchData: false - includeIngress: false service: - prefix: "" - url: https://service.pdok.nl/eigenaar/dataset/wfs/1.0.0 + accessConstraints: "http://bla/bla" + title: "title" + abstract: "abstract" + defaultCrs: "EPSG:28992" + keywords: + - "keyword" + ownerInfoRef: "owner" + prefix: "prefix" + url: "http://host/path" inspire: + language: dut serviceMetadataUrl: csw: - metadataIdentifier: 68a42961-ed55-436b-a412-cc7424fd2a6e - spatialDatasetIdentifier: "" - language: "dut" - ownerInfoRef: pdok - title: "Dataset" - abstract: "Dataset beschrijving ..." - keywords: - - keyword1 - - keyword2 - fees: "" - accessConstraints: "" - defaultCrs: "EPSG:28992" - bbox: - defaultCRS: - minx: "0" - maxx: "280000" - miny: "300000" - maxy: "625000" - countDefault: "12" + metadataIdentifier: testtest-test-test-test-testtesttest + spatialDatasetIdentifier: testtest-test-test-test-testtesttest featureTypes: - - name: Feature1 - title: Feature1 - abstract: "Feature 1 beschrijving..." + - name: "name" + title: "title" + abstract: "abstract" keywords: - - keyword1 - - keyword2 - datasetMetadataUrl: - csw: - metadataIdentifier: 07d73b60-dfd6-4c54-9c82-9fac70c6c48e - bbox: - defaultCRS: # EXTENT/wfs_extent in mapfile - minx: "0" - maxx: "280000" - miny: "300000" - maxy: "625000" + - "word" data: gpkg: - blobKey: eigenaar/dataset/data.gpkg - tableName: table1 - geometryType: "MultiPolygon" + blobKey: "container/prefix/file.gpkg" columns: - - name: naam - - name: gebiedsnum - alias: gebiedsnummer - - name: besluitnum - - name: besluitdat - alias: datum + - name: "column" + geometryType: "Point" + tableName: "table" diff --git a/internal/controller/capabilitiesgenerator/capabilities_generator_test.go b/internal/controller/capabilitiesgenerator/capabilities_generator_test.go index e157a34..b216bb7 100644 --- a/internal/controller/capabilitiesgenerator/capabilities_generator_test.go +++ b/internal/controller/capabilitiesgenerator/capabilities_generator_test.go @@ -30,6 +30,7 @@ func TestGetInputForWFS(t *testing.T) { } url, _ := smoothoperatormodel.ParseURL("http://localhost/datasetOwner/dataset/theme/wfs/v1_0") pdoknlv3.SetHost("http://localhost") + accessConstraints, _ := smoothoperatormodel.ParseURL("http://creativecommons.org/publicdomain/zero/1.0/deed.nl") tests := []struct { name string args args @@ -54,7 +55,7 @@ func TestGetInputForWFS(t *testing.T) { Title: "some Service title", Abstract: "some \"Service\" abstract", Keywords: []string{"service-keyword-1", "service-keyword-2", "infoFeatureAccessService"}, - AccessConstraints: smoothoperatorutils.Pointer("http://creativecommons.org/publicdomain/zero/1.0/deed.nl"), + AccessConstraints: smoothoperatormodel.URL{URL: accessConstraints}, Inspire: &pdoknlv3.Inspire{ ServiceMetadataURL: pdoknlv3.MetadataURL{ CSW: &pdoknlv3.Metadata{ @@ -81,7 +82,7 @@ func TestGetInputForWFS(t *testing.T) { Title: "featuretype-1-title", Abstract: "feature \"1\" abstract", Keywords: []string{"featuretype-1-keyword-1", "featuretype-1-keyword-2"}, - DatasetMetadataURL: pdoknlv3.MetadataURL{ + DatasetMetadataURL: &pdoknlv3.MetadataURL{ CSW: &pdoknlv3.Metadata{ MetadataIdentifier: "datadata-data-data-data-datadatadata", }, @@ -92,7 +93,7 @@ func TestGetInputForWFS(t *testing.T) { Title: "featuretype-2-title", Abstract: "feature \"2\" abstract", Keywords: []string{"featuretype-2-keyword-1", "featuretype-2-keyword-2"}, - DatasetMetadataURL: pdoknlv3.MetadataURL{ + DatasetMetadataURL: &pdoknlv3.MetadataURL{ CSW: &pdoknlv3.Metadata{ MetadataIdentifier: "datadata-data-data-data-datadatadata", }, diff --git a/internal/controller/capabilitiesgenerator/mapper.go b/internal/controller/capabilitiesgenerator/mapper.go index 454b641..17f27bf 100644 --- a/internal/controller/capabilitiesgenerator/mapper.go +++ b/internal/controller/capabilitiesgenerator/mapper.go @@ -54,7 +54,7 @@ func MapWFSToCapabilitiesGeneratorInput(wfs *pdoknlv3.WFS, ownerInfo *smoothoper ServiceIdentification: wfs200.ServiceIdentification{ Title: mapperutils.EscapeQuotes(wfs.Spec.Service.Title), Abstract: mapperutils.EscapeQuotes(wfs.Spec.Service.Abstract), - AccessConstraints: *wfs.Spec.Service.AccessConstraints, + AccessConstraints: wfs.Spec.Service.AccessConstraints.String(), Keywords: &wsc110.Keywords{ Keyword: wfs.Spec.Service.KeywordsIncludingInspireKeyword(), }, @@ -91,6 +91,17 @@ func MapWFSToCapabilitiesGeneratorInput(wfs *pdoknlv3.WFS, ownerInfo *smoothoper }, } } + if wfs.Spec.Service.CountDefault != nil { + operationsMetadata := config.Services.WFS200Config.Wfs200.Capabilities.OperationsMetadata + if operationsMetadata == nil { + operationsMetadata = &wfs200.OperationsMetadata{} + } + operationsMetadata.Constraint = append(operationsMetadata.Constraint, wfs200.Constraint{ + Name: "CountDefault", + DefaultValue: smoothoperatorutils.Pointer(strconv.Itoa(*wfs.Spec.Service.CountDefault)), + }) + config.Services.WFS200Config.Wfs200.Capabilities.OperationsMetadata = operationsMetadata + } return &config, nil } diff --git a/internal/controller/mapfilegenerator/mapper.go b/internal/controller/mapfilegenerator/mapper.go index 80193e7..992490a 100644 --- a/internal/controller/mapfilegenerator/mapper.go +++ b/internal/controller/mapfilegenerator/mapper.go @@ -48,7 +48,7 @@ func MapWFSToMapfileGeneratorInput(wfs *pdoknlv3.WFS, ownerInfo *smoothoperatorv metadataID = wfs.Spec.Service.Inspire.ServiceMetadataURL.CSW.MetadataIdentifier } - var extent string + extent := defaultExtent if wfs.Spec.Service.Bbox != nil { extent = wfs.Spec.Service.Bbox.DefaultCRS.ToExtent() } @@ -70,7 +70,7 @@ func MapWFSToMapfileGeneratorInput(wfs *pdoknlv3.WFS, ownerInfo *smoothoperatorv EPSGList: defaultEpsgList, // wfs.Spec.Service.OtherCrs, DebugLevel: mapserverDebugLevel, }, - MaxFeatures: smoothoperatorutils.PointerVal(wfs.Spec.Service.CountDefault, strconv.Itoa(defaultMaxFeatures)), + MaxFeatures: strconv.Itoa(smoothoperatorutils.PointerVal(wfs.Spec.Service.CountDefault, defaultMaxFeatures)), Layers: getWFSLayers(wfs.Spec.Service), } diff --git a/internal/controller/test_data/wfs/complete/expected/deployment.yaml b/internal/controller/test_data/wfs/complete/expected/deployment.yaml index 6a375b5..3c18f5c 100644 --- a/internal/controller/test_data/wfs/complete/expected/deployment.yaml +++ b/internal/controller/test_data/wfs/complete/expected/deployment.yaml @@ -97,7 +97,7 @@ spec: command: - /bin/sh - -c - - 'wget -SO- -T 10 -t 2 ''http://127.0.0.1:80/mapserver?test=123'' + - 'wget -SO- -T 10 -t 2 ''http://127.0.0.1:80/mapserver?Service=WFS&Request=GetCapabilities'' 2>&1 | egrep -aiA10 ''HTTP/1.1 200'' | egrep -i ''Content-Type: text/html''' successThreshold: 1 failureThreshold: 3 @@ -116,7 +116,7 @@ spec: command: - /bin/sh - -c - - 'wget -SO- -T 10 -t 2 ''http://127.0.0.1:80/mapserver?test=123'' + - 'wget -SO- -T 10 -t 2 ''http://127.0.0.1:80/mapserver?Service=WFS&Request=GetCapabilities'' 2>&1 | egrep -aiA10 ''HTTP/1.1 200'' | egrep -i ''Content-Type: text/html''' successThreshold: 1 failureThreshold: 3 diff --git a/internal/controller/test_data/wfs/complete/expected/ingressroute.yaml b/internal/controller/test_data/wfs/complete/expected/ingressroute.yaml index aecd241..320ae82 100644 --- a/internal/controller/test_data/wfs/complete/expected/ingressroute.yaml +++ b/internal/controller/test_data/wfs/complete/expected/ingressroute.yaml @@ -22,7 +22,7 @@ metadata: uptime.pdok.nl/id: fbe1241d4fed04fb85d2135f182427861156f692 uptime.pdok.nl/name: COMPLETE INSPIRE WFS uptime.pdok.nl/tags: public-stats,wfs,inspire - uptime.pdok.nl/url: http://localhost:32788/datasetOwner/dataset/theme/wfs/v1_0?test=123 + uptime.pdok.nl/url: http://localhost:32788/datasetOwner/dataset/theme/wfs/v1_0?Service=WFS&Request=GetCapabilities spec: routes: - kind: Rule diff --git a/internal/controller/test_data/wfs/complete/input/wfs.yaml b/internal/controller/test_data/wfs/complete/input/wfs.yaml index b2f9efe..17597f8 100644 --- a/internal/controller/test_data/wfs/complete/input/wfs.yaml +++ b/internal/controller/test_data/wfs/complete/input/wfs.yaml @@ -11,7 +11,7 @@ metadata: namespace: default spec: healthCheck: - querystring: test=123 + querystring: Service=WFS&Request=GetCapabilities mimetype: text/html horizontalPodAutoscalerPatch: maxReplicas: 50