Skip to content

Commit 3eb69e3

Browse files
committed
Setup mapfile generator config
1 parent a3895c2 commit 3eb69e3

File tree

11 files changed

+481
-25
lines changed

11 files changed

+481
-25
lines changed

api/v3/shared_types.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
package v3
22

3-
import corev1 "k8s.io/api/core/v1"
3+
import (
4+
corev1 "k8s.io/api/core/v1"
5+
"strings"
6+
)
7+
8+
var baseURL string
49

510
type Mapfile struct {
611
ConfigMapKeyRef corev1.ConfigMapKeySelector `json:"configMapKeyRef"`
@@ -67,3 +72,11 @@ type Columns struct {
6772
Name string `json:"name"`
6873
Alias *string `json:"alias,omitempty"`
6974
}
75+
76+
func SetBaseURL(url string) {
77+
baseURL = strings.TrimSuffix(url, "/")
78+
}
79+
80+
func GetBaseURL() string {
81+
return baseURL
82+
}

cmd/main.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package main
1818

1919
import (
2020
"crypto/tls"
21+
"errors"
2122
"flag"
2223
"os"
2324
"path/filepath"
@@ -45,7 +46,8 @@ import (
4546
)
4647

4748
const (
48-
defaultMultitoolImage = "docker.io/pdok/docker-multitool:0.9.1"
49+
defaultMultitoolImage = "docker.io/pdok/docker-multitool:0.9.1"
50+
defaultMapfileGeneratorImage = "docker.io/pdok/mapfile-generator:1.9.3"
4951
)
5052

5153
var (
@@ -71,7 +73,9 @@ func main() {
7173
var secureMetrics bool
7274
var enableHTTP2 bool
7375
var tlsOpts []func(*tls.Config)
76+
var baseURL string
7477
var multitoolImage string
78+
var mapfileGeneratorImage string
7579
flag.StringVar(&metricsAddr, "metrics-bind-address", "0", "The address the metrics endpoint binds to. "+
7680
"Use :8443 for HTTPS or :8080 for HTTP, or leave as 0 to disable the metrics service.")
7781
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
@@ -89,7 +93,10 @@ func main() {
8993
flag.StringVar(&metricsCertKey, "metrics-cert-key", "tls.key", "The name of the metrics server key file.")
9094
flag.BoolVar(&enableHTTP2, "enable-http2", false,
9195
"If set, HTTP/2 will be enabled for the metrics and webhook servers")
96+
flag.StringVar(&baseURL, "baseurl", "", "The base url which is used in the mapserver service.")
9297
flag.StringVar(&multitoolImage, "multitool-image", defaultMultitoolImage, "The image to use in the blob download init-container.")
98+
flag.StringVar(&mapfileGeneratorImage, "mapfile-generator-image", defaultMapfileGeneratorImage, "The image to use in the mapfile generator init-container.")
99+
93100
opts := zap.Options{
94101
Development: true,
95102
}
@@ -98,6 +105,12 @@ func main() {
98105

99106
ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts)))
100107

108+
if baseURL == "" {
109+
setupLog.Error(errors.New("baseURL is required"), "A value for baseURL must be specified.")
110+
os.Exit(1)
111+
}
112+
pdoknlv3.SetBaseURL(baseURL)
113+
101114
// if the enable-http2 flag is false (the default), http/2 should be disabled
102115
// due to its vulnerabilities. More specifically, disabling http/2 will
103116
// prevent from being vulnerable to the HTTP/2 Stream Cancellation and
@@ -219,9 +232,10 @@ func main() {
219232
os.Exit(1)
220233
}
221234
if err = (&controller.WFSReconciler{
222-
Client: mgr.GetClient(),
223-
Scheme: mgr.GetScheme(),
224-
MultitoolImage: multitoolImage,
235+
Client: mgr.GetClient(),
236+
Scheme: mgr.GetScheme(),
237+
MultitoolImage: multitoolImage,
238+
MapfileGeneratorImage: mapfileGeneratorImage,
225239
}).SetupWithManager(mgr); err != nil {
226240
setupLog.Error(err, "unable to create controller", "controller", "WFS")
227241
os.Exit(1)

config/manager/manager.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ spec:
6363
args:
6464
- --leader-elect
6565
- --health-probe-bind-address=:8081
66+
- --baseurl=https://test.example.nl
6667
image: controller:latest
6768
name: manager
6869
ports: []

config/rbac/role.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,20 @@ kind: ClusterRole
44
metadata:
55
name: manager-role
66
rules:
7+
- apiGroups:
8+
- pdok.nl
9+
resources:
10+
- ownerinfo
11+
verbs:
12+
- get
13+
- list
14+
- watch
15+
- apiGroups:
16+
- pdok.nl
17+
resources:
18+
- ownerinfo/status
19+
verbs:
20+
- get
721
- apiGroups:
822
- pdok.nl
923
resources:

go.mod

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@ godebug default=go1.23
77
require (
88
github.com/onsi/ginkgo/v2 v2.21.0
99
github.com/onsi/gomega v1.35.1
10-
github.com/pdok/smooth-operator v0.0.4
1110
k8s.io/api v0.32.0
1211
k8s.io/apimachinery v0.32.0
1312
k8s.io/client-go v0.32.0
1413
sigs.k8s.io/controller-runtime v0.20.0
1514
sigs.k8s.io/yaml v1.4.0
1615
)
1716

17+
require github.com/pdok/smooth-operator v0.0.5
18+
1819
require (
1920
cel.dev/expr v0.18.0 // indirect
2021
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
@@ -27,7 +28,7 @@ require (
2728
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
2829
github.com/evanphx/json-patch/v5 v5.9.0 // indirect
2930
github.com/felixge/httpsnoop v1.0.4 // indirect
30-
github.com/fsnotify/fsnotify v1.8.0 // indirectC
31+
github.com/fsnotify/fsnotify v1.8.0 // indirect; indirectC
3132
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
3233
github.com/go-errors/errors v1.4.2 // indirect
3334
github.com/go-logr/logr v1.4.2 // indirect

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM
9999
github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
100100
github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4=
101101
github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
102-
github.com/pdok/smooth-operator v0.0.4 h1:NVt7srlkSyiZooqn9R2pnMapY6jwZDVTj4QxUjy7UB0=
103-
github.com/pdok/smooth-operator v0.0.4/go.mod h1:oZWFuIKJGjN/C6ocgMNfMZ7SbLQi+N0qaWj7j95Wdec=
102+
github.com/pdok/smooth-operator v0.0.5 h1:7tgMeAEG34JlW6GlfxfHH+RV7c6uE6621FXv+vzfDGo=
103+
github.com/pdok/smooth-operator v0.0.5/go.mod h1:oZWFuIKJGjN/C6ocgMNfMZ7SbLQi+N0qaWj7j95Wdec=
104104
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
105105
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
106106
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package mapfilegenerator
2+
3+
import (
4+
"encoding/json"
5+
"errors"
6+
"fmt"
7+
pdoknlv3 "github.com/pdok/mapserver-operator/api/v3"
8+
smoothoperatorv1 "github.com/pdok/smooth-operator/api/v1"
9+
)
10+
11+
func GetConfig[W *pdoknlv3.WFS | *pdoknlv3.WMS](webservice W, ownerInfo *smoothoperatorv1.OwnerInfo) (config string, err error) {
12+
switch any(webservice).(type) {
13+
case *pdoknlv3.WFS:
14+
if WFS, ok := any(webservice).(*pdoknlv3.WFS); ok {
15+
return createConfigForWFS(WFS, ownerInfo)
16+
}
17+
case *pdoknlv3.WMS:
18+
if _, ok := any(webservice).(*pdoknlv3.WMS); ok {
19+
return "", errors.New("not implemented for WMS")
20+
}
21+
default:
22+
return "", fmt.Errorf("unexpected input, webservice should be of type WFS or WMS, webservice: %v", webservice)
23+
}
24+
return "", fmt.Errorf("unexpected input, webservice should be of type WFS or WMS, webservice: %v", webservice)
25+
}
26+
27+
func createConfigForWFS(wfs *pdoknlv3.WFS, ownerInfo *smoothoperatorv1.OwnerInfo) (config string, err error) {
28+
29+
input, err := MapWFSToMapfileGeneratorInput(wfs, ownerInfo)
30+
if err != nil {
31+
return "", err
32+
}
33+
34+
u, err := json.MarshalIndent(input, "", " ")
35+
if err != nil {
36+
return "", err
37+
}
38+
return string(u), nil
39+
40+
}
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
package mapfilegenerator
2+
3+
import (
4+
pdoknlv3 "github.com/pdok/mapserver-operator/api/v3"
5+
smoothoperatorv1 "github.com/pdok/smooth-operator/api/v1"
6+
shared_model "github.com/pdok/smooth-operator/model"
7+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
8+
"testing"
9+
)
10+
11+
const (
12+
WFSConfig = `{
13+
"service_title": "some Service title",
14+
"service_abstract": "some \"Service\" abstract",
15+
"service_keywords": "service-keyword-1,service-keyword-2,infoFeatureAccessService",
16+
"service_accessconstraints": "http://creativecommons.org/publicdomain/zero/1.0/deed.nl",
17+
"service_extent": "0.0 2.0 1.0 3.0",
18+
"service_wfs_maxfeatures": "1000",
19+
"service_namespace_prefix": "prefix",
20+
"service_namespace_uri": "http://prefix.geonovum.nl",
21+
"service_onlineresource": "http://localhost",
22+
"service_path": "/datasetOwner/dataset/theme/wfs/v1_0",
23+
"service_metadata_id": "metameta-meta-meta-meta-metametameta",
24+
"dataset_owner": "",
25+
"authority_url": "",
26+
"automatic_casing": true,
27+
"data_epsg": "EPSG:28992",
28+
"epsg_list": [
29+
"EPSG:28992",
30+
"EPSG:25831",
31+
"EPSG:25832",
32+
"EPSG:3034",
33+
"EPSG:3035",
34+
"EPSG:3857",
35+
"EPSG:4258",
36+
"EPSG:4326"
37+
],
38+
"layers": [
39+
{
40+
"name": "",
41+
"title": "",
42+
"abstract": "",
43+
"keywords": "",
44+
"layer_extent": "",
45+
"dataset_metadata_id": "",
46+
"dataset_source_id": "",
47+
"columns": null,
48+
"geometry_type": "",
49+
"gpkg_path": "",
50+
"tablename": ""
51+
}
52+
]
53+
}`
54+
)
55+
56+
func TestGetConfigForWFS(t *testing.T) {
57+
type args struct {
58+
WFS *pdoknlv3.WFS
59+
ownerInfo *smoothoperatorv1.OwnerInfo
60+
}
61+
pdoknlv3.SetBaseURL("http://localhost")
62+
tests := []struct {
63+
name string
64+
args args
65+
wantConfig string
66+
wantErr bool
67+
}{
68+
{
69+
name: "GetConfig for WFS",
70+
args: args{
71+
WFS: &pdoknlv3.WFS{
72+
ObjectMeta: metav1.ObjectMeta{
73+
Labels: map[string]string{
74+
"dataset": "dataset",
75+
"dataset-owner": "datasetOwner",
76+
"theme": "theme",
77+
"service-version": "v1_0",
78+
},
79+
},
80+
Spec: pdoknlv3.WFSSpec{
81+
Options: &pdoknlv3.Options{
82+
AutomaticCasing: true,
83+
},
84+
Service: pdoknlv3.WFSService{
85+
Title: "some Service title",
86+
Abstract: "some \"Service\" abstract",
87+
Keywords: []string{"service-keyword-1", "service-keyword-2", "infoFeatureAccessService"},
88+
AccessConstraints: "http://creativecommons.org/publicdomain/zero/1.0/deed.nl",
89+
Bbox: &pdoknlv3.Bbox{
90+
DefaultCRS: shared_model.BBox{
91+
MinX: "0.0",
92+
MaxX: "1.0",
93+
MinY: "2.0",
94+
MaxY: "3.0",
95+
},
96+
},
97+
Inspire: &pdoknlv3.Inspire{
98+
ServiceMetadataURL: pdoknlv3.MetadataURL{
99+
CSW: &pdoknlv3.Metadata{
100+
MetadataIdentifier: "metameta-meta-meta-meta-metametameta",
101+
},
102+
},
103+
},
104+
DefaultCrs: "EPSG:28992",
105+
OtherCrs: []string{
106+
"EPSG:28992",
107+
"EPSG:25831",
108+
"EPSG:25832",
109+
"EPSG:3034",
110+
"EPSG:3035",
111+
"EPSG:3857",
112+
"EPSG:4258",
113+
"EPSG:4326",
114+
},
115+
FeatureTypes: []pdoknlv3.FeatureType{
116+
{
117+
Title: "featuretype-1-name",
118+
},
119+
},
120+
Prefix: "prefix",
121+
},
122+
},
123+
},
124+
ownerInfo: &smoothoperatorv1.OwnerInfo{
125+
Spec: smoothoperatorv1.OwnerInfoSpec{
126+
NamespaceTemplate: "http://{{prefix}}.geonovum.nl",
127+
},
128+
},
129+
},
130+
wantConfig: WFSConfig,
131+
wantErr: false,
132+
},
133+
}
134+
for _, tt := range tests {
135+
t.Run(tt.name, func(t *testing.T) {
136+
gotConfig, err := GetConfig(tt.args.WFS, tt.args.ownerInfo)
137+
if (err != nil) != tt.wantErr {
138+
t.Errorf("GetConfig() error = %v, wantErr %v", err, tt.wantErr)
139+
return
140+
}
141+
if gotConfig != tt.wantConfig {
142+
t.Errorf("GetConfig() gotConfig = %v, want %v", gotConfig, tt.wantConfig)
143+
}
144+
})
145+
}
146+
}

0 commit comments

Comments
 (0)