Skip to content

Commit e0f0026

Browse files
committed
feat(convert): Convert pre-function 'functions' to 'access' in 2.x to 3.x
1 parent e59eb93 commit e0f0026

File tree

2 files changed

+275
-0
lines changed

2 files changed

+275
-0
lines changed

convert/convert.go

+83
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package convert
33
import (
44
"context"
55
"crypto/rand"
6+
"errors"
67
"fmt"
78
"math/big"
89
"strings"
@@ -31,6 +32,7 @@ const (
3132
FormatKongGateway3x Format = "kong-gateway-3.x"
3233

3334
rateLimitingAdvancedPluginName = "rate-limiting-advanced"
35+
preFunctionPluginName = "pre-function"
3436
rlaNamespaceDefaultLength = 32
3537
)
3638

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

171+
// update the pre-function
172+
if err := convertPreFunctions2xTo3x(outputContent); err != nil {
173+
return nil, err
174+
}
175+
169176
cprint.UpdatePrintf(
170177
"From the '%s' config file,\n"+
171178
"the _format_version field has been migrated from '%s' to '%s'.\n"+
@@ -179,6 +186,82 @@ func convertKongGateway2xTo3x(input *file.Content, filename string) (*file.Conte
179186
return outputContent, nil
180187
}
181188

189+
func convertPreFunctions2xTo3x(content *file.Content) error {
190+
191+
err := applyForEachPluginInstance(content, preFunctionPluginName, func(plugin *file.FPlugin) error {
192+
if plugin.Config["functions"] == nil {
193+
return errors.New("functions field is missing in pre-function plugin")
194+
}
195+
196+
plugin.Config["access"] = plugin.Config["functions"]
197+
delete(plugin.Config, "functions")
198+
199+
return nil
200+
})
201+
202+
// Fix Consumer Group plugins too
203+
for _, consumerGroup := range content.ConsumerGroups {
204+
for _, plugin := range consumerGroup.Plugins {
205+
if *plugin.Name == preFunctionPluginName {
206+
if plugin.Config["functions"] == nil {
207+
return errors.New("functions field is missing in pre-function plugin")
208+
}
209+
plugin.Config["access"] = plugin.Config["functions"]
210+
delete(plugin.Config, "functions")
211+
}
212+
}
213+
}
214+
215+
if err != nil {
216+
return err
217+
}
218+
219+
return nil
220+
}
221+
222+
func applyForEachPluginInstance(content *file.Content, pluginName string, f func(plugin *file.FPlugin) error) error {
223+
for _, plugin := range content.Plugins {
224+
if *plugin.Name == pluginName {
225+
plugin := plugin
226+
if err := f(&plugin); err != nil {
227+
return err
228+
}
229+
}
230+
}
231+
232+
for _, service := range content.Services {
233+
for _, plugin := range service.Plugins {
234+
if *plugin.Name == pluginName {
235+
if err := f(plugin); err != nil {
236+
return err
237+
}
238+
}
239+
}
240+
}
241+
242+
for _, route := range content.Routes {
243+
for _, plugin := range route.Plugins {
244+
if *plugin.Name == pluginName {
245+
if err := f(plugin); err != nil {
246+
return err
247+
}
248+
}
249+
}
250+
}
251+
252+
for _, consumer := range content.Consumers {
253+
for _, plugin := range consumer.Plugins {
254+
if *plugin.Name == pluginName {
255+
if err := f(plugin); err != nil {
256+
return err
257+
}
258+
}
259+
}
260+
}
261+
262+
return nil
263+
}
264+
182265
func generateAutoFields(content *file.Content) error {
183266
for _, plugin := range content.Plugins {
184267
if *plugin.Name == rateLimitingAdvancedPluginName {

convert/convert_test.go

+192
Original file line numberDiff line numberDiff line change
@@ -579,3 +579,195 @@ func Test_convertAutoFields(t *testing.T) {
579579
consumerGroupPluginConfig := got.ConsumerGroups[0].Plugins[0].Config
580580
assert.NotEmpty(t, consumerGroupPluginConfig["namespace"])
581581
}
582+
583+
func Test_convertPreFunction(t *testing.T) {
584+
content := &file.Content{
585+
Services: []file.FService{
586+
{
587+
Service: kong.Service{
588+
Name: kong.String("s1"),
589+
Host: kong.String("httpbin.org"),
590+
},
591+
Plugins: []*file.FPlugin{
592+
{
593+
Plugin: kong.Plugin{
594+
Name: kong.String("pre-function"),
595+
Config: kong.Configuration{
596+
"functions": "kong.log.err(\"service\")",
597+
},
598+
},
599+
},
600+
},
601+
},
602+
},
603+
Routes: []file.FRoute{
604+
{
605+
Route: kong.Route{
606+
Name: kong.String("r1"),
607+
Paths: []*string{kong.String("/r1")},
608+
},
609+
Plugins: []*file.FPlugin{
610+
{
611+
Plugin: kong.Plugin{
612+
Name: kong.String("pre-function"),
613+
Config: kong.Configuration{
614+
"functions": "kong.log.err(\"route\")",
615+
},
616+
},
617+
},
618+
},
619+
},
620+
},
621+
Consumers: []file.FConsumer{
622+
{
623+
Consumer: kong.Consumer{
624+
Username: kong.String("foo"),
625+
},
626+
Plugins: []*file.FPlugin{
627+
{
628+
Plugin: kong.Plugin{
629+
Name: kong.String("pre-function"),
630+
Config: kong.Configuration{
631+
"functions": "kong.log.err(\"consumer\")",
632+
},
633+
},
634+
},
635+
},
636+
},
637+
},
638+
ConsumerGroups: []file.FConsumerGroupObject{
639+
{
640+
ConsumerGroup: kong.ConsumerGroup{
641+
Name: kong.String("my_consumer_group"),
642+
},
643+
Plugins: []*kong.ConsumerGroupPlugin{
644+
{
645+
Name: kong.String("pre-function"),
646+
Config: kong.Configuration{
647+
"functions": "kong.log.err(\"consumer_group\")",
648+
},
649+
},
650+
},
651+
},
652+
},
653+
Plugins: []file.FPlugin{
654+
{
655+
Plugin: kong.Plugin{
656+
Name: kong.String("pre-function"),
657+
Config: kong.Configuration{
658+
"functions": "kong.log.err(\"global\")",
659+
},
660+
},
661+
},
662+
},
663+
}
664+
665+
got, err := convertKongGateway2xTo3x(content, "-")
666+
assert.NoError(t, err)
667+
668+
globalPluginConfig := got.Plugins[0].Config
669+
assert.Contains(t, globalPluginConfig["access"], "global")
670+
assert.Empty(t, globalPluginConfig["functions"])
671+
672+
servicePluginConfig := got.Services[0].Plugins[0].Config
673+
assert.Contains(t, servicePluginConfig["access"], "service")
674+
assert.Empty(t, servicePluginConfig["functions"])
675+
676+
routePluginConfig := got.Routes[0].Plugins[0].Config
677+
assert.Contains(t, routePluginConfig["access"], "route")
678+
assert.Empty(t, routePluginConfig["functions"])
679+
680+
consumerPluginConfig := got.Consumers[0].Plugins[0].Config
681+
assert.Contains(t, consumerPluginConfig["access"], "consumer")
682+
assert.Empty(t, consumerPluginConfig["functions"])
683+
684+
consumerGroupPluginConfig := got.ConsumerGroups[0].Plugins[0].Config
685+
assert.Contains(t, consumerGroupPluginConfig["access"], "consumer_group")
686+
assert.Empty(t, consumerGroupPluginConfig["functions"])
687+
}
688+
689+
func Test_convertPreFunctionWithError(t *testing.T) {
690+
content := &file.Content{
691+
Services: []file.FService{
692+
{
693+
Service: kong.Service{
694+
Name: kong.String("s1"),
695+
Host: kong.String("httpbin.org"),
696+
},
697+
Plugins: []*file.FPlugin{
698+
{
699+
Plugin: kong.Plugin{
700+
Name: kong.String("pre-function"),
701+
Config: kong.Configuration{
702+
"should_be_functions": "kong.log.err(\"service\")",
703+
},
704+
},
705+
},
706+
},
707+
},
708+
},
709+
Routes: []file.FRoute{
710+
{
711+
Route: kong.Route{
712+
Name: kong.String("r1"),
713+
Paths: []*string{kong.String("/r1")},
714+
},
715+
Plugins: []*file.FPlugin{
716+
{
717+
Plugin: kong.Plugin{
718+
Name: kong.String("pre-function"),
719+
Config: kong.Configuration{
720+
"should_be_functions": "kong.log.err(\"route\")",
721+
},
722+
},
723+
},
724+
},
725+
},
726+
},
727+
Consumers: []file.FConsumer{
728+
{
729+
Consumer: kong.Consumer{
730+
Username: kong.String("foo"),
731+
},
732+
Plugins: []*file.FPlugin{
733+
{
734+
Plugin: kong.Plugin{
735+
Name: kong.String("pre-function"),
736+
Config: kong.Configuration{
737+
"should_be_functions": "kong.log.err(\"consumer\")",
738+
},
739+
},
740+
},
741+
},
742+
},
743+
},
744+
ConsumerGroups: []file.FConsumerGroupObject{
745+
{
746+
ConsumerGroup: kong.ConsumerGroup{
747+
Name: kong.String("my_consumer_group"),
748+
},
749+
Plugins: []*kong.ConsumerGroupPlugin{
750+
{
751+
Name: kong.String("pre-function"),
752+
Config: kong.Configuration{
753+
"should_be_functions": "kong.log.err(\"consumer_group\")",
754+
},
755+
},
756+
},
757+
},
758+
},
759+
Plugins: []file.FPlugin{
760+
{
761+
Plugin: kong.Plugin{
762+
Name: kong.String("pre-function"),
763+
Config: kong.Configuration{
764+
"should_be_functions": "kong.log.err(\"global\")",
765+
},
766+
},
767+
},
768+
},
769+
}
770+
771+
_, err := convertKongGateway2xTo3x(content, "-")
772+
assert.Error(t, err)
773+
}

0 commit comments

Comments
 (0)