Skip to content

Commit

Permalink
feat: Backend support for feature health (#5023)
Browse files Browse the repository at this point in the history
  • Loading branch information
khvn26 authored Jan 29, 2025
1 parent 9cd9a03 commit b0d0a80
Show file tree
Hide file tree
Showing 33 changed files with 1,521 additions and 14 deletions.
7 changes: 7 additions & 0 deletions api/api/urls/v1.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from environments.identities.traits.views import SDKTraits
from environments.identities.views import SDKIdentities
from environments.sdk.views import SDKEnvironmentAPIView
from features.feature_health.views import feature_health_webhook
from features.views import SDKFeatureStates
from integrations.github.views import github_webhook
from organisations.views import chargebee_webhook
Expand Down Expand Up @@ -49,6 +50,12 @@
# GitHub integration webhook
re_path(r"github-webhook/", github_webhook, name="github-webhook"),
re_path(r"cb-webhook/", chargebee_webhook, name="chargebee-webhook"),
# Feature health webhook
re_path(
r"feature-health/(?P<path>.{0,100})$",
feature_health_webhook,
name="feature-health-webhook",
),
# Client SDK urls
re_path(r"^flags/$", SDKFeatureStates.as_view(), name="flags"),
re_path(r"^identities/$", SDKIdentities.as_view(), name="sdk-identities"),
Expand Down
1 change: 1 addition & 0 deletions api/app/settings/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
"environments.identities",
"environments.identities.traits",
"features",
"features.feature_health",
"features.import_export",
"features.multivariate",
"features.versioning",
Expand Down
1 change: 1 addition & 0 deletions api/audit/related_object_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ class RelatedObjectType(enum.Enum):
EDGE_IDENTITY = "Edge Identity"
IMPORT_REQUEST = "Import request"
EF_VERSION = "Environment feature version"
FEATURE_HEALTH = "Feature health status"
26 changes: 13 additions & 13 deletions api/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
from segments.models import Condition, Segment, SegmentRule
from tests.test_helpers import fix_issue_3869
from tests.types import (
AdminClientAuthType,
WithEnvironmentPermissionsCallable,
WithOrganisationPermissionsCallable,
WithProjectPermissionsCallable,
Expand Down Expand Up @@ -1177,23 +1178,22 @@ def github_repository(
)


@pytest.fixture(
params=[
"admin_client_original",
"admin_master_api_key_client",
]
)
def admin_client_new(
@pytest.fixture(params=AdminClientAuthType.__args__)
def admin_client_auth_type(
request: pytest.FixtureRequest,
) -> AdminClientAuthType:
return request.param


@pytest.fixture
def admin_client_new(
admin_client_auth_type: AdminClientAuthType,
admin_client_original: APIClient,
admin_master_api_key_client: APIClient,
) -> APIClient:
if request.param == "admin_client_original":
yield admin_client_original
elif request.param == "admin_master_api_key_client":
yield admin_master_api_key_client
else:
assert False, "Request param mismatch"
if admin_client_auth_type == "master_api_key":
return admin_master_api_key_client
return admin_client_original


@pytest.fixture()
Expand Down
Empty file.
35 changes: 35 additions & 0 deletions api/features/feature_health/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import typing

from django.contrib import admin
from django.http import HttpRequest

from features.feature_health.models import FeatureHealthProvider
from features.feature_health.providers.services import (
get_webhook_path_from_provider,
)


@admin.register(FeatureHealthProvider)
class FeatureHealthProviderAdmin(admin.ModelAdmin):
list_display = (
"project",
"name",
"created_by",
"webhook_url",
)

def changelist_view(
self,
request: HttpRequest,
*args: typing.Any,
**kwargs: typing.Any,
) -> None:
self.request = request
return super().changelist_view(request, *args, **kwargs)

def webhook_url(
self,
instance: FeatureHealthProvider,
) -> str:
path = get_webhook_path_from_provider(instance)
return self.request.build_absolute_uri(path)
6 changes: 6 additions & 0 deletions api/features/feature_health/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from core.apps import BaseAppConfig


class FeatureHealthConfig(BaseAppConfig):
name = "features.feature_health"
default = True
12 changes: 12 additions & 0 deletions api/features/feature_health/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FEATURE_HEALTH_PROVIDER_CREATED_MESSAGE = "Health provider %s set up for project %s."
FEATURE_HEALTH_PROVIDER_DELETED_MESSAGE = "Health provider %s removed from project %s."

FEATURE_HEALTH_EVENT_CREATED_MESSAGE = "Health status changed to %s for feature %s."
FEATURE_HEALTH_EVENT_CREATED_FOR_ENVIRONMENT_MESSAGE = (
"Health status changed to %s for feature %s in environment %s."
)
FEATURE_HEALTH_EVENT_CREATED_PROVIDER_MESSAGE = "\n\nProvided by %s"
FEATURE_HEALTH_EVENT_CREATED_REASON_MESSAGE = "\n\nReason:\n%s"

UNHEALTHY_TAG_LABEL = "Unhealthy"
UNHEALTHY_TAG_COLOUR = "#FFC0CB"
Loading

0 comments on commit b0d0a80

Please sign in to comment.