From 46d346ea090989b565667c3b4b52e54d8b2390e7 Mon Sep 17 00:00:00 2001
From: Karel van Klink <karel.vanklink@geant.org>
Date: Mon, 23 Sep 2024 14:54:56 +0200
Subject: [PATCH] =?UTF-8?q?Add=20documentation=20for=20G=C3=89ANT=20IP=20s?=
 =?UTF-8?q?ervice=20related=20code?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 build-docs.sh                                 |  1 +
 docs/source/glossary.rst                      | 13 ++++++++++
 .../products/product_blocks/bgp_session.rst   |  6 +++++
 .../products/product_blocks/geant_ip.rst      |  6 +++++
 .../module/products/product_blocks/index.rst  | 16 +++++++------
 .../product_blocks/service_binding_port.rst   |  6 +++++
 .../products/product_types/geant_ip.rst       |  6 +++++
 .../module/products/product_types/index.rst   | 13 +++++-----
 docs/source/module/utils/index.rst            |  8 +++++++
 docs/source/module/utils/types.rst            |  6 -----
 docs/source/module/utils/types/base_site.rst  |  6 +++++
 .../source/module/utils/types/coordinates.rst |  6 +++++
 .../module/utils/types/country_code.rst       |  6 +++++
 docs/source/module/utils/types/index.rst      | 24 +++++++++++++++++++
 docs/source/module/utils/types/interfaces.rst |  6 +++++
 docs/source/module/utils/types/ip_address.rst |  6 +++++
 .../module/utils/types/netbox_router.rst      |  6 +++++
 docs/source/module/utils/types/site_name.rst  |  6 +++++
 docs/source/module/utils/types/tt_number.rst  |  6 +++++
 .../module/utils/types/unique_field.rst       |  6 +++++
 .../module/workflows/edge_port/index.rst      | 18 ++++++++++++++
 .../edge_port/terminate_edge_port.rst         |  2 +-
 docs/vale/.vale.ini                           |  1 +
 .../vocabularies/geant-jargon/accept.txt      |  4 ++++
 docs/vale/styles/custom/Contractions.yml      |  1 -
 gso/products/product_blocks/edge_port.py      |  4 ++--
 gso/products/product_blocks/geant_ip.py       |  4 ++--
 gso/products/product_blocks/opengear.py       |  6 ++---
 gso/services/kentik_client.py                 |  2 ++
 gso/services/netbox_client.py                 |  2 +-
 gso/translations/en-GB.json                   |  1 +
 gso/utils/helpers.py                          | 19 ++++++++-------
 gso/workflows/edge_port/create_edge_port.py   |  2 +-
 .../edge_port/terminate_edge_port.py          |  2 +-
 gso/workflows/geant_ip/create_geant_ip.py     |  6 ++---
 gso/workflows/iptrunk/create_iptrunk.py       |  4 ++--
 gso/workflows/iptrunk/migrate_iptrunk.py      | 10 ++++----
 .../iptrunk/modify_trunk_interface.py         |  2 +-
 gso/workflows/iptrunk/validate_iptrunk.py     |  2 +-
 gso/workflows/router/create_router.py         |  2 +-
 .../router/modify_connection_strategy.py      |  4 ++--
 gso/workflows/router/promote_p_to_pe.py       |  2 +-
 .../edge_port/test_create_edge_port.py        |  2 +-
 .../edge_port/test_validate_edge_port.py      |  2 +-
 44 files changed, 206 insertions(+), 57 deletions(-)
 create mode 100644 docs/source/module/products/product_blocks/bgp_session.rst
 create mode 100644 docs/source/module/products/product_blocks/geant_ip.rst
 create mode 100644 docs/source/module/products/product_blocks/service_binding_port.rst
 create mode 100644 docs/source/module/products/product_types/geant_ip.rst
 delete mode 100644 docs/source/module/utils/types.rst
 create mode 100644 docs/source/module/utils/types/base_site.rst
 create mode 100644 docs/source/module/utils/types/coordinates.rst
 create mode 100644 docs/source/module/utils/types/country_code.rst
 create mode 100644 docs/source/module/utils/types/index.rst
 create mode 100644 docs/source/module/utils/types/interfaces.rst
 create mode 100644 docs/source/module/utils/types/ip_address.rst
 create mode 100644 docs/source/module/utils/types/netbox_router.rst
 create mode 100644 docs/source/module/utils/types/site_name.rst
 create mode 100644 docs/source/module/utils/types/tt_number.rst
 create mode 100644 docs/source/module/utils/types/unique_field.rst
 create mode 100644 docs/source/module/workflows/edge_port/index.rst

diff --git a/build-docs.sh b/build-docs.sh
index 34eadabb..f68d5ad6 100755
--- a/build-docs.sh
+++ b/build-docs.sh
@@ -3,6 +3,7 @@ set -o errexit
 set -o nounset
 
 export OSS_PARAMS_FILENAME=../gso/oss-params-example.json
+export TESTING=true
 
 pip install sphinx_rtd_theme sphinxcontrib-jquery
 
diff --git a/docs/source/glossary.rst b/docs/source/glossary.rst
index e8046503..40512a3f 100644
--- a/docs/source/glossary.rst
+++ b/docs/source/glossary.rst
@@ -9,6 +9,9 @@ Glossary of terms
   API
     Application Programming Interface
 
+  BFD
+    Bi-directional Forwarding Detection
+
   BGP
     Border Gateway Protocol: a path vector routing protocol described in
     `RFC 4271 <https://datatracker.ietf.org/doc/html/rfc4271>`_.
@@ -63,12 +66,18 @@ Glossary of terms
   LAN
     Local Area Network
 
+  LLDP
+    Link Layer Discovery Protocol
+
   LSO
     Lightweight Service Orchestrator
 
   NET
     Network Entity Title: used for :term:`ISIS` routing.
 
+  NREN
+    National Research and Education Network
+
   OIDC
     OpenID Connect
 
@@ -81,6 +90,10 @@ Glossary of terms
   OSS
     Operational Support Systems
 
+  SDP
+    Service Demarcation Point: A logical construct used for modeling partner subscriptions. It models the link between
+    the physical and the service domains.
+
   SNMP
     Simple Network Management Protocol: a protocol that's used for gathering data, widely used for network management
     and monitoring.
diff --git a/docs/source/module/products/product_blocks/bgp_session.rst b/docs/source/module/products/product_blocks/bgp_session.rst
new file mode 100644
index 00000000..5d3fe341
--- /dev/null
+++ b/docs/source/module/products/product_blocks/bgp_session.rst
@@ -0,0 +1,6 @@
+``gso.products.product_blocks.bgp_session``
+===========================================
+
+.. automodule:: gso.products.product_blocks.bgp_session
+   :members:
+   :show-inheritance:
diff --git a/docs/source/module/products/product_blocks/geant_ip.rst b/docs/source/module/products/product_blocks/geant_ip.rst
new file mode 100644
index 00000000..46958f8d
--- /dev/null
+++ b/docs/source/module/products/product_blocks/geant_ip.rst
@@ -0,0 +1,6 @@
+``gso.products.product_blocks.geant_ip``
+========================================
+
+.. automodule:: gso.products.product_blocks.geant_ip
+   :members:
+   :show-inheritance:
diff --git a/docs/source/module/products/product_blocks/index.rst b/docs/source/module/products/product_blocks/index.rst
index 09cba78b..65474b43 100644
--- a/docs/source/module/products/product_blocks/index.rst
+++ b/docs/source/module/products/product_blocks/index.rst
@@ -14,14 +14,16 @@ Submodules
 .. toctree::
    :maxdepth: 1
 
-   super_pop_switch
-   office_router
+   bgp_session
+   edge_port
+   geant_ip
    iptrunk
+   lan_switch_interconnect
+   office_router
+   opengear
+   pop_vlan
    router
+   service_binding_port
    site
+   super_pop_switch
    switch
-   lan_switch_interconnect
-   pop_vlan
-   opengear
-   edge_port
-
diff --git a/docs/source/module/products/product_blocks/service_binding_port.rst b/docs/source/module/products/product_blocks/service_binding_port.rst
new file mode 100644
index 00000000..a7036dc2
--- /dev/null
+++ b/docs/source/module/products/product_blocks/service_binding_port.rst
@@ -0,0 +1,6 @@
+``gso.products.product_blocks.service_binding_port``
+====================================================
+
+.. automodule:: gso.products.product_blocks.service_binding_port
+   :members:
+   :show-inheritance:
diff --git a/docs/source/module/products/product_types/geant_ip.rst b/docs/source/module/products/product_types/geant_ip.rst
new file mode 100644
index 00000000..bb2167f1
--- /dev/null
+++ b/docs/source/module/products/product_types/geant_ip.rst
@@ -0,0 +1,6 @@
+``gso.products.product_types.geant_ip``
+=======================================
+
+.. automodule:: gso.products.product_types.geant_ip
+   :members:
+   :show-inheritance:
diff --git a/docs/source/module/products/product_types/index.rst b/docs/source/module/products/product_types/index.rst
index 999db729..b2636eaf 100644
--- a/docs/source/module/products/product_types/index.rst
+++ b/docs/source/module/products/product_types/index.rst
@@ -14,13 +14,14 @@ Submodules
 .. toctree::
    :maxdepth: 1
 
-   super_pop_switch
-   office_router
+   edge_port
+   geant_ip
    iptrunk
+   lan_switch_interconnect
+   office_router
+   opengear
+   pop_vlan
    router
    site
+   super_pop_switch
    switch
-   lan_switch_interconnect
-   pop_vlan
-   opengear
-   edge_port
diff --git a/docs/source/module/utils/index.rst b/docs/source/module/utils/index.rst
index 52f992ba..72896907 100644
--- a/docs/source/module/utils/index.rst
+++ b/docs/source/module/utils/index.rst
@@ -5,6 +5,14 @@
    :members:
    :show-inheritance:
 
+Subpackages
+-----------
+
+.. toctree::
+   :maxdepth: 1
+
+   types/index
+
 Submodules
 ----------
 
diff --git a/docs/source/module/utils/types.rst b/docs/source/module/utils/types.rst
deleted file mode 100644
index c70c8dd0..00000000
--- a/docs/source/module/utils/types.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-``gso.utils.types``
-===================
-
-.. automodule:: gso.utils.types
-   :members:
-   :show-inheritance:
diff --git a/docs/source/module/utils/types/base_site.rst b/docs/source/module/utils/types/base_site.rst
new file mode 100644
index 00000000..ac952086
--- /dev/null
+++ b/docs/source/module/utils/types/base_site.rst
@@ -0,0 +1,6 @@
+``gso.utils.types.base_site``
+=============================
+
+.. automodule:: gso.utils.types.base_site
+   :members:
+   :show-inheritance:
diff --git a/docs/source/module/utils/types/coordinates.rst b/docs/source/module/utils/types/coordinates.rst
new file mode 100644
index 00000000..85c52ba1
--- /dev/null
+++ b/docs/source/module/utils/types/coordinates.rst
@@ -0,0 +1,6 @@
+``gso.utils.types.coordinates``
+===============================
+
+.. automodule:: gso.utils.types.coordinates
+   :members:
+   :show-inheritance:
diff --git a/docs/source/module/utils/types/country_code.rst b/docs/source/module/utils/types/country_code.rst
new file mode 100644
index 00000000..604feaf1
--- /dev/null
+++ b/docs/source/module/utils/types/country_code.rst
@@ -0,0 +1,6 @@
+``gso.utils.types.country_code``
+===============================
+
+.. automodule:: gso.utils.types.country_code
+   :members:
+   :show-inheritance:
diff --git a/docs/source/module/utils/types/index.rst b/docs/source/module/utils/types/index.rst
new file mode 100644
index 00000000..2dcf23ec
--- /dev/null
+++ b/docs/source/module/utils/types/index.rst
@@ -0,0 +1,24 @@
+``gso.utils.types``
+===================
+
+.. automodule:: gso.utils.types
+   :members:
+   :show-inheritance:
+
+
+Submodules
+----------
+
+.. toctree::
+   :maxdepth: 2
+   :titlesonly:
+
+   base_site
+   coordinates
+   country_code
+   interfaces
+   ip_address
+   netbox_router
+   site_name
+   tt_number
+   unique_field
diff --git a/docs/source/module/utils/types/interfaces.rst b/docs/source/module/utils/types/interfaces.rst
new file mode 100644
index 00000000..95c9a3da
--- /dev/null
+++ b/docs/source/module/utils/types/interfaces.rst
@@ -0,0 +1,6 @@
+``gso.utils.types.interfaces``
+==============================
+
+.. automodule:: gso.utils.types.interfaces
+   :members:
+   :show-inheritance:
diff --git a/docs/source/module/utils/types/ip_address.rst b/docs/source/module/utils/types/ip_address.rst
new file mode 100644
index 00000000..68858af7
--- /dev/null
+++ b/docs/source/module/utils/types/ip_address.rst
@@ -0,0 +1,6 @@
+``gso.utils.types.ip_address``
+==============================
+
+.. automodule:: gso.utils.types.ip_address
+   :members:
+   :show-inheritance:
diff --git a/docs/source/module/utils/types/netbox_router.rst b/docs/source/module/utils/types/netbox_router.rst
new file mode 100644
index 00000000..1d35d235
--- /dev/null
+++ b/docs/source/module/utils/types/netbox_router.rst
@@ -0,0 +1,6 @@
+``gso.utils.types.netbox_router``
+=================================
+
+.. automodule:: gso.utils.types.netbox_router
+   :members:
+   :show-inheritance:
diff --git a/docs/source/module/utils/types/site_name.rst b/docs/source/module/utils/types/site_name.rst
new file mode 100644
index 00000000..df2934a6
--- /dev/null
+++ b/docs/source/module/utils/types/site_name.rst
@@ -0,0 +1,6 @@
+``gso.utils.types.site_name``
+=============================
+
+.. automodule:: gso.utils.types.site_name
+   :members:
+   :show-inheritance:
diff --git a/docs/source/module/utils/types/tt_number.rst b/docs/source/module/utils/types/tt_number.rst
new file mode 100644
index 00000000..43410a35
--- /dev/null
+++ b/docs/source/module/utils/types/tt_number.rst
@@ -0,0 +1,6 @@
+``gso.utils.types.tt_number``
+=============================
+
+.. automodule:: gso.utils.types.tt_number
+   :members:
+   :show-inheritance:
diff --git a/docs/source/module/utils/types/unique_field.rst b/docs/source/module/utils/types/unique_field.rst
new file mode 100644
index 00000000..3a74a0d1
--- /dev/null
+++ b/docs/source/module/utils/types/unique_field.rst
@@ -0,0 +1,6 @@
+``gso.utils.types.unique_field``
+================================
+
+.. automodule:: gso.utils.types.unique_field
+   :members:
+   :show-inheritance:
diff --git a/docs/source/module/workflows/edge_port/index.rst b/docs/source/module/workflows/edge_port/index.rst
new file mode 100644
index 00000000..a77d1617
--- /dev/null
+++ b/docs/source/module/workflows/edge_port/index.rst
@@ -0,0 +1,18 @@
+``gso.workflows.edge_port``
+===========================
+
+.. automodule:: gso.workflows.edge_port
+   :members:
+   :show-inheritance:
+
+Submodules
+----------
+
+.. toctree::
+   :maxdepth: 2
+   :titlesonly:
+
+   create_edge_port
+   modify_edge_port
+   terminate_edge_port
+   validate_edge_port
diff --git a/docs/source/module/workflows/edge_port/terminate_edge_port.rst b/docs/source/module/workflows/edge_port/terminate_edge_port.rst
index 4ab880f9..4613d361 100644
--- a/docs/source/module/workflows/edge_port/terminate_edge_port.rst
+++ b/docs/source/module/workflows/edge_port/terminate_edge_port.rst
@@ -1,5 +1,5 @@
 ``gso.workflows.edge_port.terminate_edge_port``
-==============================================
+===============================================
 
 .. automodule:: gso.workflows.edge_port.terminate_edge_port
    :members:
diff --git a/docs/vale/.vale.ini b/docs/vale/.vale.ini
index 76b4b40c..063fe579 100644
--- a/docs/vale/.vale.ini
+++ b/docs/vale/.vale.ini
@@ -25,6 +25,7 @@ custom.Contractions = YES
 ; Using a "regular" - instead of an en dash is totally fine
 Microsoft.Negative = NO
 Microsoft.RangeFormat = NO
+Microsoft.We = suggestion
 
 TokenIgnores = (:term:`\S+`), (:param \S+(?: \S+)?:), (:type \S+:), (:return \S+:), (:rtype: \S+), (:class:`\S+`)
 
diff --git a/docs/vale/styles/config/vocabularies/geant-jargon/accept.txt b/docs/vale/styles/config/vocabularies/geant-jargon/accept.txt
index 9d05c092..6509f0d5 100644
--- a/docs/vale/styles/config/vocabularies/geant-jargon/accept.txt
+++ b/docs/vale/styles/config/vocabularies/geant-jargon/accept.txt
@@ -31,3 +31,7 @@ OPA
 OIDC
 HTTPBearer
 Kentik
+UTC
+EARL
+SURF
+[Ee]nsure
diff --git a/docs/vale/styles/custom/Contractions.yml b/docs/vale/styles/custom/Contractions.yml
index 9c2b94a5..ecba3923 100644
--- a/docs/vale/styles/custom/Contractions.yml
+++ b/docs/vale/styles/custom/Contractions.yml
@@ -7,7 +7,6 @@ swap:
   can't: cannot
   couldn't: could not
   didn't: did not
-  don't: do not
   doesn't: does not
   hasn't: has not
   haven't: have not
diff --git a/gso/products/product_blocks/edge_port.py b/gso/products/product_blocks/edge_port.py
index ad90ac76..b77fd938 100644
--- a/gso/products/product_blocks/edge_port.py
+++ b/gso/products/product_blocks/edge_port.py
@@ -114,7 +114,7 @@ class EdgePortBlock(EdgePortBlockProvisioning, lifecycle=[SubscriptionLifecycle.
     edge_port_enable_lacp: bool
     #: The type of encapsulation used on this edge port, by default DOT1Q.
     edge_port_encapsulation: EncapsulationType = EncapsulationType.DOT1Q
-    #: The MAC address assigned to this edge port, if applicable.
+    #: The :term:`MAC` address assigned to this edge port, if applicable.
     edge_port_mac_address: str | None = None
     #: The speed capacity of each member in the physical port.
     edge_port_member_speed: PhysicalPortCapacity
@@ -126,7 +126,7 @@ class EdgePortBlock(EdgePortBlockProvisioning, lifecycle=[SubscriptionLifecycle.
     edge_port_ignore_if_down: bool = False
     #: The GEANT GA ID associated with this edge port, if any.
     edge_port_geant_ga_id: str | None = None
-    #: A list of LAG members associated with this edge port.
+    #: A list of :term:`LAG` members associated with this edge port.
     edge_port_ae_members: LAGMemberList[EdgePortAEMemberBlock]  # type: ignore[assignment]
     #: A list of Service Binding Ports associated with this Edge Port
     edge_port_sbp_list: list[ServiceBindingPort]  # type: ignore[assignment]
diff --git a/gso/products/product_blocks/geant_ip.py b/gso/products/product_blocks/geant_ip.py
index 8104c23d..2f7bf5fb 100644
--- a/gso/products/product_blocks/geant_ip.py
+++ b/gso/products/product_blocks/geant_ip.py
@@ -21,7 +21,7 @@ class NRENAccessPortProvisioning(NRENAccessPortInactive, lifecycle=[Subscription
     """An access port for an R&E :term:`NREN` service that is being provisioned."""
 
     nren_ap_type: APType
-    geant_ip_ep: EdgePortBlockProvisioning  # type: ignore[assignment]
+    geant_ip_ep: EdgePortBlockProvisioning
 
 
 class NRENAccessPort(NRENAccessPortProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]):
@@ -30,7 +30,7 @@ class NRENAccessPort(NRENAccessPortProvisioning, lifecycle=[SubscriptionLifecycl
     #: The type of Access Port
     nren_ap_type: APType
     #: The list of Edge Ports where this service terminates.
-    geant_ip_ep: EdgePortBlock  # type: ignore[assignment]
+    geant_ip_ep: EdgePortBlock
 
 
 class GeantIPBlockInactive(
diff --git a/gso/products/product_blocks/opengear.py b/gso/products/product_blocks/opengear.py
index 84ed84b3..14a4db84 100644
--- a/gso/products/product_blocks/opengear.py
+++ b/gso/products/product_blocks/opengear.py
@@ -43,9 +43,9 @@ class OpengearBlock(OpengearBlockProvisioning, lifecycle=[SubscriptionLifecycle.
     opengear_hostname: str
     #: The site where the Opengear device is located.
     opengear_site: SiteBlock
-    #: The WAN address of the Opengear device.
+    #: The :term:`WAN` address of the Opengear device.
     opengear_wan_address: ipaddress.IPv4Address
-    #: The WAN netmask of the Opengear device.
+    #: The :term:`WAN` netmask of the Opengear device.
     opengear_wan_netmask: ipaddress.IPv4Address
-    #: The WAN gateway of the Opengear device.
+    #: The :term:`WAN` gateway of the Opengear device.
     opengear_wan_gateway: ipaddress.IPv4Address
diff --git a/gso/services/kentik_client.py b/gso/services/kentik_client.py
index 7849adee..a958aca5 100644
--- a/gso/services/kentik_client.py
+++ b/gso/services/kentik_client.py
@@ -99,6 +99,8 @@ class KentikClient:
 
         If the site is not found, return an empty dict.
 
+        .. vale off
+
         :param str site_slug: The name of the site, should be a three-letter slug like COR or POZ.
         """
         sites = self.get_sites()
diff --git a/gso/services/netbox_client.py b/gso/services/netbox_client.py
index 63ce9da8..3b71f49d 100644
--- a/gso/services/netbox_client.py
+++ b/gso/services/netbox_client.py
@@ -295,7 +295,7 @@ class NetboxClient:
         router_name = Router.from_subscription(router_id).router.router_fqdn
         device = self.get_device_by_name(router_name)
 
-        # Get the existing LAG interfaces for the device
+        # Get the existing :term:`LAG` interfaces for the device
         lag_interface_names = [
             interface["name"] for interface in self.netbox.dcim.interfaces.filter(device=device.name, type="lag")
         ]
diff --git a/gso/translations/en-GB.json b/gso/translations/en-GB.json
index 63f9e9c2..0834aa69 100644
--- a/gso/translations/en-GB.json
+++ b/gso/translations/en-GB.json
@@ -44,6 +44,7 @@
         "create_site": "Create Site",
         "create_switch": "Create Switch",
         "create_edge_port": "Create Edge Port",
+        "create_geant_ip": "Create GÉANT IP",
         "deploy_twamp": "Deploy TWAMP",
         "migrate_iptrunk": "Migrate IP Trunk",
         "modify_isis_metric": "Modify the ISIS metric",
diff --git a/gso/utils/helpers.py b/gso/utils/helpers.py
index e3dda41d..1e1470c1 100644
--- a/gso/utils/helpers.py
+++ b/gso/utils/helpers.py
@@ -209,15 +209,18 @@ def active_edge_port_selector(*, geant_only: bool | None = None) -> Choice:
     if geant_only is not None:
         # ``geant_only`` is set, so we will filter accordingly.
         geant_partner_id = get_partner_by_name("GEANT")["partner_id"]
-        edge_port_subscriptions = filter(
-            lambda subscription: geant_only ^ bool(subscription["customer_id"] != geant_partner_id),
-            edge_port_subscriptions,
+        edge_port_subscriptions = list(
+            filter(
+                lambda subscription: geant_only ^ bool(subscription["customer_id"] != geant_partner_id),
+                edge_port_subscriptions,
+            )
         )
 
-    edge_port_subscriptions = {str(port["subscription_id"]): port["description"] for port in edge_port_subscriptions}
+    edge_ports = {str(port["subscription_id"]): port["description"] for port in edge_port_subscriptions}
 
     return Choice(
-        "Select an Edge Port", zip(edge_port_subscriptions.keys(), edge_port_subscriptions.items(), strict=True)
+        "Select an Edge Port",
+        zip(edge_ports.keys(), edge_ports.items(), strict=True),  # type: ignore[arg-type]
     )
 
 
@@ -229,11 +232,11 @@ def partner_choice() -> Choice:
 
 
 def validate_edge_port_number_of_members_based_on_lacp(*, number_of_members: int, enable_lacp: bool) -> None:
-    """Validate the number of edge port members based on the LACP setting.
+    """Validate the number of edge port members based on the :term:`LACP` setting.
 
     :param number_of_members: The number of members to validate.
-    :param enable_lacp: Whether LACP is enabled or not.
-    :raises ValueError: If the number of members is greater than 1 and LACP is disabled.
+    :param enable_lacp: Whether :term:`LACP` is enabled or not.
+    :raises ValueError: If the number of members is greater than 1 and :term:`LACP` is disabled.
     """
     if number_of_members > 1 and not enable_lacp:
         err_msg = "Number of members must be 1 if LACP is disabled."
diff --git a/gso/workflows/edge_port/create_edge_port.py b/gso/workflows/edge_port/create_edge_port.py
index fdf1e760..1e57b232 100644
--- a/gso/workflows/edge_port/create_edge_port.py
+++ b/gso/workflows/edge_port/create_edge_port.py
@@ -239,7 +239,7 @@ def create_edge_port() -> StepList:
 
     * Create and initialise the subscription object in the service database
     * Deploy configuration on the new edge port, first as a dry run
-    * allocate LAG and LAG members in the Netbox.
+    * allocate :term:`LAG` and :term:`LAG` members in the Netbox.
     """
     return (
         begin
diff --git a/gso/workflows/edge_port/terminate_edge_port.py b/gso/workflows/edge_port/terminate_edge_port.py
index e191d330..893a8c1e 100644
--- a/gso/workflows/edge_port/terminate_edge_port.py
+++ b/gso/workflows/edge_port/terminate_edge_port.py
@@ -70,7 +70,7 @@ def remove_edge_port_real(
 
 @step("Netbox Clean Up")
 def netbox_clean_up(subscription: EdgePort) -> None:
-    """Update Netbox to remove the edge port LAG interface and all the LAG members."""
+    """Update Netbox to remove the edge port :term:`LAG` interface and all the :term:`LAG` members."""
     nbclient = NetboxClient()
 
     for member in subscription.edge_port.edge_port_ae_members:
diff --git a/gso/workflows/geant_ip/create_geant_ip.py b/gso/workflows/geant_ip/create_geant_ip.py
index fdaaf38e..f8c28077 100644
--- a/gso/workflows/geant_ip/create_geant_ip.py
+++ b/gso/workflows/geant_ip/create_geant_ip.py
@@ -36,15 +36,15 @@ def initial_input_form_generator(product_name: str) -> FormGenerator:
         model_config = ConfigDict(title=f"{product_name} - Select partner")
 
         tt_number: TTNumber
-        partner: partner_choice()
+        partner: partner_choice()  # type: ignore[valid-type]
 
     initial_user_input = yield CreateGeantIPForm
 
     class EdgePortSelection(BaseModel):
-        edge_port: active_edge_port_selector()
+        edge_port: active_edge_port_selector()  # type: ignore[valid-type]
         ap_type: APType
 
-        def __hash__(self):
+        def __hash__(self) -> int:
             return self.edge_port.__hash__()
 
     class EdgePortSelectionForm(FormPage):
diff --git a/gso/workflows/iptrunk/create_iptrunk.py b/gso/workflows/iptrunk/create_iptrunk.py
index e1040118..3d56bf0f 100644
--- a/gso/workflows/iptrunk/create_iptrunk.py
+++ b/gso/workflows/iptrunk/create_iptrunk.py
@@ -255,7 +255,7 @@ def dig_all_hosts_v6(new_ipv6_network: str) -> None:
 
 @step("Ping all hosts in the assigned IPv4 network")
 def ping_all_hosts_v4(new_ipv4_network: str) -> None:
-    """Ping all hosts in the IPv4 network to verify they're not in use."""
+    """Ping all hosts in the IPv4 network to verify they are not in use."""
     unavailable_hosts = [host for host in IPv4Network(new_ipv4_network) if ping(str(host), timeout=1)]
 
     if unavailable_hosts:
@@ -265,7 +265,7 @@ def ping_all_hosts_v4(new_ipv4_network: str) -> None:
 
 @step("Ping all hosts in the assigned IPv6 network")
 def ping_all_hosts_v6(new_ipv6_network: str) -> State:
-    """Ping all hosts in the IPv6 network to verify they're not in use."""
+    """Ping all hosts in the IPv6 network to verify they are not in use."""
     unavailable_hosts = [host for host in IPv6Network(new_ipv6_network) if ping(str(host), timeout=1)]
 
     if unavailable_hosts:
diff --git a/gso/workflows/iptrunk/migrate_iptrunk.py b/gso/workflows/iptrunk/migrate_iptrunk.py
index 5a7cafb0..43b43e8c 100644
--- a/gso/workflows/iptrunk/migrate_iptrunk.py
+++ b/gso/workflows/iptrunk/migrate_iptrunk.py
@@ -89,7 +89,7 @@ def initial_input_form_generator(subscription_id: UUIDstr) -> FormGenerator:
             ):
                 #  We want to stay on the same site, so all routers that are in different sites get skipped.
                 continue
-            #  If migrate_to_different_site is true, we can add ALL routers to the result map
+            #  If migrate_to_different_site is true, we can add *all* routers to the result map
             routers[str(router_id)] = router["description"]
 
     new_router_enum = Choice("Select a new router", zip(routers.keys(), routers.items(), strict=True))  # type: ignore[arg-type]
@@ -204,7 +204,7 @@ def calculate_old_side_data(subscription: Iptrunk, replace_index: int) -> State:
 
 @step("Check Optical PRE levels on the trunk endpoint")
 def check_ip_trunk_optical_levels_pre(subscription: Iptrunk) -> LSOState:
-    """Check Optical PRE levels on the trunk."""
+    """Check Optical levels on the trunk before migration."""
     extra_vars = {"wfo_ip_trunk_json": json.loads(json_dumps(subscription)), "check": "optical_pre"}
 
     return {
@@ -252,7 +252,7 @@ def check_ip_trunk_optical_levels_post(
 def check_ip_trunk_lldp(
     subscription: Iptrunk, new_node: Router, new_lag_member_interfaces: list[dict], replace_index: int
 ) -> LSOState:
-    """Check LLDP on the new trunk endpoints."""
+    """Check :term:`LLDP` on the new trunk endpoints."""
     extra_vars = {
         "wfo_ip_trunk_json": json.loads(json_dumps(subscription)),
         "new_node": json.loads(json_dumps(new_node)),
@@ -489,7 +489,7 @@ def update_remaining_side_bfd_real(
 
 @step("Check BFD session over trunk")
 def check_ip_trunk_bfd(subscription: Iptrunk, new_node: Router, replace_index: int) -> LSOState:
-    """Check BFD session across the new trunk."""
+    """Check :term:`BFD` session across the new trunk."""
     extra_vars = {
         "wfo_ip_trunk_json": json.loads(json_dumps(subscription)),
         "new_node": json.loads(json_dumps(new_node)),
@@ -830,7 +830,7 @@ def migrate_iptrunk() -> StepList:
     * Deploy a new :term:`ISIS` interface between routers A and C
     * Wait for operator confirmation that :term:`ISIS` is behaving as expected
     * Restore the old :term:`ISIS` metric on the new trunk
-    * Delete the old, disabled configuration on the routers, first as a dry run
+    * Delete the old configuration from the routers, first as a dry run
     * Reflect the changes made in :term:`IPAM`
     * Update the subscription model in the database
     * Update the reserved interfaces in Netbox
diff --git a/gso/workflows/iptrunk/modify_trunk_interface.py b/gso/workflows/iptrunk/modify_trunk_interface.py
index 16de2462..94f63128 100644
--- a/gso/workflows/iptrunk/modify_trunk_interface.py
+++ b/gso/workflows/iptrunk/modify_trunk_interface.py
@@ -205,7 +205,7 @@ def check_ip_trunk_connectivity(subscription: Iptrunk) -> LSOState:
 
 @step("Check LLDP on the trunk endpoints")
 def check_ip_trunk_lldp(subscription: Iptrunk) -> LSOState:
-    """Check LLDP on trunk endpoints."""
+    """Check :term:`LLDP` on trunk endpoints."""
     extra_vars = {"wfo_ip_trunk_json": json.loads(json_dumps(subscription)), "check": "lldp"}
 
     return {
diff --git a/gso/workflows/iptrunk/validate_iptrunk.py b/gso/workflows/iptrunk/validate_iptrunk.py
index 4ca96f8b..f66612f5 100644
--- a/gso/workflows/iptrunk/validate_iptrunk.py
+++ b/gso/workflows/iptrunk/validate_iptrunk.py
@@ -210,7 +210,7 @@ def validate_iptrunk() -> StepList:
     * Verify that the :term:`LAG` interfaces are correctly configured in :term:`IPAM`.
     * Check correct configuration of interfaces in NetBox.
     * Verify the configuration on both sides of the trunk is intact.
-    * Check the ISIS metric of the trunk.
+    * Check the :term:`ISIS` metric of the trunk.
     * Verify that TWAMP configuration is correct.
 
     If a trunk has a Juniper router on both sides, it is considered legacy and does not require validation.
diff --git a/gso/workflows/router/create_router.py b/gso/workflows/router/create_router.py
index 928fca58..4492e86e 100644
--- a/gso/workflows/router/create_router.py
+++ b/gso/workflows/router/create_router.py
@@ -44,7 +44,7 @@ def initial_input_form_generator(product_name: str) -> FormGenerator:
         tt_number: TTNumber
         partner: ReadOnlyField("GEANT", default_type=str)  # type: ignore[valid-type]
         vendor: Vendor
-        router_site: active_site_selector()
+        router_site: active_site_selector()  # type: ignore[valid-type]
         hostname: str
         ts_port: PortNumber
         router_role: RouterRole
diff --git a/gso/workflows/router/modify_connection_strategy.py b/gso/workflows/router/modify_connection_strategy.py
index 65b29b8d..890329d8 100644
--- a/gso/workflows/router/modify_connection_strategy.py
+++ b/gso/workflows/router/modify_connection_strategy.py
@@ -34,8 +34,8 @@ def initial_input_form_generator(subscription_id: UUIDstr) -> FormGenerator:
 def update_subscription_model(subscription: Router, connection_strategy: str) -> State:
     """Update the database model to reflect the new connection strategy.
 
-    If the connection strategy is set to IN-BAND, then access_via_ts should be set to False.
-    Conversely, if the connection strategy is set to OUT-OF-BAND, access_via_ts should be set to True.
+    If the connection strategy is set to in-band, then access_via_ts should be set to False.
+    Conversely, if the connection strategy is set to out-of-band, access_via_ts should be set to True.
     """
     subscription.router.router_access_via_ts = connection_strategy == ConnectionStrategy.OUT_OF_BAND
 
diff --git a/gso/workflows/router/promote_p_to_pe.py b/gso/workflows/router/promote_p_to_pe.py
index a82b4823..8bf78ea0 100644
--- a/gso/workflows/router/promote_p_to_pe.py
+++ b/gso/workflows/router/promote_p_to_pe.py
@@ -236,7 +236,7 @@ def deploy_routing_instances_real(subscription: dict[str, Any], tt_number: str,
 
 @step("Remove ISIS overload")
 def remove_isis_overload(subscription: dict[str, Any], tt_number: str, process_id: UUIDstr) -> LSOState:
-    """Remove ISIS overload."""
+    """Remove :term:`ISIS` overload."""
     extra_vars = {
         "dry_run": False,
         "subscription": subscription,
diff --git a/test/workflows/edge_port/test_create_edge_port.py b/test/workflows/edge_port/test_create_edge_port.py
index db855e8a..7b3fc8bc 100644
--- a/test/workflows/edge_port/test_create_edge_port.py
+++ b/test/workflows/edge_port/test_create_edge_port.py
@@ -112,7 +112,7 @@ def test_edge_port_creation_with_invalid_input(
     test_client,
 ):
     product_id = get_product_id_by_name(ProductName.EDGE_PORT)
-    # If the number of members is greater than 1 then LACP must be enabled.
+    # If the number of members is greater than 1 then :term:`LACP` must be enabled.
     input_form_wizard_data[0]["enable_lacp"] = False
     initial_data = [{"product": product_id}, *input_form_wizard_data]
 
diff --git a/test/workflows/edge_port/test_validate_edge_port.py b/test/workflows/edge_port/test_validate_edge_port.py
index 261d5b24..cda43407 100644
--- a/test/workflows/edge_port/test_validate_edge_port.py
+++ b/test/workflows/edge_port/test_validate_edge_port.py
@@ -58,5 +58,5 @@ def test_validate_edge_port_success(
     subscription = EdgePort.from_subscription(subscription_id)
     assert subscription.status == "active"
     assert mock_execute_playbook.call_count == 1
-    # One time for getting the LAG and two times for getting the interfaces
+    # One time for getting the :term:`LAG` and two times for getting the interfaces
     assert mock_get_interface_by_name_and_device.call_count == 3
-- 
GitLab