Skip to content

Commit

Permalink
Add new cm keys & doc
Browse files Browse the repository at this point in the history
Signed-off-by: Siddhesh Ghadi <[email protected]>
  • Loading branch information
svghadi committed May 29, 2024
1 parent d1b610d commit e440c2b
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 61 deletions.
15 changes: 9 additions & 6 deletions docs/operator-manual/argocd-cm.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -221,12 +221,15 @@ data:
# An optional comma-separated list of metadata.labels to observe in the UI.
resource.customLabels: tier

# An optional comma-separated list of metadata.labels keys to add onto k8s events generated for Applications.
# The keys are compared against Application and it's AppProject, if matched,
# the corresponding labels are added on the generated event.
# In case of conflict between labels on Application and AppProject,
# the Application label values are prioritized and added to the event.
resource.eventLabelKeys: team,env
# An optional comma-separated list of metadata.labels keys to add to Kubernetes events generated for Applications.
# The keys are compared against the Application and its AppProject. If matched,
# the corresponding labels are added to the generated event.
# In case of a conflict between labels on the Application and AppProject,
# the Application label values are prioritized and added to the event. Supports wildcards.
resource.includeEventLabelKeys: team,env*
# An optional comma-separated list of metadata.labels keys to exclude from Kubernetes events generated for Applications. Supports wildcards.
resource.excludeEventLabelKeys: environment,bu


resource.compareoptions: |
# if ignoreAggregatedRoles set to true then differences caused by aggregated roles in RBAC resources are ignored.
Expand Down
16 changes: 16 additions & 0 deletions docs/operator-manual/declarative-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -1132,6 +1132,22 @@ data:

Custom Labels configured with `resource.customLabels` (comma separated string) will be displayed in the UI (for any resource that defines them).

## Labels on Application Events

An optional comma-separated list of `metadata.labels` keys can be configured with `resource.includeEventLabelKeys` to add to Kubernetes events generated for Argo CD Applications. When events are generated for Applications containing the specified labels, the controller adds the matching labels to the event. This establishes an easy link between the event and the application, allowing for filtering using labels. In case of conflict between labels on the Application and AppProject, the Application label values are prioritized and added to the event.

```yaml
resource.includeEventLabelKeys: team,env*
```

To exclude certain labels from events, use the `resource.excludeEventLabelKeys` key, which takes a comma-separated list of `metadata.labels` keys.

```yaml
resource.excludeEventLabelKeys: environment,bu
```

Both `resource.includeEventLabelKeys` and `resource.excludeEventLabelKeys` support wildcards.

## SSO & RBAC

* SSO configuration details: [SSO](./user-management/index.md)
Expand Down
13 changes: 7 additions & 6 deletions test/e2e/app_k8s_events_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,17 @@ import (
. "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app"
)

// resource.eventLabelKeys keys set in argocd-cm
// resource.includeEventLabelKeys keys set in argocd-cm
func TestLabelsOnAppK8sEvents(t *testing.T) {
expectedLabels := map[string]string{"app": "test", "env": "dev"}
expectedLabels := map[string]string{"app": "test", "environment": "dev"}

Given(t).
Timeout(60).
Path("two-nice-pods").
When().
SetParamInSettingConfigMap("resource.eventLabelKeys", "app,env").
CreateApp("--label=app=test", "--label=env=dev", "--label=tier=ui").
SetParamInSettingConfigMap("resource.includeEventLabelKeys", "app,team,env*").
SetParamInSettingConfigMap("resource.excludeEventLabelKeys", "team").
CreateApp("--label=app=test", "--label=environment=dev", "--label=team=A", "--label=tier=ui").
Sync().
Then().
Expect(SyncStatusIs(SyncStatusCodeSynced)).
Expand All @@ -41,13 +42,13 @@ func TestLabelsOnAppK8sEvents(t *testing.T) {
})
}

// resource.eventLabelKeys keys not set in argocd-cm
// resource.includeEventLabelKeys keys not set in argocd-cm
func TestNoLabelsOnAppK8sEvents(t *testing.T) {
Given(t).
Timeout(60).
Path("two-nice-pods").
When().
CreateApp("--label=app=test", "--label=env=dev", "--label=tier=ui").
CreateApp("--label=app=test", "--label=environment=dev", "--label=team=A", "--label=tier=ui").
Sync().
Then().
Expect(SyncStatusIs(SyncStatusCodeSynced)).
Expand Down
27 changes: 20 additions & 7 deletions util/argo/argo.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
applicationsv1 "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1"
"github.com/argoproj/argo-cd/v2/reposerver/apiclient"
"github.com/argoproj/argo-cd/v2/util/db"
"github.com/argoproj/argo-cd/v2/util/glob"
"github.com/argoproj/argo-cd/v2/util/io"
"github.com/argoproj/argo-cd/v2/util/settings"
)
Expand Down Expand Up @@ -1111,13 +1112,15 @@ func IsValidContainerName(name string) bool {
return len(validationErrors) == 0
}

// GetAppEventLabels returns a map of labels to add to k8s event.
// The Application and it's AppProject labels are compared against `resource.eventLabelKeys` key in argocd-cm,
// if matched, the corresponding labels are returned to add on the generated event. In case of conflict
// between labels on Application and AppProject, the Application label values are prioritized and added to the event.
// GetAppEventLabels returns a map of labels to add to a K8s event.
// The Application and its AppProject labels are compared against the `resource.includeEventLabelKeys` key in argocd-cm.
// If matched, the corresponding labels are returned to be added to the generated event. In case of a conflict
// between labels on the Application and AppProject, the Application label values are prioritized and added to the event.
// Furthermore, labels specified in `resource.excludeEventLabelKeys` in argocd-cm are removed from the event labels, if they were included.
func GetAppEventLabels(app *argoappv1.Application, projLister applicationsv1.AppProjectLister, ns string, settingsManager *settings.SettingsManager, db db.ArgoDB, ctx context.Context) map[string]string {
eventLabels := make(map[string]string)

// Get all app & app-project labels
labels := app.Labels
if labels == nil {
labels = make(map[string]string)
Expand All @@ -1134,13 +1137,23 @@ func GetAppEventLabels(app *argoappv1.Application, projLister applicationsv1.App
log.Warn(err)
}

keys := settingsManager.GetEventLabelKeys()
for _, k := range keys {
v, found := labels[k]
// Filter out event labels to include
inKeys := settingsManager.GetIncludeEventLabelKeys()
for k, v := range labels {
found := glob.MatchStringInList(inKeys, k, false)
if found {
eventLabels[k] = v
}
}

// Remove excluded event labels
exKeys := settingsManager.GetExcludeEventLabelKeys()
for k := range eventLabels {
found := glob.MatchStringInList(exKeys, k, false)
if found {
delete(eventLabels, k)
}
}

return eventLabels
}
61 changes: 32 additions & 29 deletions util/argo/argo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1569,59 +1569,61 @@ func TestAugmentSyncMsg(t *testing.T) {
func TestGetAppEventLabels(t *testing.T) {
tests := []struct {
name string
cmEventLabelKeys string
cmInEventLabelKeys string
cmExEventLabelKeys string
appLabels map[string]string
projLabels map[string]string
expectedEventLabels map[string]string
}{
{
name: "no label keys in cm",
cmEventLabelKeys: "",
appLabels: nil,
projLabels: nil,
expectedEventLabels: nil,
},
{
name: "no label keys in cm",
cmEventLabelKeys: "",
name: "no label keys in cm - no event labels",
cmInEventLabelKeys: "",
appLabels: map[string]string{"team": "A", "tier": "frontend"},
projLabels: map[string]string{"env": "dev"},
projLabels: map[string]string{"environment": "dev"},
expectedEventLabels: nil,
},
{
name: "label keys in cm, no labels on app & proj",
cmEventLabelKeys: "team,env",
name: "label keys in cm, no labels on app & proj - no event labels",
cmInEventLabelKeys: "team, environment",
appLabels: nil,
projLabels: nil,
expectedEventLabels: nil,
},
{
name: "label keys in cm, labels on app, no labels on proj",
cmEventLabelKeys: "team,env",
name: "labels on app, no labels on proj - event labels matched on app only",
cmInEventLabelKeys: "team, environment",
appLabels: map[string]string{"team": "A", "tier": "frontend"},
projLabels: nil,
expectedEventLabels: map[string]string{"team": "A"},
},
{
name: "label keys in cm, no labels on app, labels on proj",
cmEventLabelKeys: "team,env",
name: "no labels on app, labels on proj - event labels matched on proj only",
cmInEventLabelKeys: "team, environment",
appLabels: nil,
projLabels: map[string]string{"env": "dev"},
expectedEventLabels: map[string]string{"env": "dev"},
projLabels: map[string]string{"environment": "dev"},
expectedEventLabels: map[string]string{"environment": "dev"},
},
{
name: "labels on app & proj with conflicts - event labels matched on both app & proj and app labels prioritized on conflict",
cmInEventLabelKeys: "team, environment",
appLabels: map[string]string{"team": "A", "environment": "stage", "tier": "frontend"},
projLabels: map[string]string{"environment": "dev"},
expectedEventLabels: map[string]string{"team": "A", "environment": "stage"},
},
{
name: "label keys in cm, labels on app & proj",
cmEventLabelKeys: "team,env",
name: "wildcard support - matched all labels",
cmInEventLabelKeys: "*",
appLabels: map[string]string{"team": "A", "tier": "frontend"},
projLabels: map[string]string{"env": "dev"},
expectedEventLabels: map[string]string{"team": "A", "env": "dev"},
projLabels: map[string]string{"environment": "dev"},
expectedEventLabels: map[string]string{"team": "A", "tier": "frontend", "environment": "dev"},
},
{
name: "app & proj label conflicts",
cmEventLabelKeys: "example.com/team,env",
name: "exlcude event labels",

Check failure on line 1621 in util/argo/argo_test.go

View workflow job for this annotation

GitHub Actions / Lint Go code

`exlcude` is a misspelling of `exclude` (misspell)
cmInEventLabelKeys: "example.com/team,tier,env*",
cmExEventLabelKeys: "tie*",
appLabels: map[string]string{"example.com/team": "A", "tier": "frontend"},
projLabels: map[string]string{"example.com/team": "B", "env": "dev"},
expectedEventLabels: map[string]string{"example.com/team": "A", "env": "dev"},
projLabels: map[string]string{"environment": "dev"},
expectedEventLabels: map[string]string{"example.com/team": "A", "environment": "dev"},
},
}
for _, tt := range tests {
Expand All @@ -1635,7 +1637,8 @@ func TestGetAppEventLabels(t *testing.T) {
},
},
Data: map[string]string{
"resource.eventLabelKeys": tt.cmEventLabelKeys,
"resource.includeEventLabelKeys": tt.cmInEventLabelKeys,
"resource.excludeEventLabelKeys": tt.cmExEventLabelKeys,
},
}

Expand Down Expand Up @@ -1664,7 +1667,7 @@ func TestGetAppEventLabels(t *testing.T) {
argoDB := db.NewDB("default", settingsMgr, kubeClient)

eventLabels := GetAppEventLabels(&app, applisters.NewAppProjectLister(informer.GetIndexer()), test.FakeArgoCDNamespace, settingsMgr, argoDB, ctx)
assert.Equal(t, len(eventLabels), len(tt.expectedEventLabels))
assert.Equal(t, len(tt.expectedEventLabels), len(eventLabels))
for ek, ev := range tt.expectedEventLabels {
v, found := eventLabels[ek]
assert.True(t, found)
Expand Down
26 changes: 22 additions & 4 deletions util/settings/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -447,8 +447,10 @@ const (
resourceIgnoreResourceUpdatesEnabledKey = "resource.ignoreResourceUpdatesEnabled"
// resourceCustomLabelKey is the key to a custom label to show in node info, if present
resourceCustomLabelsKey = "resource.customLabels"
// resourceEventLabelKeys is the key to labels to be added onto Application k8s events if present on an Application or it's AppProject
resourceEventLabelKeys = "resource.eventLabelKeys"
// resourceIncludeEventLabelKeys is the key to labels to be added onto Application k8s events if present on an Application or it's AppProject. Supports wildcard.
resourceIncludeEventLabelKeys = "resource.includeEventLabelKeys"
// resourceExcludeEventLabelKeys is the key to labels to be excluded from adding onto Application's k8s events. Supports wildcard.
resourceExcludeEventLabelKeys = "resource.excludeEventLabelKeys"
// kustomizeBuildOptionsKey is a string of kustomize build parameters
kustomizeBuildOptionsKey = "kustomize.buildOptions"
// kustomizeVersionKeyPrefix is a kustomize version key prefix
Expand Down Expand Up @@ -2226,14 +2228,30 @@ func (mgr *SettingsManager) GetResourceCustomLabels() ([]string, error) {
return []string{}, nil
}

func (mgr *SettingsManager) GetEventLabelKeys() []string {
func (mgr *SettingsManager) GetIncludeEventLabelKeys() []string {
labelKeys := []string{}
argoCDCM, err := mgr.getConfigMap()
if err != nil {
log.Error(fmt.Errorf("failed getting configmap: %v", err))
return labelKeys
}
if value, ok := argoCDCM.Data[resourceEventLabelKeys]; ok {
if value, ok := argoCDCM.Data[resourceIncludeEventLabelKeys]; ok {
if value != "" {
value = strings.ReplaceAll(value, " ", "")
labelKeys = strings.Split(value, ",")
}
}
return labelKeys
}

func (mgr *SettingsManager) GetExcludeEventLabelKeys() []string {
labelKeys := []string{}
argoCDCM, err := mgr.getConfigMap()
if err != nil {
log.Error(fmt.Errorf("failed getting configmap: %v", err))
return labelKeys
}
if value, ok := argoCDCM.Data[resourceExcludeEventLabelKeys]; ok {
if value != "" {
value = strings.ReplaceAll(value, " ", "")
labelKeys = strings.Split(value, ",")
Expand Down
26 changes: 17 additions & 9 deletions util/settings/settings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -719,25 +719,33 @@ func TestSettingsManager_GetEventLabelKeys(t *testing.T) {
}{
{
name: "Comma separated data",
data: "app,env, tier, example.com/team",
expectedKeys: []string{"app", "env", "tier", "example.com/team"},
data: "app,env, tier, example.com/team-*, *",
expectedKeys: []string{"app", "env", "tier", "example.com/team-*", "*"},
},
{
name: "Empty data",
data: "",
expectedKeys: []string{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, settingsManager := fixtures(map[string]string{
resourceEventLabelKeys: tt.data,
})
keys := settingsManager.GetEventLabelKeys()
assert.Equal(t, len(tt.expectedKeys), len(keys))
_, settingsManager := fixtures(map[string]string{})
if tt.data != "" {
_, settingsManager = fixtures(map[string]string{
resourceIncludeEventLabelKeys: tt.data,
resourceExcludeEventLabelKeys: tt.data,
})
}

inKeys := settingsManager.GetIncludeEventLabelKeys()
assert.Equal(t, len(tt.expectedKeys), len(inKeys))

exKeys := settingsManager.GetExcludeEventLabelKeys()
assert.Equal(t, len(tt.expectedKeys), len(exKeys))

for i := range tt.expectedKeys {
assert.Equal(t, tt.expectedKeys[i], keys[i])
assert.Equal(t, tt.expectedKeys[i], inKeys[i])
assert.Equal(t, tt.expectedKeys[i], exKeys[i])
}
})
}
Expand Down

0 comments on commit e440c2b

Please sign in to comment.