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,38 +43,55 @@ 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 {
53
+ func Convert (
54
+ inputFilenames []string ,
55
+ outputFilename string ,
56
+ outputFormat file.Format ,
57
+ from Format ,
58
+ to Format ,
59
+ mockEnvVars bool ,
60
+ ) error {
46
61
var (
47
62
outputContent * file.Content
48
63
err error
49
64
)
50
65
51
- inputContent , err := file .GetContentFromFiles ([] string { inputFilename } )
66
+ inputContent , err := file .GetContentFromFiles (inputFilenames , mockEnvVars )
52
67
if err != nil {
53
68
return err
54
69
}
55
70
56
71
switch {
57
72
case from == FormatKongGateway && to == FormatKonnect :
58
- outputContent , err = convertKongGatewayToKonnect (inputContent )
59
- if err != nil {
60
- return err
73
+ if len (inputFilenames ) > 1 {
74
+ return fmt .Errorf ("only one input file can be provided when converting from Kong to Konnect format" )
61
75
}
76
+ outputContent , err = convertKongGatewayToKonnect (inputContent )
62
77
case from == FormatKongGateway2x && to == FormatKongGateway3x :
63
- outputContent , err = convertKongGateway2xTo3x (inputContent , inputFilename )
64
- if err != nil {
65
- return err
78
+ if len (inputFilenames ) > 1 {
79
+ return fmt .Errorf ("only one input file can be provided when converting from Kong 2.x to Kong 3.x format" )
66
80
}
81
+ outputContent , err = convertKongGateway2xTo3x (inputContent , inputFilenames [0 ])
82
+ case from == FormatDistributed && to == FormatKongGateway ,
83
+ from == FormatDistributed && to == FormatKongGateway2x ,
84
+ from == FormatDistributed && to == FormatKongGateway3x :
85
+ outputContent , err = convertDistributedToKong (inputContent , outputFilename , outputFormat , to )
67
86
default :
68
87
return fmt .Errorf ("cannot convert from '%s' to '%s' format" , from , to )
69
88
}
70
89
71
- err = file .WriteContentToFile (outputContent , outputFilename , file .YAML )
90
+ if err != nil {
91
+ return err
92
+ }
93
+
94
+ err = file .WriteContentToFile (outputContent , outputFilename , outputFormat )
72
95
if err != nil {
73
96
return err
74
97
}
@@ -195,3 +218,43 @@ func removeServiceName(service *file.FService) *file.FService {
195
218
serviceCopy .ID = kong .String (utils .UUID ())
196
219
return serviceCopy
197
220
}
221
+
222
+ // convertDistributedToKong is used to convert one or many distributed format
223
+ // files to create one Kong Gateway declarative config. It also leverages some
224
+ // deck features like the defaults/centralized plugin configurations.
225
+ func convertDistributedToKong (
226
+ targetContent * file.Content ,
227
+ outputFilename string ,
228
+ format file.Format ,
229
+ kongFormat Format ,
230
+ ) (* file.Content , error ) {
231
+ var version semver.Version
232
+
233
+ switch kongFormat { //nolint:exhaustive
234
+ case FormatKongGateway ,
235
+ FormatKongGateway3x :
236
+ version = semver.Version {Major : 3 , Minor : 0 }
237
+ case FormatKongGateway2x :
238
+ version = semver.Version {Major : 2 , Minor : 8 }
239
+ }
240
+
241
+ s , _ := state .NewKongState ()
242
+ rawState , err := file .Get (context .Background (), targetContent , file.RenderConfig {
243
+ CurrentState : s ,
244
+ KongVersion : version ,
245
+ }, dump.Config {}, nil )
246
+ if err != nil {
247
+ return nil , err
248
+ }
249
+ targetState , err := state .Get (rawState )
250
+ if err != nil {
251
+ return nil , err
252
+ }
253
+
254
+ // file.KongStateToContent calls file.WriteContentToFile
255
+ return file .KongStateToContent (targetState , file.WriteConfig {
256
+ Filename : outputFilename ,
257
+ FileFormat : format ,
258
+ KongVersion : version .String (),
259
+ })
260
+ }
0 commit comments