-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(notifications): Allow notifications controller to notify on all namespaces (cherry-pick 2.8) #15855
fix(notifications): Allow notifications controller to notify on all namespaces (cherry-pick 2.8) #15855
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
apiVersion: rbac.authorization.k8s.io/v1 | ||
kind: ClusterRole | ||
metadata: | ||
labels: | ||
app.kubernetes.io/name: argocd-notifications-controller-cluster-apps | ||
app.kubernetes.io/part-of: argocd | ||
app.kubernetes.io/component: notifications-controller | ||
name: argocd-notifications-controller-cluster-apps | ||
rules: | ||
- apiGroups: | ||
- "argoproj.io" | ||
resources: | ||
- "applications" | ||
verbs: | ||
- get | ||
- list | ||
- watch | ||
- update | ||
- patch |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
apiVersion: rbac.authorization.k8s.io/v1 | ||
kind: ClusterRoleBinding | ||
metadata: | ||
labels: | ||
app.kubernetes.io/name: argocd-notifications-controller-cluster-apps | ||
app.kubernetes.io/part-of: argocd | ||
app.kubernetes.io/component: notifications-controller | ||
name: argocd-notifications-controller-cluster-apps | ||
roleRef: | ||
apiGroup: rbac.authorization.k8s.io | ||
kind: ClusterRole | ||
name: argocd-notifications-controller-cluster-apps | ||
subjects: | ||
- kind: ServiceAccount | ||
name: argocd-notifications-controller | ||
namespace: argocd | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1080,7 +1080,13 @@ spec: | |
args: | ||
- /readonly/haproxy_init.sh | ||
securityContext: | ||
null | ||
allowPrivilegeEscalation: false | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not sure where these are from |
||
capabilities: | ||
drop: | ||
- ALL | ||
runAsNonRoot: true | ||
seccompProfile: | ||
type: RuntimeDefault | ||
volumeMounts: | ||
- name: config-volume | ||
mountPath: /readonly | ||
|
@@ -1092,7 +1098,13 @@ spec: | |
image: haproxy:2.6.14-alpine | ||
imagePullPolicy: IfNotPresent | ||
securityContext: | ||
null | ||
allowPrivilegeEscalation: false | ||
capabilities: | ||
drop: | ||
- ALL | ||
runAsNonRoot: true | ||
seccompProfile: | ||
type: RuntimeDefault | ||
livenessProbe: | ||
httpGet: | ||
path: /healthz | ||
|
@@ -1188,7 +1200,14 @@ spec: | |
args: | ||
- /readonly-config/init.sh | ||
securityContext: | ||
null | ||
allowPrivilegeEscalation: false | ||
capabilities: | ||
drop: | ||
- ALL | ||
runAsNonRoot: true | ||
runAsUser: 1000 | ||
seccompProfile: | ||
type: RuntimeDefault | ||
env: | ||
- name: SENTINEL_ID_0 | ||
value: 3c0d9c0320bb34888c2df5757c718ce6ca992ce6 | ||
|
@@ -1213,7 +1232,14 @@ spec: | |
args: | ||
- /data/conf/redis.conf | ||
securityContext: | ||
null | ||
allowPrivilegeEscalation: false | ||
capabilities: | ||
drop: | ||
- ALL | ||
runAsNonRoot: true | ||
runAsUser: 1000 | ||
seccompProfile: | ||
type: RuntimeDefault | ||
livenessProbe: | ||
initialDelaySeconds: 30 | ||
periodSeconds: 15 | ||
|
@@ -1263,7 +1289,14 @@ spec: | |
args: | ||
- /data/conf/sentinel.conf | ||
securityContext: | ||
null | ||
allowPrivilegeEscalation: false | ||
capabilities: | ||
drop: | ||
- ALL | ||
runAsNonRoot: true | ||
runAsUser: 1000 | ||
seccompProfile: | ||
type: RuntimeDefault | ||
livenessProbe: | ||
initialDelaySeconds: 30 | ||
periodSeconds: 15 | ||
|
@@ -1307,7 +1340,14 @@ spec: | |
args: | ||
- /readonly-config/fix-split-brain.sh | ||
securityContext: | ||
null | ||
allowPrivilegeEscalation: false | ||
capabilities: | ||
drop: | ||
- ALL | ||
runAsNonRoot: true | ||
runAsUser: 1000 | ||
seccompProfile: | ||
type: RuntimeDefault | ||
env: | ||
- name: SENTINEL_ID_0 | ||
value: 3c0d9c0320bb34888c2df5757c718ce6ca992ce6 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,8 @@ import ( | |
"fmt" | ||
"time" | ||
|
||
"github.com/argoproj/argo-cd/v2/util/glob" | ||
|
||
"github.com/argoproj/argo-cd/v2/util/notification/k8s" | ||
|
||
service "github.com/argoproj/argo-cd/v2/util/notification/argocd" | ||
|
@@ -53,14 +55,15 @@ func NewController( | |
client dynamic.Interface, | ||
argocdService service.Service, | ||
namespace string, | ||
applicationNamespaces []string, | ||
appLabelSelector string, | ||
registry *controller.MetricsRegistry, | ||
secretName string, | ||
configMapName string, | ||
) *notificationController { | ||
appClient := client.Resource(applications) | ||
appInformer := newInformer(appClient.Namespace(namespace), appLabelSelector) | ||
appProjInformer := newInformer(newAppProjClient(client, namespace), "") | ||
appInformer := newInformer(appClient, namespace, applicationNamespaces, appLabelSelector) | ||
appProjInformer := newInformer(newAppProjClient(client, namespace), namespace, []string{namespace}, "") | ||
secretInformer := k8s.NewSecretInformer(k8sClient, namespace, secretName) | ||
configMapInformer := k8s.NewConfigMapInformer(k8sClient, namespace, configMapName) | ||
apiFactory := api.NewFactory(settings.GetFactorySettings(argocdService, secretName, configMapName), namespace, secretInformer, configMapInformer) | ||
|
@@ -77,13 +80,21 @@ func NewController( | |
if !ok { | ||
return false, "" | ||
} | ||
if checkAppNotInAdditionalNamespaces(app, namespace, applicationNamespaces) { | ||
return true, "app is not in one of the application-namespaces, nor the notification controller namespace" | ||
} | ||
return !isAppSyncStatusRefreshed(app, log.WithField("app", obj.GetName())), "sync status out of date" | ||
}), | ||
controller.WithMetricsRegistry(registry), | ||
controller.WithAlterDestinations(res.alterDestinations)) | ||
return res | ||
} | ||
|
||
// Check if app is not in the namespace where the controller is in, and also app is not in one of the applicationNamespaces | ||
func checkAppNotInAdditionalNamespaces(app *unstructured.Unstructured, namespace string, applicationNamespaces []string) bool { | ||
return namespace != app.GetNamespace() && !glob.MatchStringInList(applicationNamespaces, app.GetNamespace(), false) | ||
} | ||
|
||
func (c *notificationController) alterDestinations(obj v1.Object, destinations services.Destinations, cfg api.Config) services.Destinations { | ||
app, ok := (obj).(*unstructured.Unstructured) | ||
if !ok { | ||
|
@@ -97,21 +108,38 @@ func (c *notificationController) alterDestinations(obj v1.Object, destinations s | |
return destinations | ||
} | ||
|
||
func newInformer(resClient dynamic.ResourceInterface, selector string) cache.SharedIndexInformer { | ||
func newInformer(resClient dynamic.ResourceInterface, controllerNamespace string, applicationNamespaces []string, selector string) cache.SharedIndexInformer { | ||
informer := cache.NewSharedIndexInformer( | ||
&cache.ListWatch{ | ||
ListFunc: func(options v1.ListOptions) (object runtime.Object, err error) { | ||
ListFunc: func(options v1.ListOptions) (runtime.Object, error) { | ||
// We are only interested in apps that exist in namespaces the | ||
// user wants to be enabled. | ||
options.LabelSelector = selector | ||
return resClient.List(context.Background(), options) | ||
appList, err := resClient.List(context.TODO(), options) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is context.TODO() expected? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's equivalent to Background. iirc no functional difference |
||
if err != nil { | ||
return nil, fmt.Errorf("failed to list applications: %w", err) | ||
} | ||
newItems := []unstructured.Unstructured{} | ||
for _, res := range appList.Items { | ||
if controllerNamespace == res.GetNamespace() || glob.MatchStringInList(applicationNamespaces, res.GetNamespace(), false) { | ||
newItems = append(newItems, res) | ||
} | ||
} | ||
appList.Items = newItems | ||
return appList, nil | ||
}, | ||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { | ||
options.LabelSelector = selector | ||
return resClient.Watch(context.Background(), options) | ||
return resClient.Watch(context.TODO(), options) | ||
}, | ||
}, | ||
&unstructured.Unstructured{}, | ||
resyncPeriod, | ||
cache.Indexers{}, | ||
cache.Indexers{ | ||
cache.NamespaceIndex: func(obj interface{}) ([]string, error) { | ||
return cache.MetaNamespaceIndexFunc(obj) | ||
}, | ||
}, | ||
) | ||
return informer | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing https://github.com/mayzhang2000/argo-cd/blob/4de11d5df50d68a94e47d5322dc55acfb5c481bc/examples/k8s-rbac/argocd-server-applications/kustomization.yaml#L6-L7