Skip to content

Commit

Permalink
feat: ignoring konnect-managed entities with deck (#153)
Browse files Browse the repository at this point in the history
* feat: ignoring konnect-managed entities with deck

As of now, deck supports ignoring plugins
that are konnect-managed. We are adding further
support to ignore any entity that may have the
tag "konnect-managed" added to it. Konnect
adds these tags to some entities and they
are treated as immutable. Thus, we wish to
ignore any deck operations on them.

With this change, a deck dump would not
include the "konnect-managed" entities.
deck sync/diff would also ignore these entities.
For: Kong/deck#1442

* chore: added test-case for the new function

* chore: fixed linting issues
  • Loading branch information
Prashansa-K authored Dec 11, 2024
1 parent ba02fcd commit 56ae7c1
Show file tree
Hide file tree
Showing 4 changed files with 185 additions and 3 deletions.
60 changes: 60 additions & 0 deletions pkg/dump/dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,12 @@ func getProxyConfiguration(ctx context.Context, group *errgroup.Group,
if err != nil {
return fmt.Errorf("services: %w", err)
}

services, err = excludeKonnectManagedEntities(services)
if err != nil {
return fmt.Errorf("services: %w", err)
}

if config.LookUpSelectorTagsServices != nil {
globalServices, err := GetAllServices(ctx, client, config.LookUpSelectorTagsServices)
if err != nil {
Expand Down Expand Up @@ -263,6 +269,12 @@ func getProxyConfiguration(ctx context.Context, group *errgroup.Group,
if err != nil {
return fmt.Errorf("routes: %w", err)
}

routes, err = excludeKonnectManagedEntities(routes)
if err != nil {
return fmt.Errorf("routes: %w", err)
}

if config.LookUpSelectorTagsRoutes != nil {
globalRoutes, err := GetAllRoutes(ctx, client, config.LookUpSelectorTagsRoutes)
if err != nil {
Expand Down Expand Up @@ -318,6 +330,12 @@ func getProxyConfiguration(ctx context.Context, group *errgroup.Group,
}
return fmt.Errorf("filter chains: %w", err)
}

filterChains, err = excludeKonnectManagedEntities(filterChains)
if err != nil {
return fmt.Errorf("filter chains: %w", err)
}

state.FilterChains = filterChains
return nil
})
Expand All @@ -327,6 +345,12 @@ func getProxyConfiguration(ctx context.Context, group *errgroup.Group,
if err != nil {
return fmt.Errorf("certificates: %w", err)
}

certificates, err = excludeKonnectManagedEntities(certificates)
if err != nil {
return fmt.Errorf("certificates: %w", err)
}

state.Certificates = certificates
return nil
})
Expand All @@ -337,6 +361,12 @@ func getProxyConfiguration(ctx context.Context, group *errgroup.Group,
if err != nil {
return fmt.Errorf("ca-certificates: %w", err)
}

caCerts, err = excludeKonnectManagedEntities(caCerts)
if err != nil {
return fmt.Errorf("ca-certificates: %w", err)
}

state.CACertificates = caCerts
return nil
})
Expand All @@ -347,6 +377,12 @@ func getProxyConfiguration(ctx context.Context, group *errgroup.Group,
if err != nil {
return fmt.Errorf("snis: %w", err)
}

snis, err = excludeKonnectManagedEntities(snis)
if err != nil {
return fmt.Errorf("snis: %w", err)
}

state.SNIs = snis
return nil
})
Expand All @@ -356,11 +392,23 @@ func getProxyConfiguration(ctx context.Context, group *errgroup.Group,
if err != nil {
return fmt.Errorf("upstreams: %w", err)
}

upstreams, err = excludeKonnectManagedEntities(upstreams)
if err != nil {
return fmt.Errorf("upstreams: %w", err)
}

state.Upstreams = upstreams
targets, err := GetAllTargets(ctx, client, upstreams, config.SelectorTags)
if err != nil {
return fmt.Errorf("targets: %w", err)
}

targets, err = excludeKonnectManagedEntities(targets)
if err != nil {
return fmt.Errorf("targets: %w", err)
}

state.Targets = targets
return nil
})
Expand All @@ -370,6 +418,12 @@ func getProxyConfiguration(ctx context.Context, group *errgroup.Group,
if err != nil {
return fmt.Errorf("vaults: %w", err)
}

vaults, err = excludeKonnectManagedEntities(vaults)
if err != nil {
return fmt.Errorf("vaults: %w", err)
}

state.Vaults = vaults
return nil
})
Expand All @@ -380,6 +434,12 @@ func getProxyConfiguration(ctx context.Context, group *errgroup.Group,
if err != nil {
return fmt.Errorf("licenses: %w", err)
}

licenses, err = excludeKonnectManagedEntities(licenses)
if err != nil {
return fmt.Errorf("licenses: %w", err)
}

state.Licenses = licenses
return nil
})
Expand Down
50 changes: 47 additions & 3 deletions pkg/dump/dump_konnect.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package dump
import (
"context"
"fmt"
"reflect"
"sync"

"github.com/kong/go-database-reconciler/pkg/konnect"
Expand Down Expand Up @@ -177,19 +178,62 @@ func kongServiceIDs(cpID string,
func excludeKonnectManagedPlugins(plugins []*kong.Plugin) []*kong.Plugin {
filtered := []*kong.Plugin{}
for _, p := range plugins {
if isManagedByKonnect(p) {
if isPluginManagedByKonnect(p) {
continue
}
filtered = append(filtered, p)
}
return filtered
}

func isManagedByKonnect(plugin *kong.Plugin) bool {
func isPluginManagedByKonnect(plugin *kong.Plugin) bool {
for _, t := range plugin.Tags {
if *t == konnect.KonnectManagedPluginTag {
if *t == konnect.KonnectManagedPluginTag || *t == konnect.KonnectManagedTag {
return true
}
}
return false
}

func excludeKonnectManagedEntities[T any](kongEntities []T) ([]T, error) {
if len(kongEntities) == 0 {
return []T{}, nil
}

filteredEntities := make([]T, 0)
for _, e := range kongEntities {
isManagedByKonnect, err := isManagedByKonnect(e)
if err != nil {
return nil, err
}

if isManagedByKonnect {
continue
}
filteredEntities = append(filteredEntities, e)
}
return filteredEntities, nil
}

func isManagedByKonnect(entity interface{}) (bool, error) {
ptr := reflect.ValueOf(entity)
if ptr.Kind() != reflect.Ptr {
return false, fmt.Errorf("entity is not a pointer")
}

v := reflect.Indirect(ptr)
structTags := v.FieldByName("Tags")
var zero reflect.Value
if structTags == zero {
return false, nil
}

tags := structTags.Interface().([]*string)
for _, tag := range tags {
if *tag == konnect.KonnectManagedTag {
return true, nil
}
}

return false, nil
}
76 changes: 76 additions & 0 deletions pkg/dump/dump_konnect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -371,3 +371,79 @@ func Test_excludeKonnectManagedPlugins(t *testing.T) {
})
}
}

func Test_excludeKonnectManagedEntities(t *testing.T) {
tests := []struct {
name string
entities []any
want []any
}{
{
name: "exclude konnect managed",
entities: []any{
&kong.SNI{
Name: kong.String("foo"),
Tags: []*string{
kong.String("konnect-managed"),
},
},
&kong.SNI{
Name: kong.String("bar"),
Tags: []*string{
kong.String("bar-tag1"),
},
},
&kong.SNI{
Name: kong.String("baz"),
Tags: []*string{
kong.String("konnect-managed"),
},
},
},
want: []any{
&kong.SNI{
Name: kong.String("bar"),
Tags: []*string{
kong.String("bar-tag1"),
},
},
},
},
{
name: "empty input",
entities: []any{},
want: []any{},
},
{
name: "all konnect managed",
entities: []any{
&kong.SNI{
Name: kong.String("sni1"),
Tags: []*string{
kong.String("konnect-managed"),
},
},
&kong.SNI{
Name: kong.String("sni2"),
Tags: []*string{
kong.String("konnect-managed"),
},
},
},
want: []any{},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := excludeKonnectManagedEntities(tt.entities)
if err != nil {
t.Errorf("excludeKonnectManagedEntities() error = %v", err)
}

if !reflect.DeepEqual(got, tt.want) {
t.Errorf("excludeKonnectManagedPlugins() = %v, want %v", got, tt.want)
}
})
}
}
2 changes: 2 additions & 0 deletions pkg/konnect/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package konnect
const (
// KonnectManagedPluginTag is used by Konnect to tag internally-managed plugins
KonnectManagedPluginTag = "konnect-managed-plugin"
// KonnectManagedTag is used by Konnect to tag internally-managed entities
KonnectManagedTag = "konnect-managed"
)

func emptyString(p *string) bool {
Expand Down

0 comments on commit 56ae7c1

Please sign in to comment.