Skip to content

Commit

Permalink
feat: add FilterChain entity
Browse files Browse the repository at this point in the history
  • Loading branch information
hishamhm committed Jul 31, 2023
1 parent 6d0b704 commit 2c1b678
Show file tree
Hide file tree
Showing 19 changed files with 781 additions and 70 deletions.
1 change: 1 addition & 0 deletions cmd/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,7 @@ func containsProxyConfiguration(content utils.KongRawState) bool {
return len(content.Services) != 0 ||
len(content.Routes) != 0 ||
len(content.Plugins) != 0 ||
len(content.FilterChains) != 0 ||
len(content.Upstreams) != 0 ||
len(content.Certificates) != 0 ||
len(content.CACertificates) != 0 ||
Expand Down
3 changes: 3 additions & 0 deletions cmd/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,5 +220,8 @@ func ensureGetAllMethods() error {
if _, err := utils.CallGetAll(dummyEmptyState.RBACRoles); err != nil {
return err
}
if _, err := utils.CallGetAll(dummyEmptyState.FilterChains); err != nil {
return err
}
return nil
}
6 changes: 6 additions & 0 deletions convert/testdata/2/input.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ services:
- /r3
methods:
- GET
filter_chains:
- name: filter_chain1
service: svc1
filters:
- name: example-filter
config: "{ \"my_greeting\": \"Hello, decK!\" }"
upstreams:
- name: upstream1
algorithm: round-robin
Expand Down
6 changes: 6 additions & 0 deletions convert/testdata/2/output-expected.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,12 @@ plugins:
- http
- https
run_on: first
filter_chains:
- name: filter_chain1
service: 300f010e-3f17-48ce-8a55-f2d9f9bd65b6
filters:
- name: example-filter
config: "{ \"my_greeting\": \"Hello, decK!\" }"
service_packages:
- description: placeholder description for svc1 service package
name: svc1
Expand Down
2 changes: 1 addition & 1 deletion diff/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ func (sc *Syncer) init() error {
}

entities := []types.EntityType{
types.Service, types.Route, types.Plugin,
types.Service, types.Route, types.Plugin, types.FilterChain,

types.Certificate, types.SNI, types.CACertificate,

Expand Down
4 changes: 3 additions & 1 deletion 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 @@ -60,6 +61,7 @@ var dependencyOrder = [][]types.EntityType{
},
{
types.Plugin,
types.FilterChain,
types.Document,
},
}
Expand Down
33 changes: 33 additions & 0 deletions dump/dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,15 @@ func getProxyConfiguration(ctx context.Context, group *errgroup.Group,
return nil
})

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
})

group.Go(func() error {
certificates, err := GetAllCertificates(ctx, client, config.SelectorTags)
if err != nil {
Expand Down Expand Up @@ -388,6 +397,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
94 changes: 94 additions & 0 deletions file/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,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 @@ -679,6 +680,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 @@ -890,6 +901,48 @@ func (b *stateBuilder) plugins() {
}
}

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

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

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

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

// strip_path schema default value is 'true', but it cannot be set when
// protocols include 'grpc' and/or 'grpcs'. When users explicitly set
// strip_path to 'true' with grpc/s protocols, deck returns a schema violation error.
Expand Down Expand Up @@ -935,6 +988,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 @@ -1025,6 +1088,37 @@ func (b *stateBuilder) ingestPlugins(plugins []FPlugin) error {
return nil
}

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(*f.Name,
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 (b *stateBuilder) fillPluginConfig(plugin *FPlugin) error {
if plugin == nil {
return fmt.Errorf("plugin is nil")
Expand Down
32 changes: 31 additions & 1 deletion file/codegen/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,16 @@ func main() {

schema.Definitions["FConsumer"].AnyOf = anyOfUsernameOrID

schema.Definitions["FUpstream"].Required = []string{"name"}
schema.Definitions["FFilterChain"].AnyOf = []*jsonschema.Type{
{
Required: []string{"filters", "name"},
},
{
Required: []string{"filters", "id"},
},
}

schema.Definitions["FUpstream"].Required = []string{"name"}
schema.Definitions["FTarget"].Required = []string{"target"}
schema.Definitions["FCACertificate"].Required = []string{"cert"}
schema.Definitions["FPlugin"].Required = []string{"name"}
Expand All @@ -73,6 +81,25 @@ func main() {
},
}

schema.Definitions["FFilterChain"].Properties["filters"] = &jsonschema.Type{
Type: "array",
Items: &jsonschema.Type{
Type: "object",
Required: []string{"name"},
Properties: map[string]*jsonschema.Type{
"name": {
Type: "string",
},
"config": {
Type: "string",
},
"enabled": {
Type: "boolean",
},
},
},
}

// creds
schema.Definitions["ACLGroup"].Required = []string{"group"}
schema.Definitions["BasicAuth"].Required = []string{"username", "password"}
Expand All @@ -98,6 +125,9 @@ func main() {
schema.Definitions["FPlugin"].Properties["service"] = stringType
schema.Definitions["FPlugin"].Properties["route"] = 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 2c1b678

Please sign in to comment.