diff --git a/api/v3/shared_types.go b/api/v3/shared_types.go index 35f3855..f46ef58 100644 --- a/api/v3/shared_types.go +++ b/api/v3/shared_types.go @@ -48,7 +48,7 @@ type WMSWFS interface { // URL returns the configured service URL URL() smoothoperatormodel.URL - IngressRouteURLs() smoothoperatormodel.IngressRouteURLs + IngressRouteURLs(includeServiceURLWhenEmpty bool) smoothoperatormodel.IngressRouteURLs // DatasetMetadataIds returns list of all configured metadata identifiers configured on Layers or Featuretypes DatasetMetadataIDs() []string diff --git a/api/v3/shared_validation.go b/api/v3/shared_validation.go index 7af0c2d..a9fe797 100644 --- a/api/v3/shared_validation.go +++ b/api/v3/shared_validation.go @@ -15,23 +15,33 @@ func ValidateUpdate[W WMSWFS](newW, oldW W, validate func(W, *[]string, *field.E warnings := []string{} allErrs := field.ErrorList{} - // Check that the ingressRouteUrls contain the base url and no urls have been removed - err := sharedValidation.ValidateIngressRouteURLsContainsBaseURL(newW.IngressRouteURLs(), newW.URL(), nil) - if err != nil { - allErrs = append(allErrs, err) + // Make sure no ingressRouteURLs have been removed + sharedValidation.ValidateIngressRouteURLsNotRemoved(oldW.IngressRouteURLs(true), newW.IngressRouteURLs(true), &allErrs, nil) + + if len(newW.IngressRouteURLs(false)) == 0 { + // There are no ingressRouteURLs given, spec.service.url is immutable is that case. + path := field.NewPath("spec").Child("service").Child("url") + sharedValidation.CheckURLImmutability( + oldW.URL(), + newW.URL(), + &allErrs, + path, + ) + } else if oldW.URL().String() != newW.URL().String() { + // Make sure both the old spec.service.url and the new one are included in the ingressRouteURLs list. + err := sharedValidation.ValidateIngressRouteURLsContainsBaseURL(newW.IngressRouteURLs(true), oldW.URL(), nil) + if err != nil { + allErrs = append(allErrs, err) + } + + err = sharedValidation.ValidateIngressRouteURLsContainsBaseURL(newW.IngressRouteURLs(true), newW.URL(), nil) + if err != nil { + allErrs = append(allErrs, err) + } } - sharedValidation.ValidateIngressRouteURLsNotRemoved(oldW.IngressRouteURLs(), newW.IngressRouteURLs(), &allErrs, nil) sharedValidation.ValidateLabelsOnUpdate(oldW.GetLabels(), newW.GetLabels(), &allErrs) - path := field.NewPath("spec").Child("service").Child("url") - sharedValidation.CheckUrlImmutability( - oldW.URL(), - newW.URL(), - &allErrs, - path, - ) - if (newW.Inspire() == nil && oldW.Inspire() != nil) || (newW.Inspire() != nil && oldW.Inspire() == nil) { allErrs = append(allErrs, field.Forbidden(field.NewPath("spec").Child("service").Child("inspire"), "cannot change from inspire to not inspire or the other way around")) } diff --git a/api/v3/wfs_types.go b/api/v3/wfs_types.go index 15ad4d4..faa1170 100644 --- a/api/v3/wfs_types.go +++ b/api/v3/wfs_types.go @@ -323,9 +323,13 @@ func (wfs *WFS) ReadinessQueryString() (string, string, error) { return "SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature&TYPENAMES=" + wfs.Spec.Service.FeatureTypes[0].Name + "&STARTINDEX=0&COUNT=1", "text/xml", nil } -func (wfs *WFS) IngressRouteURLs() smoothoperatormodel.IngressRouteURLs { +func (wfs *WFS) IngressRouteURLs(includeServiceURLWhenEmpty bool) smoothoperatormodel.IngressRouteURLs { if len(wfs.Spec.IngressRouteURLs) == 0 { - return smoothoperatormodel.IngressRouteURLs{{URL: wfs.Spec.Service.URL}} + if includeServiceURLWhenEmpty { + return smoothoperatormodel.IngressRouteURLs{{URL: wfs.Spec.Service.URL}} + } + + return smoothoperatormodel.IngressRouteURLs{} } return wfs.Spec.IngressRouteURLs diff --git a/api/v3/wms_types.go b/api/v3/wms_types.go index cb0b17e..5ce8ac9 100644 --- a/api/v3/wms_types.go +++ b/api/v3/wms_types.go @@ -690,9 +690,13 @@ func (wms *WMS) ReadinessQueryString() (string, string, error) { return fmt.Sprintf("SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&BBOX=%s&CRS=EPSG:28992&WIDTH=100&HEIGHT=100&LAYERS=%s&STYLES=&FORMAT=image/png", wms.HealthCheckBBox(), firstDataLayerName), "image/png", nil } -func (wms *WMS) IngressRouteURLs() smoothoperatormodel.IngressRouteURLs { +func (wms *WMS) IngressRouteURLs(includeServiceURLWhenEmpty bool) smoothoperatormodel.IngressRouteURLs { if len(wms.Spec.IngressRouteURLs) == 0 { - return smoothoperatormodel.IngressRouteURLs{{URL: wms.Spec.Service.URL}} + if includeServiceURLWhenEmpty { + return smoothoperatormodel.IngressRouteURLs{{URL: wms.Spec.Service.URL}} + } + + return smoothoperatormodel.IngressRouteURLs{} } return wms.Spec.IngressRouteURLs diff --git a/go.mod b/go.mod index 01495d5..7876da8 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/pdok/featureinfo-generator v1.4.0-beta1 github.com/pdok/ogc-capabilities-generator v1.0.0-beta8 github.com/pdok/ogc-specifications v1.0.0-beta9 - github.com/pdok/smooth-operator v0.1.2 + github.com/pdok/smooth-operator v0.1.3 github.com/peterbourgon/ff v1.7.1 github.com/stretchr/testify v1.10.0 github.com/traefik/traefik/v3 v3.3.4 diff --git a/go.sum b/go.sum index 3cb5110..10c4d0b 100644 --- a/go.sum +++ b/go.sum @@ -155,8 +155,8 @@ github.com/pdok/ogc-capabilities-generator v1.0.0-beta8 h1:8UAv64fArp8wjpwuRIzjj github.com/pdok/ogc-capabilities-generator v1.0.0-beta8/go.mod h1:2yUZlJikf5gGH6S33FszUiI9+j85gpIINfAFsCF/eNk= github.com/pdok/ogc-specifications v1.0.0-beta9 h1:VrdggKg4d2tSway/deztAfZTviXKX0AftfUuZTXx5j8= github.com/pdok/ogc-specifications v1.0.0-beta9/go.mod h1:YDngwkwrWOfc5MYnEYseiv97K1Y9bZXlVzwi/8EaIl8= -github.com/pdok/smooth-operator v0.1.2 h1:ibGRgFjKysu665IUToQhs34hHhptftI+7RBFrGNw4nQ= -github.com/pdok/smooth-operator v0.1.2/go.mod h1:przwM7mBGmNPqabyhImKVZ15WL4zbqLqH4ExbuWKhWE= +github.com/pdok/smooth-operator v0.1.3 h1:Y+JvbFLlyb6pMNFVgAd8G6QsXL0Y6F0srTaROabRnm0= +github.com/pdok/smooth-operator v0.1.3/go.mod h1:przwM7mBGmNPqabyhImKVZ15WL4zbqLqH4ExbuWKhWE= github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys= github.com/peterbourgon/ff v1.7.1 h1:xt1lxTG+Nr2+tFtysY7abFgPoH3Lug8CwYJMOmJRXhk= github.com/peterbourgon/ff v1.7.1/go.mod h1:fYI5YA+3RDqQRExmFbHnBjEeWzh9TrS8rnRpEq7XIg0= diff --git a/internal/controller/ingressroute.go b/internal/controller/ingressroute.go index 71ff861..4863aa4 100644 --- a/internal/controller/ingressroute.go +++ b/internal/controller/ingressroute.go @@ -98,7 +98,7 @@ func mutateIngressRoute[R Reconciler, O pdoknlv3.WMSWFS](r R, obj O, ingressRout ingressRoute.Spec.Routes = []traefikiov1alpha1.Route{} if obj.Type() == pdoknlv3.ServiceTypeWMS { - for _, ingressRouteURL := range obj.IngressRouteURLs() { + for _, ingressRouteURL := range obj.IngressRouteURLs(true) { ingressRoute.Spec.Routes = append(ingressRoute.Spec.Routes, makeRoute(getLegendMatchRule(ingressRouteURL.URL), mapserverService, middlewareRef)) if obj.Options().UseWebserviceProxy() { @@ -108,7 +108,7 @@ func mutateIngressRoute[R Reconciler, O pdoknlv3.WMSWFS](r R, obj O, ingressRout } } } else { // WFS - for _, ingressRouteURL := range obj.IngressRouteURLs() { + for _, ingressRouteURL := range obj.IngressRouteURLs(true) { ingressRoute.Spec.Routes = append(ingressRoute.Spec.Routes, makeRoute(getMatchRule(ingressRouteURL.URL), mapserverService, middlewareRef)) } }