Skip to content

Commit 233b260

Browse files
committed
fix up, recover tests
1 parent 48abc45 commit 233b260

File tree

6 files changed

+157
-40
lines changed

6 files changed

+157
-40
lines changed

cmd/convert.go

+3-7
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ func executeConvert(_ *cobra.Command, _ []string) error {
2929
return err
3030
}
3131

32-
if len(convertCmdInputFile) != 0 {
32+
if convertCmdInputFile != "" {
3333
if yes, err := utils.ConfirmFileOverwrite(
3434
convertCmdOutputFile, "", convertCmdAssumeYes,
3535
); err != nil {
@@ -38,11 +38,7 @@ func executeConvert(_ *cobra.Command, _ []string) error {
3838
return nil
3939
}
4040

41-
err = convert.Convert(convertCmdInputFile,
42-
convertCmdOutputFile,
43-
sourceFormat,
44-
destinationFormat,
45-
!convertCmdDisableMockEnvVars)
41+
err = convert.Convert([]string{convertCmdInputFile}, convertCmdOutputFile, sourceFormat, destinationFormat, false)
4642
if err != nil {
4743
return fmt.Errorf("converting file: %w", err)
4844
}
@@ -56,7 +52,7 @@ func executeConvert(_ *cobra.Command, _ []string) error {
5652
return fmt.Errorf("getting files from directory: %w", err)
5753
}
5854
for _, filename := range files {
59-
err = convert.Convert([]string{filename}, filename, sourceFormat, destinationFormat, !convertCmdDisableMockEnvVars)
55+
err = convert.Convert([]string{filename}, filename, sourceFormat, destinationFormat, false)
6056
if err != nil {
6157
return fmt.Errorf("converting '%s' file: %w", filename, err)
6258
}

cmd/root.go

+1
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ It can be used to export, import, or sync entities to Kong.`,
226226
fileCmd.AddCommand(newOpenapi2KongCmd())
227227
fileCmd.AddCommand(newConvertCmd(false))
228228
fileCmd.AddCommand(newValidateCmd()) // alias; since this does both file+online
229+
fileCmd.AddCommand(newFileRenderCmd())
229230
}
230231
return rootCmd
231232
}

convert/convert.go

+66-9
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
11
package convert
22

33
import (
4+
"context"
45
"fmt"
56
"strings"
67

8+
"github.com/blang/semver/v4"
79
"github.com/kong/deck/cprint"
10+
"github.com/kong/deck/dump"
811
"github.com/kong/deck/file"
12+
"github.com/kong/deck/state"
913
"github.com/kong/deck/utils"
1014
"github.com/kong/go-kong/kong"
1115
)
1216

1317
type Format string
1418

1519
const (
20+
// FormatDistributed represents the Deck configuration format.
21+
FormatDistributed Format = "distributed"
1622
// FormatKongGateway represents the Kong gateway format.
1723
FormatKongGateway Format = "kong-gateway"
1824
// FormatKonnect represents the Konnect format.
@@ -37,38 +43,49 @@ func ParseFormat(key string) (Format, error) {
3743
return FormatKongGateway2x, nil
3844
case FormatKongGateway3x:
3945
return FormatKongGateway3x, nil
46+
case FormatDistributed:
47+
return FormatDistributed, nil
4048
default:
4149
return "", fmt.Errorf("invalid format: '%v'", key)
4250
}
4351
}
4452

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
4655
var (
4756
outputContent *file.Content
4857
err error
4958
)
5059

51-
inputContent, err := file.GetContentFromFiles([]string{inputFilename})
60+
inputContent, err := file.GetContentFromFiles(inputFilenames, mockEnvVars)
5261
if err != nil {
5362
return err
5463
}
5564

5665
switch {
5766
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")
6169
}
70+
outputContent, err = convertKongGatewayToKonnect(inputContent)
6271
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")
6674
}
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)
6780
default:
6881
return fmt.Errorf("cannot convert from '%s' to '%s' format", from, to)
6982
}
7083

71-
err = file.WriteContentToFile(outputContent, outputFilename, file.YAML)
84+
if err != nil {
85+
return err
86+
}
87+
88+
err = file.WriteContentToFile(outputContent, outputFilename, outputFormat)
7289
if err != nil {
7390
return err
7491
}
@@ -195,3 +212,43 @@ func removeServiceName(service *file.FService) *file.FService {
195212
serviceCopy.ID = kong.String(utils.UUID())
196213
return serviceCopy
197214
}
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+
}

convert/convert_test.go

+87-4
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,12 @@ func zeroOutID(sp file.FServicePackage) file.FServicePackage {
158158
func Test_Convert(t *testing.T) {
159159
type args struct {
160160
inputFilename string
161+
inputFilenames []string
161162
outputFilename string
162163
fromFormat Format
163164
toFormat Format
165+
disableMocks bool
166+
envVars map[string]string
164167
expectedOutputFilename string
165168
}
166169
tests := []struct {
@@ -237,21 +240,101 @@ func Test_Convert(t *testing.T) {
237240
},
238241
wantErr: false,
239242
},
243+
{
244+
name: "converts from distributed to kong gateway (no deck specific fields)",
245+
args: args{
246+
inputFilename: "testdata/5/input.yaml",
247+
outputFilename: "testdata/5/output.yaml",
248+
expectedOutputFilename: "testdata/5/output-expected.yaml",
249+
fromFormat: FormatDistributed,
250+
toFormat: FormatKongGateway,
251+
},
252+
wantErr: false,
253+
},
254+
{
255+
name: "converts from distributed to kong gateway with defaults",
256+
args: args{
257+
inputFilename: "testdata/6/input.yaml",
258+
outputFilename: "testdata/6/output.yaml",
259+
expectedOutputFilename: "testdata/6/output-expected.yaml",
260+
fromFormat: FormatDistributed,
261+
toFormat: FormatKongGateway,
262+
},
263+
wantErr: false,
264+
},
265+
{
266+
name: "converts from distributed to kong gateway with multiple files",
267+
args: args{
268+
inputFilenames: []string{"testdata/7/input-1.yaml", "testdata/7/input-2.yaml"},
269+
outputFilename: "testdata/7/output.yaml",
270+
expectedOutputFilename: "testdata/7/output-expected.yaml",
271+
fromFormat: FormatDistributed,
272+
toFormat: FormatKongGateway,
273+
},
274+
wantErr: false,
275+
},
276+
{
277+
name: "converts from distributed to kong gateway with env variables",
278+
args: args{
279+
inputFilenames: []string{"testdata/8/input.yaml"},
280+
outputFilename: "testdata/8/output.yaml",
281+
expectedOutputFilename: "testdata/8/output-expected.yaml",
282+
fromFormat: FormatDistributed,
283+
toFormat: FormatKongGateway,
284+
disableMocks: true,
285+
envVars: map[string]string{
286+
"DECK_MOCKBIN_HOST": "mockbin.org",
287+
"DECK_MOCKBIN_ENABLED": "true",
288+
"DECK_WRITE_TIMEOUT": "777",
289+
"DECK_FOO_FLOAT": "666",
290+
},
291+
},
292+
wantErr: false,
293+
},
294+
{
295+
name: "converts from distributed to kong gateway with env variables (mocked)",
296+
args: args{
297+
inputFilenames: []string{"testdata/9/input.yaml"},
298+
outputFilename: "testdata/9/output.yaml",
299+
expectedOutputFilename: "testdata/9/output-expected.yaml",
300+
fromFormat: FormatDistributed,
301+
toFormat: FormatKongGateway,
302+
disableMocks: false,
303+
},
304+
wantErr: false,
305+
},
306+
{
307+
name: "errors from distributed to kong gateway with env variables not set",
308+
args: args{
309+
inputFilenames: []string{"testdata/9/input.yaml"},
310+
fromFormat: FormatDistributed,
311+
toFormat: FormatKongGateway,
312+
disableMocks: true,
313+
},
314+
wantErr: true,
315+
},
240316
}
241317
for _, tt := range tests {
242318
t.Run(tt.name, func(t *testing.T) {
243-
err := Convert(tt.args.inputFilename, tt.args.outputFilename, tt.args.fromFormat,
244-
tt.args.toFormat)
319+
inputFiles := tt.args.inputFilenames
320+
if tt.args.inputFilename != "" {
321+
inputFiles = []string{tt.args.inputFilename}
322+
}
323+
for k, v := range tt.args.envVars {
324+
t.Setenv(k, v)
325+
}
326+
err := Convert(inputFiles, tt.args.outputFilename, tt.args.fromFormat,
327+
tt.args.toFormat, !tt.args.disableMocks)
245328
if (err != nil) != tt.wantErr {
246329
t.Errorf("Convert() error = %v, wantErr %v", err, tt.wantErr)
247330
}
248331

249332
if err == nil {
250-
got, err := file.GetContentFromFiles([]string{tt.args.outputFilename})
333+
got, err := file.GetContentFromFiles([]string{tt.args.outputFilename}, !tt.args.disableMocks)
251334
if err != nil {
252335
t.Errorf("failed to read output file: %v", err)
253336
}
254-
want, err := file.GetContentFromFiles([]string{tt.args.expectedOutputFilename})
337+
want, err := file.GetContentFromFiles([]string{tt.args.expectedOutputFilename}, !tt.args.disableMocks)
255338
if err != nil {
256339
t.Errorf("failed to read output file: %v", err)
257340
}

convert/testdata/3/output.yaml

-10
This file was deleted.

convert/testdata/4/output.yaml

-10
This file was deleted.

0 commit comments

Comments
 (0)