diff --git a/dev/.env.dev.example b/dev/.env.dev.example index 07258b08..9a041dc2 100644 --- a/dev/.env.dev.example +++ b/dev/.env.dev.example @@ -20,7 +20,6 @@ BASE_URL=http://localhost:8080 FEATURE_TELEGRAM_INTEGRATION_ENABLED=True FEATURE_SLACK_INTEGRATION_ENABLED=True -FEATURE_EXTRA_MESSAGING_BACKENDS_ENABLED= SLACK_INSTALL_RETURN_REDIRECT_HOST=http://localhost:8080 SOCIAL_AUTH_REDIRECT_IS_HTTPS=False diff --git a/engine/apps/api/tests/test_escalation_policy.py b/engine/apps/api/tests/test_escalation_policy.py index 07ec8d39..bbb75329 100644 --- a/engine/apps/api/tests/test_escalation_policy.py +++ b/engine/apps/api/tests/test_escalation_policy.py @@ -1,7 +1,6 @@ from unittest.mock import patch import pytest -from django.conf import settings from django.db.models import Max from django.urls import reverse from django.utils.timezone import timedelta @@ -915,23 +914,17 @@ def test_escalation_policy_filter_by_slack_channel( @pytest.mark.django_db -@pytest.mark.parametrize("enabled", [True, False]) def test_escalation_policy_escalation_options_webhooks( make_organization_and_user_with_plugin_token, make_user_auth_headers, - enabled, ): _, user, token = make_organization_and_user_with_plugin_token() client = APIClient() url = reverse("api-internal:escalation_policy-escalation-options") - settings.FEATURE_WEBHOOKS_2_ENABLED = enabled - response = client.get(url, format="json", **make_user_auth_headers(user, token)) returned_options = [option["value"] for option in response.json()] - if enabled: - assert EscalationPolicy.STEP_TRIGGER_CUSTOM_WEBHOOK in returned_options - else: - assert EscalationPolicy.STEP_TRIGGER_CUSTOM_WEBHOOK not in returned_options + + assert EscalationPolicy.STEP_TRIGGER_CUSTOM_WEBHOOK in returned_options diff --git a/engine/apps/api/tests/test_features.py b/engine/apps/api/tests/test_features.py index 9346abff..58901713 100644 --- a/engine/apps/api/tests/test_features.py +++ b/engine/apps/api/tests/test_features.py @@ -10,7 +10,6 @@ from apps.api.views.features import ( FEATURE_LIVE_SETTINGS, FEATURE_SLACK, FEATURE_TELEGRAM, - FEATURE_WEB_SCHEDULES, ) @@ -38,7 +37,6 @@ def test_features_view( ("FEATURE_SLACK_INTEGRATION_ENABLED", FEATURE_SLACK), ("FEATURE_TELEGRAM_INTEGRATION_ENABLED", FEATURE_TELEGRAM), ("FEATURE_LIVE_SETTINGS_ENABLED", FEATURE_LIVE_SETTINGS), - ("FEATURE_WEB_SCHEDULES_ENABLED", FEATURE_WEB_SCHEDULES), ], ) def test_core_features_switch( diff --git a/engine/apps/api/tests/test_webhooks.py b/engine/apps/api/tests/test_webhooks.py index 589630be..4e7fc0e2 100644 --- a/engine/apps/api/tests/test_webhooks.py +++ b/engine/apps/api/tests/test_webhooks.py @@ -1,5 +1,4 @@ import json -from unittest import mock from unittest.mock import patch import pytest @@ -116,9 +115,8 @@ def test_get_detail_webhook(webhook_internal_api_setup, make_user_auth_headers): assert response.json() == expected_payload -@mock.patch("apps.api.views.webhooks.WebhooksView.check_webhooks_2_enabled") @pytest.mark.django_db -def test_create_webhook(mocked_check_webhooks_2_enabled, webhook_internal_api_setup, make_user_auth_headers): +def test_create_webhook(webhook_internal_api_setup, make_user_auth_headers): user, token, webhook = webhook_internal_api_setup client = APIClient() url = reverse("api-internal:webhooks-list") @@ -162,7 +160,6 @@ def test_create_webhook(mocked_check_webhooks_2_enabled, webhook_internal_api_se assert webhook.user == user -@mock.patch("apps.api.views.webhooks.WebhooksView.check_webhooks_2_enabled") @pytest.mark.django_db @pytest.mark.parametrize( "field_name,value", @@ -173,9 +170,7 @@ def test_create_webhook(mocked_check_webhooks_2_enabled, webhook_internal_api_se ("url", "https://myserver/{{ alert_payload.id }}/triggered"), ], ) -def test_create_valid_templated_field( - mocked_check_webhooks_2_enabled, webhook_internal_api_setup, make_user_auth_headers, field_name, value -): +def test_create_valid_templated_field(webhook_internal_api_setup, make_user_auth_headers, field_name, value): user, token, webhook = webhook_internal_api_setup client = APIClient() url = reverse("api-internal:webhooks-list") @@ -222,7 +217,6 @@ def test_create_valid_templated_field( assert response.json() == expected_response -@mock.patch("apps.api.views.webhooks.WebhooksView.check_webhooks_2_enabled") @pytest.mark.django_db @pytest.mark.parametrize( "field_name,value", @@ -233,9 +227,7 @@ def test_create_valid_templated_field( ("url", "invalid-url/{{}}/triggered"), ], ) -def test_create_invalid_templated_field( - mocked_check_webhooks_2_enabled, webhook_internal_api_setup, make_user_auth_headers, field_name, value -): +def test_create_invalid_templated_field(webhook_internal_api_setup, make_user_auth_headers, field_name, value): user, token, webhook = webhook_internal_api_setup client = APIClient() url = reverse("api-internal:webhooks-list") @@ -252,9 +244,8 @@ def test_create_invalid_templated_field( assert response.status_code == status.HTTP_400_BAD_REQUEST -@mock.patch("apps.api.views.webhooks.WebhooksView.check_webhooks_2_enabled") @pytest.mark.django_db -def test_update_webhook(mocked_check_webhooks_2_enabled, webhook_internal_api_setup, make_user_auth_headers): +def test_update_webhook(webhook_internal_api_setup, make_user_auth_headers): user, token, webhook = webhook_internal_api_setup client = APIClient() url = reverse("api-internal:webhooks-detail", kwargs={"pk": webhook.public_primary_key}) @@ -273,9 +264,8 @@ def test_update_webhook(mocked_check_webhooks_2_enabled, webhook_internal_api_se assert updated_instance.name == "github_button_updated" -@mock.patch("apps.api.views.webhooks.WebhooksView.check_webhooks_2_enabled") @pytest.mark.django_db -def test_delete_webhook(mocked_check_webhooks_2_enabled, webhook_internal_api_setup, make_user_auth_headers): +def test_delete_webhook(webhook_internal_api_setup, make_user_auth_headers): user, token, webhook = webhook_internal_api_setup client = APIClient() url = reverse("api-internal:webhooks-detail", kwargs={"pk": webhook.public_primary_key}) @@ -548,9 +538,8 @@ def test_webhook_preview_template( assert response.data["preview"] == expected_result -@mock.patch("apps.api.views.webhooks.WebhooksView.check_webhooks_2_enabled") @pytest.mark.django_db -def test_webhook_field_masking(mock_check_webhooks_2_enabled, webhook_internal_api_setup, make_user_auth_headers): +def test_webhook_field_masking(webhook_internal_api_setup, make_user_auth_headers): user, token, webhook = webhook_internal_api_setup client = APIClient() url = reverse("api-internal:webhooks-list") @@ -600,9 +589,8 @@ def test_webhook_field_masking(mock_check_webhooks_2_enabled, webhook_internal_a assert webhook.user == user -@mock.patch("apps.api.views.webhooks.WebhooksView.check_webhooks_2_enabled") @pytest.mark.django_db -def test_webhook_copy(mock_check_webhooks_2_enabled, webhook_internal_api_setup, make_user_auth_headers): +def test_webhook_copy(webhook_internal_api_setup, make_user_auth_headers): user, token, webhook = webhook_internal_api_setup client = APIClient() url = reverse("api-internal:webhooks-list") diff --git a/engine/apps/api/views/escalation_policy.py b/engine/apps/api/views/escalation_policy.py index fd9f5d6d..fccc6dca 100644 --- a/engine/apps/api/views/escalation_policy.py +++ b/engine/apps/api/views/escalation_policy.py @@ -114,10 +114,7 @@ class EscalationPolicyView( def escalation_options(self, request): choices = [] for step in EscalationPolicy.INTERNAL_API_STEPS: - if step == EscalationPolicy.STEP_TRIGGER_CUSTOM_WEBHOOK and not settings.FEATURE_WEBHOOKS_2_ENABLED: - continue - - if step == EscalationPolicy.STEP_TRIGGER_CUSTOM_BUTTON and settings.FEATURE_WEBHOOKS_2_ENABLED: + if step == EscalationPolicy.STEP_TRIGGER_CUSTOM_BUTTON: continue verbal = EscalationPolicy.INTERNAL_API_STEPS_TO_VERBAL_MAP[step] diff --git a/engine/apps/api/views/features.py b/engine/apps/api/views/features.py index 4d46e5d2..93fcba78 100644 --- a/engine/apps/api/views/features.py +++ b/engine/apps/api/views/features.py @@ -10,8 +10,6 @@ FEATURE_TELEGRAM = "telegram" FEATURE_LIVE_SETTINGS = "live_settings" FEATURE_GRAFANA_CLOUD_NOTIFICATIONS = "grafana_cloud_notifications" FEATURE_GRAFANA_CLOUD_CONNECTION = "grafana_cloud_connection" -FEATURE_WEB_SCHEDULES = "web_schedules" -FEATURE_WEBHOOKS2 = "webhooks2" class FeaturesAPIView(APIView): @@ -26,8 +24,6 @@ class FeaturesAPIView(APIView): return Response(self._get_enabled_features(request)) def _get_enabled_features(self, request): - from apps.base.models import DynamicSetting - enabled_features = [] if settings.FEATURE_SLACK_INTEGRATION_ENABLED: @@ -44,22 +40,4 @@ class FeaturesAPIView(APIView): if live_settings.GRAFANA_CLOUD_NOTIFICATIONS_ENABLED: enabled_features.append(FEATURE_GRAFANA_CLOUD_NOTIFICATIONS) - if settings.FEATURE_WEB_SCHEDULES_ENABLED: - enabled_features.append(FEATURE_WEB_SCHEDULES) - else: - # allow enabling web schedules per org, independently of global status flag - enabled_web_schedules_orgs = DynamicSetting.objects.get_or_create( - name="enabled_web_schedules_orgs", - defaults={ - "json_value": { - "org_ids": [], - } - }, - )[0] - if request.auth.organization.pk in enabled_web_schedules_orgs.json_value["org_ids"]: - enabled_features.append(FEATURE_WEB_SCHEDULES) - - if settings.FEATURE_WEBHOOKS_2_ENABLED: - enabled_features.append(FEATURE_WEBHOOKS2) - return enabled_features diff --git a/engine/apps/api/views/webhooks.py b/engine/apps/api/views/webhooks.py index 3b186852..8e61bf63 100644 --- a/engine/apps/api/views/webhooks.py +++ b/engine/apps/api/views/webhooks.py @@ -1,7 +1,6 @@ import json -from django.conf import settings -from django.core.exceptions import ObjectDoesNotExist, PermissionDenied +from django.core.exceptions import ObjectDoesNotExist from django_filters import rest_framework as filters from rest_framework import status from rest_framework.decorators import action @@ -91,22 +90,6 @@ class WebhooksView(TeamFilteringMixin, PublicPrimaryKeyMixin, ModelViewSet): return obj - def perform_create(self, serializer): - self.check_webhooks_2_enabled() - serializer.save() - - def perform_update(self, serializer): - self.check_webhooks_2_enabled() - serializer.save() - - def perform_destroy(self, instance): - self.check_webhooks_2_enabled() - instance.delete() - - def check_webhooks_2_enabled(self): - if not settings.FEATURE_WEBHOOKS_2_ENABLED: - raise PermissionDenied("Webhooks 2 not enabled. Permission denied.") - @action(methods=["get"], detail=False) def filters(self, request): filter_name = request.query_params.get("search", None) diff --git a/engine/settings/base.py b/engine/settings/base.py index 8b881d2c..d72ddede 100644 --- a/engine/settings/base.py +++ b/engine/settings/base.py @@ -60,11 +60,9 @@ FEATURE_LIVE_SETTINGS_ENABLED = getenv_boolean("FEATURE_LIVE_SETTINGS_ENABLED", FEATURE_TELEGRAM_INTEGRATION_ENABLED = getenv_boolean("FEATURE_TELEGRAM_INTEGRATION_ENABLED", default=True) FEATURE_EMAIL_INTEGRATION_ENABLED = getenv_boolean("FEATURE_EMAIL_INTEGRATION_ENABLED", default=True) FEATURE_SLACK_INTEGRATION_ENABLED = getenv_boolean("FEATURE_SLACK_INTEGRATION_ENABLED", default=True) -FEATURE_WEB_SCHEDULES_ENABLED = getenv_boolean("FEATURE_WEB_SCHEDULES_ENABLED", default=False) FEATURE_MULTIREGION_ENABLED = getenv_boolean("FEATURE_MULTIREGION_ENABLED", default=False) FEATURE_INBOUND_EMAIL_ENABLED = getenv_boolean("FEATURE_INBOUND_EMAIL_ENABLED", default=False) FEATURE_PROMETHEUS_EXPORTER_ENABLED = getenv_boolean("FEATURE_PROMETHEUS_EXPORTER_ENABLED", default=False) -FEATURE_WEBHOOKS_2_ENABLED = getenv_boolean("FEATURE_WEBHOOKS_2_ENABLED", default=True) FEATURE_SHIFT_SWAPS_ENABLED = getenv_boolean("FEATURE_SHIFT_SWAPS_ENABLED", default=False) GRAFANA_CLOUD_ONCALL_HEARTBEAT_ENABLED = getenv_boolean("GRAFANA_CLOUD_ONCALL_HEARTBEAT_ENABLED", default=True) GRAFANA_CLOUD_NOTIFICATIONS_ENABLED = getenv_boolean("GRAFANA_CLOUD_NOTIFICATIONS_ENABLED", default=True) diff --git a/grafana-plugin/src/state/features.ts b/grafana-plugin/src/state/features.ts index 7636481d..c2ae0a7f 100644 --- a/grafana-plugin/src/state/features.ts +++ b/grafana-plugin/src/state/features.ts @@ -4,5 +4,4 @@ export enum AppFeature { LiveSettings = 'live_settings', CloudNotifications = 'grafana_cloud_notifications', CloudConnection = 'grafana_cloud_connection', - WebSchedules = 'web_schedules', }