コード例 #1
0
    def _create_proto_internal(
        cls,
        conn,
        ctx,
        name,
        monitored_entity_id,
        alerter,
        summary_sample_query,
        notification_channels,
        created_at_millis,
        updated_at_millis,
        last_evaluated_at_millis,
        # TODO: should we allow `status` and `violating samples` on create?
    ):
        msg = _AlertService.CreateAlertRequest(alert=_AlertService.Alert(
            name=name,
            monitored_entity_id=monitored_entity_id,
            created_at_millis=created_at_millis,
            updated_at_millis=updated_at_millis,
            last_evaluated_at_millis=last_evaluated_at_millis,
            notification_channels={
                channel.id: True
                for channel in notification_channels
            },
            sample_find_base=summary_sample_query._to_proto_request(),
            alerter_type=alerter._TYPE,
        ), )

        field = getattr(msg.alert, alerter._get_alert_field())
        field.CopyFrom(alerter._as_proto())

        endpoint = "/api/v1/alerts/createAlert"
        response = conn.make_proto_request("POST", endpoint, body=msg)
        alert_msg = conn.must_proto_response(response, _AlertService.Alert)
        return alert_msg
コード例 #2
0
    def add_notification_channels(self, notification_channels):
        """
        Add notification channels to this alert.

        Parameters
        ----------
        notification_channels : list of :class:`~verta.monitoring.notification_channel.entities.NotificationChannel`
            Notification channels.

        Examples
        --------
        .. code-block:: python

            from verta.monitoring.notification_channel import SlackNotificationChannel

            channels = Client().monitoring.notification_channels
            channel = notification_channels.create(
                "Slack alerts",
                SlackNotificationChannel("https://hooks.slack.com/services/.../.../......"),
            )

            alert.add_notification_channels([channel])

        """
        for channel in notification_channels:
            self._validate_notification_channel(channel)

        alert_msg = _AlertService.Alert()
        self._fetch_with_no_cache()
        alert_msg.CopyFrom(self._msg)
        alert_msg.notification_channels.update(
            {channel.id: True
             for channel in notification_channels})

        self._update(alert_msg)
コード例 #3
0
    def delete(self, channels):
        """
        Delete the given notification channels in a single request.

        Parameters
        ----------
        channels : list of :class:`NotificationChannel`
            Notification channels.

        Returns
        -------
        bool
            ``True`` if the delete was successful.

        Raises
        ------
        :class:`requests.HTTPError`
            If the delete failed.

        """
        channel_ids = arg_handler.extract_ids(channels)
        msg = _AlertService.DeleteNotificationChannelRequest(ids=channel_ids)
        endpoint = "/api/v1/alerts/deleteNotificationChannel"
        response = self._conn.make_proto_request("DELETE", endpoint, body=msg)
        self._conn.must_response(response)
        return True
コード例 #4
0
    def list(self, workspace=None):
        """
        Return accesible notification channels.

        Parameters
        ----------
        workspace : str, optional
            Workspace from which to list notification channels. Defaults to the
            client's default workspace.

        Returns
        -------
        list of :class:`NotificationChannel`
            Notification channels.

        """
        msg = _AlertService.FindNotificationChannelRequest(
            page_number=1,
            page_limit=-1,
            workspace_name=workspace,
        )
        endpoint = "/api/v1/alerts/findNotificationChannel"
        response = self._conn.make_proto_request("POST", endpoint, body=msg)
        channels = self._conn.must_proto_response(response, msg.Response).channels
        return [
            NotificationChannel(self._conn, self._conf, channel) for channel in channels
        ]
コード例 #5
0
    def _create_proto_internal(
        cls,
        conn,
        ctx,
        name,
        channel,
        workspace,
        created_at_millis,
        updated_at_millis,
    ):
        msg = _AlertService.CreateNotificationChannelRequest(
            name=name,
            created_at_millis=created_at_millis,
            updated_at_millis=updated_at_millis,
            workspace_name=workspace,
            type=channel._TYPE,
        )
        if msg.type == _AlertService.NotificationChannelTypeEnum.SLACK:
            msg.slack_webhook.CopyFrom(channel._as_proto())
        else:
            raise ValueError(
                "unrecognized notification channel type enum value {}".format(
                    msg.alert.alerter_type
                )
            )

        endpoint = "/api/v1/alerts/createNotificationChannel"
        response = conn.make_proto_request("POST", endpoint, body=msg)
        notification_channel_msg = conn.must_proto_response(
            response,
            _AlertService.NotificationChannel,
        )
        return notification_channel_msg
コード例 #6
0
    def delete(self, alerts):
        """
        Delete the given alerts in a single request.

        Parameters
        ----------
        list of :class:`Alert`
            Alerts.

        Returns
        -------
        bool
            ``True`` if the delete was successful.

        Raises
        ------
        :class:`requests.HTTPError`
            If the delete failed.

        """
        alert_ids = arg_handler.extract_ids(alerts)
        msg = _AlertService.DeleteAlertRequest(ids=alert_ids)
        endpoint = "/api/v1/alerts/deleteAlert"
        response = self._conn.make_proto_request("DELETE", endpoint, body=msg)
        self._conn.must_response(response)
        return True
コード例 #7
0
 def history(self):
     # TODO: implement lazy list and pagination
     msg = _AlertService.ListAlertHistoryRequest(id=self.id)
     endpoint = "/api/v1/alerts/listAlertHistory"
     response = self._conn.make_proto_request("POST", endpoint, body=msg)
     history = self._conn.must_proto_response(response,
                                              msg.Response).history
     return list(map(AlertHistoryItem, history))
コード例 #8
0
    def test_sample_find_base_preserves_aggregation_flags(self, summary):
        """alert.summary_sample_query fully represents sample_find_base.

        The client used to drop `store_aggregate` and `allow_aggregate_samples`
        because of how :class:`SummarySampleQuery` was written.
        """
        # define sample_find_base
        sample_find_base = _SummaryService.FindSummarySampleRequest(
            filter=_SummaryService.FilterQuerySummarySample(
                find_summaries=summary.alerts._build_summary_query(
                )._to_proto_request(), ),
            page_number=1,
            page_limit=-1,
            # following two fields are not exposed through client
            store_aggregate=True,
            allow_aggregate_samples=True,
        )

        # create alert directly via REST API
        alerter = FixedAlerter(comparison.GreaterThan(0.7))
        msg = _AlertService.CreateAlertRequest(alert=_AlertService.Alert(
            name=_utils.generate_default_name(),
            monitored_entity_id=summary._monitored_entity_id,
            sample_find_base=sample_find_base,
            alerter_type=alerter._TYPE,
            alerter_fixed=alerter._as_proto(),
        ), )
        endpoint = "/api/v1/alerts/createAlert"
        response = summary.alerts._conn.make_proto_request("POST",
                                                           endpoint,
                                                           body=msg)
        alert_id = summary.alerts._conn.must_proto_response(
            response,
            _AlertService.Alert,
        ).id

        # retrieve alert via client and verify that fields are preserved
        alert = summary.alerts.get(id=alert_id)
        retrieved_sample_find_base = alert.summary_sample_query._to_proto_request(
        )
        assert retrieved_sample_find_base.store_aggregate
        assert retrieved_sample_find_base.allow_aggregate_samples

        # verify full equality, minus time field added by alert
        retrieved_sample_find_base.filter.ClearField("created_at_after_millis")
        assert retrieved_sample_find_base == sample_find_base
コード例 #9
0
    def test_create(self, comparison, threshold):
        alerter = FixedAlerter(comparison(threshold))

        msg = _AlertService.AlertFixed(
            threshold=threshold,
            operator=comparison._OPERATOR,
        )
        assert alerter._as_proto() == msg
コード例 #10
0
    def _update_last_evaluated_at(self, last_evaluated_at=None):
        if last_evaluated_at is None:
            last_evaluated_at = time_utils.now()

        millis = time_utils.epoch_millis(last_evaluated_at)
        alert_msg = _AlertService.Alert(last_evaluated_at_millis=millis, )

        self._update(alert_msg)
コード例 #11
0
 def _update(self, alert_msg):
     alert_msg.id = self.id
     msg = _AlertService.UpdateAlertRequest(alert=alert_msg)
     endpoint = "/api/v1/alerts/updateAlert"
     response = self._conn.make_proto_request("POST", endpoint, body=msg)
     self._conn.must_response(response)
     self._clear_cache()
     return True
コード例 #12
0
    def test_from_proto(self, comparison, threshold):
        msg = _AlertService.AlertFixed(
            threshold=threshold,
            operator=comparison._OPERATOR,
        )

        alerter = _Alerter._from_proto(msg)
        assert type(alerter) is FixedAlerter
        assert alerter._as_proto() == msg
コード例 #13
0
    def test_create(self, comparison, threshold, reference_sample_id):
        alerter = ReferenceAlerter(comparison(threshold), reference_sample_id)

        msg = _AlertService.AlertReference(
            threshold=threshold,
            reference_sample_id=reference_sample_id,
            operator=comparison._OPERATOR,
        )
        assert alerter._as_proto() == msg
コード例 #14
0
ファイル: _status.py プロジェクト: martowu/modeldb
    def _to_proto_request(self):
        msg = _AlertService.UpdateAlertStatusRequest(
            status=self._ALERT_STATUS, )
        if self._sample_ids:
            msg.ok_sample_ids.extend(self._sample_ids)
        else:
            msg.clear_alerting_sample_ids = True

        return msg
コード例 #15
0
    def test_to_proto_request_no_sample_ids(self):
        status = Ok()
        proto_request = status._to_proto_request()

        assert proto_request == _AlertService.UpdateAlertStatusRequest(
            status=_AlertService.AlertStatusEnum.OK,
            alerting_sample_ids=[],
            ok_sample_ids=[],
            clear_alerting_sample_ids=True,
        )
コード例 #16
0
    def test_to_proto_request(self, sample_ids):
        status = Ok(sample_ids)
        proto_request = status._to_proto_request()

        assert proto_request == _AlertService.UpdateAlertStatusRequest(
            status=_AlertService.AlertStatusEnum.OK,
            alerting_sample_ids=[],
            ok_sample_ids=sample_ids,
            clear_alerting_sample_ids=False,
        )
コード例 #17
0
ファイル: test_alerter.py プロジェクト: vishalbelsare/modeldb
 def test_from_proto(self, lower_bound, upper_bound,
                     alert_if_outside_range):
     msg = _AlertService.AlertRange(
         lower_bound=lower_bound,
         upper_bound=upper_bound,
         alert_if_outside_range=alert_if_outside_range,
     )
     alerter = _Alerter._from_proto(msg)
     assert type(alerter) is RangeAlerter
     assert alerter._as_proto() == msg
コード例 #18
0
    def test_from_proto(self, comparison, threshold, reference_sample_id):
        msg = _AlertService.AlertReference(
            threshold=threshold,
            reference_sample_id=reference_sample_id,
            operator=comparison._OPERATOR,
        )

        alerter = _Alerter._from_proto(msg)
        assert type(alerter) is ReferenceAlerter
        assert alerter._as_proto() == msg
コード例 #19
0
ファイル: test_alerter.py プロジェクト: vishalbelsare/modeldb
 def test_to_proto(self, lower_bound, upper_bound, alert_if_outside_range):
     alerter = RangeAlerter(
         lower_bound=lower_bound,
         upper_bound=upper_bound,
         alert_if_outside_range=alert_if_outside_range,
     )
     msg = _AlertService.AlertRange(
         lower_bound=lower_bound,
         upper_bound=upper_bound,
         alert_if_outside_range=alert_if_outside_range,
     )
     assert alerter._as_proto() == msg
コード例 #20
0
 def _get_proto_by_id(cls, conn, id):
     msg = _AlertService.FindAlertRequest(
         ids=[int(id)],
         page_number=1,
         page_limit=-1,
     )
     endpoint = "/api/v1/alerts/findAlert"
     response = conn.make_proto_request("POST", endpoint, body=msg)
     alerts = conn.must_proto_response(response, msg.Response).alerts
     if len(alerts) > 1:
         warnings.warn(
             "unexpectedly found multiple alerts with the same name and"
             " monitored entity ID")
     return alerts[0]
コード例 #21
0
 def _get_proto_by_id(cls, conn, id):
     msg = _AlertService.FindNotificationChannelRequest(
         ids=[int(id)],
         page_number=1,
         page_limit=-1,
     )
     endpoint = "/api/v1/alerts/findNotificationChannel"
     response = conn.make_proto_request("POST", endpoint, body=msg)
     channels = conn.must_proto_response(response, msg.Response).channels
     if len(channels) > 1:
         warnings.warn(
             "unexpectedly found multiple notification channels with ID"
             " {}".format(id)
         )
     if channels:
         return channels[0]
     else:
         return None
コード例 #22
0
    def delete(self):
        """
        Delete this alert.

        Returns
        -------
        bool
            ``True`` if the delete was successful.

        Raises
        ------
        :class:`requests.HTTPError`
            If the delete failed.

        """
        msg = _AlertService.DeleteAlertRequest(ids=[self.id])
        endpoint = "/api/v1/alerts/deleteAlert"
        response = self._conn.make_proto_request("DELETE", endpoint, body=msg)
        self._conn.must_response(response)
        return True
コード例 #23
0
 def _as_proto(self):
     return _AlertService.AlertFixed(
         threshold=self._comparison.value,
         operator=self._comparison._operator_as_proto(),
     )
コード例 #24
0
 def _as_proto(self):
     return _AlertService.AlertReference(
         threshold=self._comparison.value,
         reference_sample_id=self._reference_sample_id,
         operator=self._comparison._operator_as_proto(),
     )
コード例 #25
0
    def test_create(self, webhook_url):
        slack_channel = SlackNotificationChannel(webhook_url)
        assert slack_channel._url == webhook_url

        msg = _AlertService.NotificationChannelSlackWebhook(url=webhook_url, )
        assert slack_channel._as_proto() == msg
コード例 #26
0
ファイル: _status.py プロジェクト: martowu/modeldb
 def _to_proto_request(self):
     return _AlertService.UpdateAlertStatusRequest(
         status=self._ALERT_STATUS,
         alerting_sample_ids=self._sample_ids,
     )
コード例 #27
0
 def _as_proto(self):
     return _AlertService.AlertRange(
         lower_bound=self.lower_bound,
         upper_bound=self.upper_bound,
         alert_if_outside_range=self.alert_if_outside_range,
     )
コード例 #28
0
 def __init__(self, conn, conf):
     super(AlertsPaginatedIterable, self).__init__(
         conn,
         conf,
         _AlertService.FindAlertRequest(),
     )