Skip to content

Commit

Permalink
feat: add wasm filter-chain entity support
Browse files Browse the repository at this point in the history
  • Loading branch information
flrgh committed Apr 4, 2024
1 parent 599ea65 commit bb91ea4
Show file tree
Hide file tree
Showing 18 changed files with 1,338 additions and 67 deletions.
2 changes: 2 additions & 0 deletions pkg/diff/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ func (sc *Syncer) init() error {
types.RBACRole, types.RBACEndpointPermission,

types.ServicePackage, types.ServiceVersion, types.Document,

types.FilterChain,
}

sc.entityDiffers = map[types.EntityType]types.Differ{}
Expand Down
4 changes: 3 additions & 1 deletion pkg/diff/order.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ L3 +---------------------------> Service <---+ +-> Route |
| Version | | |
| | | | |
| | | v |
L4 +----------> Document <---------+ +-> Plugins <----------+
L4 +----------> Document <---------+ +-> Plugins / <---------+
FilterChains
*/

// dependencyOrder defines the order in which entities will be synced by decK.
Expand Down Expand Up @@ -61,6 +62,7 @@ var dependencyOrder = [][]types.EntityType{
},
{
types.Plugin,
types.FilterChain,
types.Document,
},
}
Expand Down
40 changes: 40 additions & 0 deletions pkg/dump/dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ type Config struct {

// IsConsumerGroupScopedPluginSupported
IsConsumerGroupScopedPluginSupported bool

// IsFilterChainsSupported
IsFilterChainsSupported bool
}

func deduplicate(stringSlice []string) []string {
Expand Down Expand Up @@ -252,6 +255,19 @@ func getProxyConfiguration(ctx context.Context, group *errgroup.Group,
return nil
})

if config.IsFilterChainsSupported {
group.Go(func() error {
filterChains, err := GetAllFilterChains(ctx, client, config.SelectorTags)
if err != nil {
return fmt.Errorf("filter chains: %w", err)
}
state.FilterChains = filterChains
return nil
})
} else {
state.FilterChains = make([]*kong.FilterChain, 0)
}

group.Go(func() error {
certificates, err := GetAllCertificates(ctx, client, config.SelectorTags)
if err != nil {
Expand Down Expand Up @@ -441,6 +457,30 @@ func GetAllPlugins(ctx context.Context,
return plugins, nil
}

// GetAllFilterChains queries Kong for all the filter chains using client.
func GetAllFilterChains(ctx context.Context,
client *kong.Client, tags []string,
) ([]*kong.FilterChain, error) {
var filterChains []*kong.FilterChain
opt := newOpt(tags)

for {
s, nextopt, err := client.FilterChains.List(ctx, opt)
if err != nil {
return nil, err
}
if err := ctx.Err(); err != nil {
return nil, err
}
filterChains = append(filterChains, s...)
if nextopt == nil {
break
}
opt = nextopt
}
return filterChains, nil
}

// GetAllCertificates queries Kong for all the certificates using client.
func GetAllCertificates(ctx context.Context, client *kong.Client,
tags []string,
Expand Down
93 changes: 93 additions & 0 deletions pkg/file/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ func (b *stateBuilder) build() (*utils.KongRawState, *utils.KonnectRawState, err
b.consumerGroups()
b.consumers()
b.plugins()
b.filterChains()
b.enterprise()

// konnect
Expand Down Expand Up @@ -894,6 +895,16 @@ func (b *stateBuilder) ingestService(s *FService) error {
return err
}

// filter chains for the service
var filterChains []FFilterChain
for _, f := range s.FilterChains {
f.Service = utils.GetServiceReference(s.Service)
filterChains = append(filterChains, *f)
}
if err := b.ingestFilterChains(filterChains); err != nil {
return err
}

// routes for the service
for _, r := range s.Routes {
r := r
Expand Down Expand Up @@ -1153,6 +1164,48 @@ func (b *stateBuilder) plugins() {
}
}

func (b *stateBuilder) filterChains() {
if b.err != nil {
return
}

var filterChains []FFilterChain
for _, f := range b.targetContent.FilterChains {
f := f
if f.Service != nil && !utils.Empty(f.Service.ID) {
s, err := b.intermediate.Services.Get(*f.Service.ID)
if errors.Is(err, state.ErrNotFound) {
b.err = fmt.Errorf("service %v for filterChain %v: %w",
f.Service.FriendlyName(), *f.Name, err)

return
} else if err != nil {
b.err = err
return
}
f.Service = utils.GetServiceReference(s.Service)
}
if f.Route != nil && !utils.Empty(f.Route.ID) {
r, err := b.intermediate.Routes.Get(*f.Route.ID)
if errors.Is(err, state.ErrNotFound) {
b.err = fmt.Errorf("route %v for filterChain %v: %w",
f.Route.FriendlyName(), *f.Name, err)

return
} else if err != nil {
b.err = err
return
}
f.Route = utils.GetRouteReference(r.Route)
}
filterChains = append(filterChains, f)
}
if err := b.ingestFilterChains(filterChains); err != nil {
b.err = err
return
}
}

func (b *stateBuilder) validatePlugin(p FPlugin) error {
if b.isConsumerGroupScopedPluginSupported && *p.Name == ratelimitingAdvancedPluginName {
// check if deprecated consumer-groups configuration is present in the config
Expand Down Expand Up @@ -1270,6 +1323,16 @@ func (b *stateBuilder) ingestRoute(r FRoute) error {
return err
}

// filter chains for the route
var filterChains []FFilterChain
for _, f := range r.FilterChains {
f.Route = utils.GetRouteReference(r.Route)
filterChains = append(filterChains, *f)
}
if err := b.ingestFilterChains(filterChains); err != nil {
return err
}

// plugins for the route
var plugins []FPlugin
for _, p := range r.Plugins {
Expand Down Expand Up @@ -1398,6 +1461,36 @@ func pluginRelations(plugin *kong.Plugin) (cID, rID, sID, cgID string) {
return
}

func (b *stateBuilder) ingestFilterChains(filterChains []FFilterChain) error {
for _, f := range filterChains {
f := f
if utils.Empty(f.ID) {
rID, sID := filterChainRelations(&f.FilterChain)
filterChain, err := b.currentState.FilterChains.GetByProp(sID, rID)
if errors.Is(err, state.ErrNotFound) {
f.ID = uuid()
} else if err != nil {
return err
} else {
f.ID = kong.String(*filterChain.ID)
}
}
utils.MustMergeTags(&f, b.selectTags)
b.rawState.FilterChains = append(b.rawState.FilterChains, &f.FilterChain)
}
return nil
}

func filterChainRelations(filterChain *kong.FilterChain) (rID, sID string) {
if filterChain.Route != nil && !utils.Empty(filterChain.Route.ID) {
rID = *filterChain.Route.ID
}
if filterChain.Service != nil && !utils.Empty(filterChain.Service.ID) {
sID = *filterChain.Service.ID
}
return
}

func defaulter(
ctx context.Context, client *kong.Client, fileContent *Content, disableDynamicDefaults, isKonnect bool,
) (*utils.Defaulter, error) {
Expand Down
46 changes: 46 additions & 0 deletions pkg/file/codegen/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,49 @@ func main() {
},
}

schema.Definitions["FFilterChain"].AnyOf = []*jsonschema.Type{
{
Required: []string{"filters", "name"},
},
{
Required: []string{"filters", "id"},
},
}
schema.Definitions["FFilterChain"].Properties["enabled"] = &jsonschema.Type{
Type: "boolean",
}
schema.Definitions["FFilterChain"].Properties["filters"] = &jsonschema.Type{
Type: "array",
Items: &jsonschema.Type{
Ref: "#/definitions/FFilter",
},
}

schema.Definitions["FFilter"] = &jsonschema.Type{
Type: "object",
Required: []string{"name"},
AdditionalProperties: json.RawMessage(`false`),
Properties: map[string]*jsonschema.Type{
"name": {
Type: "string",
},
"config": {
OneOf: []*jsonschema.Type{
{Type: "array"},
{Type: "boolean"},
{Type: "integer"},
{Type: "number"},
{Type: "null"},
{Type: "object"},
{Type: "string"},
},
},
"enabled": {
Type: "boolean",
},
},
}

// creds
schema.Definitions["ACLGroup"].Required = []string{"group"}
schema.Definitions["BasicAuth"].Required = []string{"username", "password"}
Expand All @@ -102,6 +145,9 @@ func main() {
schema.Definitions["FPlugin"].Properties["route"] = stringType
schema.Definitions["FPlugin"].Properties["consumer_group"] = stringType

schema.Definitions["FFilterChain"].Properties["service"] = stringType
schema.Definitions["FFilterChain"].Properties["route"] = stringType

schema.Definitions["FService"].Properties["client_certificate"] = stringType

// konnect resources
Expand Down
Loading

0 comments on commit bb91ea4

Please sign in to comment.