Skip to content

Commit

Permalink
refactor: rework how 3.x warnings are organized
Browse files Browse the repository at this point in the history
  • Loading branch information
GGabriele committed Sep 26, 2022
1 parent 2295077 commit 53d1f52
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 71 deletions.
15 changes: 1 addition & 14 deletions cmd/common.go
Expand Up @@ -152,20 +152,7 @@ func syncMain(ctx context.Context, filenames []string, dry bool, parallelism,
}
return fmt.Errorf(
"cannot apply '%s' config format version to Kong version 3.0 or above.\n"+
"Please upgrade your configuration to account for 3.0\n"+
"breaking changes using the following command:\n\n"+
"deck convert --from kong-gateway-2.x --to kong-gateway-3.x\n\n"+
"This command performs the following changes:\n"+
" - upgrade the `_format_version` value to `3.0`\n"+
" - add the `~` prefix to all routes' paths containing a regex-pattern\n\n"+
"These changes may not be correct or exhaustive enough.\n"+
"It is strongly recommended to perform a manual audit\n"+
"of the updated configuration file before applying\n"+
"the configuration in production. Incorrect changes will result in\n"+
"unintended traffic routing by Kong Gateway.\n\n"+

"For more information about this and related changes,\n"+
"please visit: https://docs.konghq.com/deck/latest/3.0-upgrade", formatVersion)
utils.UpgradeMessage, formatVersion)
}

// TODO: instead of guessing the cobra command here, move the sendAnalytics
Expand Down
52 changes: 31 additions & 21 deletions convert/convert.go
Expand Up @@ -82,13 +82,39 @@ func convertKongGateway2xTo3x(input *file.Content, filename string) (*file.Conte
outputContent := input.DeepCopy()

convertedRoutes := []*file.FRoute{}
changedRoutes := []string{}
for _, service := range outputContent.Services {
for _, route := range service.Routes {
convertedRoutes = append(convertedRoutes, migrateRoutesPathFieldPre300(route, filename))
route, hasChanged := migrateRoutesPathFieldPre300(route)
convertedRoutes = append(convertedRoutes, route)
if hasChanged {
if route.ID != nil {
changedRoutes = append(changedRoutes, *route.ID)
} else {
changedRoutes = append(changedRoutes, *route.Name)
}
}
}
service.Routes = convertedRoutes
}

if len(changedRoutes) > 0 {
changedRoutesLen := len(changedRoutes)
// do not consider more than 10 sample routes to print out.
if changedRoutesLen > 10 {
changedRoutes = changedRoutes[:10]
}
cprint.UpdatePrintf(
"From the '%s' config file,\n"+
"%d unsupported routes' paths format with Kong version 3.0\n"+
"or above were detected. Some of these routes are (not an exhaustive list):\n\n"+
"%s\n\n"+
"Kong gateway versions 3.0 and above require that regular expressions\n"+
"start with a '~' character to distinguish from simple prefix match.\n"+
"In order to make these paths compatible with 3.x, a '~' prefix has been added.\n\n",
filename, changedRoutesLen, strings.Join(changedRoutes, "\n"))
}

cprint.UpdatePrintf(
"From the '%s' config file,\n"+
"the _format_version field has been migrated from '%s' to '%s'.\n"+
Expand All @@ -102,31 +128,15 @@ func convertKongGateway2xTo3x(input *file.Content, filename string) (*file.Conte
return outputContent, nil
}

func migrateRoutesPathFieldPre300(route *file.FRoute, filename string) *file.FRoute {
changedPaths := []string{}
func migrateRoutesPathFieldPre300(route *file.FRoute) (*file.FRoute, bool) {
var hasChanged bool
for _, path := range route.Paths {
if !strings.HasPrefix(*path, "~/") && utils.IsPathRegexLike(*path) {
changedPaths = append(changedPaths, *path)
*path = "~" + *path
hasChanged = true
}
}
if len(changedPaths) > 0 {
changedPathsLen := len(changedPaths)
// do not consider more than 3 sample routes to print out.
if changedPathsLen > 3 {
changedPaths = changedPaths[:3]
}
cprint.UpdatePrintf(
"From the '%s' config file,\n"+
"%d routes paths matching an unsupported regex pattern usage\n"+
"with Kong version 3.0 or above were detected\n"+
"(e.g. %s).\n\n"+
"Kong gateway versions 3.0 and above require that regular expressions\n"+
"start with a '~' character to distinguish from simple prefix match.\n"+
"In order to make these paths compatible with 3.x, a '~' prefix has been added.\n\n",
filename, changedPathsLen, strings.Join(changedPaths, ", "))
}
return route
return route, hasChanged
}

func convertKongGatewayToKonnect(input *file.Content) (*file.Content, error) {
Expand Down
22 changes: 18 additions & 4 deletions file/builder.go
Expand Up @@ -609,6 +609,24 @@ func (b *stateBuilder) routes() {
return
}
}

// check routes' paths format
if b.checkRoutePaths {
unsupportedRoutes := []string{}
allRoutes, err := b.intermediate.Routes.GetAll()
if err != nil {
b.err = err
return
}
for _, r := range allRoutes {
if utils.HasPathsWithRegex300AndAbove(r.Route) {
unsupportedRoutes = append(unsupportedRoutes, *r.Route.ID)
}
}
if len(unsupportedRoutes) > 0 {
utils.PrintRouteRegexWarning(unsupportedRoutes)
}
}
}

func (b *stateBuilder) enterprise() {
Expand Down Expand Up @@ -799,10 +817,6 @@ func (b *stateBuilder) ingestRoute(r FRoute) error {
return err
}

if b.checkRoutePaths {
utils.CheckRoutePaths300AndAbove(r.Route)
}

// plugins for the route
var plugins []FPlugin
for _, p := range r.Plugins {
Expand Down
15 changes: 1 addition & 14 deletions tests/integration/sync_test.go
Expand Up @@ -1803,20 +1803,7 @@ func Test_Sync_Unsupported_Formats(t *testing.T) {
kongFile: "testdata/sync/001-create-a-service/kong.yaml",
expectedError: errors.New(
"cannot apply '1.1' config format version to Kong version 3.0 or above.\n" +
"Please upgrade your configuration to account for 3.0\n" +
"breaking changes using the following command:\n\n" +
"deck convert --from kong-gateway-2.x --to kong-gateway-3.x\n\n" +
"This command performs the following changes:\n" +
" - upgrade the `_format_version` value to `3.0`\n" +
" - add the `~` prefix to all routes' paths containing a regex-pattern\n\n" +
"These changes may not be correct or exhaustive enough.\n" +
"It is strongly recommended to perform a manual audit\n" +
"of the updated configuration file before applying\n" +
"the configuration in production. Incorrect changes will result in\n" +
"unintended traffic routing by Kong Gateway.\n\n" +

"For more information about this and related changes,\n" +
"please visit: https://docs.konghq.com/deck/latest/3.0-upgrade"),
utils.UpgradeMessage),
},
}
for _, tc := range tests {
Expand Down
51 changes: 34 additions & 17 deletions utils/utils.go
Expand Up @@ -23,6 +23,21 @@ var (
Kong300Version = semver.MustParse("3.0.0")
)

var UpgradeMessage = "Please upgrade your configuration to account for 3.0\n" +
"breaking changes using the following command:\n\n" +
"deck convert --from kong-gateway-2.x --to kong-gateway-3.x\n\n" +
"This command performs the following changes:\n" +
" - upgrade the `_format_version` value to `3.0`\n" +
" - add the `~` prefix to all routes' paths containing a regex-pattern\n\n" +
"These changes may not be correct or exhaustive enough.\n" +
"It is strongly recommended to perform a manual audit\n" +
"of the updated configuration file before applying\n" +
"the configuration in production. Incorrect changes will result in\n" +
"unintended traffic routing by Kong Gateway.\n\n" +

"For more information about this and related changes,\n" +
"please visit: https://docs.konghq.com/deck/latest/3.0-upgrade\n\n"

// IsPathRegexLike checks if a path string contains a regex pattern.
func IsPathRegexLike(path string) bool {
return pathRegexPattern.MatchString(path)
Expand Down Expand Up @@ -190,27 +205,29 @@ func ConfigFilesInDir(dir string) ([]string, error) {
return res, nil
}

// CheckRoutePaths300AndAbove checks routes' paths format and prints out
// a warning if regex-like patters without the '~' prefix are found.
func CheckRoutePaths300AndAbove(route kong.Route) {
pathsWarnings := []string{}
// HasPathsWithRegex300AndAbove checks routes' paths format and returns true
// if these math a regex-pattern without a '~' prefix.
func HasPathsWithRegex300AndAbove(route kong.Route) bool {
for _, p := range route.Paths {
if strings.HasPrefix(*p, "~/") || !IsPathRegexLike(*p) {
continue
}
pathsWarnings = append(pathsWarnings, *p)
return true
}
if len(pathsWarnings) > 0 {
cprint.UpdatePrintf(
"In Route '%s', a path with regular expression was detected.\n"+
"In Kong Gateway versions 3.0 and above, all paths that use regular expressions \n"+
"must be prefixed with a ~ character. Without the ~ prefix, regular expression \n"+
"based paths will not be matched and processed correctly. \n\n"+
"Please run the following command to upgrade your config: \n\n"+
"deck convert --from kong-gateway-2.x --to kong-gateway-3.x "+
"--input-file <config-file> --output-file <new-config-file>\n\n"+
"Please refer to the following document for further details:\n"+
"https://docs.konghq.com/deck/latest/3.0-upgrade.\n\n",
*route.ID)
return false
}

// PrintRouteRegexWarning prints out a warning about 3.x routes' path usage.
func PrintRouteRegexWarning(unsupportedRoutes []string) {
unsupportedRoutesLen := len(unsupportedRoutes)
// do not consider more than 10 sample routes to print out.
if unsupportedRoutesLen > 10 {
unsupportedRoutes = unsupportedRoutes[:10]
}
cprint.UpdatePrintf(
"%d unsupported routes' paths format with Kong version 3.0\n"+
"or above were detected. Some of these routes are (not an exhaustive list):\n\n"+
"%s\n\n"+UpgradeMessage,
unsupportedRoutesLen, strings.Join(unsupportedRoutes, "\n"),
)
}
8 changes: 7 additions & 1 deletion validate/validate.go
Expand Up @@ -186,7 +186,13 @@ func (v *Validator) Validate(kongVersion semver.Version) []error {

func validate3xRoutes(routes *state.RoutesCollection) {
results, _ := routes.GetAll()
unsupportedRoutes := []string{}
for _, r := range results {
utils.CheckRoutePaths300AndAbove(r.Route)
if utils.HasPathsWithRegex300AndAbove(r.Route) {
unsupportedRoutes = append(unsupportedRoutes, *r.Route.ID)
}
}
if len(unsupportedRoutes) > 0 {
utils.PrintRouteRegexWarning(unsupportedRoutes)
}
}

0 comments on commit 53d1f52

Please sign in to comment.