def post(self, request, organization, alert_rule, alert_rule_trigger):
        """
        Create an action on a trigger
        """
        if not features.has(
                "organizations:incidents", organization, actor=request.user):
            raise ResourceDoesNotExist

        serializer = AlertRuleTriggerActionSerializer(
            context={
                "organization": organization,
                "alert_rule": alert_rule,
                "trigger": alert_rule_trigger,
                "access": request.access,
            },
            data=request.data,
        )

        if serializer.is_valid():
            try:
                action = serializer.save()
            except InvalidTriggerActionError as e:
                return Response(e.message, status=status.HTTP_400_BAD_REQUEST)
            return Response(serialize(action, request.user),
                            status=status.HTTP_201_CREATED)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
示例#2
0
 def run_fail_validation_test(self, params, errors):
     base_params = self.valid_params.copy()
     base_params.update(params)
     serializer = AlertRuleTriggerActionSerializer(context=self.context,
                                                   data=base_params)
     assert not serializer.is_valid()
     assert serializer.errors == errors
示例#3
0
 def _run_changed_fields_test(self, trigger, params, expected):
     serializer = AlertRuleTriggerActionSerializer(context=self.context,
                                                   instance=trigger,
                                                   data=params,
                                                   partial=True)
     assert serializer.is_valid(), serializer.errors
     assert serializer._remove_unchanged_fields(
         trigger, serializer.validated_data) == expected
示例#4
0
 def test_validation_no_params(self):
     serializer = AlertRuleTriggerActionSerializer(context=self.context, data={})
     assert not serializer.is_valid()
     field_is_required = ["This field is required."]
     assert serializer.errors == {
         "type": field_is_required,
         "targetType": field_is_required,
         "targetIdentifier": field_is_required,
     }
示例#5
0
    def test_slack(self):
        self.run_fail_validation_test(
            {
                "type":
                AlertRuleTriggerAction.get_registered_type(
                    AlertRuleTriggerAction.Type.SLACK).slug,
                "target_type":
                action_target_type_to_string[
                    AlertRuleTriggerAction.TargetType.USER],
                "target_identifier":
                "123",
            },
            {
                "targetType":
                ["Invalid target type for slack. Valid types are [specific]"]
            },
        )
        self.run_fail_validation_test(
            {
                "type":
                AlertRuleTriggerAction.get_registered_type(
                    AlertRuleTriggerAction.Type.SLACK).slug,
                "targetType":
                action_target_type_to_string[
                    AlertRuleTriggerAction.TargetType.SPECIFIC],
                "targetIdentifier":
                "123",
            },
            {"integration": ["Integration must be provided for slack"]},
        )
        integration = Integration.objects.create(
            external_id="1",
            provider="slack",
            metadata={
                "access_token": "xoxp-xxxxxxxxx-xxxxxxxxxx-xxxxxxxxxxxx"
            },
        )
        integration.add_organization(self.organization, self.user)

        base_params = self.valid_params.copy()
        base_params.update({
            "type":
            AlertRuleTriggerAction.get_registered_type(
                AlertRuleTriggerAction.Type.SLACK).slug,
            "targetType":
            action_target_type_to_string[
                AlertRuleTriggerAction.TargetType.SPECIFIC],
            "targetIdentifier":
            "123",
            "integration":
            six.text_type(integration.id),
        })
        serializer = AlertRuleTriggerActionSerializer(context=self.context,
                                                      data=base_params)
        assert serializer.is_valid()
        with self.assertRaises(serializers.ValidationError):
            serializer.save()
示例#6
0
    def test_valid_slack_channel_id(self):
        """
        Test that when a valid Slack channel ID is provided, we look up the channel name and validate it against the targetIdentifier.
        """
        integration = Integration.objects.create(
            external_id="1",
            provider="slack",
            metadata={
                "access_token": "xoxp-xxxxxxxxx-xxxxxxxxxx-xxxxxxxxxxxx"
            },
        )
        integration.add_organization(self.organization, self.user)

        base_params = self.valid_params.copy()
        base_params.update({
            "type":
            AlertRuleTriggerAction.get_registered_type(
                AlertRuleTriggerAction.Type.SLACK).slug,
            "targetType":
            action_target_type_to_string[
                AlertRuleTriggerAction.TargetType.SPECIFIC],
            "targetIdentifier":
            "merp",
            "integration":
            str(integration.id),
        })
        context = self.context.copy()
        context.update({"input_channel_id": "CSVK0921"})
        responses.add(
            method=responses.GET,
            url="https://slack.com/api/conversations.info",
            status=200,
            content_type="application/json",
            body=json.dumps({
                "ok": "true",
                "channel": {
                    "name": "merp",
                    "id": "CSVK0921"
                }
            }),
        )
        serializer = AlertRuleTriggerActionSerializer(context=context,
                                                      data=base_params)
        assert serializer.is_valid()

        serializer.save()

        # # Make sure the action was created.
        alert_rule_trigger_actions = list(
            AlertRuleTriggerAction.objects.filter(integration=integration))
        assert len(alert_rule_trigger_actions) == 1
示例#7
0
    def test_invalid_slack_channel_id(self):
        """
        Test that an invalid Slack channel ID is detected and blocks the action from being saved.
        """
        integration = Integration.objects.create(
            external_id="1",
            provider="slack",
            metadata={
                "access_token": "xoxp-xxxxxxxxx-xxxxxxxxxx-xxxxxxxxxxxx"
            },
        )
        integration.add_organization(self.organization, self.user)

        base_params = self.valid_params.copy()
        base_params.update({
            "type":
            AlertRuleTriggerAction.get_registered_type(
                AlertRuleTriggerAction.Type.SLACK).slug,
            "targetType":
            action_target_type_to_string[
                AlertRuleTriggerAction.TargetType.SPECIFIC],
            "targetIdentifier":
            "merp",
            "integration":
            str(integration.id),
        })
        context = self.context.copy()
        context.update({"input_channel_id": "M40W931"})
        responses.add(
            method=responses.GET,
            url="https://slack.com/api/conversations.info",
            status=200,
            content_type="application/json",
            body=json.dumps({
                "ok": False,
                "error": "channel_not_found"
            }),
        )
        serializer = AlertRuleTriggerActionSerializer(context=context,
                                                      data=base_params)
        assert not serializer.is_valid()

        # # Make sure the action was not created.
        alert_rule_trigger_actions = list(
            AlertRuleTriggerAction.objects.filter(integration=integration))
        assert len(alert_rule_trigger_actions) == 0
示例#8
0
    def put(self, request, organization, alert_rule, alert_rule_trigger,
            alert_rule_trigger_action):
        serializer = AlertRuleTriggerActionSerializer(
            context={
                "organization": organization,
                "alert_rule": alert_rule,
                "alert_rule_trigger": alert_rule_trigger,
                "access": request.access,
            },
            instance=alert_rule_trigger_action,
            data=request.data,
            partial=True,
        )

        if serializer.is_valid():
            trigger = serializer.save()
            return Response(serialize(trigger, request.user),
                            status=status.HTTP_200_OK)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
示例#9
0
    def test_create_and_update_sentry_app_action_success(self):
        responses.add(
            method=responses.POST,
            url="https://example.com/sentry/alert-rule",
            status=200,
            json={},
        )

        serializer = AlertRuleTriggerActionSerializer(
            context=self.context,
            data={
                "type":
                AlertRuleTriggerAction.get_registered_type(
                    AlertRuleTriggerAction.Type.SENTRY_APP).slug,
                "target_type":
                action_target_type_to_string[
                    AlertRuleTriggerAction.TargetType.SENTRY_APP],
                "target_identifier":
                "1",
                "sentry_app":
                self.sentry_app.id,
                "sentry_app_config": {
                    "channel": "#general"
                },
                "sentry_app_installation_uuid":
                self.sentry_app_installation.uuid,
            },
        )
        assert serializer.is_valid()

        # Create action
        serializer.save()

        # # Make sure the action was created.
        alert_rule_trigger_actions = list(
            AlertRuleTriggerAction.objects.filter(sentry_app=self.sentry_app))
        assert len(alert_rule_trigger_actions) == 1

        # Update action
        serializer = AlertRuleTriggerActionSerializer(
            context=self.context,
            data={
                "type":
                AlertRuleTriggerAction.get_registered_type(
                    AlertRuleTriggerAction.Type.SENTRY_APP).slug,
                "target_type":
                action_target_type_to_string[
                    AlertRuleTriggerAction.TargetType.SENTRY_APP],
                "target_identifier":
                "1",
                "sentry_app":
                self.sentry_app.id,
                "sentry_app_config": {
                    "channel": "#announcements"
                },
                "sentry_app_installation_uuid":
                self.sentry_app_installation.uuid,
            },
            instance=alert_rule_trigger_actions[0],
        )

        assert serializer.is_valid()

        # Update action
        serializer.save()

        alert_rule_trigger_action = AlertRuleTriggerAction.objects.get(
            sentry_app=self.sentry_app)

        # Make sure the changes got applied
        assert alert_rule_trigger_action.sentry_app_config == {
            "channel": "#announcements"
        }