(domains) add admin action to fetch domain DNS config

Create a Django admin action to allow retrieval of
the expected domain configuration from dimail.
These values shouldn't change unless external
intervention occurs. An admin command seems sufficient to handle
hypothetical changes.
This commit is contained in:
Sabrina Demagny
2025-02-15 12:08:35 +01:00
parent cad065da84
commit 38de864d68
2 changed files with 88 additions and 1 deletions

View File

@@ -101,6 +101,35 @@ def fetch_domain_status_from_dimail(modeladmin, request, queryset): # pylint: d
)
@admin.action(description=_("Fetch domain expected config from dimail"))
def fetch_domain_expected_config_from_dimail(modeladmin, request, queryset): # pylint: disable=unused-argument
"""Admin action to fetch domain expected config from dimail."""
client = DimailAPIClient()
excluded_domains = []
for domain in queryset:
# do not check disabled domains
if domain.status == enums.MailDomainStatusChoices.DISABLED:
excluded_domains.append(domain.name)
continue
response = client.fetch_domain_expected_config(domain)
if response:
messages.success(
request,
_(f"Domain expected config fetched with success for {domain.name}."),
)
else:
messages.error(
request, _(f"Failed to fetch domain expected config for {domain.name}.")
)
if excluded_domains:
messages.warning(
request,
_(
f"Domains disabled are excluded from fetch: {', '.join(excluded_domains)}"
),
)
class UserMailDomainAccessInline(admin.TabularInline):
"""Inline admin class for mail domain accesses."""
@@ -124,7 +153,11 @@ class MailDomainAdmin(admin.ModelAdmin):
readonly_fields = ["created_at", "slug"]
list_filter = ("status",)
inlines = (UserMailDomainAccessInline,)
actions = (sync_mailboxes_from_dimail, fetch_domain_status_from_dimail)
actions = (
sync_mailboxes_from_dimail,
fetch_domain_status_from_dimail,
fetch_domain_expected_config_from_dimail,
)
@admin.register(models.Mailbox)

View File

@@ -18,6 +18,7 @@ from mailbox_manager import enums, factories, models
from .fixtures.dimail import (
CHECK_DOMAIN_BROKEN,
CHECK_DOMAIN_OK,
DOMAIN_SPEC,
TOKEN_OK,
response_mailbox_created,
)
@@ -150,3 +151,56 @@ def test_fetch_domain_status__should_switch_to_enabled_when_domain_ok(client):
assert "Check domains done with success" in response.content.decode("utf-8")
for mailbox in models.Mailbox.objects.filter(domain=domain1):
assert mailbox.status == enums.MailboxStatusChoices.ENABLED
@pytest.mark.parametrize(
"domain_status",
[
enums.MailDomainStatusChoices.PENDING,
enums.MailDomainStatusChoices.FAILED,
enums.MailDomainStatusChoices.ENABLED,
],
)
@responses.activate
@pytest.mark.django_db
def test_fetch_domain_expected_config(client, domain_status):
"""Test admin action to fetch domain expected config from dimail."""
admin = core_factories.UserFactory(is_staff=True, is_superuser=True)
client.force_login(admin)
domain = factories.MailDomainFactory(status=domain_status)
data = {
"action": "fetch_domain_expected_config_from_dimail",
"_selected_action": [domain.id],
}
responses.add(
responses.GET,
re.compile(rf".*/domains/{domain.name}/spec/"),
body=json.dumps(DOMAIN_SPEC),
status=status.HTTP_200_OK,
content_type="application/json",
)
url = reverse("admin:mailbox_manager_maildomain_changelist")
response = client.post(url, data, follow=True)
assert response.status_code == status.HTTP_200_OK
domain.refresh_from_db()
assert domain.expected_config == DOMAIN_SPEC
@pytest.mark.django_db
def test_fetch_domain_expected_config__should_not_fetch_for_disabled_domain(client):
"""Test admin action to fetch domain expected config from dimail."""
admin = core_factories.UserFactory(is_staff=True, is_superuser=True)
client.force_login(admin)
domain = factories.MailDomainFactory(status=enums.MailDomainStatusChoices.DISABLED)
data = {
"action": "fetch_domain_expected_config_from_dimail",
"_selected_action": [domain.id],
}
url = reverse("admin:mailbox_manager_maildomain_changelist")
response = client.post(url, data, follow=True)
assert response.status_code == status.HTTP_200_OK
domain.refresh_from_db()
assert domain.expected_config is None
assert "Domains disabled are excluded from fetch" in response.content.decode(
"utf-8"
)