Skip to content

Commit

Permalink
feat(convert): Convert pre-function 'functions' to 'access' in 2.x to…
Browse files Browse the repository at this point in the history
… 3.x
  • Loading branch information
mheap committed May 3, 2024
1 parent e59eb93 commit 5e0de31
Show file tree
Hide file tree
Showing 2 changed files with 274 additions and 0 deletions.
82 changes: 82 additions & 0 deletions convert/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package convert
import (
"context"
"crypto/rand"
"errors"
"fmt"
"math/big"
"strings"
Expand Down Expand Up @@ -31,6 +32,7 @@ const (
FormatKongGateway3x Format = "kong-gateway-3.x"

rateLimitingAdvancedPluginName = "rate-limiting-advanced"
preFunctionPluginName = "pre-function"
rlaNamespaceDefaultLength = 32
)

Expand Down Expand Up @@ -166,6 +168,11 @@ func convertKongGateway2xTo3x(input *file.Content, filename string) (*file.Conte
return nil, err
}

// update the pre-function
if err := convertPreFunctions2xTo3x(outputContent); err != nil {
return nil, err
}

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

func convertPreFunctions2xTo3x(content *file.Content) error {
err := applyForEachPluginInstance(content, preFunctionPluginName, func(plugin *file.FPlugin) error {
if plugin.Config["functions"] == nil {
return errors.New("functions field is missing in pre-function plugin")
}

plugin.Config["access"] = plugin.Config["functions"]
delete(plugin.Config, "functions")

return nil
})

// Fix Consumer Group plugins too
for _, consumerGroup := range content.ConsumerGroups {
for _, plugin := range consumerGroup.Plugins {
if *plugin.Name == preFunctionPluginName {
if plugin.Config["functions"] == nil {
return errors.New("functions field is missing in pre-function plugin")
}
plugin.Config["access"] = plugin.Config["functions"]
delete(plugin.Config, "functions")
}
}
}

if err != nil {
return err
}

return nil
}

func applyForEachPluginInstance(content *file.Content, pluginName string, f func(plugin *file.FPlugin) error) error {
for _, plugin := range content.Plugins {
if *plugin.Name == pluginName {
plugin := plugin
if err := f(&plugin); err != nil {
return err
}
}
}

for _, service := range content.Services {
for _, plugin := range service.Plugins {
if *plugin.Name == pluginName {
if err := f(plugin); err != nil {
return err
}
}
}
}

for _, route := range content.Routes {
for _, plugin := range route.Plugins {
if *plugin.Name == pluginName {
if err := f(plugin); err != nil {
return err
}
}
}
}

for _, consumer := range content.Consumers {
for _, plugin := range consumer.Plugins {
if *plugin.Name == pluginName {
if err := f(plugin); err != nil {
return err
}
}
}
}

return nil
}

func generateAutoFields(content *file.Content) error {
for _, plugin := range content.Plugins {
if *plugin.Name == rateLimitingAdvancedPluginName {
Expand Down
192 changes: 192 additions & 0 deletions convert/convert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -579,3 +579,195 @@ func Test_convertAutoFields(t *testing.T) {
consumerGroupPluginConfig := got.ConsumerGroups[0].Plugins[0].Config
assert.NotEmpty(t, consumerGroupPluginConfig["namespace"])
}

func Test_convertPreFunction(t *testing.T) {
content := &file.Content{
Services: []file.FService{
{
Service: kong.Service{
Name: kong.String("s1"),
Host: kong.String("httpbin.org"),
},
Plugins: []*file.FPlugin{
{
Plugin: kong.Plugin{
Name: kong.String("pre-function"),
Config: kong.Configuration{
"functions": "kong.log.err(\"service\")",
},
},
},
},
},
},
Routes: []file.FRoute{
{
Route: kong.Route{
Name: kong.String("r1"),
Paths: []*string{kong.String("/r1")},
},
Plugins: []*file.FPlugin{
{
Plugin: kong.Plugin{
Name: kong.String("pre-function"),
Config: kong.Configuration{
"functions": "kong.log.err(\"route\")",
},
},
},
},
},
},
Consumers: []file.FConsumer{
{
Consumer: kong.Consumer{
Username: kong.String("foo"),
},
Plugins: []*file.FPlugin{
{
Plugin: kong.Plugin{
Name: kong.String("pre-function"),
Config: kong.Configuration{
"functions": "kong.log.err(\"consumer\")",
},
},
},
},
},
},
ConsumerGroups: []file.FConsumerGroupObject{
{
ConsumerGroup: kong.ConsumerGroup{
Name: kong.String("my_consumer_group"),
},
Plugins: []*kong.ConsumerGroupPlugin{
{
Name: kong.String("pre-function"),
Config: kong.Configuration{
"functions": "kong.log.err(\"consumer_group\")",
},
},
},
},
},
Plugins: []file.FPlugin{
{
Plugin: kong.Plugin{
Name: kong.String("pre-function"),
Config: kong.Configuration{
"functions": "kong.log.err(\"global\")",
},
},
},
},
}

got, err := convertKongGateway2xTo3x(content, "-")
assert.NoError(t, err)

globalPluginConfig := got.Plugins[0].Config
assert.Contains(t, globalPluginConfig["access"], "global")
assert.Empty(t, globalPluginConfig["functions"])

servicePluginConfig := got.Services[0].Plugins[0].Config
assert.Contains(t, servicePluginConfig["access"], "service")
assert.Empty(t, servicePluginConfig["functions"])

routePluginConfig := got.Routes[0].Plugins[0].Config
assert.Contains(t, routePluginConfig["access"], "route")
assert.Empty(t, routePluginConfig["functions"])

consumerPluginConfig := got.Consumers[0].Plugins[0].Config
assert.Contains(t, consumerPluginConfig["access"], "consumer")
assert.Empty(t, consumerPluginConfig["functions"])

consumerGroupPluginConfig := got.ConsumerGroups[0].Plugins[0].Config
assert.Contains(t, consumerGroupPluginConfig["access"], "consumer_group")
assert.Empty(t, consumerGroupPluginConfig["functions"])
}

func Test_convertPreFunctionWithError(t *testing.T) {
content := &file.Content{
Services: []file.FService{
{
Service: kong.Service{
Name: kong.String("s1"),
Host: kong.String("httpbin.org"),
},
Plugins: []*file.FPlugin{
{
Plugin: kong.Plugin{
Name: kong.String("pre-function"),
Config: kong.Configuration{
"should_be_functions": "kong.log.err(\"service\")",
},
},
},
},
},
},
Routes: []file.FRoute{
{
Route: kong.Route{
Name: kong.String("r1"),
Paths: []*string{kong.String("/r1")},
},
Plugins: []*file.FPlugin{
{
Plugin: kong.Plugin{
Name: kong.String("pre-function"),
Config: kong.Configuration{
"should_be_functions": "kong.log.err(\"route\")",
},
},
},
},
},
},
Consumers: []file.FConsumer{
{
Consumer: kong.Consumer{
Username: kong.String("foo"),
},
Plugins: []*file.FPlugin{
{
Plugin: kong.Plugin{
Name: kong.String("pre-function"),
Config: kong.Configuration{
"should_be_functions": "kong.log.err(\"consumer\")",
},
},
},
},
},
},
ConsumerGroups: []file.FConsumerGroupObject{
{
ConsumerGroup: kong.ConsumerGroup{
Name: kong.String("my_consumer_group"),
},
Plugins: []*kong.ConsumerGroupPlugin{
{
Name: kong.String("pre-function"),
Config: kong.Configuration{
"should_be_functions": "kong.log.err(\"consumer_group\")",
},
},
},
},
},
Plugins: []file.FPlugin{
{
Plugin: kong.Plugin{
Name: kong.String("pre-function"),
Config: kong.Configuration{
"should_be_functions": "kong.log.err(\"global\")",
},
},
},
},
}

_, err := convertKongGateway2xTo3x(content, "-")
assert.Error(t, err)
}

0 comments on commit 5e0de31

Please sign in to comment.