Skip to content

Commit

Permalink
Implement retrieval "Farm" APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
hoangpn committed Nov 19, 2024
1 parent 57cebc3 commit b78c3fa
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 1 deletion.
17 changes: 17 additions & 0 deletions promgen/filters.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from distutils.util import strtobool

import django_filters


Expand All @@ -19,3 +21,18 @@ class RuleFilter(django_filters.rest_framework.FilterSet):
name = django_filters.CharFilter(field_name="name", lookup_expr="contains")
parent = django_filters.CharFilter(field_name="parent__name", lookup_expr="contains")
enabled = django_filters.BooleanFilter(field_name="enabled")


class FarmFilter(django_filters.rest_framework.FilterSet):
name = django_filters.CharFilter(method="filter_by_name")
source = django_filters.CharFilter(field_name="source", lookup_expr="exact")

def filter_by_name(self, queryset, name, value):
name_exact_match_param = self.request.GET.get('name_exact_match', 'true')
name_exact_match = strtobool(name_exact_match_param)
if name_exact_match:
lookup_expr = 'exact'
else:
lookup_expr = 'contains'
filter_kwargs = {f'name__{lookup_expr}': value}
return queryset.filter(**filter_kwargs)
22 changes: 21 additions & 1 deletion promgen/rest.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Copyright (c) 2019 LINE Corporation
# These sources are released under the terms of the MIT license: see LICENSE

from django.core.serializers import get_serializer
from django.http import HttpResponse
from django.views.generic import View
from rest_framework import permissions, viewsets
Expand Down Expand Up @@ -110,3 +110,23 @@ def targets(self, request, name):
prometheus.render_config(project=self.get_object()),
content_type="application/json",
)


class FarmViewSet(NotifierMixin, RuleMixin, viewsets.ModelViewSet):
queryset = models.Farm.objects.all()
filterset_class = filters.FarmFilter
serializer_class = serializers.FarmSerializer
lookup_value_regex = "[^/]+"
lookup_field = "id"

def retrieve(self, request, id):
farm = self.get_object()
farm_data = self.get_serializer(farm).data

hosts = farm.host_set.all()
hosts_data = serializers.HostSerializer(hosts, many=True).data
farm_detail = {
**farm_data,
"hosts": hosts_data
}
return Response(farm_detail)
16 changes: 16 additions & 0 deletions promgen/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,19 @@ def to_representation(self, obj):
"labels": obj.labels,
"annotations": annotations,
}


class FarmSerializer(serializers.ModelSerializer):
url = WebLinkField()

class Meta:
model = models.Farm
fields = '__all__'


class HostSerializer(serializers.ModelSerializer):
url = WebLinkField()

class Meta:
model = models.Host
exclude = ("id", "farm")
49 changes: 49 additions & 0 deletions promgen/tests/test_rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@


from django.test import override_settings
from django.urls import reverse

from promgen import models, rest, tests

Expand All @@ -21,3 +22,51 @@ def test_alert(self):
response = self.fireAlert()
self.assertEqual(response.status_code, 202)
self.assertCount(models.Alert, 1, "Alert Queued")

@override_settings(PROMGEN=tests.SETTINGS)
def test_retrieve_farm(self):
response = self.client.get(reverse("api:farm-list"))
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data), 1)
self.assertEqual(response.data[0]["id"], 1)
self.assertEqual(response.data[0]["name"], "test-farm")
self.assertEqual(response.data[0]["source"], "promgen")
self.assertEqual(response.data[0]["url"], "http://promgen.example.com/farm/1")

response = self.client.get(reverse("api:farm-list"), {"name": "test-farm"})
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data), 1)

response = self.client.get(reverse("api:farm-list"), {"source": "promgen"})
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data), 1)

response = self.client.get(reverse("api:farm-list"), {"name": "farm", "name_exact_match": "false"})
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data), 1)

response = self.client.get(reverse("api:farm-list"), {"source": "other-source"})
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data), 0)

response = self.client.get(reverse("api:farm-list"), {"name": "farm", "name_exact_match": "true"})
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data), 0)

response = self.client.get(reverse("api:farm-list"), {"name": "farm"})
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data), 0)


farm = models.Farm.objects.get(id=1)
models.Host.objects.create(name="host.example.com", farm=farm)

response = self.client.get(reverse("api:farm-detail", args=[1]))
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data["id"], 1)
self.assertEqual(response.data["name"], "test-farm")
self.assertEqual(response.data["source"], "promgen")
self.assertEqual(response.data["url"], "http://promgen.example.com/farm/1")
self.assertEqual(len(response.data["hosts"]), 1)
self.assertEqual(response.data["hosts"][0]["url"], "http://promgen.example.com/host/host.example.com")
self.assertEqual(response.data["hosts"][0]["name"], "host.example.com")
1 change: 1 addition & 0 deletions promgen/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
router.register("service", rest.ServiceViewSet)
router.register("shard", rest.ShardViewSet)
router.register("project", rest.ProjectViewSet)
router.register("farm", rest.FarmViewSet)


urlpatterns = [
Expand Down

0 comments on commit b78c3fa

Please sign in to comment.