From 5be5d7ef16f40d25461cb31d3eb52b0b21b20a26 Mon Sep 17 00:00:00 2001 From: Antoine Jacquemin Date: Thu, 30 Nov 2023 23:08:08 +0100 Subject: [PATCH] add lookup tag --- pkg/dump/dump.go | 23 +++++++++++++++++++++++ pkg/file/builder.go | 26 ++++++++++++++++++++++---- pkg/file/kong_json_schema.json | 16 ++++++++++++++++ pkg/file/reader.go | 4 ++++ pkg/file/types.go | 12 ++++++++++-- pkg/file/zz_generated.deepcopy.go | 26 ++++++++++++++++++++++++++ 6 files changed, 101 insertions(+), 6 deletions(-) diff --git a/pkg/dump/dump.go b/pkg/dump/dump.go index 1a22528..826c5ac 100644 --- a/pkg/dump/dump.go +++ b/pkg/dump/dump.go @@ -28,6 +28,10 @@ type Config struct { // tags. SelectorTags []string + // LookUpSelectorTagsConsumers can be used to lookup entities using other + // tags. + LookUpSelectorTagsConsumers []string + // KonnectControlPlane KonnectControlPlane string @@ -93,6 +97,25 @@ func getConsumerConfiguration(ctx context.Context, group *errgroup.Group, if err != nil { return fmt.Errorf("consumers: %w", err) } + if config.LookUpSelectorTagsConsumers != nil { + globalConsumers, err := GetAllConsumers(ctx, client, config.LookUpSelectorTagsConsumers) + if err != nil { + return fmt.Errorf("error retrieving global consumers: %w", err) + } + // if globalConsumers are not present, add them. + for _, globalConsumer := range globalConsumers { + found := false + for _, consumer := range consumers { + if *globalConsumer.ID == *consumer.ID { + found = true + break + } + } + if !found { + consumers = append(consumers, globalConsumer) + } + } + } state.Consumers = consumers return nil }) diff --git a/pkg/file/builder.go b/pkg/file/builder.go index df9a26d..92d16e4 100644 --- a/pkg/file/builder.go +++ b/pkg/file/builder.go @@ -4,6 +4,8 @@ import ( "context" "errors" "fmt" + "reflect" + "sort" "github.com/blang/semver/v4" "github.com/kong/go-database-reconciler/pkg/konnect" @@ -22,9 +24,10 @@ type stateBuilder struct { defaulter *utils.Defaulter kongVersion semver.Version - selectTags []string - skipCACerts bool - intermediate *state.KongState + selectTags []string + lookupTagsConsumers []string + skipCACerts bool + intermediate *state.KongState client *kong.Client ctx context.Context @@ -321,7 +324,22 @@ func (b *stateBuilder) consumers() { c.ID = kong.String(*consumer.ID) } } - utils.MustMergeTags(&c.Consumer, b.selectTags) + + stringTags := make([]string, len(c.Tags)) + for i, tag := range c.Tags { + if tag != nil { + stringTags[i] = *tag + } + } + sort.Strings(stringTags) + sort.Strings(b.lookupTagsConsumers) + // if the consumer tags and the lookup tags are the same, it means + // that the consumer is a global consumer retrieved from upstream, + // therefore we don't want to merge its tags with the selected tags. + if !reflect.DeepEqual(stringTags, b.lookupTagsConsumers) { + utils.MustMergeTags(&c.Consumer, b.selectTags) + } + if consumer != nil { c.Consumer.CreatedAt = consumer.CreatedAt } diff --git a/pkg/file/kong_json_schema.json b/pkg/file/kong_json_schema.json index 5f9d7b8..64c4687 100644 --- a/pkg/file/kong_json_schema.json +++ b/pkg/file/kong_json_schema.json @@ -1217,6 +1217,10 @@ "$schema": "http://json-schema.org/draft-04/schema#", "$ref": "#/definitions/KongDefaults" }, + "default_lookup_tags": { + "$schema": "http://json-schema.org/draft-04/schema#", + "$ref": "#/definitions/LookUpSelectorTags" + }, "select_tags": { "items": { "type": "string" @@ -1338,6 +1342,18 @@ "additionalProperties": false, "type": "object" }, + "LookUpSelectorTags": { + "properties": { + "consumers": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "additionalProperties": false, + "type": "object" + }, "MTLSAuth": { "required": [ "id", diff --git a/pkg/file/reader.go b/pkg/file/reader.go index 7f9a917..c7ac57d 100644 --- a/pkg/file/reader.go +++ b/pkg/file/reader.go @@ -84,6 +84,10 @@ func Get(ctx context.Context, fileContent *Content, opt RenderConfig, dumpConfig builder.selectTags = dumpConfig.SelectorTags } + if len(dumpConfig.LookUpSelectorTagsConsumers) > 0 { + builder.lookupTagsConsumers = dumpConfig.LookUpSelectorTagsConsumers + } + if fileContent.Transform != nil && !*fileContent.Transform { return nil, ErrorTransformFalseNotSupported } diff --git a/pkg/file/types.go b/pkg/file/types.go index 2974fd7..8b8bfc2 100644 --- a/pkg/file/types.go +++ b/pkg/file/types.go @@ -597,8 +597,16 @@ type KongDefaults struct { // Info contains meta-data of the file. // +k8s:deepcopy-gen=true type Info struct { - SelectorTags []string `json:"select_tags,omitempty" yaml:"select_tags,omitempty"` - Defaults KongDefaults `json:"defaults,omitempty" yaml:"defaults,omitempty"` + SelectorTags []string `json:"select_tags,omitempty" yaml:"select_tags,omitempty"` + LookUpSelectorTags *LookUpSelectorTags `json:"default_lookup_tags,omitempty" yaml:"default_lookup_tags,omitempty"` + Defaults KongDefaults `json:"defaults,omitempty" yaml:"defaults,omitempty"` +} + +// LookUpSelectorTags contains tags to lookup +// for corresponding entities already in Kong. +// +k8s:deepcopy-gen=true +type LookUpSelectorTags struct { + Consumers []string `json:"consumers,omitempty" yaml:"consumers,omitempty"` } // Konnect contains configuration specific to Konnect. diff --git a/pkg/file/zz_generated.deepcopy.go b/pkg/file/zz_generated.deepcopy.go index 7185893..00a9086 100644 --- a/pkg/file/zz_generated.deepcopy.go +++ b/pkg/file/zz_generated.deepcopy.go @@ -735,6 +735,11 @@ func (in *Info) DeepCopyInto(out *Info) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.LookUpSelectorTags != nil { + in, out := &in.LookUpSelectorTags, &out.LookUpSelectorTags + *out = new(LookUpSelectorTags) + (*in).DeepCopyInto(*out) + } in.Defaults.DeepCopyInto(&out.Defaults) return } @@ -821,3 +826,24 @@ func (in *Konnect) DeepCopy() *Konnect { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LookUpSelectorTags) DeepCopyInto(out *LookUpSelectorTags) { + *out = *in + if in.Consumers != nil { + in, out := &in.Consumers, &out.Consumers + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LookUpSelectorTags. +func (in *LookUpSelectorTags) DeepCopy() *LookUpSelectorTags { + if in == nil { + return nil + } + out := new(LookUpSelectorTags) + in.DeepCopyInto(out) + return out +}