Skip to content

Commit e2759c1

Browse files
committed
Add v2 APIs for Shard
We have added several APIs for retrieving Shard data and the list of projects for each shard.
1 parent a04957a commit e2759c1

10 files changed

+218
-0
lines changed

promgen/fixtures/testcases.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@
3838
url: http://prometheus.example.com
3939
proxy: true
4040
enabled: true
41+
- model: promgen.shard
42+
pk: 2
43+
fields:
44+
name: other-shard
45+
url: http://prometheus-002.example.com
46+
proxy: false
47+
enabled: false
4148
- model: promgen.service
4249
pk: 1
4350
fields:

promgen/rest_v2.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,3 +607,37 @@ def register_project(self, request, id):
607607
return Response(
608608
serializers.ProjectRetrieveSerializer(project).data, status=HTTPStatus.CREATED
609609
)
610+
611+
612+
@extend_schema_view(
613+
list=extend_schema(summary="List Shards", description="Retrieve a list of all shards."),
614+
retrieve=extend_schema(
615+
summary="Retrieve Shard",
616+
description="Retrieve detailed information about a specific shard.",
617+
),
618+
)
619+
@extend_schema(tags=["Shard"])
620+
class ShardViewSet(mixins.RetrieveModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet):
621+
queryset = models.Shard.objects.all()
622+
filterset_class = filters.ShardFilter
623+
serializer_class = serializers.ShardRetrieveSerializer
624+
lookup_field = "id"
625+
pagination_class = PromgenPagination
626+
627+
@extend_schema(
628+
summary="List Projects in Shard",
629+
description="Retrieve all projects associated with the specified shard.",
630+
parameters=[
631+
OpenApiParameter(name="page_number", required=False, type=int),
632+
OpenApiParameter(name="page_size", required=False, type=int),
633+
],
634+
responses=serializers.ProjectRetrieveSerializer(many=True),
635+
)
636+
@action(detail=True, methods=["get"], filterset_class=None)
637+
def projects(self, request, id):
638+
shard = self.get_object()
639+
projects = shard.project_set.all()
640+
page = self.paginate_queryset(projects)
641+
return self.get_paginated_response(
642+
serializers.ProjectRetrieveSerializer(page, many=True).data
643+
)

promgen/serializers.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,3 +417,9 @@ class ServiceUpdateSerializer(serializers.ModelSerializer):
417417
class Meta:
418418
model = models.Service
419419
fields = "__all__"
420+
421+
422+
class ShardRetrieveSerializer(serializers.ModelSerializer):
423+
class Meta:
424+
model = models.Shard
425+
exclude = ("authorization",)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"count": 2,
3+
"next": null,
4+
"previous": null,
5+
"results": [
6+
{
7+
"enabled": false,
8+
"id": 2,
9+
"name": "other-shard",
10+
"proxy": false,
11+
"samples": 5000000,
12+
"targets": 10000,
13+
"url": "http://prometheus-002.example.com"
14+
},
15+
{
16+
"enabled": true,
17+
"id": 1,
18+
"name": "test-shard",
19+
"proxy": true,
20+
"samples": 5000000,
21+
"targets": 10000,
22+
"url": "http://prometheus.example.com"
23+
}
24+
]
25+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"enabled": true,
3+
"id": 1,
4+
"name": "test-shard",
5+
"proxy": true,
6+
"samples": 5000000,
7+
"targets": 10000,
8+
"url": "http://prometheus.example.com"
9+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"count": 1,
3+
"next": null,
4+
"previous": null,
5+
"results": [
6+
{
7+
"enabled": true,
8+
"id": 1,
9+
"name": "test-shard",
10+
"proxy": true,
11+
"samples": 5000000,
12+
"targets": 10000,
13+
"url": "http://prometheus.example.com"
14+
}
15+
]
16+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"count": 2,
3+
"next": "http://testserver/rest/v2/shards/?page_number=2&page_size=1",
4+
"previous": null,
5+
"results": [
6+
{
7+
"enabled": false,
8+
"id": 2,
9+
"name": "other-shard",
10+
"proxy": false,
11+
"samples": 5000000,
12+
"targets": 10000,
13+
"url": "http://prometheus-002.example.com"
14+
}
15+
]
16+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"count": 2,
3+
"next": null,
4+
"previous": null,
5+
"results": [
6+
{
7+
"description": "",
8+
"farm": "test-farm",
9+
"id": 2,
10+
"name": "another-project",
11+
"owner": "demo",
12+
"service": "other-service",
13+
"shard": "test-shard"
14+
},
15+
{
16+
"description": "",
17+
"farm": "test-farm",
18+
"id": 1,
19+
"name": "test-project",
20+
"owner": "admin",
21+
"service": "test-service",
22+
"shard": "test-shard"
23+
}
24+
]
25+
}

promgen/tests/test_rest.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2205,3 +2205,82 @@ def test_rest_service(self):
22052205
HTTP_AUTHORIZATION=f"Token {token}",
22062206
)
22072207
self.assertEqual(response.status_code, 204)
2208+
2209+
@override_settings(PROMGEN=tests.SETTINGS)
2210+
def test_rest_shard(self):
2211+
token = Token.objects.filter(user__username="demo").first().key
2212+
2213+
# Check retrieving shards without token returns 401 Unauthorized
2214+
response = self.client.get(reverse("api-v2:shard-list"))
2215+
self.assertEqual(response.status_code, 401)
2216+
2217+
# Check retrieving all shards
2218+
expected = tests.Data("examples", "rest.shard.default.json").json()
2219+
response = self.client.get(
2220+
reverse("api-v2:shard-list"),
2221+
HTTP_AUTHORIZATION=f"Token {token}",
2222+
)
2223+
self.assertEqual(response.status_code, 200)
2224+
self.assertEqual(response.json(), expected)
2225+
2226+
# Check retrieving paginated shards
2227+
expected = tests.Data("examples", "rest.shard.paginated.json").json()
2228+
response = self.client.get(
2229+
reverse("api-v2:shard-list"),
2230+
{"page_number": 1, "page_size": 1},
2231+
HTTP_AUTHORIZATION=f"Token {token}",
2232+
)
2233+
self.assertEqual(response.status_code, 200)
2234+
self.assertEqual(response.json(), expected)
2235+
2236+
# Check retrieving shards whose "name" contains "test"
2237+
expected = tests.Data("examples", "rest.shard.filter_by_name.json").json()
2238+
response = self.client.get(
2239+
reverse("api-v2:shard-list"),
2240+
{"name": "test"},
2241+
HTTP_AUTHORIZATION=f"Token {token}",
2242+
)
2243+
self.assertEqual(response.status_code, 200)
2244+
self.assertEqual(response.json(), expected)
2245+
2246+
# Check retrieving shards with a non-existent "name" returns an empty list
2247+
response = self.client.get(
2248+
reverse("api-v2:shard-list"),
2249+
{"name": "non-existent"},
2250+
HTTP_AUTHORIZATION=f"Token {token}",
2251+
)
2252+
self.assertEqual(response.status_code, 200)
2253+
self.assertEqual(response.data["count"], 0)
2254+
2255+
# Check retrieving shards whose "id" is "1" without token returns 401 Unauthorized
2256+
response = self.client.get(reverse("api-v2:shard-detail", args=[1]))
2257+
self.assertEqual(response.status_code, 401)
2258+
2259+
# Check retrieving shards whose "id" is "1"
2260+
expected = tests.Data("examples", "rest.shard.detail.json").json()
2261+
response = self.client.get(
2262+
reverse("api-v2:shard-detail", args=[1]),
2263+
HTTP_AUTHORIZATION=f"Token {token}",
2264+
)
2265+
self.assertEqual(response.status_code, 200)
2266+
self.assertEqual(response.json(), expected)
2267+
2268+
# Check retrieving shards with a non-existent "id" returns 404 Not Found
2269+
response = self.client.get(
2270+
reverse("api-v2:shard-detail", args=[-1]),
2271+
HTTP_AUTHORIZATION=f"Token {token}",
2272+
)
2273+
self.assertEqual(response.status_code, 404)
2274+
2275+
# Check retrieving list of projects for a shard without token returns 401 Unauthorized
2276+
response = self.client.get(reverse("api-v2:shard-projects", args=[1]))
2277+
self.assertEqual(response.status_code, 401)
2278+
2279+
# Check retrieving list of projects for a shard
2280+
expected = tests.Data("examples", "rest.shard.projects.json").json()
2281+
response = self.client.get(
2282+
reverse("api-v2:shard-projects", args=[1]),
2283+
HTTP_AUTHORIZATION=f"Token {token}",
2284+
)
2285+
self.assertEqual(response.status_code, 200)
2286+
self.assertEqual(response.json(), expected)

promgen/urls.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
v2_router.register("urls", rest_v2.URLViewSet)
4343
v2_router.register("projects", rest_v2.ProjectViewSet)
4444
v2_router.register("services", rest_v2.ServiceViewSet)
45+
v2_router.register("shards", rest_v2.ShardViewSet)
4546

4647
urlpatterns = [
4748
path("admin/", admin.site.urls),

0 commit comments

Comments
 (0)