Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions api/v2beta1/shared_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,17 @@ func ConvertOptionsV2ToV3(src *WMSWFSOptions) *pdoknlv3.Options {
}

return &pdoknlv3.Options{
AutomaticCasing: src.AutomaticCasing,
IncludeIngress: src.IncludeIngress,
PrefetchData: smoothoperatorutils.PointerVal(src.PrefetchData, defaults.PrefetchData),
ValidateRequests: smoothoperatorutils.PointerVal(src.ValidateRequests, defaults.ValidateRequests),
RewriteGroupToDataLayers: smoothoperatorutils.PointerVal(src.RewriteGroupToDataLayers, defaults.RewriteGroupToDataLayers),
DisableWebserviceProxy: smoothoperatorutils.PointerVal(src.DisableWebserviceProxy, defaults.DisableWebserviceProxy),
ValidateChildStyleNameEqual: smoothoperatorutils.PointerVal(src.ValidateChildStyleNameEqual, defaults.ValidateChildStyleNameEqual),
BaseOptions: pdoknlv3.BaseOptions{
AutomaticCasing: src.AutomaticCasing,
IncludeIngress: src.IncludeIngress,
PrefetchData: smoothoperatorutils.PointerVal(src.PrefetchData, defaults.PrefetchData),
},
WMSOptions: pdoknlv3.WMSOptions{
ValidateRequests: smoothoperatorutils.PointerVal(src.ValidateRequests, defaults.ValidateRequests),
RewriteGroupToDataLayers: smoothoperatorutils.PointerVal(src.RewriteGroupToDataLayers, defaults.RewriteGroupToDataLayers),
DisableWebserviceProxy: smoothoperatorutils.PointerVal(src.DisableWebserviceProxy, defaults.DisableWebserviceProxy),
ValidateChildStyleNameEqual: smoothoperatorutils.PointerVal(src.ValidateChildStyleNameEqual, defaults.ValidateChildStyleNameEqual),
},
}
}

Expand Down
28 changes: 15 additions & 13 deletions api/v2beta1/wfs_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func (src *WFS) ToV3(dst *pdoknlv3.WFS) error {
dst.Spec.PodSpecPatch = ConvertResources(*src.Spec.Kubernetes.Resources)
}

dst.Spec.Options = ConvertOptionsV2ToV3(src.Spec.Options)
dst.Spec.Options = &ConvertOptionsV2ToV3(src.Spec.Options).BaseOptions

if src.Spec.Kubernetes.HealthCheck != nil {
dst.Spec.HealthCheck = &pdoknlv3.HealthCheckWFS{
Expand Down Expand Up @@ -92,15 +92,17 @@ func (src *WFS) ToV3(dst *pdoknlv3.WFS) error {
return err
}
service := pdoknlv3.WFSService{
Prefix: src.Spec.General.Dataset,
URL: *url,
OwnerInfoRef: "pdok",
Title: src.Spec.Service.Title,
Abstract: src.Spec.Service.Abstract,
Keywords: src.Spec.Service.Keywords,
Fees: nil,
AccessConstraints: smoothoperatormodel.URL{URL: accessConstraints},
DefaultCrs: src.Spec.Service.DataEPSG,
BaseService: pdoknlv3.BaseService{
Prefix: src.Spec.General.Dataset,
URL: *url,
OwnerInfoRef: "pdok",
Title: src.Spec.Service.Title,
Abstract: src.Spec.Service.Abstract,
Keywords: src.Spec.Service.Keywords,
Fees: nil,
AccessConstraints: smoothoperatormodel.URL{URL: accessConstraints},
},
DefaultCrs: src.Spec.Service.DataEPSG,
OtherCrs: []string{
"EPSG:25831",
"EPSG:25832",
Expand Down Expand Up @@ -144,14 +146,14 @@ func (src *WFS) ToV3(dst *pdoknlv3.WFS) error {

// TODO - where to place the MetadataIdentifier and FeatureTypes[0].SourceMetadataIdentifier if the service is not inspire?
if src.Spec.Service.Inspire {
service.Inspire = &pdoknlv3.Inspire{
service.Inspire = &pdoknlv3.WFSInspire{Inspire: pdoknlv3.Inspire{
ServiceMetadataURL: pdoknlv3.MetadataURL{
CSW: &pdoknlv3.Metadata{
MetadataIdentifier: src.Spec.Service.MetadataIdentifier,
},
},
Language: "dut"},
SpatialDatasetIdentifier: src.Spec.Service.FeatureTypes[0].SourceMetadataIdentifier,
Language: "dut",
}
}

Expand Down Expand Up @@ -203,7 +205,7 @@ func (dst *WFS) ConvertFrom(srcRaw conversion.Hub) error {

dst.Spec.Kubernetes = NewV2KubernetesObject(src.Spec.Lifecycle, src.Spec.PodSpecPatch, src.Spec.HorizontalPodAutoscalerPatch)

dst.Spec.Options = ConvertOptionsV3ToV2(src.Spec.Options)
dst.Spec.Options = ConvertOptionsV3ToV2(&pdoknlv3.Options{BaseOptions: *src.Spec.Options})

if src.Spec.HealthCheck != nil {
dst.Spec.Kubernetes.HealthCheck = &HealthCheck{
Expand Down
37 changes: 25 additions & 12 deletions api/v2beta1/wms_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import (
"strconv"
"strings"

"k8s.io/utils/ptr"

pdoknlv3 "github.com/pdok/mapserver-operator/api/v3"
smoothoperatormodel "github.com/pdok/smooth-operator/model"
smoothoperatorutils "github.com/pdok/smooth-operator/pkg/util"
Expand All @@ -47,7 +49,7 @@ func (src *WMS) ConvertTo(dstRaw conversion.Hub) error {
return src.ToV3(dst)
}

//nolint:gosec
//nolint:gosec,cyclop,funlen
func (src *WMS) ToV3(target *pdoknlv3.WMS) error {
dst := target

Expand Down Expand Up @@ -79,20 +81,32 @@ func (src *WMS) ToV3(target *pdoknlv3.WMS) error {
return err
}

service := pdoknlv3.WMSService{
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
}
}

service := pdoknlv3.WMSService{BaseService: pdoknlv3.BaseService{
Prefix: src.Spec.General.Dataset,
URL: *url,
OwnerInfoRef: "pdok",
Title: src.Spec.Service.Title,
Abstract: src.Spec.Service.Abstract,
Keywords: src.Spec.Service.Keywords,
AccessConstraints: smoothoperatorutils.PointerVal(src.Spec.Service.AccessConstraints, "https://creativecommons.org/publicdomain/zero/1.0/deed.nl"),
MaxSize: nil,
Resolution: nil,
DefResolution: nil,
Inspire: nil,
DataEPSG: src.Spec.Service.DataEPSG,
Layer: src.Spec.Service.MapLayersToV3(),
AccessConstraints: smoothoperatormodel.URL{URL: accessConstraints},
},
Inspire: nil,
MaxSize: nil,
Resolution: nil,
DefResolution: nil,
DataEPSG: src.Spec.Service.DataEPSG,
Layer: src.Spec.Service.MapLayersToV3(),
}

if src.Spec.Service.Maxsize != nil {
Expand Down Expand Up @@ -120,8 +134,7 @@ func (src *WMS) ToV3(target *pdoknlv3.WMS) error {
MetadataIdentifier: src.Spec.Service.MetadataIdentifier,
},
},
SpatialDatasetIdentifier: *src.Spec.Service.Layers[0].SourceMetadataIdentifier,
Language: "dut",
Language: "dut",
}
} else {
// Annotation to be able to convert back to v2
Expand Down Expand Up @@ -185,7 +198,7 @@ func (dst *WMS) ConvertFrom(srcRaw conversion.Hub) error {
Title: src.Spec.Service.Title,
Abstract: src.Spec.Service.Abstract,
Keywords: src.Spec.Service.Keywords,
AccessConstraints: &src.Spec.Service.AccessConstraints,
AccessConstraints: ptr.To(src.Spec.Service.AccessConstraints.String()),
Extent: nil,
DataEPSG: src.Spec.Service.DataEPSG,
Layers: []WMSLayer{},
Expand Down
89 changes: 58 additions & 31 deletions api/v3/shared_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ type WMSWFS interface {
metav1.Object

GroupKind() schema.GroupKind
Inspire() *Inspire
Inspire() *WFSInspire
Mapfile() *Mapfile
PodSpecPatch() corev1.PodSpec
HorizontalPodAutoscalerPatch() *HorizontalPodAutoscalerPatch
Expand Down Expand Up @@ -66,9 +66,8 @@ type Mapfile struct {
ConfigMapKeyRef corev1.ConfigMapKeySelector `json:"configMapKeyRef"`
}

// Options configures optional behaviors of the operator, like ingress, casing, and data prefetching.
// +kubebuilder:validation:Type=object
type Options struct {
// BaseOptions for all apis
type BaseOptions struct {
// IncludeIngress dictates whether to deploy an Ingress or ensure none exists.
// +kubebuilder:default:=true
IncludeIngress bool `json:"includeIngress"`
Expand All @@ -77,51 +76,80 @@ type Options struct {
// +kubebuilder:default:=true
AutomaticCasing bool `json:"automaticCasing"`

// ValidateRequests enables request validation against the service schema.
// +kubebuilder:default:=true
ValidateRequests bool `json:"validateRequests"`

// RewriteGroupToDataLayers merges group layers into individual data layers.
// +kubebuilder:default:=false
RewriteGroupToDataLayers bool `json:"rewriteGroupToDataLayers"`

// DisableWebserviceProxy disables the built-in proxy for external web services.
// +kubebuilder:default:=false
DisableWebserviceProxy bool `json:"disableWebserviceProxy"`

// Whether to prefetch data from blob storage, and store it on the local filesystem.
// If `false`, the data will be served directly out of blob storage
// +kubebuilder:default:=true
PrefetchData bool `json:"prefetchData"`
}

// ValidateChildStyleNameEqual ensures child style names match the parent style.
// +kubebuilder:default=false
ValidateChildStyleNameEqual bool `json:"validateChildStyleNameEqual"`
// Options configures optional behaviors of the operator, like ingress, casing, and data prefetching.
// +kubebuilder:validation:Type=object
type Options struct {
BaseOptions `json:",inline"`
WMSOptions `json:",inline"`
}

func GetDefaultOptions() *Options {
return &Options{
IncludeIngress: true,
AutomaticCasing: true,
ValidateRequests: true,
RewriteGroupToDataLayers: false,
DisableWebserviceProxy: false,
PrefetchData: true,
ValidateChildStyleNameEqual: false,
BaseOptions: BaseOptions{
IncludeIngress: true,
AutomaticCasing: true,
PrefetchData: true,
},
WMSOptions: WMSOptions{
ValidateRequests: true,
RewriteGroupToDataLayers: false,
DisableWebserviceProxy: false,
ValidateChildStyleNameEqual: false,
},
}
}

// BaseService holds all shared Services field for all apis
type BaseService struct {
// Geonovum subdomein
// +kubebuilder:validation:MinLength:=1
Prefix string `json:"prefix"`

// URL of the service
URL smoothoperatormodel.URL `json:"url"`

// External Mapfile reference
Mapfile *Mapfile `json:"mapfile,omitempty"`

// Reference to OwnerInfo CR
// +kubebuilder:validation:MinLength:=1
OwnerInfoRef string `json:"ownerInfoRef"`

// Service title
// +kubebuilder:validation:MinLength:=1
Title string `json:"title"`

// Service abstract
// +kubebuilder:validation:MinLength:=1
Abstract string `json:"abstract"`

// Keywords for capabilities
// +kubebuilder:validation:MinItems:=1
// +kubebuilder:validation:items:MinLength:=1
Keywords []string `json:"keywords"`

// Optional Fees
// +kubebuilder:validation:MinLength:=1
Fees *string `json:"fees,omitempty"`

// AccessConstraints URL
// +kubebuilder:default="https://creativecommons.org/publicdomain/zero/1.0/deed.nl"
AccessConstraints smoothoperatormodel.URL `json:"accessConstraints,omitempty"`
}

// Inspire holds INSPIRE-specific metadata for the service.
// +kubebuilder:validation:Type=object
type Inspire struct {
// ServiceMetadataURL references the CSW or custom metadata record.
// +kubebuilder:validation:Type=object
ServiceMetadataURL MetadataURL `json:"serviceMetadataUrl"`

// SpatialDatasetIdentifier is the ID uniquely identifying the dataset.
// +kubebuilder:validation:Pattern:=`^[0-9a-zA-Z]{8}\-[0-9a-zA-Z]{4}\-[0-9a-zA-Z]{4}\-[0-9a-zA-Z]{4}\-[0-9a-zA-Z]{12}$`
SpatialDatasetIdentifier string `json:"spatialDatasetIdentifier"`

// Language of the INSPIRE metadata record
// +kubebuilder:validation:Pattern:=`bul|cze|dan|dut|eng|est|fin|fre|ger|gre|hun|gle|ita|lav|lit|mlt|pol|por|rum|slo|slv|spa|swe`
Language string `json:"language"`
Expand Down Expand Up @@ -196,7 +224,6 @@ type Postgis struct {

// GeometryType of the table
// +kubebuilder:validation:Pattern=`^(Multi)?(Point|LineString|Polygon)$`
// +kubebuilder:validation:MinLength:=1
GeometryType string `json:"geometryType"`

// Columns to expose from table
Expand Down
53 changes: 14 additions & 39 deletions api/v3/wfs_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ type WFSSpec struct {
PodSpecPatch corev1.PodSpec `json:"podSpecPatch"`
HorizontalPodAutoscalerPatch *HorizontalPodAutoscalerPatch `json:"horizontalPodAutoscalerPatch,omitempty"`
// TODO omitting the options field or setting an empty value results in incorrect defaulting of the options
Options *Options `json:"options,omitempty"`
// Options configures optional behaviors of the operator, like ingress, casing, and data prefetching.
Options *BaseOptions `json:"options,omitempty"`

// Custom healthcheck options
HealthCheck *HealthCheckWFS `json:"healthCheck,omitempty"`
Expand All @@ -97,43 +98,10 @@ type WFSSpec struct {

// +kubebuilder:validation:XValidation:message="otherCrs can't contain the defaultCrs",rule="!has(self.otherCrs) || (has(self.otherCrs) && !(self.defaultCrs in self.otherCrs))",fieldPath=".otherCrs"
type WFSService struct {
// Geonovum subdomein
// +kubebuilder:validation:MinLength:=1
Prefix string `json:"prefix"`

// URL of the service
URL smoothoperatormodel.URL `json:"url"`

// Config for Inspire services
Inspire *Inspire `json:"inspire,omitempty"`

// External Mapfile reference
Mapfile *Mapfile `json:"mapfile,omitempty"`

// Reference to OwnerInfo CR
// +kubebuilder:validation:MinLength:=1
OwnerInfoRef string `json:"ownerInfoRef"`

// Service title
// +kubebuilder:validation:MinLength:=1
Title string `json:"title"`

// Service abstract
// +kubebuilder:validation:MinLength:=1
Abstract string `json:"abstract"`

// Keywords for capabilities
// +kubebuilder:validation:MinItems:=1
// +kubebuilder:validation:items:MinLength:=1
Keywords []string `json:"keywords"`

// Optional Fees
// +kubebuilder:validation:MinLength:=1
Fees *string `json:"fees,omitempty"`
BaseService `json:",inline"`

// AccessConstraints URL
// +kubebuilder:default="https://creativecommons.org/publicdomain/zero/1.0/deed.nl"
AccessConstraints smoothoperatormodel.URL `json:"accessConstraints,omitempty"`
// Inspire holds INSPIRE-specific metadata for the service.
Inspire *WFSInspire `json:"inspire,omitempty"`

// Default CRS (DataEPSG)
// +kubebuilder:validation:Pattern:="^EPSG:(28992|25831|25832|3034|3035|3857|4258|4326)$"
Expand Down Expand Up @@ -175,6 +143,13 @@ type HealthCheckWFS struct {
Mimetype string `json:"mimetype"`
}

type WFSInspire struct {
Inspire `json:",inline"`
// SpatialDatasetIdentifier is the ID uniquely identifying the dataset.
// +kubebuilder:validation:Pattern:=`^[0-9a-zA-Z]{8}\-[0-9a-zA-Z]{4}\-[0-9a-zA-Z]{4}\-[0-9a-zA-Z]{4}\-[0-9a-zA-Z]{12}$`
SpatialDatasetIdentifier string `json:"spatialDatasetIdentifier"`
}

type Bbox struct {
// EXTENT/wfs_extent in mapfile
//nolint:tagliatelle
Expand Down Expand Up @@ -240,7 +215,7 @@ func (wfs *WFS) GroupKind() schema.GroupKind {
return schema.GroupKind{Group: GroupVersion.Group, Kind: wfs.Kind}
}

func (wfs *WFS) Inspire() *Inspire {
func (wfs *WFS) Inspire() *WFSInspire {
return wfs.Spec.Service.Inspire
}

Expand Down Expand Up @@ -276,7 +251,7 @@ func (wfs *WFS) Options() Options {
return *GetDefaultOptions()
}

return *wfs.Spec.Options
return Options{BaseOptions: *wfs.Spec.Options}
}

func (wfs *WFS) URL() smoothoperatormodel.URL {
Expand Down
Loading
Loading