forked from argoproj/argo-cd
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Migrate argocd notifications to argocd (argoproj#7744)
feat: Migrate argocd notifications to argocd (argoproj#7744) Signed-off-by: pashavictorovich <[email protected]>
- Loading branch information
1 parent
d346fce
commit 0f2f9a9
Showing
90 changed files
with
6,787 additions
and
148 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
package commands | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"net/http" | ||
"os" | ||
"strings" | ||
|
||
service "github.com/argoproj/argo-cd/v2/util/notification/argocd" | ||
|
||
notificationscontroller "github.com/argoproj/argo-cd/v2/notification_controller/controller" | ||
|
||
controller "github.com/argoproj/notifications-engine/pkg/controller" | ||
"github.com/prometheus/client_golang/prometheus" | ||
"github.com/prometheus/client_golang/prometheus/promhttp" | ||
log "github.com/sirupsen/logrus" | ||
"github.com/spf13/cobra" | ||
"k8s.io/client-go/dynamic" | ||
"k8s.io/client-go/kubernetes" | ||
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp" | ||
"k8s.io/client-go/tools/clientcmd" | ||
) | ||
|
||
const ( | ||
defaultMetricsPort = 9001 | ||
) | ||
|
||
func addK8SFlagsToCmd(cmd *cobra.Command) clientcmd.ClientConfig { | ||
loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() | ||
loadingRules.DefaultClientConfig = &clientcmd.DefaultClientConfig | ||
overrides := clientcmd.ConfigOverrides{} | ||
kflags := clientcmd.RecommendedConfigOverrideFlags("") | ||
cmd.PersistentFlags().StringVar(&loadingRules.ExplicitPath, "kubeconfig", "", "Path to a kube config. Only required if out-of-cluster") | ||
clientcmd.BindOverrideFlags(&overrides, cmd.PersistentFlags(), kflags) | ||
return clientcmd.NewInteractiveDeferredLoadingClientConfig(loadingRules, &overrides, os.Stdin) | ||
} | ||
|
||
func NewCommand() *cobra.Command { | ||
var ( | ||
clientConfig clientcmd.ClientConfig | ||
processorsCount int | ||
namespace string | ||
appLabelSelector string | ||
logLevel string | ||
logFormat string | ||
metricsPort int | ||
argocdRepoServer string | ||
argocdRepoServerPlaintext bool | ||
argocdRepoServerStrictTLS bool | ||
configMapName string | ||
secretName string | ||
) | ||
var command = cobra.Command{ | ||
Use: "controller", | ||
Short: "Starts Argo CD Notifications controller", | ||
RunE: func(c *cobra.Command, args []string) error { | ||
restConfig, err := clientConfig.ClientConfig() | ||
if err != nil { | ||
return err | ||
} | ||
dynamicClient, err := dynamic.NewForConfig(restConfig) | ||
if err != nil { | ||
return err | ||
} | ||
k8sClient, err := kubernetes.NewForConfig(restConfig) | ||
if err != nil { | ||
return err | ||
} | ||
if namespace == "" { | ||
namespace, _, err = clientConfig.Namespace() | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
level, err := log.ParseLevel(logLevel) | ||
if err != nil { | ||
return err | ||
} | ||
log.SetLevel(level) | ||
|
||
switch strings.ToLower(logFormat) { | ||
case "json": | ||
log.SetFormatter(&log.JSONFormatter{}) | ||
case "text": | ||
if os.Getenv("FORCE_LOG_COLORS") == "1" { | ||
log.SetFormatter(&log.TextFormatter{ForceColors: true}) | ||
} | ||
default: | ||
return fmt.Errorf("Unknown log format '%s'", logFormat) | ||
} | ||
|
||
argocdService, err := service.NewArgoCDService(k8sClient, namespace, argocdRepoServer, argocdRepoServerPlaintext, argocdRepoServerStrictTLS) | ||
if err != nil { | ||
return err | ||
} | ||
defer argocdService.Close() | ||
|
||
registry := controller.NewMetricsRegistry("argocd") | ||
http.Handle("/metrics", promhttp.HandlerFor(prometheus.Gatherers{registry, prometheus.DefaultGatherer}, promhttp.HandlerOpts{})) | ||
|
||
go func() { | ||
log.Fatal(http.ListenAndServe(fmt.Sprintf("0.0.0.0:%d", metricsPort), http.DefaultServeMux)) | ||
}() | ||
log.Infof("serving metrics on port %d", metricsPort) | ||
log.Infof("loading configuration %d", metricsPort) | ||
|
||
ctrl := notificationscontroller.NewController(k8sClient, dynamicClient, argocdService, namespace, appLabelSelector, registry, secretName, configMapName) | ||
err = ctrl.Init(context.Background()) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
go ctrl.Run(context.Background(), processorsCount) | ||
<-context.Background().Done() | ||
return nil | ||
}, | ||
} | ||
clientConfig = addK8SFlagsToCmd(&command) | ||
command.Flags().IntVar(&processorsCount, "processors-count", 1, "Processors count.") | ||
command.Flags().StringVar(&appLabelSelector, "app-label-selector", "", "App label selector.") | ||
command.Flags().StringVar(&namespace, "namespace", "", "Namespace which controller handles. Current namespace if empty.") | ||
command.Flags().StringVar(&logLevel, "loglevel", "info", "Set the logging level. One of: debug|info|warn|error") | ||
command.Flags().StringVar(&logFormat, "logformat", "text", "Set the logging format. One of: text|json") | ||
command.Flags().IntVar(&metricsPort, "metrics-port", defaultMetricsPort, "Metrics port") | ||
command.Flags().StringVar(&argocdRepoServer, "argocd-repo-server", "argocd-repo-server:8081", "Argo CD repo server address") | ||
command.Flags().BoolVar(&argocdRepoServerPlaintext, "argocd-repo-server-plaintext", false, "Use a plaintext client (non-TLS) to connect to repository server") | ||
command.Flags().BoolVar(&argocdRepoServerStrictTLS, "argocd-repo-server-strict-tls", false, "Perform strict validation of TLS certificates when connecting to repo server") | ||
command.Flags().StringVar(&configMapName, "config-map-name", "argocd-notifications-cm", "Set notifications ConfigMap name") | ||
command.Flags().StringVar(&secretName, "secret-name", "argocd-notifications-secret", "Set notifications Secret name") | ||
return &command | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package admin | ||
|
||
import ( | ||
"log" | ||
|
||
"k8s.io/apimachinery/pkg/runtime/schema" | ||
"k8s.io/client-go/kubernetes" | ||
"k8s.io/client-go/tools/clientcmd" | ||
|
||
service "github.com/argoproj/argo-cd/v2/util/notification/argocd" | ||
settings "github.com/argoproj/argo-cd/v2/util/notification/settings" | ||
|
||
"github.com/argoproj/notifications-engine/pkg/cmd" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
var ( | ||
applications = schema.GroupVersionResource{Group: "argoproj.io", Version: "v1alpha1", Resource: "applications"} | ||
) | ||
|
||
func NewNotificationsCommand() *cobra.Command { | ||
var ( | ||
argocdRepoServer string | ||
argocdRepoServerPlaintext bool | ||
argocdRepoServerStrictTLS bool | ||
) | ||
|
||
var argocdService service.Service | ||
toolsCommand := cmd.NewToolsCommand( | ||
"argocd-notifications", | ||
"argocd-notifications", | ||
applications, | ||
settings.GetFactorySettings(argocdService, "argocd-notifications-secret", "argocd-notifications-cm"), func(clientConfig clientcmd.ClientConfig) { | ||
k8sCfg, err := clientConfig.ClientConfig() | ||
if err != nil { | ||
log.Fatalf("Failed to parse k8s config: %v", err) | ||
} | ||
ns, _, err := clientConfig.Namespace() | ||
if err != nil { | ||
log.Fatalf("Failed to parse k8s config: %v", err) | ||
} | ||
argocdService, err = service.NewArgoCDService(kubernetes.NewForConfigOrDie(k8sCfg), ns, argocdRepoServer, argocdRepoServerPlaintext, argocdRepoServerStrictTLS) | ||
if err != nil { | ||
log.Fatalf("Failed to initalize Argo CD service: %v", err) | ||
} | ||
}) | ||
toolsCommand.PersistentFlags().StringVar(&argocdRepoServer, "argocd-repo-server", "argocd-repo-server:8081", "Argo CD repo server address") | ||
toolsCommand.PersistentFlags().BoolVar(&argocdRepoServerPlaintext, "argocd-repo-server-plaintext", false, "Use a plaintext client (non-TLS) to connect to repository server") | ||
toolsCommand.PersistentFlags().BoolVar(&argocdRepoServerStrictTLS, "argocd-repo-server-strict-tls", false, "Perform strict validation of TLS certificates when connecting to repo server") | ||
return toolsCommand | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
95 changes: 95 additions & 0 deletions
95
docs/operator-manual/notifications/argocd-notifications-cm.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
apiVersion: v1 | ||
kind: ConfigMap | ||
metadata: | ||
name: argocd-notifications-cm | ||
data: | ||
# Triggers define the condition when the notification should be sent and list of templates required to generate the message | ||
# Recipients can subscribe to the trigger and specify the required message template and destination notification service. | ||
trigger.on-sync-status-unknown: | | ||
- when: app.status.sync.status == 'Unknown' | ||
send: [my-custom-template] | ||
# Optional 'oncePer' property ensure that notification is sent only once per specified field value | ||
# E.g. following is triggered once per sync revision | ||
trigger.on-deployed: | | ||
- when: app.status.operationState.phase in ['Succeeded'] and app.status.health.status == 'Healthy' | ||
oncePer: app.status.sync.revision | ||
send: [app-sync-succeeded] | ||
# Templates are used to generate the notification template message | ||
template.my-custom-template: | | ||
message: | | ||
Application details: {{.context.argocdUrl}}/applications/{{.app.metadata.name}}. | ||
# Templates might have notification service specific fields. E.g. slack message might include annotations | ||
template.my-custom-template-slack-template: | | ||
message: | | ||
Application {{.app.metadata.name}} sync is {{.app.status.sync.status}}. | ||
Application details: {{.context.argocdUrl}}/applications/{{.app.metadata.name}}. | ||
email: | ||
subject: Application {{.app.metadata.name}} sync status is {{.app.status.sync.status}} | ||
slack: | ||
attachments: | | ||
[{ | ||
"title": "{{.app.metadata.name}}", | ||
"title_link": "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}", | ||
"color": "#18be52" | ||
}] | ||
# Holds list of triggers that are used by default if trigger is not specified explicitly in the subscription | ||
defaultTriggers: | | ||
- on-sync-status-unknown | ||
# Notification services are used to deliver message. | ||
# Service definition might reference values from argocd-notifications-secret Secret using $my-key format | ||
# Service format key is: service.<type>.<optional-custom-name> | ||
# Slack | ||
service.slack: | | ||
token: $slack-token | ||
username: <override-username> # optional username | ||
icon: <override-icon> # optional icon for the message (supports both emoij and url notation) | ||
# Slack based notifier with name mattermost | ||
service.slack.mattermost: | | ||
apiURL: https://my-mattermost-url.com/api | ||
token: $slack-token | ||
username: <override-username> # optional username | ||
icon: <override-icon> # optional icon for the message (supports both emoij and url notation) | ||
service.email: | | ||
host: smtp.gmail.com | ||
port: 587 | ||
from: <myemail>@gmail.com | ||
username: $email-username | ||
password: $email-password | ||
# Opsgenie | ||
service.opsgenie: | | ||
apiUrl: api.opsgenie.com | ||
apiKeys: | ||
$opsgenie-team-id: $opsgenie-team-api-key | ||
... | ||
# Telegram | ||
service.telegram: | | ||
token: $telegram-token | ||
# Context holds list of variables that can be referenced in templates | ||
context: | | ||
argocdUrl: https://cd.apps.argoproj.io/ | ||
# Contains centrally managed global application subscriptions | ||
subscriptions: | | ||
# subscription for on-sync-status-unknown trigger notifications | ||
- recipients: | ||
- slack:test2 | ||
- email:[email protected] | ||
triggers: | ||
- on-sync-status-unknown | ||
# subscription restricted to applications with matching labels only | ||
- recipients: | ||
- slack:test3 | ||
selector: test=true | ||
triggers: | ||
- on-sync-status-unknown |
10 changes: 10 additions & 0 deletions
10
docs/operator-manual/notifications/argocd-notifications-secret.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
apiVersion: v1 | ||
kind: Secret | ||
metadata: | ||
name: argocd-notifications-secret | ||
stringData: | ||
slack-token: <my-slack-token> | ||
email-username: <myemail>@gmail.com | ||
email-password: <mypassword> | ||
|
||
type: Opaque |
Oops, something went wrong.