Skip to content

Commit

Permalink
feat/grafana integration
Browse files Browse the repository at this point in the history
  • Loading branch information
dabeeeenster committed Jun 18, 2024
1 parent 218bb8c commit c02ea2a
Show file tree
Hide file tree
Showing 5 changed files with 266 additions and 0 deletions.
6 changes: 6 additions & 0 deletions api/projects/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from features.multivariate.views import MultivariateFeatureOptionViewSet
from features.views import FeatureViewSet
from integrations.datadog.views import DataDogConfigurationViewSet
from integrations.grafana.views import GrafanaConfigurationViewSet
from integrations.launch_darkly.views import LaunchDarklyImportRequestViewSet
from integrations.new_relic.views import NewRelicConfigurationViewSet
from projects.tags.views import TagViewSet
Expand Down Expand Up @@ -56,6 +57,11 @@
LaunchDarklyImportRequestViewSet,
basename="imports-launch-darkly",
)
projects_router.register(
r"integrations/grafana",
GrafanaConfigurationViewSet,
basename="integrations-grafana",
)
projects_router.register(
"audit",
ProjectAuditLogViewSet,
Expand Down
Empty file.
12 changes: 12 additions & 0 deletions api/tests/unit/integrations/grafana/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import pytest

from integrations.grafana.models import GrafanaConfiguration


@pytest.fixture()
def deleted_grafana_configuration(project):
configuration = GrafanaConfiguration.objects.create(
project=project, base_url="http://localhost:3001", api_key="some-key"
)
configuration.delete()
return configuration
84 changes: 84 additions & 0 deletions api/tests/unit/integrations/grafana/test_unit_grafana.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
from audit.models import AuditLog
from environments.models import Environment
from integrations.grafana.grafana import ANNOTATIONS_API_URI, GrafanaWrapper


def test_grafana_initialized_correctly():
# Given
api_key = "123key"
base_url = "http://test.com"

# When initialized
grafana = GrafanaWrapper(base_url=base_url, api_key=api_key)

# Then
expected_url = f"{base_url}{ANNOTATIONS_API_URI}"
assert grafana.url == expected_url


def test_grafana_when_generate_event_data_with_correct_values_then_success(
django_user_model,
):
# Given
log = "some log data"

author = django_user_model(email="test@email.com")
environment = Environment(name="test")

audit_log_record = AuditLog(log=log, author=author, environment=environment)

grafana = GrafanaWrapper(base_url="http://test.com", api_key="123key")

# When
event_data = grafana.generate_event_data(audit_log_record=audit_log_record)

# Then
expected_event_text = f"{log} by user {author.email}"

assert event_data.get("time") is not None
assert event_data.get("timeEnd") is not None
assert event_data.get("text") == expected_event_text


def test_grafana_when_generate_event_data_with_missing_author_then_success():
# Given
log = "some log data"

environment = Environment(name="test")

audit_log_record = AuditLog(log=log, environment=environment)

grafana = GrafanaWrapper(base_url="http://test.com", api_key="123key")

# When
event_data = grafana.generate_event_data(audit_log_record=audit_log_record)

# Then
expected_event_text = f"{log} by user system"

assert event_data.get("time") is not None
assert event_data.get("timeEnd") is not None
assert event_data.get("text") == expected_event_text


def test_grafana_when_generate_event_data_with_missing_env_then_success(
django_user_model,
):
# Given
log = "some log data"

author = django_user_model(email="test@email.com")

audit_log_record = AuditLog(log=log, author=author)

grafana = GrafanaWrapper(base_url="http://test.com", api_key="123key")

# When
event_data = grafana.generate_event_data(audit_log_record=audit_log_record)

# Then
expected_event_text = f"{log} by user {author.email}"

assert event_data.get("time") is not None
assert event_data.get("timeEnd") is not None
assert event_data.get("text") == expected_event_text
164 changes: 164 additions & 0 deletions api/tests/unit/integrations/grafana/test_unit_grafana_views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
import json

from django.urls import reverse
from rest_framework import status
from rest_framework.test import APIClient

from integrations.grafana.models import GrafanaConfiguration
from projects.models import Project


def test_should_create_grafana_config_when_post(
admin_client: APIClient,
project: Project,
) -> None:
# Given
data = {
"base_url": "http://test.com",
"api_key": "key-123",
}
url = reverse("api-v1:projects:integrations-grafana-list", args=[project.id])
# When
response = admin_client.post(
url,
data=json.dumps(data),
content_type="application/json",
)

# Then
assert response.status_code == status.HTTP_201_CREATED
assert GrafanaConfiguration.objects.filter(project=project).count() == 1


def test_should_return_400_when_duplicate_grafana_config_is_posted(
admin_client: APIClient,
project: Project,
) -> None:
# Given
GrafanaConfiguration.objects.create(
base_url="http://test.com",
api_key="key-123",
project=project,
)

data = {
"base_url": "http://test.com",
"api_key": "key-123",
}
url = reverse("api-v1:projects:integrations-grafana-list", args=[project.id])

# When
response = admin_client.post(
url,
data=json.dumps(data),
content_type="application/json",
)

# Then
assert response.status_code == status.HTTP_400_BAD_REQUEST
assert GrafanaConfiguration.objects.filter(project=project).count() == 1


def test_should_update_configuration_when_put(
admin_client: APIClient,
project: Project,
) -> None:
# Given
config = GrafanaConfiguration.objects.create(
base_url="http://test.com",
api_key="key-123",
project=project,
)

api_key_updated = "new api"
data = {
"base_url": config.base_url,
"api_key": api_key_updated,
}

# When
url = reverse(
"api-v1:projects:integrations-grafana-detail",
args=[project.id, config.id],
)
response = admin_client.put(
url,
data=json.dumps(data),
content_type="application/json",
)
config.refresh_from_db()

# Then
assert response.status_code == status.HTTP_200_OK
assert config.api_key == api_key_updated


def test_should_return_grafana_config_list_when_requested(
admin_client: APIClient,
project: Project,
) -> None:
# Given
config = GrafanaConfiguration.objects.create(
base_url="http://test.com",
api_key="key-123",
project=project,
)
url = reverse("api-v1:projects:integrations-grafana-list", args=[project.id])

# When
response = admin_client.get(url)

# Then
assert response.status_code == status.HTTP_200_OK
assert response.data == [
{
"api_key": config.api_key,
"base_url": config.base_url,
"id": config.id,
}
]


def test_should_remove_configuration_when_delete(
admin_client: APIClient,
project: Project,
) -> None:
# Given
config = GrafanaConfiguration.objects.create(
base_url="http://test.com",
api_key="key-123",
project=project,
)
# When
url = reverse(
"api-v1:projects:integrations-grafana-detail",
args=[project.id, config.id],
)
response = admin_client.delete(url)

# Then
assert response.status_code == status.HTTP_204_NO_CONTENT
assert not GrafanaConfiguration.objects.filter(project=project).exists()


def test_create_Grafana_configuration_in_project_with_deleted_configuration(
admin_client, project, deleted_Grafana_configuration
):
# Given
url = reverse("api-v1:projects:integrations-grafana-list", args=[project.id])

api_key, base_url = "some-key", "https://api.Grafana.com/"

# When
response = admin_client.post(
path=url,
data=json.dumps({"api_key": api_key, "base_url": base_url}),
content_type="application/json",
)

# Then
assert response.status_code == status.HTTP_201_CREATED

response_json = response.json()
assert response_json["api_key"] == api_key
assert response_json["base_url"] == base_url

0 comments on commit c02ea2a

Please sign in to comment.