From dd37c703fc759ec00bde6f3010fda7edf0cb1f7c Mon Sep 17 00:00:00 2001 From: msansen1 Date: Sat, 23 Jan 2021 23:27:59 +0100 Subject: [PATCH] Add control over available integrations to be able to enable only some integrations to users in my study i want thay all checks to be send to few services of our choice and don't leave to many choice to the user --- hc/api/transports.py | 38 +++++ hc/front/views.py | 17 ++- hc/settings.py | 26 +++- locale/fr/LC_MESSAGES/django.mo | Bin 0 -> 12275 bytes locale/fr/LC_MESSAGES/django.po | 256 ++++++++++++++------------------ templates/front/channels.html | 26 ++++ 6 files changed, 215 insertions(+), 148 deletions(-) create mode 100644 locale/fr/LC_MESSAGES/django.mo diff --git a/hc/api/transports.py b/hc/api/transports.py index 4b6c3c34..5e26b03f 100644 --- a/hc/api/transports.py +++ b/hc/api/transports.py @@ -64,6 +64,8 @@ class Transport(object): class Email(Transport): def notify(self, check): + if not settings.EMAIL_ENABLED: + return "Emails are not enabled" if not self.channel.email_verified: return "Email not verified" @@ -260,6 +262,8 @@ class Webhook(HttpTransport): class Slack(HttpTransport): def notify(self, check): + if not settings.SLACK_ENABLED: + return "Slack is not enabled" text = tmpl("slack_message.json", check=check) payload = json.loads(text) return self.post(self.channel.slack_webhook_url, json=payload) @@ -279,6 +283,8 @@ class OpsGenie(HttpTransport): pass def notify(self, check): + if not settings.OPSGENIE_ENABLED: + return "OpsGenie is not enabled" headers = { "Conent-Type": "application/json", "Authorization": "GenieKey %s" % self.channel.opsgenie_key, @@ -306,6 +312,8 @@ class PagerDuty(HttpTransport): URL = "https://events.pagerduty.com/generic/2010-04-15/create_event.json" def notify(self, check): + if not settings.PAGERDUTY_ENABLED: + return "PagerDuty is not enabled" description = tmpl("pd_description.html", check=check) payload = { "service_key": self.channel.pd_service_key, @@ -321,6 +329,8 @@ class PagerDuty(HttpTransport): class PagerTree(HttpTransport): def notify(self, check): + if not settings.PAGERTREE_ENABLED: + return "PagerTree is not enabled" url = self.channel.value headers = {"Conent-Type": "application/json"} payload = { @@ -343,6 +353,8 @@ class PagerTeam(HttpTransport): class Pushbullet(HttpTransport): def notify(self, check): + if not settings.PUSHBULLET_ENABLED: + return "Pushbullet is not enabled" text = tmpl("pushbullet_message.html", check=check) url = "https://api.pushbullet.com/v2/pushes" headers = { @@ -358,6 +370,8 @@ class Pushover(HttpTransport): URL = "https://api.pushover.net/1/messages.json" def notify(self, check): + if not settings.PUSHOVER_ENABLED: + return "Pushover is not enabled" others = self.checks().filter(status="down").exclude(code=check.code) # list() executes the query, to avoid DB access while @@ -391,6 +405,8 @@ class Pushover(HttpTransport): class VictorOps(HttpTransport): def notify(self, check): + if not settings.VICTOROPS_ENABLED: + return "VictorOps is not enabled" description = tmpl("victorops_description.html", check=check) mtype = "CRITICAL" if check.status == "down" else "RECOVERY" payload = { @@ -414,6 +430,8 @@ class Matrix(HttpTransport): return url def notify(self, check): + if not settings.MATRIX_ENABLED: + return "Matrix Chat is not enabled" plain = tmpl("matrix_description.html", check=check) formatted = tmpl("matrix_description_formatted.html", check=check) payload = { @@ -428,6 +446,8 @@ class Matrix(HttpTransport): class Discord(HttpTransport): def notify(self, check): + if not settings.DISCORD_ENABLED: + return "Discord Chat is not enabled" text = tmpl("slack_message.json", check=check) payload = json.loads(text) url = self.channel.discord_webhook_url + "/slack" @@ -453,6 +473,8 @@ class Telegram(HttpTransport): ) def notify(self, check): + if not settings.TELEGRAM_ENABLED: + return "Telegram Chat is not enabled" from hc.api.models import TokenBucket if not TokenBucket.authorize_telegram(self.channel.telegram_id): @@ -469,6 +491,8 @@ class Sms(HttpTransport): return check.status != "down" def notify(self, check): + if not settings.SMS_ENABLED: + return "Sms is not enabled" profile = Profile.objects.for_user(self.channel.project.owner) if not profile.authorize_sms(): profile.send_sms_limit_notice("SMS") @@ -495,6 +519,8 @@ class Call(HttpTransport): return check.status != "down" def notify(self, check): + if not settings.CALL_ENABLED: + return "Call is not enabled" profile = Profile.objects.for_user(self.channel.project.owner) if not profile.authorize_call(): profile.send_call_limit_notice() @@ -524,6 +550,8 @@ class WhatsApp(HttpTransport): return not self.channel.whatsapp_notify_up def notify(self, check): + if not settings.WHATSAPP_ENABLED: + return "WhatsApp is not enabled" profile = Profile.objects.for_user(self.channel.project.owner) if not profile.authorize_sms(): profile.send_sms_limit_notice("WhatsApp") @@ -550,6 +578,8 @@ class Trello(HttpTransport): return check.status != "down" def notify(self, check): + if not settings.TRELLO_ENABLED: + return "Trello is not enabled" params = { "idList": self.channel.trello_list_id, "name": tmpl("trello_name.html", check=check), @@ -597,6 +627,8 @@ class MsTeams(HttpTransport): return s def notify(self, check): + if not settings.MSTEAMS_ENABLED: + return "MsTeams is not enabled" text = tmpl("msteams_message.json", check=check) payload = json.loads(text) @@ -629,6 +661,8 @@ class Zulip(HttpTransport): pass def notify(self, check): + if not settings.ZULIP_ENABLED: + return "Zulip is not enabled" url = self.channel.zulip_site + "/api/v1/messages" auth = (self.channel.zulip_bot_email, self.channel.zulip_api_key) data = { @@ -643,6 +677,8 @@ class Zulip(HttpTransport): class Spike(HttpTransport): def notify(self, check): + if not settings.SPIKE_ENABLED: + return "Spike is not enabled" url = self.channel.value headers = {"Conent-Type": "application/json"} payload = { @@ -659,6 +695,8 @@ class LineNotify(HttpTransport): URL = "https://notify-api.line.me/api/notify" def notify(self, check): + if not settings.LINENOTIFY_ENABLED: + return "LineNotify is not enabled" headers = { "Content-Type": "application/x-www-form-urlencoded", "Authorization": "Bearer %s" % self.channel.linenotify_token, diff --git a/hc/front/views.py b/hc/front/views.py index 0b614b63..590492eb 100644 --- a/hc/front/views.py +++ b/hc/front/views.py @@ -756,20 +756,31 @@ def channels(request, code): "project": project, "profile": project.owner_profile, "channels": channels, + "enable_email": settings.EMAIL_ENABLED is True, "enable_apprise": settings.APPRISE_ENABLED is True, "enable_call": settings.TWILIO_AUTH is not None, "enable_discord": settings.DISCORD_CLIENT_ID is not None, "enable_linenotify": settings.LINENOTIFY_CLIENT_ID is not None, "enable_matrix": settings.MATRIX_ACCESS_TOKEN is not None, + "enable_mattermost": settings.MATTERMOST_ENABLED is True, + "enable_msteams": settings.MSTEAMS_ENABLED is True, + "enable_pagerduty": settings.PAGERDUTY_ENABLED is True, "enable_pdc": settings.PD_VENDOR_KEY is not None, + "enable_prometheus": settings.PROMETHEUS_ENABLED is True, "enable_pushbullet": settings.PUSHBULLET_CLIENT_ID is not None, "enable_pushover": settings.PUSHOVER_API_TOKEN is not None, + "enable_spike": settings.SPIKE_ENABLED is True, "enable_shell": settings.SHELL_ENABLED is True, + "enable_slack": settings.SLACK_ENABLED is True, "enable_signal": settings.SIGNAL_CLI_ENABLED is True, "enable_slack_btn": settings.SLACK_CLIENT_ID is not None, - "enable_sms": settings.TWILIO_AUTH is not None, - "enable_telegram": settings.TELEGRAM_TOKEN is not None, - "enable_trello": settings.TRELLO_APP_KEY is not None, + "enable_sms": settings.SMS_ENABLED is True, + "enable_telegram": settings.TELEGRAM_ENABLED is True, + "enable_trello": settings.TRELLO_ENABLED is True, + "enable_zulip": settings.ZULIP_ENABLED is True, + "enable_opsgenie": settings.OPSGENIE_ENABLED is True, + "enable_victorops": settings.VICTOROPS_ENABLED is True, + "enable_webhook": settings.WEBHOOK_ENABLED is True, "enable_whatsapp": settings.TWILIO_USE_WHATSAPP, "use_payments": settings.USE_PAYMENTS, } diff --git a/hc/settings.py b/hc/settings.py index 2c2ed55a..0f6e7c4f 100644 --- a/hc/settings.py +++ b/hc/settings.py @@ -26,7 +26,7 @@ def envint(s, default): return int(v) -SECRET_KEY = os.getenv("SECRET_KEY", "") +SECRET_KEY = os.getenv("SECRET_KEY", "---") METRICS_KEY = os.getenv("METRICS_KEY") DEBUG = envbool("DEBUG", "True") ALLOWED_HOSTS = os.getenv("ALLOWED_HOSTS", "*").split(",") @@ -173,10 +173,12 @@ COMPRESS_CSS_HASHING_METHOD = "content" RP_ID = os.getenv("RP_ID") # Discord integration +DISCORD_ENABLED = envbool("DISCORD_ENABLED", "False") DISCORD_CLIENT_ID = os.getenv("DISCORD_CLIENT_ID") DISCORD_CLIENT_SECRET = os.getenv("DISCORD_CLIENT_SECRET") # Email integration +EMAIL_ENABLED = envbool("EMAIL_ENABLED", "False") EMAIL_HOST = os.getenv("EMAIL_HOST", "") EMAIL_PORT = envint("EMAIL_PORT", "587") EMAIL_HOST_USER = os.getenv("EMAIL_HOST_USER", "") @@ -185,20 +187,24 @@ EMAIL_USE_TLS = envbool("EMAIL_USE_TLS", "True") EMAIL_USE_VERIFICATION = envbool("EMAIL_USE_VERIFICATION", "True") # Slack integration +SLACK_ENABLED = envbool("SLACK_ENABLED", "False") SLACK_CLIENT_ID = os.getenv("SLACK_CLIENT_ID") SLACK_CLIENT_SECRET = os.getenv("SLACK_CLIENT_SECRET") # Pushover integration +PUSHOVER_ENABLED = envbool("PUSHOVER_ENABLED", "False") PUSHOVER_API_TOKEN = os.getenv("PUSHOVER_API_TOKEN") PUSHOVER_SUBSCRIPTION_URL = os.getenv("PUSHOVER_SUBSCRIPTION_URL") PUSHOVER_EMERGENCY_RETRY_DELAY = int(os.getenv("PUSHOVER_EMERGENCY_RETRY_DELAY", "300")) PUSHOVER_EMERGENCY_EXPIRATION = int(os.getenv("PUSHOVER_EMERGENCY_EXPIRATION", "86400")) # Pushbullet integration +PUSHBULLET_ENABLED = envbool("PUSHBULLET_ENABLED", "False") PUSHBULLET_CLIENT_ID = os.getenv("PUSHBULLET_CLIENT_ID") PUSHBULLET_CLIENT_SECRET = os.getenv("PUSHBULLET_CLIENT_SECRET") # Telegram integration -- override in local_settings.py +TELEGRAM_ENABLED = envbool("TELEGRAM_ENABLED", "False") TELEGRAM_BOT_NAME = os.getenv("TELEGRAM_BOT_NAME", "ExampleBot") TELEGRAM_TOKEN = os.getenv("TELEGRAM_TOKEN") @@ -209,12 +215,15 @@ TWILIO_FROM = os.getenv("TWILIO_FROM") TWILIO_USE_WHATSAPP = envbool("TWILIO_USE_WHATSAPP", "False") # PagerDuty +PAGERDUTY_ENABLED = envbool("PAGERDUTY_ENABLED", "False") PD_VENDOR_KEY = os.getenv("PD_VENDOR_KEY") # Trello +TRELLO_ENABLED = envbool("TRELLO_ENABLED", "False") TRELLO_APP_KEY = os.getenv("TRELLO_APP_KEY") # Matrix +MATRIX_ENABLED = envbool("MATRIX_ENABLED", "False") MATRIX_HOMESERVER = os.getenv("MATRIX_HOMESERVER") MATRIX_USER_ID = os.getenv("MATRIX_USER_ID") MATRIX_ACCESS_TOKEN = os.getenv("MATRIX_ACCESS_TOKEN") @@ -225,7 +234,22 @@ APPRISE_ENABLED = envbool("APPRISE_ENABLED", "False") # Local shell commands SHELL_ENABLED = envbool("SHELL_ENABLED", "False") +#Intégration Feature Toggle +MATTERMOST_ENABLED = envbool("MATTERMOST_ENABLED", "False") +OPSGENIE_ENABLED = envbool("OPSGENIE_ENABLED", "False") +PAGERTREE_ENABLED = envbool("PAGERTREE_ENABLED", "False") +PROMETHEUS_ENABLED = envbool("PROMETHEUS_ENABLED", "False") +VICTOROPS_ENABLED = envbool("VICTOROPS_ENABLED", "False") +SMS_ENABLED = envbool("SMS_ENABLED", "False") +CALL_ENABLED = envbool("CALL_ENABLED", "False") +WEBHOOK_ENABLED = envbool("WEBHOOK_ENABLED", "True") +WHATSAPP_ENABLED = envbool("WHATSAPP_ENABLED", "False") +MSTEAMS_ENABLED = envbool("MSTEAMS_ENABLED", "False") +ZULIP_ENABLED = envbool("ZULIP_ENABLED", "False") +SPIKE_ENABLED = envbool("SPIKE_ENABLED", "False") + # LINE Notify +LINENOTIFY_ENABLED = envbool("LINENOTIFY_ENABLED", "False") LINENOTIFY_CLIENT_ID = os.getenv("LINENOTIFY_CLIENT_ID") LINENOTIFY_CLIENT_SECRET = os.getenv("LINENOTIFY_CLIENT_SECRET") diff --git a/locale/fr/LC_MESSAGES/django.mo b/locale/fr/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..e2be36ebfbc3275b300842cdd8dd1beed5610e39 GIT binary patch literal 12275 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

pjuTe! zN|L(9+r>eO;S8BN*p#Ja`SV@VFJqr{`VDJYXf?8G(z>?euhc-ivb5etkR_4I(!-D3 z)a$ia*|@c0N^HHf{oX4UQ+ZT6u&!_4I>6wQ4*p&uoKC}`N=!gQ-Z152zMD3KV{A4P zf7=tI@#&dw;_12LbGCWP<~NRorN!6;A&bK=VGK(NX2(!Y9g`E~=Q@&Q19-|9Vx(fC zEwxZ;kS)xiVgXv?sb9+;G}5U&)wf$rUkDbnJgWhL5)oW&F@bAyB3Vjp(59yx`^osG ztlZ;=_t5F3tKc)wo75~XhK6N=OquSCo4akWpEORd(5W_i>^@g+ioWmCFNnfZB;4#8{P057Xlb<4XDSW-p!)yxs@cR% z0x$y>oj)q8WGsX2s6T@oifLOnfa3b-n%?Y|ttSQP_t=sHlRG!MU5vUhrpsg-iuFuo zg#>MD1xdo8Q*^z831r#pbmZYSVvfs&azak5hO*y=}J{avck`3a0!~#@6KpvrLPg*yJ{+ z0I}^~q2vM1UwVjzMA}%IQgn%hjl*GsrV_UtxH$rU0HHtGP-Hf)!~Sv(<*0Nalga1R zFlOs&Dw4ZX#p71DuY)?*HSoob_}tOw;(pd*PJRZnNCSAJ7VzZ;xXllXXE$w zg(mmc)8#sV$Hp#}Z4H+h~6fZWNF?Y8kfWdyYw$kAdZ%`j@k<`z`I zb4{(LP_APL^VS28d}cnYP9%x7_JSw$>EhAFQd$eAG%2&bi`5%T85_rZJ9fn>*`t$Q zmuAgNsW_}B&c2PV`2jtt_>(3chezfb%L+X5E>gmla4de^7zNsx%?~PxHFA`;tNNT*U_!`NFIb@h zJ6Iz~)r}FiIs`1N7-@eGLe*gDrp!TAtxbs$)Hp*~&}`MPT5Po2b261kOfWZa#BJ40 zVWd7rI=W#~bLED)0$I^~c4ahzqrfWWm^XQfr7*aqwJ6juoJW=zGkV`% zC}|%_Bm87vcY4asNLK6*-;|fdm`@*JAeAi_wBzfpKOfDapMT6&jm;t&vtj^_;XGED zv9xW_dTdRZL}^>nFl#hBD@m-I)1cf8wXn7|?5Tj@F=h|gOj%^pe6!9VNLSl*Q4MpT sqh%5Q@{d3NqMJLi-{fU+\n" "Language-Team: fr <>\n" @@ -24,17 +24,16 @@ msgstr "" msgid "" "%(site_name)s - Monitor Cron Jobs. Get Notified When Your Cron Jobs Fail" msgstr "" -"%(site_name)s - Surveiller les traitements de Cron. Soyez averti en cas d'échec" +"%(site_name)s - Surveiller les traitements de Cron. Soyez averti en cas " +"d'échec" #: templates/base.html:67 msgid "Toggle navigation" -msgstr "" -"Basculer la navigation" +msgstr "Basculer la navigation" #: templates/base.html:101 msgid "Checks" -msgstr "" -"Contrôles" +msgstr "Contrôles" #: templates/base.html:108 templates/front/welcome.html:368 msgid "Integrations" @@ -46,8 +45,7 @@ msgstr "" #: templates/base.html:122 msgid "Settings" -msgstr "" -"Réglages" +msgstr "Réglages" #: templates/base.html:133 templates/base.html:137 msgid "Pricing" @@ -55,81 +53,72 @@ msgstr "" #: templates/base.html:145 msgid "Docs" -msgstr "" -"Documentations" +msgstr "Documentations" #: templates/base.html:152 msgid "Account" -msgstr "" -"Mon compte" +msgstr "Mon compte" #: templates/base.html:158 msgid "Site Administration" -msgstr "" -"Administration" +msgstr "Administration" #: templates/base.html:164 msgid "Projects" -msgstr "" -"Projets" +msgstr "Projets" #: templates/base.html:184 msgid "Account Settings" -msgstr "" -"Paramètres du compte" +msgstr "Paramètres du compte" #: templates/base.html:189 msgid "Log Out" -msgstr "" -"Se déconnecter" +msgstr "Se déconnecter" #: templates/base.html:197 msgid "Sign In" -msgstr "" -"Se connecter" +msgstr "Se connecter" #: templates/base.html:206 templates/front/welcome.html:743 msgid "Sign Up" -msgstr "" -"S'inscrire" +msgstr "S'inscrire" #: templates/base.html:227 msgid "Powered by Healthchecks open-source project" -msgstr "" -"S'inscrire" +msgstr "S'inscrire" #: templates/front/welcome.html:5 msgid "" "Cron Monitoring. Monitor nightly backups, weekly reports, cron jobs and " "background tasks. Receive alerts when your tasks don't run on time." msgstr "" -"Surveillance Cron. Surveillez les sauvegardes nocturnes, les rapports hebdomadaires, les tâches cron et" -"tâches en arrière-plan. Recevez des alertes lorsque vos tâches ne sont pas exécutées à temps." +"Surveillance Cron. Surveillez les sauvegardes nocturnes, les rapports " +"hebdomadaires, les tâches cron ettâches en arrière-plan. Recevez des alertes " +"lorsque vos tâches ne sont pas exécutées à temps." #: templates/front/welcome.html:19 msgid "" "Monitoring for your nightly backups, weekly reports, cron jobs and " "background tasks." msgstr "" -"Surveillance de vos sauvegardes nocturnes, rapports hebdomadaires, tâches cron et " -"tâches d'arrière-plan" +"Surveillance de vos sauvegardes nocturnes, rapports hebdomadaires, tâches " +"cron et tâches d'arrière-plan" #: templates/front/welcome.html:27 msgid "Make HTTP requests to the Ping URL at regular intervals." -msgstr "" -"Envoyez des requêtes HTTP à l'URL Ping à intervalles réguliers" +msgstr "Envoyez des requêtes HTTP à l'URL Ping à intervalles réguliers" #: templates/front/welcome.html:29 #, python-format msgid "" "When the URL is not pinged on time, %(site_name)s will send you an alert." msgstr "" -"Lorsque l'URL n'est pas soumise à temps, %(site_name)s vous enverra une alerte." +"Lorsque l'URL n'est pas soumise à temps, %(site_name)s vous enverra une " +"alerte." #: templates/front/welcome.html:35 msgid "You can monitor any service that can make HTTP requests or send emails." -msgstr "" -"Vous pouvez surveiller tout service capable de faire des requêtes HTTP" +msgstr "Vous pouvez surveiller tout service capable de faire des requêtes HTTP" #: templates/front/welcome.html:40 #, python-format @@ -142,8 +131,7 @@ msgstr "" #: templates/front/welcome.html:79 msgid "Browser" -msgstr "" -"Navigateur" +msgstr "Navigateur" #: templates/front/welcome.html:85 templates/front/welcome.html:378 msgid "Email" @@ -154,8 +142,8 @@ msgid "" "As an alternative to HTTP requests, you can also report \"liveness\" by " "sending email messages." msgstr "" -"Comme alternative aux requêtes HTTP, vous pouvez également signaler \"vivacité\" par " -" l'envoie d' e-mails ." +"Comme alternative aux requêtes HTTP, vous pouvez également signaler " +"\"vivacité\" par l'envoie d' e-mails ." #: templates/front/welcome.html:131 #, python-format @@ -164,9 +152,10 @@ msgid "" "subject line. This is handy when your backup software sends an email after " "every run, and uses a different subject line depending on success or failure." msgstr "" -"Vous pouvez demander à %(site_name)s de rechercher un mot-clé particulier dans la" -"ligne d'objet. C'est pratique lorsque votre logiciel de sauvegarde envoie un e-mail après" -"chaque exécution, et utilise une ligne d'objet différente selon le succès ou l'échec." +"Vous pouvez demander à %(site_name)s de rechercher un mot-clé particulier " +"dans laligne d'objet. C'est pratique lorsque votre logiciel de sauvegarde " +"envoie un e-mail aprèschaque exécution, et utilise une ligne d'objet " +"différente selon le succès ou l'échec." #: templates/front/welcome.html:151 #, python-format @@ -174,37 +163,36 @@ msgid "" "%(site_name)s monitors the heartbeat messages sent by your cron jobs, " "services and APIs. Get immediate alerts when they don't arrive on schedule." msgstr "" -"%(site_name)s surveille les messages de pulsation envoyés par vos tâches cron," -"services et API. Recevez des alertes immédiates lorsqu'ils n'arrivent pas dans les délais." +"%(site_name)s surveille les messages de pulsation envoyés par vos tâches " +"cron,services et API. Recevez des alertes immédiates lorsqu'ils n'arrivent " +"pas dans les délais." #: templates/front/welcome.html:158 msgid "Sign Up – It's Free" -msgstr "" -"Inscrivez-vous" +msgstr "Inscrivez-vous" #: templates/front/welcome.html:170 msgid "A quick peek of what's inside:" -msgstr "" -"Un aperçu rapide de ce qu'il y a à l'intérieur:" +msgstr "Un aperçu rapide de ce qu'il y a à l'intérieur:" #: templates/front/welcome.html:185 msgid "Live-updating Dashboard" -msgstr "" -"Tableau de bord de mise à jour en direct" +msgstr "Tableau de bord de mise à jour en direct" #: templates/front/welcome.html:188 msgid "" "A list of your checks, one for each Cron job, daemon or scheduled task you " "want to monitor." msgstr "" -"Une liste de vos contrôles, un pour chaque tâche Cron, démon ou tâche planifiée que vous " -"voulez surveiller." +"Une liste de vos contrôles, un pour chaque tâche Cron, démon ou tâche " +"planifiée que vous voulez surveiller." #: templates/front/welcome.html:194 msgid "" "Give names and assign tags to your checks to easily recognize them later." msgstr "" -"Donnez des noms et attribuez des balises à vos contrôles pour les reconnaître facilement plus tard." +"Donnez des noms et attribuez des balises à vos contrôles pour les " +"reconnaître facilement plus tard." #: templates/front/welcome.html:200 msgid "Tap on the integration icons to toggle them on and off." @@ -216,13 +204,12 @@ msgid "" "Adjust Period and Grace time to match the periodicity and duration of your " "tasks." msgstr "" -"Ajustez la période et le délai de grâce en fonction de la périodicité et de la durée de votre " -"tâche." +"Ajustez la période et le délai de grâce en fonction de la périodicité et de " +"la durée de votre tâche." #: templates/front/welcome.html:222 msgid "Simple Configuration" -msgstr "" -"Configuration simple" +msgstr "Configuration simple" #: templates/front/welcome.html:223 msgid "" @@ -230,9 +217,10 @@ msgid "" "strong> parameters. Depending on these parameters and time since the last " "ping, the check is in one of the following states:" msgstr "" -"Chaque contrôle a des paramètres configurables que sont période et délai de grâce . En fonction de ces paramètres et du temps écoulé depuis le dernier " -"ping, le contrôle est dans l'un des états suivants:" +"Chaque contrôle a des paramètres configurables que sont période et délai de grâce . En fonction de ces paramètres " +"et du temps écoulé depuis le dernier ping, le contrôle est dans l'un des " +"états suivants:" #: templates/front/welcome.html:235 msgid "New. A check that has been created, but has not received any pings yet." @@ -242,15 +230,17 @@ msgstr "" #: templates/front/welcome.html:246 msgid "Up. Time since last ping has not exceeded Period." msgstr "" -"OK. Le temps écoulé depuis le dernier ping n'a pas dépassé la période ." +"OK. Le temps écoulé depuis le dernier ping n'a pas dépassé la " +"période ." #: templates/front/welcome.html:257 msgid "" "Late. Time since last ping has exceeded Period, but has not " "yet exceeded Period + Grace." msgstr "" -"En retard. Le temps écoulé depuis le dernier ping a dépassé la période , mais n'a pas " -"encore dépassé période + grâce ." +"En retard. Le temps écoulé depuis le dernier ping a dépassé la " +"période , mais n'a pas encore dépassé période + " +" grâce ." #: templates/front/welcome.html:269 #, python-format @@ -259,32 +249,29 @@ msgid "" "Grace. When check goes from \"Late\" to \"Down\", " "%(site_name)s sends you a notification." msgstr "" -"KO. Le temps écoulé depuis le dernier ping a dépassé période +" -" Grace . Lorsque la vérification passe de \"En retard\" à \"KO\", " -"%(site_name)s vous envoie une notification." +"KO. Le temps écoulé depuis le dernier ping a dépassé période + Grace . Lorsque la vérification passe de \"En " +"retard\" à \"KO\", %(site_name)s vous envoie une notification." #: templates/front/welcome.html:291 msgid "Cron Expression Support" -msgstr "" -"Prise en charge des expressions Cron" +msgstr "Prise en charge des expressions Cron" #: templates/front/welcome.html:293 msgid "" "Alternatively, you can define the expected ping dates and times using a cron " "expression. See" msgstr "" -"Alternativement, vous pouvez définir les dates et heures de ping attendues à l'aide d'une expression " -"cron. Voir" +"Alternativement, vous pouvez définir les dates et heures de ping attendues à " +"l'aide d'une expression cron. Voir" #: templates/front/welcome.html:298 msgid "Cron Syntax Cheatsheet" -msgstr "" -"Aide de syntaxe Cron" +msgstr "Aide de syntaxe Cron" #: templates/front/welcome.html:300 msgid "for the supported syntax features." -msgstr "" -"pour les syntaxe prises en charge." +msgstr "pour les syntaxe prises en charge." #: templates/front/welcome.html:305 msgid "" @@ -292,33 +279,32 @@ msgid "" "will be alerted. Set it to be a little above the expected duration of your " "cron job." msgstr "" -"Temps de Grace spécifie à quel point un ping peut être \" en retard \" avant l'envoi " -"d'une alerte. Réglez-le légèrement au-dessus de la durée prévue de votre " -"Tâche planifiée." +"Temps de Grace spécifie à quel point un ping peut être \" " +"en retard \" avant l'envoi d'une alerte. Réglez-le légèrement au-dessus de " +"la durée prévue de votre Tâche planifiée." #: templates/front/welcome.html:323 msgid "Details and Event Log" -msgstr "" -"Détails et journal des événements" +msgstr "Détails et journal des événements" #: templates/front/welcome.html:325 msgid "" "You can add a longer, free-form description to each check. Leave notes and " "pointers for yourself and for your team." msgstr "" -"Vous pouvez ajouter une description plus longue et de forme libre à chaque contôle. Laissez des notes et " -"des pointeurs pour vous et votre équipe." +"Vous pouvez ajouter une description plus longue et de forme libre à chaque " +"contôle. Laissez des notes et des pointeurs pour vous et votre équipe." #: templates/front/welcome.html:332 msgid "" "You can also see the log of received pings and sent \"Down\" notifications." msgstr "" -"Vous pouvez également voir le journal des pings reçus et des notifications \"KO\" envoyées." +"Vous pouvez également voir le journal des pings reçus et des notifications " +"\"KO\" envoyées." #: templates/front/welcome.html:349 msgid "Public Status Badges" -msgstr "" -"Badges de statut public" +msgstr "Badges de statut public" #: templates/front/welcome.html:351 #, python-format @@ -327,22 +313,21 @@ msgid "" "Additionally, the \"%(site_name)s\" badge shows the overall status of all " "checks in your account." msgstr "" -"%(site_name)s fournit des badges de statut pour chacune des balises que vous avez utilisées. " -"De plus, le badge \"%(site_name)s \" indique l'état général de tous " -"les contrôles de votre compte." +"%(site_name)s fournit des badges de statut pour chacune des balises que vous " +"avez utilisées. De plus, le badge \"%(site_name)s \" indique l'état général " +"de tous les contrôles de votre compte." #: templates/front/welcome.html:358 msgid "" "The badges have public, but hard-to-guess URLs. You can use them in your " "READMEs, dashboards or status pages." msgstr "" -"Les badges ont des URL publiques, mais difficiles à deviner. Vous pouvez les utiliser dans votre " -"README, tableaux de bord ou pages d'état." +"Les badges ont des URL publiques, mais difficiles à deviner. Vous pouvez les " +"utiliser dans votre README, tableaux de bord ou pages d'état." #: templates/front/welcome.html:370 msgid "Set up multiple ways to get notified:" -msgstr "" -"Configurez plusieurs façons de recevoir des notifications:" +msgstr "Configurez plusieurs façons de recevoir des notifications:" #: templates/front/welcome.html:400 templates/front/welcome.html:408 #: templates/front/welcome.html:432 templates/front/welcome.html:453 @@ -350,36 +335,30 @@ msgstr "" #: templates/front/welcome.html:583 templates/front/welcome.html:617 #: templates/front/welcome.html:651 templates/front/welcome.html:662 msgid "Chat" -msgstr "" -"Conversations" +msgstr "Conversations" #: templates/front/welcome.html:420 templates/front/welcome.html:547 #: templates/front/welcome.html:559 msgid "Push Notifications" -msgstr "" -"Notifications push" +msgstr "Notifications push" #: templates/front/welcome.html:484 templates/front/welcome.html:495 #: templates/front/welcome.html:503 templates/front/welcome.html:514 #: templates/front/welcome.html:606 templates/front/welcome.html:640 msgid "Incident Management" -msgstr "" -"La gestion des incidents" +msgstr "La gestion des incidents" #: templates/front/welcome.html:524 msgid "Phone Call" -msgstr "" -"Appel téléphonique" +msgstr "Appel téléphonique" #: templates/front/welcome.html:536 msgid "Event Monitoring" -msgstr "" -"Surveillance d'événements" +msgstr "Surveillance d'événements" #: templates/front/welcome.html:570 msgid "Shell Commands" -msgstr "" -"Commandes Shell" +msgstr "Commandes Shell" #: templates/front/welcome.html:582 msgid "Signal" @@ -391,14 +370,12 @@ msgstr "" #: templates/front/welcome.html:629 msgid "Project Management" -msgstr "" -"Gestion de projet" +msgstr "Gestion de projet" #: templates/front/welcome.html:671 #, python-format msgid "What Can I Monitor With %(site_name)s?" -msgstr "" -"Que puis-je surveiller avec %(site_name)s?" +msgstr "Que puis-je surveiller avec %(site_name)s?" #: templates/front/welcome.html:677 msgid "Cron Jobs" @@ -412,55 +389,47 @@ msgid "" "cron-like interface, Heroku Scheduler, ...). A failed cron job often has no " "immediate visible consequences, and can go unnoticed for a long time." msgstr "" -"La surveillance de %(site_name)s convient parfaitement aux tâches cron et aux systèmes de type cron" -"(minuteries systemd, tâches de build Jenkins, tâches planifiées Windows, wp-cron, uwsgi" -"interface de type cron, Heroku Scheduler, ...). Une tâche cron échouée n'a souvent pas de " -"conséquences visibles immédiates, et peut passer inaperçues pendant longtemps." +"La surveillance de %(site_name)s convient parfaitement aux tâches cron et " +"aux systèmes de type cron(minuteries systemd, tâches de build Jenkins, " +"tâches planifiées Windows, wp-cron, uwsgiinterface de type cron, Heroku " +"Scheduler, ...). Une tâche cron échouée n'a souvent pas de conséquences " +"visibles immédiates, et peut passer inaperçues pendant longtemps." #: templates/front/welcome.html:688 templates/front/welcome.html:712 msgid "Specific examples:" -msgstr "" -"Exemples spécifiques:" +msgstr "Exemples spécifiques:" #: templates/front/welcome.html:690 msgid "Filesystem backups" -msgstr "" -"Sauvegardes du système de fichiers" +msgstr "Sauvegardes du système de fichiers" #: templates/front/welcome.html:691 msgid "Database backups" -msgstr "" -"Sauvegardes de base de données" +msgstr "Sauvegardes de base de données" #: templates/front/welcome.html:692 msgid "Daily, weekly, monthly report emails" -msgstr "" -"E-mails de rapport quotidien, hebdomadaire et mensuel" +msgstr "E-mails de rapport quotidien, hebdomadaire et mensuel" #: templates/front/welcome.html:693 msgid "SSL renewals" -msgstr "" -"Renouvellements SSL" +msgstr "Renouvellements SSL" #: templates/front/welcome.html:694 msgid "Business data import and sync" -msgstr "" -"Importation et synchronisation des données d'entreprise" +msgstr "Importation et synchronisation des données d'entreprise" #: templates/front/welcome.html:695 msgid "Antivirus scans" -msgstr "" -"Analyses antivirus" +msgstr "Analyses antivirus" #: templates/front/welcome.html:696 msgid "Dynamic DNS updates" -msgstr "" -"Mises à jour DNS dynamiques" +msgstr "Mises à jour DNS dynamiques" #: templates/front/welcome.html:700 msgid "Processes, Services, Servers" -msgstr "" -"Processus, services, serveurs" +msgstr "Processus, services, serveurs" #: templates/front/welcome.html:703 #, python-format @@ -470,15 +439,15 @@ msgid "" "healthy. Write a shell script that checks for a specific condition, and " "pings %(site_name)s if successful. Run the shell script regularly." msgstr "" -"La surveillance de %(site_name)s peut être utilisée pour la surveillance de webservice: " -"garantir qu'un service système particulier, ou le serveur dans son ensemble est actif et " -"sain. Écrivez un script shell qui vérifie une condition spécifique, et " -"pings %(site_name)s en cas de succès. Exécutez ce script shell a fréquence régulière." +"La surveillance de %(site_name)s peut être utilisée pour la surveillance de " +"webservice: garantir qu'un service système particulier, ou le serveur dans " +"son ensemble est actif et sain. Écrivez un script shell qui vérifie une " +"condition spécifique, et pings %(site_name)s en cas de succès. Exécutez ce " +"script shell a fréquence régulière." #: templates/front/welcome.html:714 msgid "Check a specific docker container is running" -msgstr "" -"Vérifier qu'un conteneur Docker spécifique est en cours d'exécution" +msgstr "Vérifier qu'un conteneur Docker spécifique est en cours d'exécution" #: templates/front/welcome.html:715 msgid "Check a specific application process is running" @@ -487,21 +456,19 @@ msgstr "" #: templates/front/welcome.html:716 msgid "Check database replication lag" -msgstr "" -"Vérifier le décalage de réplication de la base de données" +msgstr "Vérifier le décalage de réplication de la base de données" #: templates/front/welcome.html:717 msgid "Check system resources: free disk, free RAM, ..." -msgstr "" -"Vérifier les ressources système: disque libre, RAM libre, ..." +msgstr "Vérifier les ressources système: disque libre, RAM libre, ..." #: templates/front/welcome.html:719 msgid "" "Send simple, unconditional \"I'm alive\" messages from your server (or your " "NAS, router, Raspberry Pi, ...)" msgstr "" -"Envoyez des messages simples et inconditionnels \"Je suis en vie\" depuis un serveur, " -"un service, ...)" +"Envoyez des messages simples et inconditionnels \"Je suis en vie\" depuis un " +"serveur, un service, ...)" #: templates/front/welcome.html:735 #, python-format @@ -510,6 +477,7 @@ msgid "" "healthchecks/healthchecks\">open source service. Setting up monitoring " "for your cron jobs only takes minutes. Start sleeping better at nights!" msgstr "" -"%(site_name)s est un service gratuit et open source . La configuration de la surveillance " -"de vos contrôles ne prend que quelques minutes. Restez serein!" +"%(site_name)s est un service gratuit et open source . La " +"configuration de la surveillance de vos contrôles ne prend que quelques " +"minutes. Restez serein!" diff --git a/templates/front/channels.html b/templates/front/channels.html index 8535680e..a841a219 100644 --- a/templates/front/channels.html +++ b/templates/front/channels.html @@ -186,6 +186,8 @@ {% if rw %}

Add More

    + + {% if enable_slack %}
  • Slack icon @@ -198,6 +200,9 @@ Add Integration {% endif %}
  • + {% endif %} + + {% if enable_email %}
  • Email icon @@ -206,7 +211,9 @@

    Get an email message when a check goes up or down.

    Add Integration
  • + {% endif %} + {% if enable_webhook %}
  • Webhook icon @@ -215,6 +222,7 @@

    Receive an HTTP callback when a check goes down.

    Add Integration
  • + {% endif %} {% if enable_apprise %}
  • @@ -260,6 +268,7 @@
  • {% endif %} + {% if enable_mattermost %}
  • Mattermost icon @@ -268,7 +277,9 @@

    High Trust Messaging for the Enterprise.

    Add Integration
  • + {% endif %} + {% if enable_msteams %}
  • Microsoft Teams @@ -277,7 +288,9 @@

    Chat and collaboration platform for Microsoft Office 365 customers.

    Add Integration
  • + {% endif %} + {% if enable_opsgenie %}
  • OpsGenie icon @@ -286,7 +299,9 @@

    Alerting & Incident Management Solution for Dev & Ops.

    Add Integration
  • + {% endif %} + {% if enable_pagerduty %}
  • PagerDuty icon @@ -300,7 +315,9 @@ Add Integration {% endif %}
  • + {% endif %} + {% if enable_pagertree %}
  • PagerTree icon @@ -309,6 +326,7 @@

    DevOps Incident Management - On-Call Schedules, Alerts, & Notifications.

    Add Integration
  • + {% endif %} {% if enable_call %}
  • @@ -321,6 +339,7 @@
  • {% endif %} + {% if enable_prometheus %}
  • Prometheus icon @@ -329,6 +348,7 @@

    Export check and tag status values to Prometheus.

    Add Integration
  • + {% endif %} {% if enable_pushbullet %}
  • @@ -385,6 +405,7 @@
  • {% endif %} + {% if enable_spike %}
  • Spike.sh icon @@ -393,6 +414,7 @@ Add Integration
  • + {% endif %} {% if enable_telegram %}
  • @@ -416,6 +438,7 @@
  • {% endif %} + {% if enable_victorops %}
  • VictorOps icon @@ -424,6 +447,7 @@

    On-call scheduling, alerting, and incident tracking.

    Add Integration
  • + {% endif %} {% if enable_whatsapp %}
  • @@ -436,6 +460,7 @@
  • {% endif %} + {% if enable_zulip %}
  • Zulip icon @@ -444,6 +469,7 @@

    Open-source group chat.

    Add Integration
  • + {% endif %}