From 7b27e3918dceeba2b45c2206e698818b06edd0b1 Mon Sep 17 00:00:00 2001 From: bart-maykin Date: Fri, 10 May 2024 17:40:09 +0200 Subject: [PATCH] :sparkles: [#1617] added feature to see if connection is alive in service admin list page --- zgw_consumers/admin.py | 52 ++++++++++++++++++- .../migrations/0020_service_timeout.py | 1 - .../0021_service_api_health_check_endpoint.py | 23 ++++++++ zgw_consumers/models/services.py | 9 ++++ 4 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 zgw_consumers/migrations/0021_service_api_health_check_endpoint.py diff --git a/zgw_consumers/admin.py b/zgw_consumers/admin.py index f94f0c3..ff6b673 100644 --- a/zgw_consumers/admin.py +++ b/zgw_consumers/admin.py @@ -1,21 +1,71 @@ +import logging + from django.contrib import admin from django.db import models from django.http import HttpRequest from privates.admin import PrivateMediaMixin +from requests.exceptions import ConnectionError, RequestException from solo.admin import SingletonModelAdmin from .admin_fields import get_nlx_field +from .client import build_client from .models.services import NLXConfig, Service from .settings import get_setting from .widgets import NoDownloadPrivateFileWidget +logger = logging.getLogger(__name__) + @admin.register(Service) class ServiceAdmin(admin.ModelAdmin): - list_display = ("label", "api_type", "api_root", "nlx", "auth_type") + list_display = ( + "label", + "api_type", + "api_root", + "nlx", + "auth_type", + ) list_filter = ("api_type", "auth_type") search_fields = ("label", "api_root", "nlx", "uuid") + fields = [ + "label", + "uuid", + "api_type", + "api_root", + "oas", + "oas_file", + "client_id", + "secret", + "auth_type", + "header_key", + "header_value", + "nlx", + "user_id", + "user_representation", + "client_certificate", + "server_certificate", + "timeout", + "api_health_check_endpoint", + "get_health_check_connection_indication", + ] + readonly_fields = [ + "get_health_check_connection_indication", + ] + + @admin.display(description="Health Check", boolean=True) + def get_health_check_connection_indication(self, obj): + try: + client = build_client(obj) + if ( + client.get(obj.api_health_check_endpoint or obj.api_root).status_code + == 200 + ): + return True + except (ConnectionError, RequestException) as e: + logger.exception(obj, exc_info=e) + + return False def get_fields(self, request: HttpRequest, obj: models.Model | None = None): fields = super().get_fields(request, obj=obj) diff --git a/zgw_consumers/migrations/0020_service_timeout.py b/zgw_consumers/migrations/0020_service_timeout.py index 34e23ab..5d24526 100644 --- a/zgw_consumers/migrations/0020_service_timeout.py +++ b/zgw_consumers/migrations/0020_service_timeout.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ("zgw_consumers", "0019_alter_service_uuid"), ] diff --git a/zgw_consumers/migrations/0021_service_api_health_check_endpoint.py b/zgw_consumers/migrations/0021_service_api_health_check_endpoint.py new file mode 100644 index 0000000..d2ad27d --- /dev/null +++ b/zgw_consumers/migrations/0021_service_api_health_check_endpoint.py @@ -0,0 +1,23 @@ +# Generated by Django 3.2 on 2024-05-10 08:58 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("zgw_consumers", "0020_service_timeout"), + ] + + operations = [ + migrations.AddField( + model_name="service", + name="api_health_check_endpoint", + field=models.CharField( + help_text="An optional API endpoint which will be used to check if the API is configured correctly and is currently up or down. This field is only used for in the admin's 'health check' field.", + max_length=255, + null=True, + verbose_name="health check endpoint", + ), + ), + ] diff --git a/zgw_consumers/models/services.py b/zgw_consumers/models/services.py index 7b7e2dd..5b418c1 100644 --- a/zgw_consumers/models/services.py +++ b/zgw_consumers/models/services.py @@ -28,6 +28,15 @@ class Service(RestAPIService): uuid = models.UUIDField(_("UUID"), default=uuid.uuid4) api_type = models.CharField(_("type"), max_length=20, choices=APITypes.choices) api_root = models.CharField(_("api root url"), max_length=255, unique=True) + api_health_check_endpoint = models.CharField( + _("health check endpoint"), + help_text=_( + "An optional API endpoint which will be used to check if the API is configured correctly and " + "is currently up or down. This field is only used for in the admin's 'health check' field." + ), + max_length=255, + null=True, + ) # credentials for the API client_id = models.CharField(max_length=255, blank=True)