Skip to content

Commit

Permalink
refactor reconcile loop
Browse files Browse the repository at this point in the history
  • Loading branch information
OrNovo committed Sep 12, 2024
1 parent dbf56eb commit 834db1a
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 19 deletions.
4 changes: 1 addition & 3 deletions apis/coralogix/v1alpha1/outboundwebhook_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,9 +287,7 @@ var (
)

type Slack struct {
// +optional
Digests []SlackConfigDigest `json:"digests"`
// +optional
Digests []SlackConfigDigest `json:"digests"`
Attachments []SlackConfigAttachment `json:"attachments"`
Url string `json:"url"`
}
Expand Down
4 changes: 4 additions & 0 deletions config/crd/bases/coralogix.com_outboundwebhooks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ spec:
url:
type: string
required:
- attachments
- digests
- url
type: object
type: object
Expand Down Expand Up @@ -340,6 +342,8 @@ spec:
url:
type: string
required:
- attachments
- digests
- url
type: object
type: object
Expand Down
7 changes: 7 additions & 0 deletions config/samples/alertmanger/apiKey.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
apiVersion: v1
kind: Secret
metadata:
name: opsgenie-webhook-secret
type: Opaque
data:
api-key: c2xhY2stZm9vLXNlY3JldA==
7 changes: 7 additions & 0 deletions config/samples/alertmanger/apiUrl.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
apiVersion: v1
kind: Secret
metadata:
name: slack-webhook-secret
type: Opaque
data:
webhook-url: c2xhY2stZm9vLXNlY3JldA==
31 changes: 29 additions & 2 deletions config/samples/alertmanger/example-alertmanager.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,34 @@ spec:
- name: opsgenie-general
opsgenieConfigs:
- sendResolved: true
apiURL: https://api.opsgenie.com/
apiURL: https://api.opsgenie.com/v2/alerts
message: '{{ template "opsgenie.custom.message" . }}'
description: '{{ template "opsgenie.custom.description" . }}'
source: '{{ template "opsgenie.default.source" . }}'
responders:
- name: '{{ .CommonLabels.opsgenie_team }}'
type: team
priority: '{{ template "opsgenie.custom.priority" . }}'
apiKey:
name: "opsgenie-webhook-secret" # Name of the Kubernetes Secret
key: "api-key" # Key in the Kubernetes Secret
- name: slack-default
slackConfigs:
- sendResolved: true
- sendResolved: true
apiURL:
name: "slack-webhook-secret" # Name of the Kubernetes Secret
key: "webhook-url" # Key in the Kubernetes Secret
channel: '#{{ .CommonLabels.slack_channel }}'
username: '{{ template "slack.default.username" . }}'
color: '{{ template "slack.custom.color" . }}'
title: '{{ template "slack.custom.title" . }}'
titleLink: '{{ template "slack.default.titlelink" . }}'
pretext: '{{ template "slack.default.pretext" . }}'
text: '{{ template "slack.custom.text" . }}'
shortFields: false
footer: '{{ template "slack.default.footer" . }}'
fallback: '{{ template "slack.default.fallback" . }}'
callbackId: '{{ template "slack.default.callbackid" . }}'
iconEmoji: '{{ template "slack.default.iconemoji" . }}'
iconURL: https://avatars3.githubusercontent.com/u/3380462
linkNames: false
133 changes: 119 additions & 14 deletions controllers/alertmanagerconfig_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/coralogix/coralogix-operator/controllers/clientset"
prometheus "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1alpha1"
"github.com/prometheus/common/model"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
Expand Down Expand Up @@ -93,7 +94,7 @@ func (r *AlertmanagerConfigReconciler) Reconcile(ctx context.Context, req ctrl.R
return ctrl.Result{RequeueAfter: defaultErrRequeuePeriod}, err
}

return reconcile.Result{RequeueAfter: 20 * time.Second}, nil
return reconcile.Result{RequeueAfter: 5 * time.Minute}, nil
}

func (r *AlertmanagerConfigReconciler) convertAlertmanagerConfigToCxIntegrations(ctx context.Context, alertmanagerConfig *prometheus.AlertmanagerConfig) error {
Expand All @@ -116,13 +117,13 @@ func (r *AlertmanagerConfigReconciler) convertAlertmanagerConfigToCxIntegrations
opsGenieWebhook.Name = fmt.Sprintf("%s.%s.%d", receiver.Name, "opsgenie", i)
if err := r.Get(ctx, client.ObjectKeyFromObject(opsGenieWebhook), opsGenieWebhook); err != nil {
if errors.IsNotFound(err) {
opsGenieWebhookType, err := r.opsgenieToOutboundWebhookType(ctx, opsGenieConfig, alertmanagerConfig.Namespace)
if err != nil {
return fmt.Errorf("received an error while trying to convert OpsGenieConfig to OutboundWebhookType: %w", err)
}
opsGenieWebhook.Spec = coralogixv1alpha1.OutboundWebhookSpec{
Name: opsGenieWebhook.Name,
OutboundWebhookType: coralogixv1alpha1.OutboundWebhookType{
Opsgenie: &coralogixv1alpha1.Opsgenie{
Url: opsGenieConfig.APIURL,
},
},
Name: opsGenieWebhook.Name,
OutboundWebhookType: opsGenieWebhookType,
}
if err = r.Create(ctx, opsGenieWebhook); err != nil {
return fmt.Errorf("received an error while trying to create OutboundWebhook CRD from alertmanagerConfig: %w", err)
Expand All @@ -136,18 +137,18 @@ func (r *AlertmanagerConfigReconciler) convertAlertmanagerConfigToCxIntegrations
}
}
}
for i := range receiver.SlackConfigs {
for i, slackConfig := range receiver.SlackConfigs {
slackWebhook := outboundWebhook.DeepCopy()
slackWebhook.Name = fmt.Sprintf("%s.%s.%d", receiver.Name, "slack", i)
if err := r.Get(ctx, client.ObjectKeyFromObject(slackWebhook), slackWebhook); err != nil {
if errors.IsNotFound(err) {
outboundWebhookType, err := r.slackConfigToOutboundWebhookType(ctx, slackConfig, alertmanagerConfig.Namespace)
if err != nil {
return fmt.Errorf("received an error while trying to convert SlackConfig to OutboundWebhookType: %w", err)
}
slackWebhook.Spec = coralogixv1alpha1.OutboundWebhookSpec{
Name: slackWebhook.Name,
OutboundWebhookType: coralogixv1alpha1.OutboundWebhookType{
Slack: &coralogixv1alpha1.Slack{
Url: "https://slack.com/api/chat.postMessage",
},
},
Name: slackWebhook.Name,
OutboundWebhookType: outboundWebhookType,
}
if err = r.Create(ctx, slackWebhook); err != nil {
return fmt.Errorf("received an error while trying to create OutboundWebhook CRD from alertmanagerConfig: %w", err)
Expand All @@ -165,6 +166,81 @@ func (r *AlertmanagerConfigReconciler) convertAlertmanagerConfigToCxIntegrations
return nil
}

func (r *AlertmanagerConfigReconciler) slackConfigToOutboundWebhookType(ctx context.Context, config prometheus.SlackConfig, namespace string) (coralogixv1alpha1.OutboundWebhookType, error) {
//// Construct the Slack message payload with all required fields
//payload := map[string]interface{}{
// "channel": config.Channel,
// "username": config.Username,
// "icon_emoji": config.IconEmoji,
// "icon_url": config.IconURL,
// "link_names": config.LinkNames,
// "text": config.Text,
// "attachments": []map[string]interface{}{},
//}
//
//// Construct attachment with additional fields
//attachment := map[string]interface{}{
// "color": config.Color,
// "title": config.Title,
// "title_link": config.TitleLink,
// "pretext": config.Pretext,
// "footer": config.Footer,
// "fallback": config.Fallback,
// "callback_id": config.CallbackID,
// "mrkdwn_in": []string{"text", "pretext", "fields"},
//}
//
//// Add attachment to payload
//if len(config.Color) > 0 || len(config.Title) > 0 || len(config.Pretext) > 0 || len(config.Footer) > 0 || len(config.Fallback) > 0 {
// payload["attachments"] = append(payload["attachments"].([]map[string]interface{}), attachment)
//}
//
//// Encode the payload to JSON
//jsonPayload, err := json.Marshal(payload)
//if err != nil {
// return coralogixv1alpha1.OutboundWebhookType{}, fmt.Errorf("received an error while trying to marshal payload: %w", err)
//}
_, err := r.getSecret(ctx, config.APIURL, namespace)
if err != nil {
return coralogixv1alpha1.OutboundWebhookType{}, fmt.Errorf("received an error while trying to get API URL from secret: %w", err)
}
payload := fmt.Sprintf(`{"text": "%s"}`, config.Text)
return coralogixv1alpha1.OutboundWebhookType{
GenericWebhook: &coralogixv1alpha1.GenericWebhook{
Url: "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX", //url,
Headers: map[string]string{
"Content-Type": "application/json",
},
Method: coralogixv1alpha1.GenericWebhookMethodTypePost,
Payload: pointer.String(payload),
},
}, nil
}

func (r *AlertmanagerConfigReconciler) getSecret(ctx context.Context, secretKeySelector *v1.SecretKeySelector, namespace string) (string, error) {
if secretKeySelector == nil {
return "", nil
}
// Get the secret name and key
secretName := secretKeySelector.Name
secretKey := secretKeySelector.Key

// Retrieve the secret from Kubernetes
var secret v1.Secret
err := r.Get(ctx, client.ObjectKey{Namespace: namespace, Name: secretName}, &secret)
if err != nil {
return "", fmt.Errorf("failed to get secret: %v", err)
}

// Extract the value of the API URL from the secret data
apiURLValue, ok := secret.Data[secretKey]
if !ok {
return "", fmt.Errorf("key %s not found in secret %s", secretKey, secretName)
}

return string(apiURLValue), nil
}

func (r *AlertmanagerConfigReconciler) linkCxAlertToCxIntegrations(ctx context.Context, config *prometheus.AlertmanagerConfig) error {
if config.Spec.Route == nil {
return nil
Expand Down Expand Up @@ -211,6 +287,35 @@ func (r *AlertmanagerConfigReconciler) deleteWebhooksFromRelatedAlerts(ctx conte
return nil
}

func (r *AlertmanagerConfigReconciler) opsgenieToOutboundWebhookType(ctx context.Context, opsGenieConfig prometheus.OpsGenieConfig, namespace string) (coralogixv1alpha1.OutboundWebhookType, error) {
apiKey, err := r.getSecret(ctx, opsGenieConfig.APIKey, namespace)
if err != nil {
return coralogixv1alpha1.OutboundWebhookType{}, err
}
//
//payloadMap := map[string]interface{}{
// "message": opsGenieConfig.Message,
// "description": opsGenieConfig.Description,
// "responders": opsGenieConfig.Responders,
// "source": opsGenieConfig.Source,
// "details": opsGenieConfig.Details,
// "priority": opsGenieConfig.Priority,
//}
//payload, _ := json.Marshal(payloadMap)

return coralogixv1alpha1.OutboundWebhookType{
GenericWebhook: &coralogixv1alpha1.GenericWebhook{
Method: coralogixv1alpha1.GenericWebhookMethodTypePost,
Url: opsGenieConfig.APIURL,
Headers: map[string]string{
"Content-Type": "application/json",
"Authorization": fmt.Sprintf("GenieKey %s", apiKey),
},
//Payload: pointer.String(string(payload)),
},
}, nil
}

func matchedRoutesToMatchedReceiversMap(matchedRoutes []*prometheus.Route, allReceivers []prometheus.Receiver) map[string]*prometheus.Receiver {
matchedReceiversMap := make(map[string]*prometheus.Receiver)
for _, route := range matchedRoutes {
Expand Down

0 comments on commit 834db1a

Please sign in to comment.