예제 #1
0
    def test_sms_gateway_returns_exception(self, mock_post_request,
                                           mock_log_error):
        mock_post_request.side_effect = Exception
        sms_sender = SMSSender(text_message="test sms",
                               phone_numbers=[31612345678])

        assert sms_sender.send_sms() is False
        mock_log_error.assert_called_once_with(
            "Sending a SMS is failed to [31612345678] with this message: test sms"
        )
예제 #2
0
    def test_sms_gateway_returns_bad_request_error(self, mock_post_request,
                                                   mock_log_error):
        mock_post_request.return_value = mock.MagicMock(
            status_code=400,
            json=mock.MagicMock(
                return_value={
                    "error": {
                        "code": "105",
                        "description": "Invalid Destination Address",
                    }
                }))

        sms_sender = SMSSender(text_message="test sms",
                               phone_numbers=[31612345678])
        assert sms_sender.send_sms() is True
        mock_log_error.assert_called_once_with(
            "Sending a SMS to [31612345678] with this message: 'test sms' returned an error. "
            "Error code: 105, Error description: Invalid Destination Address")
예제 #3
0
    def handle(self, email_alert, push_notification_alert, sms_alert, history_filename, *args, **options):
        results = ['-', ] * len(DOMAINS)
        not_healthy = []
        for i in range(len(DOMAINS)):
            domain = DOMAINS[i]
            try:
                req = requests.get('http://' + domain, verify=False)
                req.raise_for_status()
            except:
                logger.exception('domain %r not healthy' % domain)
                not_healthy.append(domain)
                continue
            results[i] = '+'

        with open(history_filename, 'at') as fout:
            fout.write((''.join(results)) + '\n')

        if '-' in results:
            domains_txt_report = prepare_report(history_filename)

            if email_alert:
                for email_address in settings.ALERT_EMAIL_RECIPIENTS:
                    try:
                        send_email(
                            subject='ZENAIDA ALERT: %s' % (', '.join(not_healthy)),
                            text_content=domains_txt_report,
                            from_email=settings.EMAIL_ADMIN,
                            to_email=email_address,
                        )
                    except:
                        logger.exception('alert email send failed')

            if sms_alert:
                try:
                    SMSSender(
                        text_message='ZENAIDA ALERT: %s' % (', '.join(not_healthy))
                    ).send_sms()
                except:
                    logger.exception('alert sms send failed')

            if push_notification_alert:
                try:
                    PushNotificationService(
                        notification_message='ZENAIDA ALERT: %s' % (', '.join(not_healthy))
                    ).push()
                except:
                    logger.exception('alert push notification send failed')
예제 #4
0
def run(history_filename,
        email_alert=False,
        push_notification_alert=False,
        sms_alert=False):
    """
    Runs sequence of smoke tests for given hosts from `settings.SMOKETEST_HOSTS` list and fire
    alerts if needed.
    """

    health_results = [
        "-",
    ] * len(settings.SMOKETEST_HOSTS)
    for index, host in enumerate(settings.SMOKETEST_HOSTS):
        method, host = get_method_host(host)
        if single_smoke_test(host, method):
            health_results[index] = "+"

    # If file is empty, write health results for the first time.
    try:
        file_exists_but_empty = os.stat(history_filename).st_size == 0
        file_does_not_exist = False
    except Exception:
        file_does_not_exist = True
        file_exists_but_empty = False

    if file_exists_but_empty or file_does_not_exist:
        with open(history_filename, "w") as health_check_file:
            health_check_file.write("\n".join(health_results))
        return

    unhealthy_hosts = []
    hosts_to_be_notified = []
    updated_lines_of_file = ""
    all_hosts_conf = settings.SMOKETEST_HOSTS_CONFIG.get('*', {}) or {}
    with open(history_filename, 'r') as health_check_file:
        lines_of_files = health_check_file.readlines()
        for index, host in enumerate(settings.SMOKETEST_HOSTS):
            host_conf = settings.SMOKETEST_HOSTS_CONFIG.get(host, {}) or {}
            if index < len(lines_of_files):
                # Add health of the host to its line.
                updated_line = lines_of_files[index].strip(
                ) + f"{health_results[index]}\n"
                # Do not make any line more than 20 characters.
                if len(updated_line) == 20:
                    updated_line = updated_line[1:]
            else:
                # If there is new host is added after file was created, add new line with the health result
                updated_line = f"{health_results[index]}\n"

            updated_lines_of_file += updated_line
            # If last X amount of health checks are negative, add that host to the unhealthy hosts group.
            if updated_line.split('\n')[0].endswith(
                    settings.SMOKETEST_MAXIMUM_UNAVAILABLE_AMOUNT * '-'):
                unhealthy_hosts.append(settings.SMOKETEST_HOSTS[index])
                if host_conf.get('notify_once') or all_hosts_conf.get(
                        'notify_once'):
                    # Raise an alert only one time
                    if updated_line.split('\n')[0].endswith(
                            '+' +
                            settings.SMOKETEST_MAXIMUM_UNAVAILABLE_AMOUNT *
                            '-'):
                        hosts_to_be_notified.append(
                            settings.SMOKETEST_HOSTS[index])

    # Update the file with the new values.
    with open(history_filename, "w") as health_check_file:
        health_check_file.write(updated_lines_of_file)

    alerts = []
    if hosts_to_be_notified:
        hosts_txt_report = prepare_report(history_filename)

        if email_alert:
            for email_address in settings.ALERT_EMAIL_RECIPIENTS:
                alerts.append((
                    'email',
                    email_address,
                    hosts_txt_report,
                ))
                try:
                    send_email(
                        subject='ZENAIDA ALERT: %s' %
                        (', '.join(unhealthy_hosts)),
                        text_content=hosts_txt_report,
                        from_email=settings.EMAIL_ADMIN,
                        to_email=email_address,
                    )
                except:
                    logger.exception('alert EMAIL sending failed')

        if sms_alert:
            alerts.append((
                'sms',
                '',
                hosts_txt_report,
            ))
            try:
                SMSSender(text_message='ZENAIDA ALERT: %s' %
                          (', '.join(unhealthy_hosts))).send_sms()
            except:
                logger.exception('alert SMS sending failed')

        if push_notification_alert:
            alerts.append((
                'push',
                '',
                hosts_txt_report,
            ))
            try:
                PushNotificationService(
                    notification_message='ZENAIDA ALERT: %s' %
                    (', '.join(unhealthy_hosts))).push()
            except:
                logger.exception('alert PUSH notification sending failed')

    return alerts
예제 #5
0
 def test_successful_send_sms(self, mock_post_request):
     mock_post_request.return_value = mock.MagicMock(status_code=202)
     sms_sender = SMSSender(text_message="test sms",
                            phone_numbers=[31612345678])
     assert sms_sender.send_sms() is True