Repository: Kong/deck (go)

Issue:
render adding "regex_priority" key to expression route resulting sync to fails
Kong file render generates legacy route "regex_priority" key when expression routes are used resulting that rendered file validation fails and file cannot be synched, resulting error

```
Error: 1 errors occurred:
        while processing event: Update route debug_node_log-level failed: HTTP status 400 (message: "schema violation (regex_priority: unknown field)")
```
repro steps

Kong version 3.6.1.1, deck 1.35, linux

create declarative config with single service/route/plugin pointing to Kong itself
```
services:
# debug
- host: localhost
  name: debug_node_log-level
  port: 8001
  protocol: http
  routes:
  - expression: (net.protocol == "http") && (http.method == "GET") && (http.path ==
      "/api/debug/node/log-level")
    name: debug_node_log-level
  priority: 100
plugins:
- config:
    replace:
      uri: /debug/node/log-level
  name: request-transformer
  route: debug_node_log-level
```

render the declarative configuration. 

deck file render kong-common*.yaml merge-routes.yaml -o render-kong-deck.yaml
deck file merge kong-common*.yaml merge-routes.yaml -o merge-kong-deck.yaml

rendered file contains "regex_priority" which is used with legacy routes.

```
- connect_timeout: 60000
  host: localhost
  name: debug_node_log-level
  port: 8001
  protocol: http
  read_timeout: 60000
  routes:
  - expression: (net.protocol == "http") && (http.method == "GET") && (http.path ==
      "/api/dbf/ca/debug/node/log-level")
    name: debug_node_log-level
    plugins:
    - config:
        replace:
          uri: /debug/node/log-level
      name: request-transformer
    preserve_host: false
    priority: 100
    protocols:
    - http
    - https
    regex_priority: 0 # this is not valid key in expression route
    strip_path: true
    tags:
    - debug

```
Validation of rendered file fails.
Rendered file cannot be used to sync with Kong.

Merged file can be synched because it does not contain regex_priority key

Workaround - use kong deck patch to remove invalid key
cat render-kong-deck.yaml | deck file patch --selector="$..routes[*]" --value="regex_priority:" -o render-kong-deck.yaml


Pull request:
fix: update go-database-reconciler for fixing expression route handling
Till now, expression routes were getting incorrectly rendered. Added changes in go-database-reconciler to allow proper rendering for both kinds of routes. https://github.com/Kong/go-database-reconciler/pull/116
Added tests here to ensure the functionality stays intact for future updates.

Fix #1250.

Patch:
diff --git a/go.mod b/go.mod
index d020c11..935f1c8 100644
--- a/go.mod
+++ b/go.mod
@@ -11,7 +11,7 @@ require (
 	github.com/fatih/color v1.15.0
 	github.com/google/go-cmp v0.6.0
 	github.com/kong/go-apiops v0.1.33
-	github.com/kong/go-database-reconciler v1.13.0
+	github.com/kong/go-database-reconciler v1.14.1
 	github.com/kong/go-kong v0.55.0
 	github.com/mitchellh/go-homedir v1.1.0
 	github.com/spf13/cobra v1.8.0
@@ -136,8 +136,8 @@ require (
 	golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect
 	golang.org/x/mod v0.17.0 // indirect
 	golang.org/x/net v0.25.0 // indirect
-	golang.org/x/sys v0.21.0 // indirect
-	golang.org/x/term v0.21.0 // indirect
+	golang.org/x/sys v0.22.0 // indirect
+	golang.org/x/term v0.22.0 // indirect
 	golang.org/x/text v0.15.0 // indirect
 	golang.org/x/tools v0.21.0 // indirect
 	google.golang.org/protobuf v1.33.0 // indirect
diff --git a/go.sum b/go.sum
index 00c0753..057c8e1 100644
--- a/go.sum
+++ b/go.sum
@@ -186,8 +186,8 @@ github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/q
 github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
 github.com/kong/go-apiops v0.1.33 h1:Y7IVksHPdHcXM6C+gPc25JiY4KRgYDAOn/jTx3sDU1k=
 github.com/kong/go-apiops v0.1.33/go.mod h1:o8lzBtbCLSXCMKzzqR8dcBhB7yzPs+9csAMZ1T1hsL0=
-github.com/kong/go-database-reconciler v1.13.0 h1:6gRGeLDep0mvzT/5fCQY5waQp0F/T9MsyZ9fJmJq+Cc=
-github.com/kong/go-database-reconciler v1.13.0/go.mod h1:bUPJkoeW//x4hzNxewQMoIkeoDzJzunI0stDMYJ3BkU=
+github.com/kong/go-database-reconciler v1.14.1 h1:NkMiarWUnCzK/0kMgMVlVRqFlccBq3XfZeQAuy72dKk=
+github.com/kong/go-database-reconciler v1.14.1/go.mod h1:OsyUWH3SUvXAd5HJx3PhRU3PyzH0uCy7bTlzoSfw8Ew=
 github.com/kong/go-kong v0.55.0 h1:lonKRzsDGk12dh9E+y+pWnY2ThXhKuMHjzBHSpCvQLw=
 github.com/kong/go-kong v0.55.0/go.mod h1:i1cMgTu6RYPHSyMpviShddRnc+DML/vlpgKC00hr8kU=
 github.com/kong/go-slugify v1.0.0 h1:vCFAyf2sdoSlBtLcrmDWUFn0ohlpKiKvQfXZkO5vSKY=
@@ -440,15 +440,15 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
-golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
+golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
-golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
-golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
+golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
+golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=


Test patch:
diff --git a/tests/integration/render_test.go b/tests/integration/render_test.go
index 908dde2..19698fa 100644
--- a/tests/integration/render_test.go
+++ b/tests/integration/render_test.go
@@ -33,6 +33,20 @@ func Test_RenderPlain(t *testing.T) {
 				"DECK_FOO_FLOAT":       "123",
 			},
 		},
+		{
+			name:           "render with traditional route",
+			stateFile:      "testdata/render/003-traditional-routes/input.yaml",
+			additionalArgs: []string{},
+			expectedFile:   "testdata/render/003-traditional-routes/expected.yaml",
+			envVars:        map[string]string{},
+		},
+		{
+			name:           "render with expression route",
+			stateFile:      "testdata/render/004-expression-routes/input.yaml",
+			additionalArgs: []string{},
+			expectedFile:   "testdata/render/004-expression-routes/expected.yaml",
+			envVars:        map[string]string{},
+		},
 	}
 	for _, tc := range tests {
 		t.Run(tc.name, func(t *testing.T) {
diff --git a/tests/integration/testdata/render/003-traditional-routes/expected.yaml b/tests/integration/testdata/render/003-traditional-routes/expected.yaml
new file mode 100644
index 0000000..b3d95ee
--- /dev/null
+++ b/tests/integration/testdata/render/003-traditional-routes/expected.yaml
@@ -0,0 +1,19 @@
+_format_version: "3.0"
+services:
+- connect_timeout: 60000
+  host: localhost
+  name: foo
+  port: 8001
+  protocol: http
+  read_timeout: 60000
+  routes:
+  - name: foo
+    paths:
+    - /foo
+    preserve_host: false
+    protocols:
+    - http
+    - https
+    regex_priority: 0
+    strip_path: true
+  write_timeout: 60000
diff --git a/tests/integration/testdata/render/003-traditional-routes/input.yaml b/tests/integration/testdata/render/003-traditional-routes/input.yaml
new file mode 100644
index 0000000..2c0d18d
--- /dev/null
+++ b/tests/integration/testdata/render/003-traditional-routes/input.yaml
@@ -0,0 +1,14 @@
+services:
+- host: localhost
+  name: foo
+  port: 8001
+  protocol: http
+  routes:
+  routes:
+   - name: foo
+     paths:
+     - /foo
+     preserve_host: false
+     protocols:
+     - http
+     - https
\ No newline at end of file
diff --git a/tests/integration/testdata/render/004-expression-routes/expected.yaml b/tests/integration/testdata/render/004-expression-routes/expected.yaml
new file mode 100644
index 0000000..3315792
--- /dev/null
+++ b/tests/integration/testdata/render/004-expression-routes/expected.yaml
@@ -0,0 +1,19 @@
+_format_version: "3.0"
+services:
+- connect_timeout: 60000
+  host: localhost
+  name: foo
+  port: 8001
+  protocol: http
+  read_timeout: 60000
+  routes:
+  - expression: (net.protocol == "http") && (http.method == "GET") && (http.path ==
+      "/foo")
+    name: foo
+    preserve_host: false
+    priority: 0
+    protocols:
+    - http
+    - https
+    strip_path: true
+  write_timeout: 60000
diff --git a/tests/integration/testdata/render/004-expression-routes/input.yaml b/tests/integration/testdata/render/004-expression-routes/input.yaml
new file mode 100644
index 0000000..89f779f
--- /dev/null
+++ b/tests/integration/testdata/render/004-expression-routes/input.yaml
@@ -0,0 +1,9 @@
+services:
+- host: localhost
+  name: foo
+  port: 8001
+  protocol: http
+  routes:
+  - expression: (net.protocol == "http") && (http.method == "GET") && (http.path ==
+      "/foo")
+    name: foo
\ No newline at end of file