Skip to content

Commit 28cf170

Browse files
Tag filter support
1 parent c60697e commit 28cf170

15 files changed

+552
-118
lines changed

api/v1/azureappconfigurationprovider_types.go

Lines changed: 72 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,10 @@ 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+
TagFilters []string `json:"tagFilters,omitempty"`
93+
SnapshotName *string `json:"snapshotName,omitempty"`
8994
}
9095

9196
// Defines the settings for dynamic configuration.
@@ -243,6 +248,70 @@ type AzureAppConfigurationProviderList struct {
243248
Items []AzureAppConfigurationProvider `json:"items"`
244249
}
245250

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

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: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ spec:
121121
type: string
122122
snapshotName:
123123
type: string
124+
tagFilters:
125+
items:
126+
type: string
127+
type: array
124128
type: object
125129
type: array
126130
trimKeyPrefixes:
@@ -163,6 +167,10 @@ spec:
163167
type: string
164168
snapshotName:
165169
type: string
170+
tagFilters:
171+
items:
172+
type: string
173+
type: array
166174
type: object
167175
type: array
168176
type: object

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ require (
1515
)
1616

1717
require (
18+
github.com/Azure/azure-sdk-for-go/sdk/data/azappconfig/v2 v2.0.0 // indirect
1819
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 // indirect
1920
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0 // indirect
2021
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 // indirect
@@ -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 & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+
66
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8=
77
github.com/Azure/azure-sdk-for-go/sdk/data/azappconfig v1.2.0 h1:uU4FujKFQAz31AbWOO3INV9qfIanHeIUSsGhRlcJJmg=
88
github.com/Azure/azure-sdk-for-go/sdk/data/azappconfig v1.2.0/go.mod h1:qr3M3Oy6V98VR0c5tCHKUpaeJTRQh6KYzJewRtFWqfc=
9+
github.com/Azure/azure-sdk-for-go/sdk/data/azappconfig/v2 v2.0.0 h1:K7LqZL3VW+DElZhW+5tY/cp2RRFrB3W45WUG/9fhhls=
10+
github.com/Azure/azure-sdk-for-go/sdk/data/azappconfig/v2 v2.0.0/go.mod h1:4IPby+BYf0rPMnMur/mNtowysFd4NoEW5U1vhrkhARA=
911
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 h1:9iefClla7iYpfYWdzPCRDozdmndjTm8DXdpCzPajMgA=
1012
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2/go.mod h1:XtLgD3ZD34DAaVIIAyG3objl5DynM3CQ/vMcbBNJZGI=
1113
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)