Skip to content

Commit d3dfa64

Browse files
committed
feat: add selector-based ignoreResourceUpdates for orphaned resources
Adds support for configuring ignoreResourceUpdates behavior for orphaned resources via name patterns in argocd-cm, removing the need for external tools like Kyverno to inject annotations. Operators can now configure in argocd-cm: resource.orphaned.ignore.namePatterns: | namePatterns: - "*-cluster-config-map" - "*-config-map" Fixes #28099 Signed-off-by: Mahesh Pansare <maheshpansare099+github@gmail.com>
1 parent 266b604 commit d3dfa64

3 files changed

Lines changed: 74 additions & 1 deletion

File tree

controller/appcontroller.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"runtime/debug"
1414
"sort"
1515
"strconv"
16+
"path/filepath"
1617
"strings"
1718
"sync"
1819
"time"
@@ -637,6 +638,9 @@ func (ctrl *ApplicationController) getResourceTree(destCluster *appv1.Cluster, a
637638
orphanedNodesKeys := make([]kube.ResourceKey, 0)
638639
for k := range orphanedNodesMap {
639640
if k.Namespace != "" && proj.IsGroupKindNamePermitted(k.GroupKind(), k.Name, true) && !isKnownOrphanedResourceExclusion(k, proj) {
641+
if ctrl.isOrphanedResourceIgnored(k) {
642+
continue
643+
}
640644
orphanedNodesKeys = append(orphanedNodesKeys, k)
641645
}
642646
}
@@ -2751,3 +2755,19 @@ func (ctrl *ApplicationController) applyImpersonationConfig(config *rest.Config,
27512755
}
27522756

27532757
type ClusterFilterFunction func(c *appv1.Cluster, distributionFunction sharding.DistributionFunction) bool
2758+
2759+
// isOrphanedResourceIgnored returns true if the given resource key matches
2760+
// any name pattern defined in resource.orphaned.ignore.namePatterns in argocd-cm
2761+
func (ctrl *ApplicationController) isOrphanedResourceIgnored(key kube.ResourceKey) bool {
2762+
config, err := ctrl.settingsMgr.GetOrphanedIgnoreConfig()
2763+
if err != nil || config == nil {
2764+
return false
2765+
}
2766+
for _, pattern := range config.NamePatterns {
2767+
matched, err := filepath.Match(pattern, key.Name)
2768+
if err == nil && matched {
2769+
return true
2770+
}
2771+
}
2772+
return false
2773+
}

util/settings/settings.go

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,10 @@ const (
476476
resourceInclusionsKey = "resource.inclusions"
477477
// resourceIgnoreResourceUpdatesEnabledKey is the key to a boolean determining whether the resourceIgnoreUpdates feature is enabled
478478
resourceIgnoreResourceUpdatesEnabledKey = "resource.ignoreResourceUpdatesEnabled"
479+
// resourceOrphanedIgnorePatternsKey is the key to a list of name patterns for orphaned resources to ignore
480+
resourceOrphanedIgnorePatternsKey = "resource.orphaned.ignore.namePatterns"
479481
// resourceSensitiveAnnotationsKey is the key to list of annotations to mask in secret resource
482+
// resourceSensitiveAnnotationsKey is the key to list of annotations to mask
480483
resourceSensitiveAnnotationsKey = "resource.sensitive.mask.annotations"
481484
// resourceCustomLabelKey is the key to a custom label to show in node info, if present
482485
resourceCustomLabelsKey = "resource.customLabels"
@@ -2639,7 +2642,6 @@ func (m myFeatureGates) Enabled(f clientgofeatures.Feature) bool {
26392642
return m.parent.Enabled(f)
26402643
}
26412644

2642-
// FIXME: remove when we have proper WatchListClient and InOrderInformers support
26432645
func ConfigureGoClientFeatures() {
26442646
gates := clientgofeatures.FeatureGates()
26452647
isWatchListEnabled := gates.Enabled(clientgofeatures.WatchListClient)
@@ -2650,3 +2652,28 @@ func ConfigureGoClientFeatures() {
26502652
clientgofeatures.ReplaceFeatureGates(wrapper)
26512653
}
26522654
}
2655+
// OrphanedResourceIgnoreConfig holds name patterns for orphaned resources
2656+
// that should be ignored during reconciliation
2657+
2658+
type OrphanedResourceIgnoreConfig struct {
2659+
NamePatterns []string `json:"namePatterns,omitempty"`
2660+
}
2661+
2662+
// GetOrphanedIgnoreConfig returns the config for ignoring orphaned
2663+
// resources by name pattern, read from argocd-cm
2664+
func (mgr *SettingsManager) GetOrphanedIgnoreConfig() (*OrphanedResourceIgnoreConfig, error) {
2665+
argoCDCM, err := mgr.getConfigMap()
2666+
if err != nil {
2667+
return nil, err
2668+
}
2669+
val, ok := argoCDCM.Data[resourceOrphanedIgnorePatternsKey]
2670+
if !ok || val == "" {
2671+
return &OrphanedResourceIgnoreConfig{}, nil
2672+
}
2673+
config := &OrphanedResourceIgnoreConfig{}
2674+
err = yaml.Unmarshal([]byte(val), config)
2675+
if err != nil {
2676+
return nil, fmt.Errorf("failed to parse %s: %w", resourceOrphanedIgnorePatternsKey, err)
2677+
}
2678+
return config, nil
2679+
}

util/settings/settings_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2789,3 +2789,29 @@ func TestEscapeDollarSignsInMap(t *testing.T) {
27892789
assert.Equal(t, original, input["bindPW"])
27902790
})
27912791
}
2792+
2793+
2794+
func TestGetOrphanedIgnoreConfig_NoConfig(t *testing.T) {
2795+
_, settingsManager := fixtures(t.Context(), nil)
2796+
config, err := settingsManager.GetOrphanedIgnoreConfig()
2797+
require.NoError(t, err)
2798+
assert.Empty(t, config.NamePatterns)
2799+
}
2800+
2801+
func TestGetOrphanedIgnoreConfig_WithPatterns(t *testing.T) {
2802+
_, settingsManager := fixtures(t.Context(), map[string]string{
2803+
"resource.orphaned.ignore.namePatterns": "namePatterns:\n - \"*-cluster-config-map\"\n - \"*-config-map\"\n",
2804+
})
2805+
config, err := settingsManager.GetOrphanedIgnoreConfig()
2806+
require.NoError(t, err)
2807+
assert.Equal(t, []string{"*-cluster-config-map", "*-config-map"}, config.NamePatterns)
2808+
}
2809+
2810+
func TestGetOrphanedIgnoreConfig_NoMatch(t *testing.T) {
2811+
_, settingsManager := fixtures(t.Context(), map[string]string{
2812+
"resource.orphaned.ignore.namePatterns": "namePatterns:\n - \"*-cluster-config-map\"\n",
2813+
})
2814+
config, err := settingsManager.GetOrphanedIgnoreConfig()
2815+
require.NoError(t, err)
2816+
assert.NotContains(t, config.NamePatterns, "some-other-resource")
2817+
}

0 commit comments

Comments
 (0)