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