Skip to content

Commit a04957a

Browse files
committed
Add v2 APIs for Service
We have added several APIs to help users easily manage Services and objects related to each service, includes notifiers and rules.
1 parent c1d636f commit a04957a

20 files changed

+706
-1
lines changed

promgen/filters.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,3 +215,16 @@ class ProjectFilterV2(django_filters.rest_framework.FilterSet):
215215
lookup_expr="exact",
216216
help_text="Filter by exact owner username. Example: owner=Example Owner",
217217
)
218+
219+
220+
class ServiceFilterV2(django_filters.rest_framework.FilterSet):
221+
name = django_filters.CharFilter(
222+
field_name="name",
223+
lookup_expr="contains",
224+
help_text="Filter by service name containing a specific substring. Example: name=Example Service",
225+
)
226+
owner = django_filters.CharFilter(
227+
field_name="owner__username",
228+
lookup_expr="exact",
229+
help_text="Filter by exact owner username. Example: owner=Example Owner",
230+
)

promgen/fixtures/testcases.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
pk: 2
4848
fields:
4949
name: other-service
50-
owner: 1
50+
owner: 2
5151
- model: promgen.farm
5252
pk: 1
5353
fields:

promgen/rest_v2.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,3 +531,79 @@ def delete_exporter(self, request, id, exporter_id):
531531
project = self.get_object()
532532
models.Exporter.objects.filter(project=project, pk=exporter_id).delete()
533533
return Response(status=HTTPStatus.NO_CONTENT)
534+
535+
536+
@extend_schema_view(
537+
list=extend_schema(
538+
summary="List Services",
539+
description="Retrieve a list of all services.",
540+
),
541+
retrieve=extend_schema(
542+
summary="Retrieve Service",
543+
description="Retrieve detailed information about a specific service.",
544+
),
545+
create=extend_schema(summary="Create Service", description="Create a new service."),
546+
update=extend_schema(summary="Update Service", description="Update an existing service."),
547+
partial_update=extend_schema(
548+
summary="Partially Update Service", description="Partially update an existing service."
549+
),
550+
destroy=extend_schema(summary="Delete Service", description="Delete an existing service."),
551+
)
552+
@extend_schema(tags=["Service"])
553+
class ServiceViewSet(NotifierMixin, RuleMixin, viewsets.ModelViewSet):
554+
model = "Service"
555+
queryset = models.Service.objects.all()
556+
filterset_class = filters.ServiceFilterV2
557+
serializer_class = serializers.ServiceSerializer
558+
lookup_value_regex = "[^/]+"
559+
lookup_field = "id"
560+
pagination_class = PromgenPagination
561+
562+
def get_serializer_class(self):
563+
if self.action == "list":
564+
return serializers.ServiceRetrieveSerializer
565+
if self.action == "retrieve":
566+
return serializers.ServiceRetrieveSerializer
567+
if self.action == "create":
568+
return serializers.ServiceCreateSerializer
569+
if self.action == "update":
570+
return serializers.ServiceUpdateSerializer
571+
if self.action == "partial_update":
572+
return serializers.ServiceUpdateSerializer
573+
return serializers.ServiceRetrieveSerializer
574+
575+
@extend_schema(
576+
summary="List Projects",
577+
description="Retrieve all projects associated with the specified service.",
578+
responses=serializers.ProjectRetrieveSerializer(many=True),
579+
)
580+
@action(detail=True, methods=["get"], pagination_class=None, filterset_class=None)
581+
def projects(self, request, id):
582+
service = self.get_object()
583+
return Response(
584+
serializers.ProjectRetrieveSerializer(service.project_set.all(), many=True).data
585+
)
586+
587+
@extend_schema(
588+
summary="Register Project",
589+
description="Register a new project for the specified service.",
590+
request=serializers.ProjectUpdateSerializer,
591+
responses={201: serializers.ProjectRetrieveSerializer},
592+
)
593+
@projects.mapping.post
594+
def register_project(self, request, id):
595+
serializer = serializers.ProjectUpdateSerializer(data=request.data)
596+
serializer.is_valid(raise_exception=True)
597+
service = self.get_object()
598+
599+
attributes = {"service": service}
600+
601+
for field in serializer.fields:
602+
value = serializer.validated_data.get(field)
603+
if value is not None:
604+
attributes[field] = value
605+
606+
project, _ = models.Project.objects.get_or_create(**attributes)
607+
return Response(
608+
serializers.ProjectRetrieveSerializer(project).data, status=HTTPStatus.CREATED
609+
)

promgen/serializers.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,3 +389,31 @@ class RegisterNotifierSerializer(serializers.Serializer):
389389
alias = serializers.CharField(required=False)
390390
enabled = serializers.BooleanField(required=False, default=True)
391391
filters = FilterSerializer(many=True, required=False)
392+
393+
394+
class ServiceRetrieveSerializer(serializers.ModelSerializer):
395+
owner = serializers.ReadOnlyField(source="owner.username")
396+
397+
class Meta:
398+
model = models.Service
399+
fields = "__all__"
400+
401+
402+
class ServiceCreateSerializer(serializers.ModelSerializer):
403+
owner = OwnerField(required=False, default=serializers.CurrentUserDefault())
404+
id = serializers.ReadOnlyField()
405+
406+
class Meta:
407+
model = models.Service
408+
fields = "__all__"
409+
410+
411+
class ServiceUpdateSerializer(serializers.ModelSerializer):
412+
owner = OwnerField(required=False)
413+
name = serializers.CharField(required=False)
414+
description = serializers.CharField(required=False)
415+
id = serializers.ReadOnlyField()
416+
417+
class Meta:
418+
model = models.Service
419+
fields = "__all__"
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"description": "Test New Service Description",
3+
"id": 3,
4+
"name": "new-service",
5+
"owner": "demo"
6+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"count": 2,
3+
"next": null,
4+
"previous": null,
5+
"results": [
6+
{
7+
"description": "",
8+
"id": 2,
9+
"name": "other-service",
10+
"owner": "demo"
11+
},
12+
{
13+
"description": "",
14+
"id": 1,
15+
"name": "test-service",
16+
"owner": "admin"
17+
}
18+
]
19+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"description": "",
3+
"id": 1,
4+
"name": "test-service",
5+
"owner": "admin"
6+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"count": 1,
3+
"next": null,
4+
"previous": null,
5+
"results": [
6+
{
7+
"description": "",
8+
"id": 1,
9+
"name": "test-service",
10+
"owner": "admin"
11+
}
12+
]
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"count": 1,
3+
"next": null,
4+
"previous": null,
5+
"results": [
6+
{
7+
"description": "",
8+
"id": 2,
9+
"name": "other-service",
10+
"owner": "demo"
11+
}
12+
]
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[
2+
{
3+
"alias": "",
4+
"content_type": 11,
5+
"enabled": true,
6+
"id": 1,
7+
"label": "[email protected]",
8+
"object_id": 1,
9+
"owner": "admin",
10+
"sender": "promgen.notification.email",
11+
"value": "[email protected]"
12+
}
13+
]
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"count": 2,
3+
"next": "http://testserver/rest/v2/services/?page_number=2&page_size=1",
4+
"previous": null,
5+
"results": [
6+
{
7+
"description": "",
8+
"id": 2,
9+
"name": "other-service",
10+
"owner": "demo"
11+
}
12+
]
13+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"description": "Test Updated Description",
3+
"id": 1,
4+
"name": "partial-updated-service",
5+
"owner": "demo"
6+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[
2+
{
3+
"description": "",
4+
"farm": "test-farm",
5+
"id": 1,
6+
"name": "test-project",
7+
"owner": "admin",
8+
"service": "test-service",
9+
"shard": "test-shard"
10+
}
11+
]
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
[
2+
{
3+
"alias": "",
4+
"content_name": "partial-updated-service",
5+
"content_type": "service",
6+
"enabled": true,
7+
"filters": [
8+
{
9+
"name": "severity",
10+
"value": "critical"
11+
}
12+
],
13+
"id": 1,
14+
"owner": "admin",
15+
"sender": "promgen.notification.email",
16+
"value": "[email protected]"
17+
},
18+
{
19+
"alias": "",
20+
"content_name": "partial-updated-service",
21+
"content_type": "service",
22+
"enabled": false,
23+
"filters": [
24+
{
25+
"name": "test-name",
26+
"value": "test-value"
27+
}
28+
],
29+
"id": 6,
30+
"sender": "promgen.notification.slack",
31+
"value": "https://test.slack.com"
32+
}
33+
]
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"description": "",
3+
"id": 3,
4+
"name": "new-project",
5+
"owner": "demo",
6+
"service": "partial-updated-service",
7+
"shard": "test-shard"
8+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
[
2+
{
3+
"annotations": {
4+
"rule": "http://promgen.example.com/rule/1"
5+
},
6+
"clause": "up == 0",
7+
"content_name": "partial-updated-service",
8+
"content_type": "service",
9+
"description": "Test Rule Description",
10+
"duration": "5m",
11+
"enabled": true,
12+
"id": 1,
13+
"labels": {
14+
"severity": "critical"
15+
},
16+
"name": "Test Rule",
17+
"parent": null
18+
},
19+
{
20+
"annotations": {
21+
"rule": "http://promgen.example.com/rule/4",
22+
"summary": "Test Rule Summary"
23+
},
24+
"clause": "up == 1",
25+
"content_name": "partial-updated-service",
26+
"content_type": "service",
27+
"description": "Test Rule Description",
28+
"duration": "5m",
29+
"enabled": false,
30+
"id": 4,
31+
"labels": {
32+
"severity": "critical"
33+
},
34+
"name": "TestRuleCreated",
35+
"parent": null
36+
}
37+
]
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
[
2+
{
3+
"annotations": {
4+
"rule": "http://promgen.example.com/rule/1"
5+
},
6+
"clause": "up == 0",
7+
"content_name": "test-service",
8+
"content_type": "service",
9+
"description": "Test Rule Description",
10+
"duration": "5m",
11+
"enabled": true,
12+
"id": 1,
13+
"labels": {
14+
"severity": "critical"
15+
},
16+
"name": "Test Rule",
17+
"parent": null
18+
}
19+
]
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"description": "Test Updated Description",
3+
"id": 1,
4+
"name": "updated-service",
5+
"owner": "demo"
6+
}

0 commit comments

Comments
 (0)