Skip to main content

NotificationChannel

Beta

Being rolled out. The interface described here is the one of the next release: it may still change, and may not be enabled on your tenant yet.

Monitoring is being rolled out; the Email type is not available yet.

apiVersionmonitoring.stackngo.io/v1alpha1
kindNotificationChannel
Applied bysng apply
Related commandssng template gen NotificationChannel, sng apply, sng kind list NotificationChannel, sng kind delete NotificationChannel NAME; sng monitor create --channel NAME to link a monitor to it

What it is for​

A NotificationChannel is an alert destination: an HTTPS webhook, a Slack, Discord, or Microsoft Teams channel, or email addresses. Monitors reference it by name in notificationChannelRefs. When one of them goes down, comes back, or its TLS certificate approaches expiry, the channel receives a notification, then a reminder every repeatInterval for as long as the incident lasts.

Minimal example​

ops.yml
apiVersion: monitoring.stackngo.io/v1alpha1
kind: NotificationChannel
metadata:
name: ops
spec:
type: Webhook
webhook:
url: https://hooks.example.com/uptime
sng apply ops.yml
sng monitor create api --http https://api.example.com/health --interval 5m --channel ops

Complete annotated example​

slack.yml
apiVersion: monitoring.stackngo.io/v1alpha1
kind: NotificationChannel
metadata:
name: slack # name referenced by the monitors (DNS label)
spec:
type: Slack # Webhook, Slack, Discord, MSTeams, or Email
slack:
webhookSecretRef: # the Slack URL is a secret: never in plaintext
name: slack-webhook # tenant secret
key: value # key that contains the https://hooks.slack.com/… URL
channel: "#ops" # optional: channel or @user
sendResolved: true # also notifies the return to normal (default true)
repeatInterval: 4h # reminder while the alert lasts: <integer>m or <integer>h (default 4h)

Other destinations:

spec:
type: Discord # MSTeams: same shape, "msteams" block
discord:
url: https://discord.com/api/webhooks/123/abc # or urlSecretRef: {name, key}
---
spec:
type: Webhook
webhook:
urlSecretRef: { name: ops-webhook, key: value }
---
spec:
type: Email # not available yet (NotSupported)
email:
to: [ops@example.com, astreinte@example.com] # 1 to 10 addresses

Fields​

Cross-field validation rules​

The schema rejects, as early as sng apply:

  • a destination block that does not match the type: webhook is required for Webhook and forbidden otherwise; likewise slack, discord, msteams, and email;
  • for webhook, discord, and msteams: neither url nor urlSecretRef, or both;
  • a url that does not start with https:// (at most 2048 characters);
  • a slack.channel not of the form #nom, @nom, or nom (lowercase, digits, -_., at most 80 characters);
  • an empty email.to, one with more than 10 addresses, or an address without @ or domain;
  • a repeatInterval that is not an integer followed by m or h.

The platform also rejects, after application (Accepted=False):

  • an Email channel as long as no email relay is configured (NotSupported);
  • a channel beyond the number allowed by the tier: the most recent ones are rejected (QuotaExceeded);
  • a channel whose referenced secret is missing or has no value under the given key (SecretNotFound), or whose value is not an https:// URL (Invalid). Only that channel is set aside: the tenant's other channels keep sending their alerts.

NotificationChannel​

NotificationChannel déclare une destination pour les alertes de vos monitors.

ChampDescriptionDéfautValidation
apiVersion stringmonitoring.stackngo.io/v1alpha1
kind stringNotificationChannel
metadata ObjectMetaSeul metadata.name est à renseigner (nom de la ressource dans votre tenant).
spec NotificationChannelSpec
status NotificationChannelStatus

NotificationChannelSpec​

NotificationChannelSpec décrit où envoyer les alertes de vos monitors. Renseignez le bloc qui correspond à type, et lui seul.

ChampDescriptionDéfautValidation
type ChannelTypeType de destination.Enum: [Webhook Slack Discord MSTeams Email]
webhook URLDestinationURL appelée en POST à chaque alerte (type Webhook).Optional: {}
slack SlackDestinationWebhook entrant Slack (type Slack).Optional: {}
discord URLDestinationWebhook Discord (type Discord).Optional: {}
msteams URLDestinationWebhook Microsoft Teams (type MSTeams).Optional: {}
email EmailDestinationDestinataires e-mail (type Email).Optional: {}
sendResolved booleanNotifie aussi le retour à la normale.true
repeatInterval stringRappel tant que l'alerte reste active.4hPattern: ^([1-9][0-9]*)(m|h)$

NotificationChannelStatus​

NotificationChannelStatus : acceptation du canal par la plateforme.

ChampDescriptionDéfautValidation
observedGeneration integerDernière version du manifeste prise en compte.Optional: {}
conditions Condition arrayConditions : Accepted (canal valide et utilisable).Optional: {}

ChannelType​

Type sous-jacent : string

ChannelType : destination des notifications : Webhook, Slack, Discord, MSTeams ou Email.

Règles de validation :

  • Enum: [Webhook Slack Discord MSTeams Email]
ValeurDescription
WebhookAppel HTTP vers l'adresse de votre choix.
SlackMessage dans un canal Slack.
DiscordMessage dans un canal Discord.
MSTeamsMessage dans un canal Microsoft Teams.
EmailCourriel envoyé aux adresses indiquées.

URLDestination​

URLDestination : URL https, en clair ou lue dans un secret de votre tenant (exactement l'un des deux).

ChampDescriptionDéfautValidation
url stringURL https en clair.MaxLength: 2048
Optional: {}
urlSecretRef SecretKeySelectorClé d'un secret de votre tenant qui contient l'URL (recommandé quand l'URL vaut un jeton).Optional: {}

SlackDestination​

SlackDestination : webhook entrant Slack. Son URL est secrète : elle est toujours lue dans un secret.

ChampDescriptionDéfautValidation
webhookSecretRef SecretKeySelectorClé d'un secret de votre tenant qui contient l'URL du webhook.
channel stringCanal Slack (#canal ou @utilisateur). Vide : canal du webhook.Pattern: ^[#@]?[-_a-z0-9.]\{1,80\}$
Optional: {}

EmailDestination​

EmailDestination : alertes envoyées par e-mail par la plateforme.

ChampDescriptionDéfautValidation
to string arrayAdresses des destinataires (1 à 10).MaxItems: 10
MinItems: 1
items:Pattern: ^[^@\s]+@[^@\s]+\.[^@\s]+$

SecretKeySelector​

SecretKeySelector désigne une clé d'un secret de votre tenant.

ChampDescriptionDéfautValidation
name stringName est le nom du secret.Pattern: ^[a-z0-9]([-.a-z0-9]\{0,251\}[a-z0-9])?$
key stringKey est la clé du secret qui contient la valeur.Pattern: ^[-._a-zA-Z0-9]\{1,253\}$

Status and conditions​

ConditionTrue whenFalse when
Acceptedthe channel is admitted (reason Accepted)rejection by the platform (reasons below); the monitors that reference it are rejected in turn (ChannelNotFound)
reasonExplanationAction
AcceptedChannel admitted—
QuotaExceededThe tier's number of channels is reached (2 on 3XS, 5 on 2XS, 10 on XS/S/M, 20 on L/XL, 50 above)Delete a channel, or change tier
NotSupportedtype: Email without an email relay on the platformUse a webhook
SecretNotFoundThe secret of urlSecretRef / webhookSecretRef is missing, or has no value under the given key. This channel sends nothing; the others are not affectedCreate the secret or fix name / key; the channel resumes on its own
InvalidThe secret's value is not an https:// URLFix the secret's value

Example message for SecretNotFound: secret "slack-webhook" introuvable ou sans valeur pour la clé "value" : aucune notification n'est envoyée par ce canal, les autres canaux ne sont pas affectés ; le canal reprendra automatiquement une fois le secret créé (the message is in French).

Accepted=True does not guarantee delivery: the destination itself may refuse the message. In this version, sng kind get NotificationChannel ops shows the saved manifest without the channel's state (# status: not observed yet).

What happens when you apply​

Creation. The channel is admitted and then added to the tenant's alerting configuration, as soon as at least one admitted monitor references it; a channel without a monitor sends nothing. The URLs of urlSecretRef / webhookSecretRef are read from the tenant's secrets at that point.

If a channel's secret is missing, does not have the given key, or does not contain an https:// URL, only that channel is set aside (Accepted=False, SecretNotFound or Invalid): the other channels and your other changes are applied normally. The channel resumes on its own as soon as the secret is fixed.

Secret used by a channel

The secret designated by urlSecretRef or webhookSecretRef must be declared by an SSMSecret with materialize: true: that is what makes it usable by a notification channel. Without this field, a secret is only made available to the Apps that reference it, and the channel stays set aside (SecretNotFound).

Update. A new sng apply replaces the destination; the alerting configuration is rewritten. A changed secret is read again within ten minutes at most.

What happens when you delete​

sng kind delete NotificationChannel ops: the channel no longer sends anything; the monitors that still reference it are rejected (ChannelNotFound) and are no longer probed. Remove the reference from the monitors in the same sng apply.

Common errors​

SymptomCauseFix
sng apply rejects: webhook : requis pour le type Webhook, interdit sinonBlock missing or of another typeA single block, the one for the type
sng apply rejects: url ou urlSecretRef : exactement un des deuxBoth, or neitherKeep one
sng apply rejects: url : https:// requishttp://Switch to HTTPS
Monitors rejected with ChannelNotFound after adding a channelChannel rejected (QuotaExceeded, NotSupported) or misspelled nameFix the channel or the name
Channel Accepted=False, SecretNotFoundMissing secret, missing or empty key, or a secret declared without materialize: trueDeclare the secret with materialize: true, fix name / key; see the note above
Channel Accepted=False, InvalidThe secret's value is not an https:// URLFix the value
No notification received, channel Accepted=TrueNo admitted monitor references the channel, or a destination that refuses the messageCheck notificationChannelRefs; test the URL with curl
No recovery notificationsendResolved: false, or monitor deleted or paused during the outagesendResolved: true; let the monitor go back to Up

See also​