Skip to content

Commit 03ac44f

Browse files
Tag filter support (#130)
* Tag filter support * go mod tidy * update * update * update * update
1 parent b2e40d5 commit 03ac44f

15 files changed

+594
-123
lines changed

api/v1/azureappconfigurationprovider_types.go

Lines changed: 75 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ limitations under the License.
1919
package v1
2020

2121
import (
22+
"encoding/json"
23+
"sort"
24+
"strings"
25+
2226
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2327
)
2428

@@ -83,9 +87,13 @@ type AzureAppConfigurationFeatureFlagOptions struct {
8387

8488
// KeyLabelSelector defines the filters when fetching the data from Azure AppConfiguration
8589
type Selector struct {
86-
KeyFilter *string `json:"keyFilter,omitempty"`
87-
LabelFilter *string `json:"labelFilter,omitempty"`
88-
SnapshotName *string `json:"snapshotName,omitempty"`
90+
KeyFilter *string `json:"keyFilter,omitempty"`
91+
LabelFilter *string `json:"labelFilter,omitempty"`
92+
// +kubebuilder:validation:MaxItems=5
93+
// +kubebuilder:validation:items:MinLength=1
94+
// +kubebuilder:validation:items:Pattern=^[^=]+=[^=]*$
95+
TagFilters []string `json:"tagFilters,omitempty"`
96+
SnapshotName *string `json:"snapshotName,omitempty"`
8997
}
9098

9199
// Defines the settings for dynamic configuration.
@@ -243,6 +251,70 @@ type AzureAppConfigurationProviderList struct {
243251
Items []AzureAppConfigurationProvider `json:"items"`
244252
}
245253

254+
type ComparableSelector struct {
255+
KeyFilter *string
256+
LabelFilter *string
257+
TagFilters *string
258+
SnapshotName *string
259+
}
260+
261+
func MakeComparable(selector Selector) ComparableSelector {
262+
comparable := ComparableSelector{}
263+
264+
if selector.KeyFilter != nil {
265+
comparable.KeyFilter = selector.KeyFilter
266+
}
267+
if selector.LabelFilter != nil {
268+
comparable.LabelFilter = selector.LabelFilter
269+
}
270+
if selector.SnapshotName != nil {
271+
comparable.SnapshotName = selector.SnapshotName
272+
}
273+
if len(selector.TagFilters) > 0 {
274+
sortedTags := make([]string, len(selector.TagFilters))
275+
copy(sortedTags, selector.TagFilters)
276+
sort.Strings(sortedTags)
277+
// Use JSON encoding to safely handle tags
278+
tagFiltersBytes, err := json.Marshal(sortedTags)
279+
if err != nil {
280+
// Fallback to comma-separated string if JSON marshaling fails
281+
tagFiltersStr := strings.Join(sortedTags, ",")
282+
comparable.TagFilters = &tagFiltersStr
283+
} else {
284+
tagFiltersStr := string(tagFiltersBytes)
285+
comparable.TagFilters = &tagFiltersStr
286+
}
287+
}
288+
289+
return comparable
290+
}
291+
292+
func FromComparable(comparable ComparableSelector) Selector {
293+
selector := Selector{}
294+
295+
if comparable.KeyFilter != nil {
296+
selector.KeyFilter = comparable.KeyFilter
297+
}
298+
if comparable.LabelFilter != nil {
299+
selector.LabelFilter = comparable.LabelFilter
300+
}
301+
if comparable.SnapshotName != nil {
302+
selector.SnapshotName = comparable.SnapshotName
303+
}
304+
if comparable.TagFilters != nil && *comparable.TagFilters != "" {
305+
// Try JSON decoding first to safely deserialize tags
306+
var tagFilters []string
307+
err := json.Unmarshal([]byte(*comparable.TagFilters), &tagFilters)
308+
if err != nil {
309+
// Fallback to comma-separated parsing if JSON fails
310+
tagFilters = strings.Split(*comparable.TagFilters, ",")
311+
}
312+
selector.TagFilters = tagFilters
313+
}
314+
315+
return selector
316+
}
317+
246318
func init() {
247319
SchemeBuilder.Register(&AzureAppConfigurationProvider{}, &AzureAppConfigurationProviderList{})
248320
}

api/v1/zz_generated.deepcopy.go

Lines changed: 40 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/azconfig.io_azureappconfigurationproviders.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,13 @@ spec:
121121
type: string
122122
snapshotName:
123123
type: string
124+
tagFilters:
125+
items:
126+
minLength: 1
127+
pattern: ^[^=]+=[^=]*$
128+
type: string
129+
maxItems: 5
130+
type: array
124131
type: object
125132
type: array
126133
trimKeyPrefixes:
@@ -163,6 +170,13 @@ spec:
163170
type: string
164171
snapshotName:
165172
type: string
173+
tagFilters:
174+
items:
175+
minLength: 1
176+
pattern: ^[^=]+=[^=]*$
177+
type: string
178+
maxItems: 5
179+
type: array
166180
type: object
167181
type: array
168182
type: object

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ go 1.24.0
44

55
require (
66
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.2
7+
github.com/Azure/azure-sdk-for-go/sdk/data/azappconfig/v2 v2.0.0
78
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets v1.4.0
89
github.com/golang/mock v1.6.0
910
github.com/onsi/gomega v1.36.1
@@ -43,7 +44,6 @@ require (
4344

4445
require (
4546
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.11.0
46-
github.com/Azure/azure-sdk-for-go/sdk/data/azappconfig v1.2.0
4747
github.com/beorn7/perks v1.0.1 // indirect
4848
github.com/cespare/xxhash/v2 v2.3.0 // indirect
4949
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.11.0 h1:MhRfI58HblXzCtWEZCO0
44
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.11.0/go.mod h1:okZ+ZURbArNdlJ+ptXoyHNuOETzOl1Oww19rm8I2WLA=
55
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY=
66
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8=
7-
github.com/Azure/azure-sdk-for-go/sdk/data/azappconfig v1.2.0 h1:uU4FujKFQAz31AbWOO3INV9qfIanHeIUSsGhRlcJJmg=
8-
github.com/Azure/azure-sdk-for-go/sdk/data/azappconfig v1.2.0/go.mod h1:qr3M3Oy6V98VR0c5tCHKUpaeJTRQh6KYzJewRtFWqfc=
7+
github.com/Azure/azure-sdk-for-go/sdk/data/azappconfig/v2 v2.0.0 h1:K7LqZL3VW+DElZhW+5tY/cp2RRFrB3W45WUG/9fhhls=
8+
github.com/Azure/azure-sdk-for-go/sdk/data/azappconfig/v2 v2.0.0/go.mod h1:4IPby+BYf0rPMnMur/mNtowysFd4NoEW5U1vhrkhARA=
99
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 h1:9iefClla7iYpfYWdzPCRDozdmndjTm8DXdpCzPajMgA=
1010
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2/go.mod h1:XtLgD3ZD34DAaVIIAyG3objl5DynM3CQ/vMcbBNJZGI=
1111
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets v1.4.0 h1:/g8S6wk65vfC6m3FIxJ+i5QDyN9JWwXI8Hb0Img10hU=

internal/controller/appconfigurationprovider_controller.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ type ReconciliationState struct {
5454
ConfigMapResourceVersion *string
5555
Annotations map[string]string
5656
SentinelETags map[acpv1.Sentinel]*azcore.ETag
57-
KeyValueETags map[acpv1.Selector][]*azcore.ETag
58-
FeatureFlagETags map[acpv1.Selector][]*azcore.ETag
57+
KeyValueETags map[acpv1.ComparableSelector][]*azcore.ETag
58+
FeatureFlagETags map[acpv1.ComparableSelector][]*azcore.ETag
5959
ExistingK8sSecrets map[string]*loader.TargetK8sSecretMetadata
6060
NextKeyValueRefreshReconcileTime metav1.Time
6161
NextSecretReferenceRefreshReconcileTime metav1.Time
@@ -147,8 +147,8 @@ func (reconciler *AzureAppConfigurationProviderReconciler) Reconcile(ctx context
147147
ConfigMapResourceVersion: nil,
148148
Annotations: make(map[string]string),
149149
SentinelETags: make(map[acpv1.Sentinel]*azcore.ETag),
150-
KeyValueETags: make(map[acpv1.Selector][]*azcore.ETag),
151-
FeatureFlagETags: make(map[acpv1.Selector][]*azcore.ETag),
150+
KeyValueETags: make(map[acpv1.ComparableSelector][]*azcore.ETag),
151+
FeatureFlagETags: make(map[acpv1.ComparableSelector][]*azcore.ETag),
152152
ExistingK8sSecrets: make(map[string]*loader.TargetK8sSecretMetadata),
153153
ClientManager: nil,
154154
}

internal/controller/processor.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ type RefreshOptions struct {
4141
sentinelChanged bool
4242
keyValuePageETagsChanged bool
4343
updatedSentinelETags map[acpv1.Sentinel]*azcore.ETag
44-
updatedKeyValueETags map[acpv1.Selector][]*azcore.ETag
45-
updatedFeatureFlagETags map[acpv1.Selector][]*azcore.ETag
44+
updatedKeyValueETags map[acpv1.ComparableSelector][]*azcore.ETag
45+
updatedFeatureFlagETags map[acpv1.ComparableSelector][]*azcore.ETag
4646
}
4747

4848
func (processor *AppConfigurationProviderProcessor) PopulateSettings(existingConfigMap *corev1.ConfigMap, existingSecrets map[string]corev1.Secret) error {

0 commit comments

Comments
 (0)