generated from giantswarm/template-operator
-
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.
Reconciles the Alertmanager secret created by the observability-operator Helm chart and load the configuration and templates from the secret into Mimir Alertmanager. It also watches the Mimir Alertmanager pod and re-queue events to the controller when the pod is restarted, so the configuration is reloaded. Predicates are being used to filter the secret and pods being watched to only act on Alertmanager related resources. Finalizers are not used by this controller as the configuration is never deleted, only updated. --------- Co-authored-by: Taylor Bot <[email protected]> Co-authored-by: Quentin Bisson <[email protected]>
- Loading branch information
1 parent
fbfd0f1
commit b16ca41
Showing
8 changed files
with
200 additions
and
1 deletion.
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
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,95 @@ | ||
package controller | ||
|
||
import ( | ||
"context" | ||
|
||
v1 "k8s.io/api/core/v1" | ||
"k8s.io/apimachinery/pkg/types" | ||
ctrl "sigs.k8s.io/controller-runtime" | ||
"sigs.k8s.io/controller-runtime/pkg/builder" | ||
"sigs.k8s.io/controller-runtime/pkg/client" | ||
"sigs.k8s.io/controller-runtime/pkg/handler" | ||
"sigs.k8s.io/controller-runtime/pkg/log" | ||
"sigs.k8s.io/controller-runtime/pkg/reconcile" | ||
|
||
"github.com/pkg/errors" | ||
|
||
"github.com/giantswarm/observability-operator/internal/controller/predicates" | ||
"github.com/giantswarm/observability-operator/pkg/alertmanager" | ||
"github.com/giantswarm/observability-operator/pkg/config" | ||
) | ||
|
||
// AlertmanagerReconciler reconciles the Alertmanager secret created by the observability-operator Helm chart | ||
// and configures the Alertmanager instance with the configuration stored in the secret. | ||
// This controller do not make use of finalizers as the configuration is not removed from Alertmanager when the secret is deleted. | ||
type AlertmanagerReconciler struct { | ||
client client.Client | ||
|
||
alertmanagerService alertmanager.Service | ||
} | ||
|
||
// SetupAlertmanagerReconciler adds a controller into mgr that reconciles the Alertmanager secret. | ||
func SetupAlertmanagerReconciler(mgr ctrl.Manager, conf config.Config) error { | ||
r := &AlertmanagerReconciler{ | ||
client: mgr.GetClient(), | ||
alertmanagerService: alertmanager.New(conf), | ||
} | ||
|
||
// Filter only the Alertmanager secret created by the observability-operator Helm chart | ||
secretPredicate := predicates.NewAlertmanagerSecretPredicate(conf) | ||
|
||
// Filter only the Mimir Alertmanager pod | ||
podPredicate := predicates.NewAlertmanagerPodPredicate() | ||
|
||
// Requeue the Alertmanager secret when the Mimir Alertmanager pod changes | ||
p := podEventHandler(conf) | ||
|
||
// Setup the controller | ||
return ctrl.NewControllerManagedBy(mgr). | ||
For(&v1.Secret{}, builder.WithPredicates(secretPredicate)). | ||
Watches(&v1.Pod{}, p, builder.WithPredicates(podPredicate)). | ||
Complete(r) | ||
} | ||
|
||
// podEventHandler returns an event handler that enqueues requests for the Alertmanager secret only. | ||
// For now there is only one Alertmanager secret to be reconciled. | ||
func podEventHandler(conf config.Config) handler.EventHandler { | ||
return handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, obj client.Object) []ctrl.Request { | ||
return []reconcile.Request{ | ||
{ | ||
NamespacedName: types.NamespacedName{ | ||
Name: conf.Monitoring.AlertmanagerSecretName, | ||
Namespace: conf.OperatorNamespace, | ||
}, | ||
}, | ||
} | ||
}) | ||
} | ||
|
||
// Reconcile main logic | ||
func (r AlertmanagerReconciler) Reconcile(ctx context.Context, req reconcile.Request) (ctrl.Result, error) { | ||
logger := log.FromContext(ctx) | ||
|
||
logger.Info("Started reconciling") | ||
|
||
// Retrieve the secret being reconciled | ||
secret := &v1.Secret{} | ||
if err := r.client.Get(ctx, req.NamespacedName, secret); err != nil { | ||
return ctrl.Result{}, errors.WithStack(err) | ||
} | ||
|
||
if !secret.DeletionTimestamp.IsZero() { | ||
// Nothing to do if the secret is being deleted | ||
// Configuration is not removed from Alertmanager when the secret is deleted. | ||
return ctrl.Result{}, nil | ||
} | ||
|
||
err := r.alertmanagerService.Configure(ctx, secret) | ||
if err != nil { | ||
return ctrl.Result{}, errors.WithStack(err) | ||
} | ||
|
||
logger.Info("Finished reconciling") | ||
|
||
return ctrl.Result{}, nil | ||
} |
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,78 @@ | ||
package predicates | ||
|
||
import ( | ||
v1 "k8s.io/api/core/v1" | ||
"sigs.k8s.io/controller-runtime/pkg/client" | ||
"sigs.k8s.io/controller-runtime/pkg/predicate" | ||
|
||
"github.com/giantswarm/observability-operator/pkg/config" | ||
) | ||
|
||
// NewAlertmanagerSecretPredicate returns a predicate that filters only the Alertmanager secret created by the observability-operator Helm chart. | ||
func NewAlertmanagerSecretPredicate(conf config.Config) predicate.Predicate { | ||
filter := func(object client.Object) bool { | ||
if object == nil { | ||
return false | ||
} | ||
|
||
secret, ok := object.(*v1.Secret) | ||
if !ok { | ||
return false | ||
} | ||
|
||
if !secret.DeletionTimestamp.IsZero() { | ||
return false | ||
} | ||
|
||
labels := secret.GetLabels() | ||
|
||
ok = secret.GetName() == conf.Monitoring.AlertmanagerSecretName && | ||
secret.GetNamespace() == conf.OperatorNamespace && | ||
labels != nil && | ||
labels["app.kubernetes.io/name"] == "observability-operator" | ||
|
||
return ok | ||
} | ||
|
||
p := predicate.NewPredicateFuncs(filter) | ||
|
||
return p | ||
} | ||
|
||
const ( | ||
mimirNamespace = "mimir" | ||
mimirInstance = "mimir" | ||
mimirAlertmanagerComponent = "alertmanager" | ||
) | ||
|
||
// NewAlertmanagerPodPredicate returns a predicate that filters only the Mimir Alertmanager pod. | ||
func NewAlertmanagerPodPredicate() predicate.Predicate { | ||
filter := func(object client.Object) bool { | ||
if object == nil { | ||
return false | ||
} | ||
|
||
pod, ok := object.(*v1.Pod) | ||
if !ok { | ||
return false | ||
} | ||
|
||
if !pod.DeletionTimestamp.IsZero() { | ||
return false | ||
} | ||
|
||
labels := pod.GetLabels() | ||
|
||
ok = pod.GetNamespace() == mimirNamespace && | ||
labels != nil && | ||
labels["app.kubernetes.io/component"] == mimirAlertmanagerComponent && | ||
labels["app.kubernetes.io/instance"] == mimirInstance && | ||
isPodReady(pod) | ||
|
||
return ok | ||
} | ||
|
||
p := predicate.NewPredicateFuncs(filter) | ||
|
||
return p | ||
} |
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
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