From a3b3ec811fb50dcced5eb2a35ca270bb6cdf5e86 Mon Sep 17 00:00:00 2001
From: Karel van Klink <karel.vanklink@geant.org>
Date: Fri, 29 Nov 2024 10:40:12 +0100
Subject: [PATCH] Move workflow docstrings into Python files

---
 docs/index.md                                 |  5 +-
 docs/workflow/activate_iptrunk.md             |  5 --
 docs/workflow/activate_router.md              |  5 --
 docs/workflow/create_iptrunk.md               | 30 -----------
 docs/workflow/create_router.md                | 50 -------------------
 docs/workflow/create_site.md                  |  5 --
 docs/workflow/deploy_twamp.md                 |  4 --
 docs/workflow/index.md                        |  3 --
 docs/workflow/migrate_iptrunk.md              |  4 --
 docs/workflow/modify_connection_strategy.md   |  4 --
 docs/workflow/modify_isis_metric.md           |  7 ---
 docs/workflow/modify_router_kentik_license.md |  5 --
 docs/workflow/modify_site.md                  | 12 -----
 docs/workflow/modify_trunk_interface.md       |  8 ---
 docs/workflow/promote_p_to_pe.md              |  3 --
 docs/workflow/redeploy_base_config.md         | 12 -----
 docs/workflow/terminate_iptrunk.md            | 13 -----
 docs/workflow/terminate_router.md             | 17 -------
 docs/workflow/terminate_site.md               |  7 ---
 docs/workflow/update_ibgp_mesh.md             | 22 --------
 gso/workflows/iptrunk/activate_iptrunk.py     |  6 ++-
 gso/workflows/iptrunk/create_iptrunk.py       | 27 +++++++++-
 gso/workflows/iptrunk/deploy_twamp.py         |  6 ++-
 gso/workflows/iptrunk/migrate_iptrunk.py      |  2 +
 gso/workflows/iptrunk/modify_isis_metric.py   |  6 ++-
 .../iptrunk/modify_trunk_interface.py         |  8 ++-
 gso/workflows/iptrunk/terminate_iptrunk.py    | 13 ++++-
 gso/workflows/router/activate_router.py       |  6 ++-
 gso/workflows/router/create_router.py         | 42 +++++++++++++++-
 .../router/modify_connection_strategy.py      |  6 ++-
 gso/workflows/router/modify_kentik_license.py |  6 ++-
 gso/workflows/router/redeploy_base_config.py  | 10 +++-
 gso/workflows/router/terminate_router.py      | 17 ++++++-
 gso/workflows/router/update_ibgp_mesh.py      | 20 +++++++-
 gso/workflows/site/create_site.py             |  6 ++-
 gso/workflows/site/modify_site.py             | 14 +++++-
 gso/workflows/site/terminate_site.py          |  7 ++-
 37 files changed, 189 insertions(+), 234 deletions(-)
 delete mode 100644 docs/workflow/activate_iptrunk.md
 delete mode 100644 docs/workflow/activate_router.md
 delete mode 100644 docs/workflow/create_iptrunk.md
 delete mode 100644 docs/workflow/create_router.md
 delete mode 100644 docs/workflow/create_site.md
 delete mode 100644 docs/workflow/deploy_twamp.md
 delete mode 100644 docs/workflow/index.md
 delete mode 100644 docs/workflow/migrate_iptrunk.md
 delete mode 100644 docs/workflow/modify_connection_strategy.md
 delete mode 100644 docs/workflow/modify_isis_metric.md
 delete mode 100644 docs/workflow/modify_router_kentik_license.md
 delete mode 100644 docs/workflow/modify_site.md
 delete mode 100644 docs/workflow/modify_trunk_interface.md
 delete mode 100644 docs/workflow/promote_p_to_pe.md
 delete mode 100644 docs/workflow/redeploy_base_config.md
 delete mode 100644 docs/workflow/terminate_iptrunk.md
 delete mode 100644 docs/workflow/terminate_router.md
 delete mode 100644 docs/workflow/terminate_site.md
 delete mode 100644 docs/workflow/update_ibgp_mesh.md

diff --git a/docs/index.md b/docs/index.md
index 900c5ed2..e91efa9d 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -38,8 +38,9 @@ This site is organized in 4 main sections:
   including all the components and the interactions between them
 - [Admin guide](admin_guide/index.md): provides detailed information of 
   the domain models in WFO and all the Ansible mechanics
-- [Workflows](workflow/index.md): provides operational guides of the 
-  Workflow Orchestrator based GAP
+- [Code Documentation](reference/gso/index.md): provides code documentation of the 
+  Workflow Orchestrator based GAP. This includes all models, workflows, and external services
+  that the GAP interacts with.
 
 The documentation provided in this portal is final and reviewed. For information
 about the ongoing work please refer to the [internal wiki page](https://wiki.
diff --git a/docs/workflow/activate_iptrunk.md b/docs/workflow/activate_iptrunk.md
deleted file mode 100644
index 903e0356..00000000
--- a/docs/workflow/activate_iptrunk.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# Activate IP trunk
-
-When the SharePoint checklist of a trunk is completed, this workflow is run to 
-take the subscription from `PROVISIONING` to `ACTIVE`. The operator is asked 
-to give a URL to the completed checklist.
diff --git a/docs/workflow/activate_router.md b/docs/workflow/activate_router.md
deleted file mode 100644
index 01ab3626..00000000
--- a/docs/workflow/activate_router.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# Activate Router
-
-When the SharePoint checklist of a router is completed, this workflow is run to 
-take the subscription from `PROVISIONING` to `ACTIVE`. The operator is asked 
-to give a URL to the completed checklist.
diff --git a/docs/workflow/create_iptrunk.md b/docs/workflow/create_iptrunk.md
deleted file mode 100644
index 59b951fe..00000000
--- a/docs/workflow/create_iptrunk.md
+++ /dev/null
@@ -1,30 +0,0 @@
-# Create IP trunk
-
-This the workflow that brings the subscription from `INACTIVE` to `PROVISIONING`.
-The deployment of a new IPtrunk consist in the following steps:
-
-- Fill the form with the necessary fields:
-    - SID
-    - Type
-    - Speed
-    - Nodes
-    - LAG interfaces with description
-    - LAG members with description
-- WFO will query IPAM to retrieve the IPv4/IPv6 Networks necessary for the
-trunk. The container to use is specified in `oss-params.json`
-- The configuration necessary to deploy the LAG is generated and applied to the
-destination nodes using the Ansible playbook `iptrunks.yaml` This is done first 
-in a dry mode (without committing) and then in a real mode committing the
-configuration. The commit message has the `subscription_id` and the
-`process_id`. Included in this, is the configuration necessary to enable LLDP on
-the physical interfaces.
-- Once the LAG interface is deployed, another Ansible playbook is called to 
-verify that IP traffic can actually flow over the trunk ( `iptrunk_checks.yaml`)
-- Once the check is passed, the ISIS configuration will take place using the 
-same `iptrunks.yaml`. Also in this case first there is a dry run and then a
-commit.
-- After this step the ISIS adjacency gets checked using again
-`iptrunks_checks.yaml`
-
-The trunk is deployed with an initial ISIS metric of 90.000 to prevent traffic 
-to pass.
diff --git a/docs/workflow/create_router.md b/docs/workflow/create_router.md
deleted file mode 100644
index 5b54151d..00000000
--- a/docs/workflow/create_router.md
+++ /dev/null
@@ -1,50 +0,0 @@
-# Create Router
-
-To add a new router to the GÉANT network, the `create_router` workflow must 
-be executed first. The intake form for this workflow requires the following 
-fields to be filled in:
-
-* Trouble ticket number
-* Router vendor
-* Router site
-* Hostname
-* Terminal server port
-* Router role
-
-The hostname is validated, by checking that the resulting FQDN is not 
-already taken in IPAM.
-
-!!! warning
-    The validation only checks whether the FQDN is already taken in IPAM, 
-    **not** whether it is registered somewhere on the internet.
-
-When the workflow is started, a subscription object is first instantiated in 
-the service database, containing all the information that was provided in 
-the input form at the beginning. Then, the loopback addresses are allocated 
-in IPAM, which results in both the IPv4 and IPv6 addresses in the product model.
-
-Once allocated, the first dry run of deploying router configuration takes place.
-An Ansible playbook is run, with all the attributes of the new router. This 
-is where GSO communicates with LSO, and the router configuration is checked, 
-but not committed to the machine.
-
-After the dry run, the operator is presented with a view of the outcome of 
-this playbook. This is their opportunity to verify successful execution of 
-the Ansible playbook, and whether the difference in configuration is as 
-expected. If not, this is their chance to abort the workflow, and no harm is
-done to the router.
-
-When the operator confirms the outcome of this playbook execution, the 
-playbook runs once again, but it will also commit the configuration after 
-checking. With the new router configured, the IPAM resources are verified to 
-ensure this external system is configured correctly.
-
-If the new router is a Nokia, all its interfaces are added to Netbox. This 
-is done to keep track of interface reservations and bookkeeping. For Juniper 
-routers, this does not need to take place. These existing devices are not 
-migrated into Netbox.
-
-Finally, an Ansible playbook is run to verify that the connectivity and 
-optical power levels of the router are in order. Once this is completed, a 
-checklist item is created in SharePoint and the router is taken into the
-`PROVISIONING` state.
diff --git a/docs/workflow/create_site.md b/docs/workflow/create_site.md
deleted file mode 100644
index 456e61f9..00000000
--- a/docs/workflow/create_site.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# Create Site
-
-The `create_site` workflow creates a new site object in the service database,
-and sets the subscription lifecycle to `ACTIVE`. The attributes that are input
-using the intake form of the workflow are stored, and nothing else happens.
diff --git a/docs/workflow/deploy_twamp.md b/docs/workflow/deploy_twamp.md
deleted file mode 100644
index f70845bc..00000000
--- a/docs/workflow/deploy_twamp.md
+++ /dev/null
@@ -1,4 +0,0 @@
-# Deploy TWAMP
-
-Takes a trunk that is either `PROVISIONING` or `ACTIVE` and deploy configuration
-for TWAMP. The trunk will not change state after running this workflow.
diff --git a/docs/workflow/index.md b/docs/workflow/index.md
deleted file mode 100644
index 11095f24..00000000
--- a/docs/workflow/index.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Workflows
-
-This section contains an overview of all documented workflows in GAP.
diff --git a/docs/workflow/migrate_iptrunk.md b/docs/workflow/migrate_iptrunk.md
deleted file mode 100644
index afad60a7..00000000
--- a/docs/workflow/migrate_iptrunk.md
+++ /dev/null
@@ -1,4 +0,0 @@
-# Migrate IP trunk
-
-Migrate one side of an IP trunk from one router to another. In the input form,
-the operator selects a new router where this trunk should terminate on.  
diff --git a/docs/workflow/modify_connection_strategy.md b/docs/workflow/modify_connection_strategy.md
deleted file mode 100644
index 32bfb839..00000000
--- a/docs/workflow/modify_connection_strategy.md
+++ /dev/null
@@ -1,4 +0,0 @@
-# Modify connection strategy
-
-Run this workflow to change the way Ansible playbooks connect to a router.
-Either via OOB access, or directly to the loopback interface.
diff --git a/docs/workflow/modify_isis_metric.md b/docs/workflow/modify_isis_metric.md
deleted file mode 100644
index 0fda396a..00000000
--- a/docs/workflow/modify_isis_metric.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Modify ISIS metric
-
-This workflow modifies the ISIS metric of a trunk.
-
-The strategy is to re-apply the necessary template to the configuration
-construct: using a "replace" strategy only the necessary modifications will be
-applied.
diff --git a/docs/workflow/modify_router_kentik_license.md b/docs/workflow/modify_router_kentik_license.md
deleted file mode 100644
index 195bf928..00000000
--- a/docs/workflow/modify_router_kentik_license.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# Modify Router Kentik license
-
-Change the license of a router in Kentik. The operator can select the license
-from a list of all available plans in Kentik, and it will show the utilisation
-of each license.
diff --git a/docs/workflow/modify_site.md b/docs/workflow/modify_site.md
deleted file mode 100644
index ecea9037..00000000
--- a/docs/workflow/modify_site.md
+++ /dev/null
@@ -1,12 +0,0 @@
-# Modify Site
-
-Attributes of an existing site can be modified using the `modify_site` workflow.
-As a result, other subscriptions that rely on this site will have referenced 
-attributes updated as well. 
-
-!!! warning
-
-    Be aware that although this *does* update attributes in the services 
-    database, it does **not** update any active subscription instances that are
-    already deployed. You will need to run additional workflows to update
-    subscriptions that depend on this change
diff --git a/docs/workflow/modify_trunk_interface.md b/docs/workflow/modify_trunk_interface.md
deleted file mode 100644
index 242c8571..00000000
--- a/docs/workflow/modify_trunk_interface.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# Modify IP trunk interface
-
-Modifies LAG interfaces and members. This is used to  increase capacity or to
-change SID/interface descriptions.
-
-The strategy is to re-apply the necessary template to the configuration
-construct: using a "replace" strategy only the necessary modifications will be
-applied.
diff --git a/docs/workflow/promote_p_to_pe.md b/docs/workflow/promote_p_to_pe.md
deleted file mode 100644
index 79980bda..00000000
--- a/docs/workflow/promote_p_to_pe.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Promote P to PE
-
-Promote a router from the P role to a PE role.
diff --git a/docs/workflow/redeploy_base_config.md b/docs/workflow/redeploy_base_config.md
deleted file mode 100644
index aea7a73b..00000000
--- a/docs/workflow/redeploy_base_config.md
+++ /dev/null
@@ -1,12 +0,0 @@
-# Redeploy base configuration
-
-When a new router is deployed, it is loaded with the current version of
-configuration that contain the bare necessities. For various reasons, this 
-template may change, and the resulting configuration follows from this. To 
-update a router 'in the wild' where this change should be reflected, the 
-workflow `redeploy_base_config` is used.
-
-This workflow only takes a trouble ticket number as initial input, and 
-deploys the base configuration, first as a dry run. After confirmation by an 
-operator, the configuration is committed to the machine, and this completes 
-the workflow.
diff --git a/docs/workflow/terminate_iptrunk.md b/docs/workflow/terminate_iptrunk.md
deleted file mode 100644
index af3c0799..00000000
--- a/docs/workflow/terminate_iptrunk.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# Terminate IP trunk
-
-This workflow deletes all the configuration related with an IPtrunk from the
-network and brings the subscription from `ACTIVE` to `TERMINATED`. The steps
-are the following:
-
-- Modify the ISIS metric of the trunks so to evacuate traffic - and await
-confirmation from an operator.
-- Delete all the configuration (first dry then actual deletion):
-    - LAG and members of the LAG
-    - reference in LLDP protocol (if Juniper)
-    - reference in ISIS protocol
-- Delete the IPv4/IPv6 networks from IPAM
diff --git a/docs/workflow/terminate_router.md b/docs/workflow/terminate_router.md
deleted file mode 100644
index 93a21c30..00000000
--- a/docs/workflow/terminate_router.md
+++ /dev/null
@@ -1,17 +0,0 @@
-# Terminate Router
-
-To terminate a router, the workflow `terminate_router` is used. The operator 
-is presented with an input form that requires once again a trouble ticket 
-number. On top of this, there is also the option whether this workflow should
-remove all configuration on the router, and whether IPAM entries related to 
-this device should be removed.
-
-The workflow consists of the following steps:
-
-- Deprovision IPAM resources (if selected).
-- Try to remove configuration form the router (if selected).
-- Commit removal of configuration (if selected).
-- For Nokia devices: remove interfaces from Netbox.
-- Remove the device from LibreNMS.
-- For PE routers: apply the archiving license in Kentik.
-- Set the subscription status to `TERMINATED`.
diff --git a/docs/workflow/terminate_site.md b/docs/workflow/terminate_site.md
deleted file mode 100644
index 461b8338..00000000
--- a/docs/workflow/terminate_site.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Terminate Site
-
-The `terminate_site` workflow will take an existing and active site 
-subscription from an `ACTIVE` to a `TERMINATED` state. This requires all 
-dependant subscription instances to already be terminated. If this is not 
-the case, the workflow will be unavailable for an operator to run, accompanied
-by an error message explaining this fact.
diff --git a/docs/workflow/update_ibgp_mesh.md b/docs/workflow/update_ibgp_mesh.md
deleted file mode 100644
index 7f9543e0..00000000
--- a/docs/workflow/update_ibgp_mesh.md
+++ /dev/null
@@ -1,22 +0,0 @@
-# Update iBGP mesh
-
-Once a new router is added to the network, it must become reachable by all 
-other devices. To achieve this, the `update_ibgp_mesh` workflow must be 
-executed. This workflow will add the new P router to all PE routers in the 
-network, and add all existing PE routers to the new P router. The only input 
-this workflow takes, is a trouble ticket number. All other required 
-information is already in the service database.
-
-The workflow will run 5 Ansible playbooks:
-
-1. Check: add P router to all PE routers
-2. Deploy: add P router to all PE routers
-3. Check: add all PE routers to P router
-4. Deploy: add all PE routers to P router
-5. Verify: check that the iBGP has come up
-
-Once these playbooks have been run successfully, the new P router is added 
-to LibreNMS. Finally, the subscription model of the router is updated such that
-`router_access_via_ts` is set to `False`. This is because the router is now 
-reachable by other machines by its loopback address. Using out of band access is
-therefore not needed anymore.
diff --git a/gso/workflows/iptrunk/activate_iptrunk.py b/gso/workflows/iptrunk/activate_iptrunk.py
index 4ec1dff0..64a2fe8f 100644
--- a/gso/workflows/iptrunk/activate_iptrunk.py
+++ b/gso/workflows/iptrunk/activate_iptrunk.py
@@ -1,4 +1,8 @@
-"""Activate IP trunk takes a provisioning trunk to the active lifecycle state."""
+"""Activate IP trunk takes a provisioning trunk to the active lifecycle state.
+
+When the SharePoint checklist of a trunk is completed, this workflow is run to take the subscription from `PROVISIONING`
+to `ACTIVE`. The operator is asked to give a URL to the completed checklist.
+"""
 
 from orchestrator.config.assignee import Assignee
 from orchestrator.forms import FormPage
diff --git a/gso/workflows/iptrunk/create_iptrunk.py b/gso/workflows/iptrunk/create_iptrunk.py
index 9074af7c..39a0faf4 100644
--- a/gso/workflows/iptrunk/create_iptrunk.py
+++ b/gso/workflows/iptrunk/create_iptrunk.py
@@ -1,4 +1,29 @@
-"""A creation workflow that deploys a new IP trunk service."""
+"""A creation workflow that deploys a new IP trunk service.
+
+This the workflow that brings the subscription from `INACTIVE` to `PROVISIONING`. The deployment of a new IPtrunk
+consist in the following steps:
+
+- Fill the form with the necessary fields:
+    - SID
+    - Type
+    - Speed
+    - Nodes
+    - LAG interfaces with description
+    - LAG members with description
+- WFO will query IPAM to retrieve the IPv4/IPv6 Networks necessary for the trunk. The container to use is specified in
+`oss-params.json`
+- The configuration necessary to deploy the LAG is generated and applied to the destination nodes using the Ansible
+playbook `iptrunks.yaml` This is done first in a dry mode (without committing) and then in a real mode committing the
+configuration. The commit message has the `subscription_id` and the `process_id`. Included in this, is the configuration
+necessary to enable LLDP on the physical interfaces.
+- Once the LAG interface is deployed, another Ansible playbook is called to verify that IP traffic can actually flow
+over the trunk ( `iptrunk_checks.yaml`)
+- Once the check is passed, the ISIS configuration will take place using the same `iptrunks.yaml`. Also in this case
+first there is a dry run and then a commit.
+- After this step the ISIS adjacency gets checked using `iptrunks_checks.yaml`
+
+The trunk is deployed with an initial ISIS metric of 90.000 to prevent traffic to pass.
+"""
 
 import json
 from ipaddress import IPv4Address, IPv4Network, IPv6Address, IPv6Network
diff --git a/gso/workflows/iptrunk/deploy_twamp.py b/gso/workflows/iptrunk/deploy_twamp.py
index dbbe55ee..468564de 100644
--- a/gso/workflows/iptrunk/deploy_twamp.py
+++ b/gso/workflows/iptrunk/deploy_twamp.py
@@ -1,4 +1,8 @@
-"""Workflow for adding :term:`TWAMP` to an existing IP trunk."""
+"""Workflow for adding :term:`TWAMP` to an existing IP trunk.
+
+Takes a trunk that is either `PROVISIONING` or `ACTIVE` and deploy configuration for TWAMP. The trunk will not change
+state after running this workflow.
+"""
 
 import json
 
diff --git a/gso/workflows/iptrunk/migrate_iptrunk.py b/gso/workflows/iptrunk/migrate_iptrunk.py
index fa5e26c9..e288000a 100644
--- a/gso/workflows/iptrunk/migrate_iptrunk.py
+++ b/gso/workflows/iptrunk/migrate_iptrunk.py
@@ -2,6 +2,8 @@
 
 For a trunk that originally connected endpoints A and B, this workflow introduces a new endpoint C. The trunk is then
 configured to run from A to C. B is then no longer associated with this IP trunk.
+
+In the input form, the operator selects a new router where this trunk should terminate on.
 """
 
 import copy
diff --git a/gso/workflows/iptrunk/modify_isis_metric.py b/gso/workflows/iptrunk/modify_isis_metric.py
index 45865e39..26c1b35b 100644
--- a/gso/workflows/iptrunk/modify_isis_metric.py
+++ b/gso/workflows/iptrunk/modify_isis_metric.py
@@ -1,4 +1,8 @@
-"""A modification workflow for setting a new :term:`ISIS` metric for an IP trunk."""
+"""A modification workflow for setting a new :term:`ISIS` metric for an IP trunk.
+
+The strategy is to re-apply the necessary template to the configuration construct: using a "replace" strategy only the
+necessary modifications will be applied.
+"""
 
 import json
 
diff --git a/gso/workflows/iptrunk/modify_trunk_interface.py b/gso/workflows/iptrunk/modify_trunk_interface.py
index 3537f64b..dec0d149 100644
--- a/gso/workflows/iptrunk/modify_trunk_interface.py
+++ b/gso/workflows/iptrunk/modify_trunk_interface.py
@@ -1,4 +1,10 @@
-"""A modification workflow that updates the :term:`LAG` interfaces that are part of an existing IP trunk."""
+"""A modification workflow that updates the :term:`LAG` interfaces that are part of an existing IP trunk.
+
+Modifies LAG interfaces and members. This is used to  increase capacity or to change SID/interface descriptions.
+
+The strategy is to re-apply the necessary template to the configuration construct: using a "replace" strategy only the
+necessary modifications will be applied.
+"""
 
 import json
 from typing import Annotated
diff --git a/gso/workflows/iptrunk/terminate_iptrunk.py b/gso/workflows/iptrunk/terminate_iptrunk.py
index 9b5cf71a..1e448ad0 100644
--- a/gso/workflows/iptrunk/terminate_iptrunk.py
+++ b/gso/workflows/iptrunk/terminate_iptrunk.py
@@ -1,4 +1,15 @@
-"""A termination workflow for an active IP trunk."""
+"""A termination workflow for an active IP trunk.
+
+This workflow deletes all the configuration related with an IPtrunk from the network and brings the subscription from
+`ACTIVE` to `TERMINATED`. The steps are the following:
+
+- Modify the ISIS metric of the trunks so to evacuate traffic - and await confirmation from an operator.
+- Delete all the configuration (first dry then actual deletion):
+    - LAG and members of the LAG
+    - reference in LLDP protocol (if Juniper)
+    - reference in ISIS protocol
+- Delete the IPv4/IPv6 networks from IPAM
+"""
 
 import ipaddress
 import json
diff --git a/gso/workflows/router/activate_router.py b/gso/workflows/router/activate_router.py
index 751fc356..6070faaf 100644
--- a/gso/workflows/router/activate_router.py
+++ b/gso/workflows/router/activate_router.py
@@ -1,4 +1,8 @@
-"""Activate router takes a provisioning router to the active lifecycle state."""
+"""Activate router takes a provisioning router to the active lifecycle state.
+
+When the SharePoint checklist of a router is completed, this workflow is run to take the subscription from
+`PROVISIONING` to `ACTIVE`. The operator is asked to give a URL to the completed checklist.
+"""
 
 from orchestrator.config.assignee import Assignee
 from orchestrator.forms import FormPage
diff --git a/gso/workflows/router/create_router.py b/gso/workflows/router/create_router.py
index 920973a7..22c86665 100644
--- a/gso/workflows/router/create_router.py
+++ b/gso/workflows/router/create_router.py
@@ -1,4 +1,44 @@
-"""A creation workflow for adding a new router to the network."""
+"""A creation workflow for adding a new router to the network.
+
+To add a new router to the GÉANT network, the `create_router` workflow must be executed first. The intake form for this
+workflow requires the following fields to be filled in:
+
+* Trouble ticket number
+* Router vendor
+* Router site
+* Hostname
+* Terminal server port
+* Router role
+
+The hostname is validated, by checking that the resulting FQDN is not already taken in IPAM.
+
+!!! warning
+    The validation only checks whether the FQDN is already taken in IPAM, **not** whether it is registered somewhere on
+    the internet.
+
+When the workflow is started, a subscription object is first instantiated in the service database, containing all the
+information that was provided in the input form at the beginning. Then, the loopback addresses are allocated in IPAM,
+which results in both the IPv4 and IPv6 addresses in the product model.
+
+Once allocated, the first dry run of deploying router configuration takes place. An Ansible playbook is run, with all
+the attributes of the new router. This is where GSO communicates with LSO, and the router configuration is checked, but
+not committed to the machine.
+
+After the dry run, the operator is presented with a view of the outcome of this playbook. This is their opportunity to
+verify successful execution of the Ansible playbook, and whether the difference in configuration is as expected. If not,
+this is their chance to abort the workflow, and no harm is done to the router.
+
+When the operator confirms the outcome of this playbook execution, the playbook runs once again, but it will also commit
+the configuration after checking. With the new router configured, the IPAM resources are verified to ensure this
+external system is configured correctly.
+
+If the new router is a Nokia, all its interfaces are added to Netbox. This is done to keep track of interface
+reservations and bookkeeping. For Juniper routers, this does not need to take place. These existing devices are not
+migrated into Netbox.
+
+Finally, an Ansible playbook is run to verify that the connectivity and optical power levels of the router are in order.
+Once this is completed, a checklist item is created in SharePoint and the router is taken into the `PROVISIONING` state.
+"""
 
 from typing import Self
 
diff --git a/gso/workflows/router/modify_connection_strategy.py b/gso/workflows/router/modify_connection_strategy.py
index 890329d8..ea1b589c 100644
--- a/gso/workflows/router/modify_connection_strategy.py
+++ b/gso/workflows/router/modify_connection_strategy.py
@@ -1,4 +1,8 @@
-"""Modify connection strategy workflow. Flipping the connection between in-band to out-of-band."""
+"""Modify connection strategy workflow.
+
+Run this workflow to change the way Ansible playbooks connect to a router. Either via OOB access, or directly to the
+loopback interface.
+"""
 
 from orchestrator.forms import FormPage
 from orchestrator.targets import Target
diff --git a/gso/workflows/router/modify_kentik_license.py b/gso/workflows/router/modify_kentik_license.py
index e1a87021..581c97d6 100644
--- a/gso/workflows/router/modify_kentik_license.py
+++ b/gso/workflows/router/modify_kentik_license.py
@@ -1,4 +1,8 @@
-"""A workflow that modifies the Kentik license of a router."""
+"""A workflow that modifies the Kentik license of a router.
+
+Change the license of a router in Kentik. The operator can select the license from a list of all available plans in
+Kentik, and it will show the utilisation of each license.
+"""
 
 import logging
 from typing import Any
diff --git a/gso/workflows/router/redeploy_base_config.py b/gso/workflows/router/redeploy_base_config.py
index 48348abb..9a1de70b 100644
--- a/gso/workflows/router/redeploy_base_config.py
+++ b/gso/workflows/router/redeploy_base_config.py
@@ -1,4 +1,12 @@
-"""A workflow that re-deploys base config on a router."""
+"""A workflow that re-deploys base config on a router.
+
+When a new router is deployed, it is loaded with the current version of configuration that contain the bare necessities.
+For various reasons, this template may change, and the resulting configuration follows from this. To update a router
+'in the wild' where this change should be reflected, the workflow `redeploy_base_config` is used.
+
+This workflow only takes a trouble ticket number as initial input, and deploys the base configuration, first as a dry
+run. After confirmation by an operator, the configuration is committed to the machine, and this completes the workflow.
+"""
 
 from orchestrator.forms import FormPage
 from orchestrator.forms.validators import Label
diff --git a/gso/workflows/router/terminate_router.py b/gso/workflows/router/terminate_router.py
index 56344fc2..604265f7 100644
--- a/gso/workflows/router/terminate_router.py
+++ b/gso/workflows/router/terminate_router.py
@@ -1,4 +1,19 @@
-"""A workflow that terminates a router."""
+"""A workflow that terminates a router.
+
+To terminate a router, the workflow `terminate_router` is used. The operator is presented with an input form that
+requires once again a trouble ticket number. On top of this, there is also the option whether this workflow should
+remove all configuration on the router, and whether IPAM entries related to this device should be removed.
+
+The workflow consists of the following steps:
+
+- Deprovision IPAM resources (if selected).
+- Try to remove configuration form the router (if selected).
+- Commit removal of configuration (if selected).
+- For Nokia devices: remove interfaces from Netbox.
+- Remove the device from LibreNMS.
+- For PE routers: apply the archiving license in Kentik.
+- Set the subscription status to `TERMINATED`.
+"""
 
 import ipaddress
 import json
diff --git a/gso/workflows/router/update_ibgp_mesh.py b/gso/workflows/router/update_ibgp_mesh.py
index 7adea41c..6cee29fa 100644
--- a/gso/workflows/router/update_ibgp_mesh.py
+++ b/gso/workflows/router/update_ibgp_mesh.py
@@ -1,4 +1,22 @@
-"""Update iBGP mesh workflow. Adds a new P router to the mesh of PE routers in the network."""
+"""Update iBGP mesh workflow. Adds a new P router to the mesh of PE routers in the network.
+
+Once a new router is added to the network, it must become reachable by all other devices. To achieve this, the
+`update_ibgp_mesh` workflow must be executed. This workflow will add the new P router to all PE routers in the network,
+and add all existing PE routers to the new P router. The only input this workflow takes, is a trouble ticket number.
+All other required information is already in the service database.
+
+The workflow will run 5 Ansible playbooks:
+
+1. Check: add P router to all PE routers
+2. Deploy: add P router to all PE routers
+3. Check: add all PE routers to P router
+4. Deploy: add all PE routers to P router
+5. Verify: check that the iBGP has come up
+
+Once these playbooks have been run successfully, the new P router is added to LibreNMS. Finally, the subscription model
+of the router is updated such that `router_access_via_ts` is set to `False`. This is because the router is now reachable
+by other machines by its loopback address. Using out of band access is therefore not needed anymore.
+"""
 
 from typing import Any
 
diff --git a/gso/workflows/site/create_site.py b/gso/workflows/site/create_site.py
index 384dd59f..6bf4bd74 100644
--- a/gso/workflows/site/create_site.py
+++ b/gso/workflows/site/create_site.py
@@ -1,4 +1,8 @@
-"""A creation workflow for adding a new site to the service database."""
+"""A creation workflow for adding a new site to the service database.
+
+The `create_site` workflow creates a new site object in the service database, and sets the subscription lifecycle to
+`ACTIVE`. The attributes that are input using the intake form of the workflow are stored, and nothing else happens.
+"""
 
 from orchestrator.forms import FormPage
 from orchestrator.targets import Target
diff --git a/gso/workflows/site/modify_site.py b/gso/workflows/site/modify_site.py
index a522a714..2a1913f6 100644
--- a/gso/workflows/site/modify_site.py
+++ b/gso/workflows/site/modify_site.py
@@ -1,4 +1,16 @@
-"""A modification workflow for a site."""
+"""A modification workflow for a site.
+
+Attributes of an existing site can be modified using the `modify_site` workflow.
+As a result, other subscriptions that rely on this site will have referenced
+attributes updated as well.
+
+!!! warning
+
+    Be aware that although this *does* update attributes in the services
+    database, it does **not** update any active subscription instances that are
+    already deployed. You will need to run additional workflows to update
+    subscriptions that depend on this change
+"""
 
 from functools import partial
 from typing import Annotated
diff --git a/gso/workflows/site/terminate_site.py b/gso/workflows/site/terminate_site.py
index cd710752..8f13e358 100644
--- a/gso/workflows/site/terminate_site.py
+++ b/gso/workflows/site/terminate_site.py
@@ -1,4 +1,9 @@
-"""A workflow for terminating a site subscription."""
+"""A workflow for terminating a site subscription.
+
+The `terminate_site` workflow will take an existing and active site subscription from an `ACTIVE` to a `TERMINATED`
+state. This requires all dependant subscription instances to already be terminated. If this is not the case, the
+workflow will be unavailable for an operator to run, accompanied by an error message explaining this fact.
+"""
 
 from orchestrator.forms import FormPage
 from orchestrator.forms.validators import Label
-- 
GitLab