(plugin) add CommuneCreation plugin

Add test for zone creation call
This commit is contained in:
Laurent Bossavit
2025-01-22 15:24:13 +01:00
committed by Laurent Bossavit
parent 87907d57de
commit dc938d3159
3 changed files with 84 additions and 8 deletions

View File

@@ -1,9 +1,9 @@
"""Organization related plugins."""
from django.conf import settings
import logging
from django.conf import settings
import requests
from requests.adapters import HTTPAdapter, Retry
@@ -73,9 +73,13 @@ class NameFromSiretOrganizationPlugin(BaseOrganizationPlugin):
organization.save(update_fields=["name", "updated_at"])
logger.info("Organization %s name updated to %s", organization, name)
def run_after_grant_access(self, organization):
pass
class ApiCall:
"""Encapsulates a call to an external API"""
inputs: dict = {}
method: str = "GET"
base: str = ""
url: str = ""
@@ -115,6 +119,19 @@ class CommuneCreation(BaseOrganizationPlugin):
logger.warning("No organization name found for SIRET %s", siret)
return None
def dns_call(self, spec):
"""Call to add a DNS record"""
records = [
{"name": item["target"], "type": item["type"], "data": item["value"]}
for item in spec.response
]
result = ApiCall()
result.method = "PATCH"
result.base = "https://api.scaleway.com"
result.url = f"/domain/v2beta1/dns-zones/{spec.inputs["name"]}.collectivite.fr/records"
result.params = {"changes": [{"add": {"records": records}}]}
return result
def complete_commune_creation(self, name: str) -> ApiCall:
"""Specify the tasks to be completed after a commune is created."""
inputs = {"name": name.lower()}
@@ -137,24 +154,29 @@ class CommuneCreation(BaseOrganizationPlugin):
create_domain.base = settings.MAIL_PROVISIONING_API_URL
create_domain.url = "/domains"
create_domain.params = {
"name": f"{inputs["name"]}.collectivite.fr",
"name": f"{inputs['name']}.collectivite.fr",
"delivery": "virtual",
"features": ["webmail","mailbox"],
"context_name": f"{inputs["name"]}.collectivite.fr",
"features": ["webmail", "mailbox"],
"context_name": f"{inputs['name']}.collectivite.fr",
}
create_domain.headers = {
"Authorization": f"Basic: {settings.MAIL_PROVISIONING_API_CREDENTIALS}"
}
spec_domain = ApiCall()
spec_domain.inputs = inputs
spec_domain.base = settings.MAIL_PROVISIONING_API_URL
spec_domain.url = f"/domains/{inputs["name"]}.collectivite.fr/spec"
spec_domain.url = f"/domains/{inputs['name']}.collectivite.fr/spec"
spec_domain.headers = {
"Authorization": f"Basic: {settings.MAIL_PROVISIONING_API_CREDENTIALS}"
}
return [create_zone, create_domain, spec_domain]
def complete_zone_creation(self, spec_call):
"""Specify the tasks to be performed to set up the zone."""
return self.dns_call(spec_call)
def run_after_create(self, organization):
"""After creating an organization, update the organization name."""
if not organization.registration_id_list:
@@ -183,3 +205,6 @@ class CommuneCreation(BaseOrganizationPlugin):
organization.name = name
organization.save(update_fields=["name", "updated_at"])
logger.info("Organization %s name updated to %s", organization, name)
def run_after_grant_access(self, organization):
pass

View File

@@ -9,6 +9,7 @@ from plugins.organizations import ApiCall, CommuneCreation
pytestmark = pytest.mark.django_db
def test_extract_name_from_org_data_when_commune():
"""Test the name is extracted correctly for a French commune."""
data = {
@@ -98,6 +99,7 @@ def test_tasks_on_commune_creation_include_dimail_domain_creation():
== f"Basic: {settings.MAIL_PROVISIONING_API_CREDENTIALS}"
)
def test_tasks_on_commune_creation_include_fetching_spec():
"""Test the third task in commune creation: asking Dimail for the spec"""
plugin = CommuneCreation()
@@ -112,3 +114,54 @@ def test_tasks_on_commune_creation_include_fetching_spec():
tasks[2].headers["Authorization"]
== f"Basic: {settings.MAIL_PROVISIONING_API_CREDENTIALS}"
)
def test_tasks_on_commune_creation_include_dns_records():
"""Test the next several tasks in commune creation: creating records"""
plugin = CommuneCreation()
name = "Abidos"
spec_response = [
{"target": "", "type": "mx", "value": "mx.dev.ox.numerique.gouv.fr."},
{
"target": "dimail._domainkey",
"type": "txt",
"value": "v=DKIM1; h=sha256; k=rsa; p=MIICIjANB<truncated>AAQ==",
},
{"target": "imap", "type": "cname", "value": "imap.dev.ox.numerique.gouv.fr."},
{"target": "smtp", "type": "cname", "value": "smtp.dev.ox.numerique.gouv.fr."},
{
"target": "",
"type": "txt",
"value": "v=spf1 include:_spf.dev.ox.numerique.gouv.fr -all",
},
{
"target": "webmail",
"type": "cname",
"value": "webmail.dev.ox.numerique.gouv.fr.",
},
]
tasks = plugin.complete_commune_creation(name)
tasks[2].response = spec_response
expected = {
"changes": [
{
"add": {
"records": [
{
"name": item["target"],
"type": item["type"],
"data": item["value"],
}
for item in spec_response
]
}
}
]
}
zone_call = plugin.complete_zone_creation(tasks[2])
assert zone_call.params == expected
assert zone_call.url == "/domain/v2beta1/dns-zones/abidos.collectivite.fr/records"

View File

@@ -6,8 +6,6 @@ import responses
from core.models import Organization
from core.plugins.loader import get_organization_plugins
from plugins.organizations import NameFromSiretOrganizationPlugin
pytestmark = pytest.mark.django_db