From 6a847ed2761faa8e2f8c038f77dec0ce3503a273 Mon Sep 17 00:00:00 2001
From: Karel van Klink <karel.vanklink@geant.org>
Date: Tue, 23 Apr 2024 12:58:30 +0200
Subject: [PATCH] Add import workflows for other products as well

also condense migrations into a single one
---
 ...e_add_site_modification_import_workflow.py | 39 ------------
 ...2ec1d9bd92_add_product_import_workflows.py | 63 +++++++++++++++++++
 gso/translations/en-GB.json                   |  6 +-
 gso/workflows/__init__.py                     | 17 ++++-
 gso/workflows/iptrunk/import_iptrunk.py       | 27 ++++++++
 .../office_router/import_office_router.py     | 34 ++++++++++
 gso/workflows/router/import_router.py         | 27 ++++++++
 gso/workflows/site/import_site.py             |  2 +-
 .../import_super_pop_switch.py                | 34 ++++++++++
 9 files changed, 206 insertions(+), 43 deletions(-)
 delete mode 100644 gso/migrations/versions/2024-04-23_8ebfc8a34c2e_add_site_modification_import_workflow.py
 create mode 100644 gso/migrations/versions/2024-04-23_c12ec1d9bd92_add_product_import_workflows.py
 create mode 100644 gso/workflows/iptrunk/import_iptrunk.py
 create mode 100644 gso/workflows/office_router/import_office_router.py
 create mode 100644 gso/workflows/router/import_router.py
 create mode 100644 gso/workflows/super_pop_switch/import_super_pop_switch.py

diff --git a/gso/migrations/versions/2024-04-23_8ebfc8a34c2e_add_site_modification_import_workflow.py b/gso/migrations/versions/2024-04-23_8ebfc8a34c2e_add_site_modification_import_workflow.py
deleted file mode 100644
index f1802a3f..00000000
--- a/gso/migrations/versions/2024-04-23_8ebfc8a34c2e_add_site_modification_import_workflow.py
+++ /dev/null
@@ -1,39 +0,0 @@
-"""Add site modification import workflow.
-
-Revision ID: 8ebfc8a34c2e
-Revises: ab8d805d27b3
-Create Date: 2024-04-23 11:32:39.502729
-
-"""
-import sqlalchemy as sa
-from alembic import op
-
-# revision identifiers, used by Alembic.
-revision = '8ebfc8a34c2e'
-down_revision = 'ab8d805d27b3'
-branch_labels = None
-depends_on = None
-
-
-from orchestrator.migrations.helpers import create_workflow, delete_workflow
-
-new_workflows = [
-    {
-        "name": "import_site",
-        "target": "MODIFY",
-        "description": "Import Site",
-        "product_type": "ImportedSite"
-    }
-]
-
-
-def upgrade() -> None:
-    conn = op.get_bind()
-    for workflow in new_workflows:
-        create_workflow(conn, workflow)
-
-
-def downgrade() -> None:
-    conn = op.get_bind()
-    for workflow in new_workflows:
-        delete_workflow(conn, workflow["name"])
diff --git a/gso/migrations/versions/2024-04-23_c12ec1d9bd92_add_product_import_workflows.py b/gso/migrations/versions/2024-04-23_c12ec1d9bd92_add_product_import_workflows.py
new file mode 100644
index 00000000..a7ac0093
--- /dev/null
+++ b/gso/migrations/versions/2024-04-23_c12ec1d9bd92_add_product_import_workflows.py
@@ -0,0 +1,63 @@
+"""Add product import workflows.
+
+Revision ID: c12ec1d9bd92
+Revises: ab8d805d27b3
+Create Date: 2024-04-23 12:57:51.227269
+
+"""
+import sqlalchemy as sa
+from alembic import op
+
+# revision identifiers, used by Alembic.
+revision = 'c12ec1d9bd92'
+down_revision = 'ab8d805d27b3'
+branch_labels = None
+depends_on = None
+
+
+from orchestrator.migrations.helpers import create_workflow, delete_workflow
+
+new_workflows = [
+    {
+        "name": "import_site",
+        "target": "MODIFY",
+        "description": "Import Site",
+        "product_type": "ImportedSite"
+    },
+    {
+        "name": "import_office_router",
+        "target": "MODIFY",
+        "description": "Import OfficeRouter",
+        "product_type": "ImportedOfficeRouter"
+    },
+    {
+        "name": "import_super_pop_switch",
+        "target": "MODIFY",
+        "description": "Import SuperPopSwitch",
+        "product_type": "ImportedSuperPopSwitch"
+    },
+    {
+        "name": "import_router",
+        "target": "MODIFY",
+        "description": "Import Router",
+        "product_type": "ImportedRouter"
+    },
+    {
+        "name": "import_iptrunk",
+        "target": "MODIFY",
+        "description": "Import Iptrunk",
+        "product_type": "ImportedIptrunk"
+    }
+]
+
+
+def upgrade() -> None:
+    conn = op.get_bind()
+    for workflow in new_workflows:
+        create_workflow(conn, workflow)
+
+
+def downgrade() -> None:
+    conn = op.get_bind()
+    for workflow in new_workflows:
+        delete_workflow(conn, workflow["name"])
diff --git a/gso/translations/en-GB.json b/gso/translations/en-GB.json
index e2b50e04..9fdf1dfa 100644
--- a/gso/translations/en-GB.json
+++ b/gso/translations/en-GB.json
@@ -51,6 +51,10 @@
         "create_imported_iptrunk": "NOT FOR HUMANS -- Import existing IP trunk",
         "create_imported_super_pop_switch": "NOT FOR HUMANS -- Import existing super PoP switch",
         "create_imported_office_router": "NOT FOR HUMANS -- Import existing office router",
-        "import_site": "Finalize import into a Site product"
+        "import_site": "NOT FOR HUMANS -- Finalize import into a Site product",
+        "import_router": "NOT FOR HUMANS -- Finalize import into a Router product",
+        "import_iptrunk": "NOT FOR HUMANS -- Finalize import into an IP trunk product",
+        "import_office_router": "NOT FOR HUMANS -- Finalize import into an Office router product",
+        "import_super_pop_switch": "NOT FOR HUMANS -- Finalize import into a Super PoP switch"
     }
 }
diff --git a/gso/workflows/__init__.py b/gso/workflows/__init__.py
index 535f6e1f..7fd75ed9 100644
--- a/gso/workflows/__init__.py
+++ b/gso/workflows/__init__.py
@@ -24,6 +24,7 @@ WF_USABLE_MAP.update(
     }
 )
 
+#  IP trunk workflows
 LazyWorkflowInstance("gso.workflows.iptrunk.activate_iptrunk", "activate_iptrunk")
 LazyWorkflowInstance("gso.workflows.iptrunk.create_iptrunk", "create_iptrunk")
 LazyWorkflowInstance("gso.workflows.iptrunk.deploy_twamp", "deploy_twamp")
@@ -31,20 +32,32 @@ LazyWorkflowInstance("gso.workflows.iptrunk.modify_isis_metric", "modify_isis_me
 LazyWorkflowInstance("gso.workflows.iptrunk.modify_trunk_interface", "modify_trunk_interface")
 LazyWorkflowInstance("gso.workflows.iptrunk.migrate_iptrunk", "migrate_iptrunk")
 LazyWorkflowInstance("gso.workflows.iptrunk.terminate_iptrunk", "terminate_iptrunk")
+LazyWorkflowInstance("gso.workflows.iptrunk.create_imported_iptrunk", "create_imported_iptrunk")
+LazyWorkflowInstance("gso.workflows.iptrunk.import_iptrunk", "import_iptrunk")
+
+#  Router workflows
 LazyWorkflowInstance("gso.workflows.router.activate_router", "activate_router")
 LazyWorkflowInstance("gso.workflows.router.create_router", "create_router")
 LazyWorkflowInstance("gso.workflows.router.redeploy_base_config", "redeploy_base_config")
 LazyWorkflowInstance("gso.workflows.router.terminate_router", "terminate_router")
 LazyWorkflowInstance("gso.workflows.router.update_ibgp_mesh", "update_ibgp_mesh")
 LazyWorkflowInstance("gso.workflows.router.modify_connection_strategy", "modify_connection_strategy")
+LazyWorkflowInstance("gso.workflows.router.import_router", "import_router")
+LazyWorkflowInstance("gso.workflows.router.create_imported_router", "create_imported_router")
+
+#  Site workflows
 LazyWorkflowInstance("gso.workflows.site.create_site", "create_site")
 LazyWorkflowInstance("gso.workflows.site.modify_site", "modify_site")
 LazyWorkflowInstance("gso.workflows.site.terminate_site", "terminate_site")
 LazyWorkflowInstance("gso.workflows.site.create_imported_site", "create_imported_site")
 LazyWorkflowInstance("gso.workflows.site.import_site", "import_site")
-LazyWorkflowInstance("gso.workflows.router.create_imported_router", "create_imported_router")
-LazyWorkflowInstance("gso.workflows.iptrunk.create_imported_iptrunk", "create_imported_iptrunk")
+
+#  Super PoP switch workflows
+LazyWorkflowInstance("gso.workflows.super_pop_switch.import_super_pop_switch", "import_super_pop_switch")
 LazyWorkflowInstance(
     "gso.workflows.super_pop_switch.create_imported_super_pop_switch", "create_imported_super_pop_switch"
 )
+
+#  Office router workflows
+LazyWorkflowInstance("gso.workflows.office_router.import_office_router", "import_office_router")
 LazyWorkflowInstance("gso.workflows.office_router.create_imported_office_router", "create_imported_office_router")
diff --git a/gso/workflows/iptrunk/import_iptrunk.py b/gso/workflows/iptrunk/import_iptrunk.py
new file mode 100644
index 00000000..dee0e3b1
--- /dev/null
+++ b/gso/workflows/iptrunk/import_iptrunk.py
@@ -0,0 +1,27 @@
+"""A modification workflow for migrating an ImportedIptrunk to an Iptrunk subscription."""
+
+from orchestrator.targets import Target
+from orchestrator.types import State, UUIDstr
+from orchestrator.workflow import StepList, done, init, step, workflow
+from orchestrator.workflows.steps import resync, store_process_subscription, unsync
+from orchestrator.workflows.utils import wrap_modify_initial_input_form
+
+from gso.products import ProductName
+from gso.products.product_types.iptrunk import ImportedIptrunk, Iptrunk
+from gso.services.subscriptions import get_product_id_by_name
+
+
+@step("Create new IP trunk subscription")
+def import_iptrunk_subscription(subscription_id: UUIDstr) -> State:
+    """Take an ImportedIptrunk subscription, and turn it into an Iptrunk subscription."""
+    old_iptrunk = ImportedIptrunk.from_subscription(subscription_id)
+    new_subscription_id = get_product_id_by_name(ProductName.SITE)
+    new_subscription = Iptrunk.from_other_product(old_iptrunk, new_subscription_id)
+
+    return {"subscription": new_subscription}
+
+
+@workflow("Import Iptrunk", target=Target.MODIFY, initial_input_form=wrap_modify_initial_input_form(None))
+def import_iptrunk() -> StepList:
+    """Modify an ImportedIptrunk subscription into an Iptrunk subscription to complete the import."""
+    return init >> store_process_subscription(Target.MODIFY) >> unsync >> import_iptrunk_subscription >> resync >> done
diff --git a/gso/workflows/office_router/import_office_router.py b/gso/workflows/office_router/import_office_router.py
new file mode 100644
index 00000000..0a774d51
--- /dev/null
+++ b/gso/workflows/office_router/import_office_router.py
@@ -0,0 +1,34 @@
+"""A modification workflow for migrating an ImportedOfficeRouter to an OfficeRouter subscription."""
+
+from orchestrator.targets import Target
+from orchestrator.types import State, UUIDstr
+from orchestrator.workflow import StepList, done, init, step, workflow
+from orchestrator.workflows.steps import resync, store_process_subscription, unsync
+from orchestrator.workflows.utils import wrap_modify_initial_input_form
+
+from gso.products import ProductName
+from gso.products.product_types.office_router import ImportedOfficeRouter, OfficeRouter
+from gso.services.subscriptions import get_product_id_by_name
+
+
+@step("Create new office_router subscription")
+def import_office_router_subscription(subscription_id: UUIDstr) -> State:
+    """Take an ImportedOfficeRouter subscription, and turn it into an OfficeRouter subscription."""
+    old_office_router = ImportedOfficeRouter.from_subscription(subscription_id)
+    new_subscription_id = get_product_id_by_name(ProductName.SITE)
+    new_subscription = OfficeRouter.from_other_product(old_office_router, new_subscription_id)
+
+    return {"subscription": new_subscription}
+
+
+@workflow("Import OfficeRouter", target=Target.MODIFY, initial_input_form=wrap_modify_initial_input_form(None))
+def import_office_router() -> StepList:
+    """Modify an ImportedOfficeRouter subscription into an OfficeRouter subscription to complete the import."""
+    return (
+        init
+        >> store_process_subscription(Target.MODIFY)
+        >> unsync
+        >> import_office_router_subscription
+        >> resync
+        >> done
+    )
diff --git a/gso/workflows/router/import_router.py b/gso/workflows/router/import_router.py
new file mode 100644
index 00000000..ea5d495f
--- /dev/null
+++ b/gso/workflows/router/import_router.py
@@ -0,0 +1,27 @@
+"""A modification workflow for setting a new :term:`ISIS` metric for an IP trunk."""
+
+from orchestrator.targets import Target
+from orchestrator.types import State, UUIDstr
+from orchestrator.workflow import StepList, done, init, step, workflow
+from orchestrator.workflows.steps import resync, store_process_subscription, unsync
+from orchestrator.workflows.utils import wrap_modify_initial_input_form
+
+from gso.products import ProductName
+from gso.products.product_types.router import ImportedRouter, Router
+from gso.services.subscriptions import get_product_id_by_name
+
+
+@step("Create new router subscription")
+def import_router_subscription(subscription_id: UUIDstr) -> State:
+    """Take an ImportedRouter subscription, and turn it into a Router subscription."""
+    old_router = ImportedRouter.from_subscription(subscription_id)
+    new_subscription_id = get_product_id_by_name(ProductName.SITE)
+    new_subscription = Router.from_other_product(old_router, new_subscription_id)
+
+    return {"subscription": new_subscription}
+
+
+@workflow("Import Router", target=Target.MODIFY, initial_input_form=wrap_modify_initial_input_form(None))
+def import_router() -> StepList:
+    """Modify an ImportedRouter subscription into a Router subscription to complete the import."""
+    return init >> store_process_subscription(Target.MODIFY) >> unsync >> import_router_subscription >> resync >> done
diff --git a/gso/workflows/site/import_site.py b/gso/workflows/site/import_site.py
index b49e8a06..1a144f64 100644
--- a/gso/workflows/site/import_site.py
+++ b/gso/workflows/site/import_site.py
@@ -1,4 +1,4 @@
-"""A modification workflow for setting a new :term:`ISIS` metric for an IP trunk."""
+"""A modification workflow for migrating an ImportedSite to a Site subscription."""
 
 from orchestrator.targets import Target
 from orchestrator.types import State, UUIDstr
diff --git a/gso/workflows/super_pop_switch/import_super_pop_switch.py b/gso/workflows/super_pop_switch/import_super_pop_switch.py
new file mode 100644
index 00000000..6ad665d9
--- /dev/null
+++ b/gso/workflows/super_pop_switch/import_super_pop_switch.py
@@ -0,0 +1,34 @@
+"""A modification workflow for migrating an ImportedSuperPopSwitch to a SuperPopSwitch subscription."""
+
+from orchestrator.targets import Target
+from orchestrator.types import State, UUIDstr
+from orchestrator.workflow import StepList, done, init, step, workflow
+from orchestrator.workflows.steps import resync, store_process_subscription, unsync
+from orchestrator.workflows.utils import wrap_modify_initial_input_form
+
+from gso.products import ProductName
+from gso.products.product_types.super_pop_switch import ImportedSuperPopSwitch, SuperPopSwitch
+from gso.services.subscriptions import get_product_id_by_name
+
+
+@step("Create new super_pop_switch subscription")
+def import_super_pop_switch_subscription(subscription_id: UUIDstr) -> State:
+    """Take an ImportedSuperPopSwitch subscription, and turn it into a SuperPopSwitch subscription."""
+    old_super_pop_switch = ImportedSuperPopSwitch.from_subscription(subscription_id)
+    new_subscription_id = get_product_id_by_name(ProductName.SITE)
+    new_subscription = SuperPopSwitch.from_other_product(old_super_pop_switch, new_subscription_id)
+
+    return {"subscription": new_subscription}
+
+
+@workflow("Import SuperPopSwitch", target=Target.MODIFY, initial_input_form=wrap_modify_initial_input_form(None))
+def import_super_pop_switch() -> StepList:
+    """Modify an ImportedSuperPopSwitch subscription into a SuperPopSwitch subscription to complete the import."""
+    return (
+        init
+        >> store_process_subscription(Target.MODIFY)
+        >> unsync
+        >> import_super_pop_switch_subscription
+        >> resync
+        >> done
+    )
-- 
GitLab