Skip to content

Commit 5fe92fb

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 e4fb0ad commit 5fe92fb

20 files changed

+699
-1
lines changed

promgen/filters.py

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

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
@@ -543,3 +543,79 @@ def delete_exporter(self, request, id, exporter_id):
543543
project = self.get_object()
544544
models.Exporter.objects.filter(project=project, pk=exporter_id).delete()
545545
return Response(status=HTTPStatus.NO_CONTENT)
546+
547+
548+
@extend_schema_view(
549+
list=extend_schema(
550+
summary="List Services",
551+
description="Retrieve a list of all services.",
552+
),
553+
retrieve=extend_schema(
554+
summary="Retrieve Service",
555+
description="Retrieve detailed information about a specific service.",
556+
),
557+
create=extend_schema(summary="Create Service", description="Create a new service."),
558+
update=extend_schema(summary="Update Service", description="Update an existing service."),
559+
partial_update=extend_schema(
560+
summary="Partially Update Service", description="Partially update an existing service."
561+
),
562+
destroy=extend_schema(summary="Delete Service", description="Delete an existing service."),
563+
)
564+
@extend_schema(tags=["Service"])
565+
class ServiceViewSet(NotifierMixin, RuleMixin, viewsets.ModelViewSet):
566+
model = "Service"
567+
queryset = models.Service.objects.all()
568+
filterset_class = filters.ServiceFilterV2
569+
serializer_class = serializers.ServiceSerializer
570+
lookup_value_regex = "[^/]+"
571+
lookup_field = "id"
572+
pagination_class = PromgenPagination
573+
574+
def get_serializer_class(self):
575+
if self.action == "list":
576+
return serializers.ServiceV2Serializer
577+
if self.action == "retrieve":
578+
return serializers.ServiceV2Serializer
579+
if self.action == "create":
580+
return serializers.ServiceV2Serializer
581+
if self.action == "update":
582+
return serializers.ServiceUpdateSerializer
583+
if self.action == "partial_update":
584+
return serializers.ServiceUpdateSerializer
585+
return serializers.ServiceV2Serializer
586+
587+
@extend_schema(
588+
summary="List Projects",
589+
description="Retrieve all projects associated with the specified service.",
590+
responses=serializers.ProjectV2Serializer(many=True),
591+
)
592+
@action(detail=True, methods=["get"], pagination_class=None, filterset_class=None)
593+
def projects(self, request, id):
594+
service = self.get_object()
595+
return Response(
596+
serializers.ProjectV2Serializer(service.project_set.all(), many=True).data
597+
)
598+
599+
@extend_schema(
600+
summary="Register Project",
601+
description="Register a new project for the specified service.",
602+
request=serializers.ProjectUpdateSerializer,
603+
responses={201: serializers.ProjectV2Serializer},
604+
)
605+
@projects.mapping.post
606+
def register_project(self, request, id):
607+
serializer = serializers.ProjectUpdateSerializer(data=request.data)
608+
serializer.is_valid(raise_exception=True)
609+
service = self.get_object()
610+
611+
attributes = {"service": service}
612+
613+
for field in serializer.fields:
614+
value = serializer.validated_data.get(field)
615+
if value is not None:
616+
attributes[field] = value
617+
618+
project, _ = models.Project.objects.get_or_create(**attributes)
619+
return Response(
620+
serializers.ProjectV2Serializer(project).data, status=HTTPStatus.CREATED
621+
)

promgen/serializers.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,3 +389,23 @@ 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 ServiceV2Serializer(serializers.ModelSerializer):
395+
owner = OwnerField(required=False, default=serializers.CurrentUserDefault())
396+
id = serializers.ReadOnlyField()
397+
398+
class Meta:
399+
model = models.Service
400+
fields = "__all__"
401+
402+
403+
class ServiceUpdateSerializer(serializers.ModelSerializer):
404+
owner = OwnerField(required=False)
405+
name = serializers.CharField(required=False)
406+
description = serializers.CharField(required=False)
407+
id = serializers.ReadOnlyField()
408+
409+
class Meta:
410+
model = models.Service
411+
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+
]

0 commit comments

Comments
 (0)