1
1
package convert
2
2
3
3
import (
4
+ "context"
4
5
"fmt"
5
6
"strings"
6
7
8
+ "github.com/blang/semver/v4"
7
9
"github.com/kong/deck/cprint"
10
+ "github.com/kong/deck/dump"
8
11
"github.com/kong/deck/file"
12
+ "github.com/kong/deck/state"
9
13
"github.com/kong/deck/utils"
10
14
"github.com/kong/go-kong/kong"
11
15
)
12
16
13
17
type Format string
14
18
15
19
const (
20
+ // FormatDistributed represents the Deck configuration format.
21
+ FormatDistributed Format = "distributed"
16
22
// FormatKongGateway represents the Kong gateway format.
17
23
FormatKongGateway Format = "kong-gateway"
18
24
// FormatKonnect represents the Konnect format.
@@ -37,42 +43,61 @@ func ParseFormat(key string) (Format, error) {
37
43
return FormatKongGateway2x , nil
38
44
case FormatKongGateway3x :
39
45
return FormatKongGateway3x , nil
46
+ case FormatDistributed :
47
+ return FormatDistributed , nil
40
48
default :
41
49
return "" , fmt .Errorf ("invalid format: '%v'" , key )
42
50
}
43
51
}
44
52
45
- func Convert (inputFilename , outputFilename string , from , to Format ) error {
46
- var (
47
- outputContent * file.Content
48
- err error
49
- )
53
+ func Convert (
54
+ inputFilenames []string ,
55
+ outputFilename string ,
56
+ outputFormat file.Format ,
57
+ from Format ,
58
+ to Format ,
59
+ mockEnvVars bool ,
60
+ ) error {
61
+ var outputContent * file.Content
50
62
51
- inputContent , err := file .GetContentFromFiles ([] string { inputFilename } )
63
+ inputContent , err := file .GetContentFromFiles (inputFilenames , mockEnvVars )
52
64
if err != nil {
53
65
return err
54
66
}
55
67
56
68
switch {
57
69
case from == FormatKongGateway && to == FormatKonnect :
70
+ if len (inputFilenames ) > 1 {
71
+ return fmt .Errorf ("only one input file can be provided when converting from Kong to Konnect format" )
72
+ }
58
73
outputContent , err = convertKongGatewayToKonnect (inputContent )
59
74
if err != nil {
60
75
return err
61
76
}
77
+
62
78
case from == FormatKongGateway2x && to == FormatKongGateway3x :
63
- outputContent , err = convertKongGateway2xTo3x (inputContent , inputFilename )
79
+ if len (inputFilenames ) > 1 {
80
+ return fmt .Errorf ("only one input file can be provided when converting from Kong 2.x to Kong 3.x format" )
81
+ }
82
+ outputContent , err = convertKongGateway2xTo3x (inputContent , inputFilenames [0 ])
64
83
if err != nil {
65
84
return err
66
85
}
86
+
87
+ case from == FormatDistributed && to == FormatKongGateway ,
88
+ from == FormatDistributed && to == FormatKongGateway2x ,
89
+ from == FormatDistributed && to == FormatKongGateway3x :
90
+ outputContent , err = convertDistributedToKong (inputContent , outputFilename , outputFormat , to )
91
+ if err != nil {
92
+ return err
93
+ }
94
+
67
95
default :
68
96
return fmt .Errorf ("cannot convert from '%s' to '%s' format" , from , to )
69
97
}
70
98
71
- err = file .WriteContentToFile (outputContent , outputFilename , file .YAML )
72
- if err != nil {
73
- return err
74
- }
75
- return nil
99
+ err = file .WriteContentToFile (outputContent , outputFilename , outputFormat )
100
+ return err
76
101
}
77
102
78
103
func convertKongGateway2xTo3x (input * file.Content , filename string ) (* file.Content , error ) {
@@ -195,3 +220,43 @@ func removeServiceName(service *file.FService) *file.FService {
195
220
serviceCopy .ID = kong .String (utils .UUID ())
196
221
return serviceCopy
197
222
}
223
+
224
+ // convertDistributedToKong is used to convert one or many distributed format
225
+ // files to create one Kong Gateway declarative config. It also leverages some
226
+ // deck features like the defaults/centralized plugin configurations.
227
+ func convertDistributedToKong (
228
+ targetContent * file.Content ,
229
+ outputFilename string ,
230
+ format file.Format ,
231
+ kongFormat Format ,
232
+ ) (* file.Content , error ) {
233
+ var version semver.Version
234
+
235
+ switch kongFormat { //nolint:exhaustive
236
+ case FormatKongGateway ,
237
+ FormatKongGateway3x :
238
+ version = semver.Version {Major : 3 , Minor : 0 }
239
+ case FormatKongGateway2x :
240
+ version = semver.Version {Major : 2 , Minor : 8 }
241
+ }
242
+
243
+ s , _ := state .NewKongState ()
244
+ rawState , err := file .Get (context .Background (), targetContent , file.RenderConfig {
245
+ CurrentState : s ,
246
+ KongVersion : version ,
247
+ }, dump.Config {}, nil )
248
+ if err != nil {
249
+ return nil , err
250
+ }
251
+ targetState , err := state .Get (rawState )
252
+ if err != nil {
253
+ return nil , err
254
+ }
255
+
256
+ // file.KongStateToContent calls file.WriteContentToFile
257
+ return file .KongStateToContent (targetState , file.WriteConfig {
258
+ Filename : outputFilename ,
259
+ FileFormat : format ,
260
+ KongVersion : version .String (),
261
+ })
262
+ }
0 commit comments