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)