From 60f24f68df0aecf122469e0be6bdb56379aef28f Mon Sep 17 00:00:00 2001 From: Ubuntu <jorge.sasiain@ehu.eus> Date: Mon, 13 Mar 2023 10:02:53 +0000 Subject: [PATCH] CREATE workflows (not registered/tested yet) --- workflows/__init__.py | 6 + workflows/trunk/create_trunk.py | 73 ++++++++++++ workflows/trunk/create_trunk_config.py | 95 ++++++++++++++++ workflows/trunk/create_trunk_config_common.py | 102 +++++++++++++++++ workflows/trunk/create_trunk_config_side.py | 106 ++++++++++++++++++ 5 files changed, 382 insertions(+) create mode 100644 workflows/__init__.py create mode 100644 workflows/trunk/create_trunk.py create mode 100644 workflows/trunk/create_trunk_config.py create mode 100644 workflows/trunk/create_trunk_config_common.py create mode 100644 workflows/trunk/create_trunk_config_side.py diff --git a/workflows/__init__.py b/workflows/__init__.py new file mode 100644 index 000000000..9dc5e5f19 --- /dev/null +++ b/workflows/__init__.py @@ -0,0 +1,6 @@ +from orchestrator.workflows import LazyWorkflowInstance + +LazyWorkflowInstance("workflows.trunk.create_trunk", "create_trunk") +LazyWorkflowInstance("workflows.trunk.create_trunk_config", "create_trunk_config") +LazyWorkflowInstance("workflows.trunk.create_trunk_config_common", "create_trunk_config_common") +LazyWorkflowInstance("workflows.trunk.create_trunk_config_side", "create_trunk_config_side") diff --git a/workflows/trunk/create_trunk.py b/workflows/trunk/create_trunk.py new file mode 100644 index 000000000..16c5444bc --- /dev/null +++ b/workflows/trunk/create_trunk.py @@ -0,0 +1,73 @@ +from typing import Optional +from uuid import uuid4 + +from orchestrator.forms import FormPage +from orchestrator.targets import Target +from orchestrator.types import FormGenerator, State, SubscriptionLifecycle, UUIDstr +from orchestrator.workflow import done, init, step, workflow +from orchestrator.workflows.steps import resync, set_status, store_process_subscription +from orchestrator.workflows.utils import wrap_create_initial_input_form + +from products.product_types.trunk import TrunkInactive, TrunkProvisioning + + +def initial_input_form_generator(product_name: str) -> FormGenerator: + class CreateTrunkForm(FormPage): + class Config: + title = product_name + + trunk_name: str + geant_s_sid: Optional[str] + + user_input = yield CreateTrunkForm + + return user_input.dict() + + +def _provision_in_group_management_system(trunk_name: str) -> int: + + return abs(hash(trunk_name)) + + +@step("Create subscription") +def create_subscription(product: UUIDstr) -> State: + subscription = TrunkInactive.from_product_id(product, uuid4()) + + return {"subscription": subscription, "subscription_id": subscription.subscription_id} + + +@step("Initialize subscription") +def initialize_subscription(subscription: TrunkInactive, trunk_name: str, geant_s_sid: str) -> State: + subscription.trunk.trunk_name = trunk_name + subscription.trunk.geant_s_sid = geant_s_sid + subscription.description = f"Trunk {trunk_name}" + subscription = TrunkProvisioning.from_other_lifecycle(subscription, SubscriptionLifecycle.PROVISIONING) + + return {"subscription": subscription} + + +@step("Provision trunk") +def provision_trunk(subscription: TrunkProvisioning, trunk_name: str) -> State: + trunk_id = _provision_in_group_management_system(trunk_name) + subscription.trunk.trunk_id = trunk_id + + return {"subscription": subscription} + + +@workflow( + "Create trunk", + initial_input_form=wrap_create_initial_input_form(initial_input_form_generator), + target=Target.CREATE, +) +def create_trunk(): + + return ( + init + >> create_subscription + >> store_process_subscription(Target.CREATE) + >> initialize_subscription + >> provision_trunk + >> set_status(SubscriptionLifecycle.ACTIVE) + >> resync + >> done + ) diff --git a/workflows/trunk/create_trunk_config.py b/workflows/trunk/create_trunk_config.py new file mode 100644 index 000000000..44464dd06 --- /dev/null +++ b/workflows/trunk/create_trunk_config.py @@ -0,0 +1,95 @@ +from typing import List, Optional +from uuid import uuid4 +from random import randint + +from orchestrator.db.models import ProductTable, SubscriptionTable +from orchestrator.forms import FormPage +from orchestrator.forms.validators import Choice, choice_list +from orchestrator.targets import Target +from orchestrator.types import FormGenerator, State, SubscriptionLifecycle, UUIDstr +from orchestrator.workflow import done, init, step, workflow +from orchestrator.workflows.steps import resync, set_status, store_process_subscription +from orchestrator.workflows.utils import wrap_create_initial_input_form + +from products.product_types.trunk_config import TrunkConfigInactive, TrunkConfigProvisioning +from products.product_types.trunk import Trunk + + +def trunk_selector() -> list: + trunk_subscriptions = {} + for trunk_id, trunk_description in ( + SubscriptionTable.query.join(ProductTable) + .filter( + ProductTable.product_type == "Trunk", + SubscriptionTable.status == "active", + ) + .with_entities(SubscriptionTable.subscription_id, SubscriptionTable.description) + .all() + ): + trunk_subscriptions[str(trunk_id)] = trunk_description + + return choice_list( + Choice("TrunkEnum", zip(trunk_subscriptions.keys(), trunk_subscriptions.items())), + min_items=1, + max_items=1, + ) + + +def initial_input_form_generator(product_name: str) -> FormGenerator: + class CreateTrunkConfigForm(FormPage): + class Config: + title = product_name + + trunk_ids: trunk_selector() + + user_input = yield CreateTrunkConfigForm + + return user_input.dict() + + +def _provision_in_group_management_system() -> int: + + return random.randint(0, 2147483648) + + +@step("Create subscription") +def create_subscription(product: UUIDstr) -> State: + subscription = TrunkConfigInactive.from_product_id(product, uuid4()) + + return {"subscription": subscription, "subscription_id": subscription.subscription_id} + + +@step("Initialize subscription") +def initialize_subscription(subscription: TrunkConfigInactive, trunk_ids: List[str]) -> State: + subscription.trunk_config.trunk = Trunk.from_subscription(trunk_ids[0]).trunk + subscription.description = f"TrunkConfig from Trunk {subscription.trunk_config.trunk.trunk_name}" + subscription = TrunkConfigProvisioning.from_other_lifecycle(subscription, SubscriptionLifecycle.PROVISIONING) + + return {"subscription": subscription} + + +@step("Provision trunk config") +def provision_trunk_config(subscription: TrunkConfigProvisioning) -> State: + trunk_config_id = _provision_in_group_management_system() + subscription.trunk_config.trunk_config_id = trunk_config_id + + return {"subscription": subscription} + + +@workflow( + "Create trunk config", + initial_input_form=wrap_create_initial_input_form(initial_input_form_generator), + target=Target.CREATE, +) +def create_trunk(): + + return ( + init + >> create_subscription + >> store_process_subscription(Target.CREATE) + >> initialize_subscription + >> provision_trunk_config + >> set_status(SubscriptionLifecycle.ACTIVE) + >> resync + >> done + ) diff --git a/workflows/trunk/create_trunk_config_common.py b/workflows/trunk/create_trunk_config_common.py new file mode 100644 index 000000000..875a9f39e --- /dev/null +++ b/workflows/trunk/create_trunk_config_common.py @@ -0,0 +1,102 @@ +from typing import List, Optional +from uuid import uuid4 + +from orchestrator.db.models import ProductTable, SubscriptionTable +from orchestrator.forms import FormPage +from orchestrator.forms.validators import Choice, choice_list +from orchestrator.targets import Target +from orchestrator.types import FormGenerator, State, SubscriptionLifecycle, UUIDstr +from orchestrator.workflow import done, init, step, workflow +from orchestrator.workflows.steps import resync, set_status, store_process_subscription +from orchestrator.workflows.utils import wrap_create_initial_input_form + +from products.product_types.trunk_config_common import TrunkConfigCommonInactive, TrunkConfigCommonProvisioning +from products.product_types.trunk_config import TrunkConfig + + +def trunk_config_selector() -> list: + trunk_config_subscriptions = {} + for trunk_config_id, trunk_config_description in ( + SubscriptionTable.query.join(ProductTable) + .filter( + ProductTable.product_type == "TrunkConfig", + SubscriptionTable.status == "active", + ) + .with_entities(SubscriptionTable.subscription_id, SubscriptionTable.description) + .all() + ): + trunk_config_subscriptions[str(trunk_config_id)] = trunk_config_description + + return choice_list( + Choice("TrunkConfigEnum", zip(trunk_config_subscriptions.keys(), trunk_config_subscriptions.items())), + min_items=1, + max_items=1, + ) + + +def initial_input_form_generator(product_name: str) -> FormGenerator: + class CreateTrunkConfigForm(FormPage): + class Config: + title = product_name + + speed: str + is_leased_line: Optional[bool] + isis_metric: int + minimum_links: int + trunk_config_ids: trunk_config_selector() + + user_input = yield CreateTrunkConfigCommonForm + + return user_input.dict() + + +def _provision_in_group_management_system() -> int: + + return random.randint(0, 2147483648) + + +@step("Create subscription") +def create_subscription(product: UUIDstr) -> State: + subscription = TrunkConfigCommonInactive.from_product_id(product, uuid4()) + + return {"subscription": subscription, "subscription_id": subscription.subscription_id} + + +@step("Initialize subscription") +def initialize_subscription(subscription: TrunkConfigCommonInactive, speed: str, is_leased_line: bool, isis_metric: int, minimum_links: int, trunk_config_ids: List[str]) -> State: + subscription.trunk_config_common.speed = speed + subscription.trunk_config_common.is_leased_line = is_leased_line + subscription.trunk_config_common.isis_metric = isis_metric + subscription.trunk_config_common.minimum_links = minimum_links + subscription.trunk_config_common.trunk_config = TrunkConfig.from_subscription(trunk_config_ids[0]).trunk_config + subscription.description = f"TrunkConfigCommon from TrunkConfig {subscription.trunk_config_common.trunk_config.trunk_config_id}" + subscription = TrunkConfigCommonProvisioning.from_other_lifecycle(subscription, SubscriptionLifecycle.PROVISIONING) + + return {"subscription": subscription} + + +@step("Provision trunk config common") +def provision_trunk_config_common(subscription: TrunkConfigCommonProvisioning) -> State: + trunk_config_common_id = _provision_in_group_management_system() + subscription.trunk_config_common.trunk_config_common_id = trunk_config_common_id + + return {"subscription": subscription} + + +@workflow( + "Create trunk config common", + initial_input_form=wrap_create_initial_input_form(initial_input_form_generator), + target=Target.CREATE, +) +def create_trunk(): + + return ( + init + >> create_subscription + >> store_process_subscription(Target.CREATE) + >> initialize_subscription + >> provision_trunk_config_common + >> set_status(SubscriptionLifecycle.ACTIVE) + >> resync + >> done + ) diff --git a/workflows/trunk/create_trunk_config_side.py b/workflows/trunk/create_trunk_config_side.py new file mode 100644 index 000000000..5b67836f1 --- /dev/null +++ b/workflows/trunk/create_trunk_config_side.py @@ -0,0 +1,106 @@ +from typing import List, Optional +from uuid import uuid4 + +from orchestrator.db.models import ProductTable, SubscriptionTable +from orchestrator.forms import FormPage +from orchestrator.forms.validators import Choice, choice_list +from orchestrator.targets import Target +from orchestrator.types import FormGenerator, State, SubscriptionLifecycle, UUIDstr +from orchestrator.workflow import done, init, step, workflow +from orchestrator.workflows.steps import resync, set_status, store_process_subscription +from orchestrator.workflows.utils import wrap_create_initial_input_form + +from products.product_types.trunk_config_side import TrunkConfigSideInactive, TrunkConfigSideProvisioning +from products.product_types.trunk_config import TrunkConfig + + +def trunk_config_selector() -> list: + trunk_config_subscriptions = {} + for trunk_config_id, trunk_config_description in ( + SubscriptionTable.query.join(ProductTable) + .filter( + ProductTable.product_type == "TrunkConfig", + SubscriptionTable.status == "active", + ) + .with_entities(SubscriptionTable.subscription_id, SubscriptionTable.description) + .all() + ): + trunk_config_subscriptions[str(trunk_config_id)] = trunk_config_description + + return choice_list( + Choice("TrunkConfigEnum", zip(trunk_config_subscriptions.keys(), trunk_config_subscriptions.items())), + min_items=1, + max_items=1, + ) + + +def initial_input_form_generator(product_name: str) -> FormGenerator: + class CreateTrunkConfigForm(FormPage): + class Config: + title = product_name + + fqdn: str + ae_name: Optional[str] + geant_a_sid: Optional[str] + ipv4_address: Optional[str] + ipv6_address: Optional[str] + members: Optional[list] + trunk_config_ids: trunk_config_selector() + + user_input = yield CreateTrunkConfigSideForm + + return user_input.dict() + + +def _provision_in_group_management_system(fqdn: str) -> int: + + return abs(hash(fqdn)) + + +@step("Create subscription") +def create_subscription(product: UUIDstr) -> State: + subscription = TrunkConfigSideInactive.from_product_id(product, uuid4()) + + return {"subscription": subscription, "subscription_id": subscription.subscription_id} + + +@step("Initialize subscription") +def initialize_subscription(subscription: TrunkConfigSideInactive, fqdn: str, ae_name: str, geant_a_sid: str, ipv4_address: str, ipv6_address: str, members: list, trunk_config_ids: List[str]) -> State: + subscription.trunk_config_side.fqdn = fqdn + subscription.trunk_config_side.ae_name = ae_name + subscription.trunk_config_side.geant_a_sid = geant_a_sid + subscription.trunk_config_side.ipv4_address = ipv4_address + subscription.trunk_config_side.ipv6_address = ipv6_address + subscription.trunk_config_side.members = members + subscription.trunk_config_side.trunk_config = TrunkConfig.from_subscription(trunk_config_ids[0]).trunk_config + subscription.description = f"TrunkConfigSide from TrunkConfig {subscription.trunk_config_side.trunk_config.trunk_config_id}" + subscription = TrunkConfigSideProvisioning.from_other_lifecycle(subscription, SubscriptionLifecycle.PROVISIONING) + + return {"subscription": subscription} + + +@step("Provision trunk config side") +def provision_trunk_config_side(subscription: TrunkConfigSideProvisioning, fqdn: str) -> State: + trunk_config_side_id = _provision_in_group_management_system(fqdn) + subscription.trunk_config_side.trunk_config_side_id = trunk_config_side_id + + return {"subscription": subscription} + + +@workflow( + "Create trunk config side", + initial_input_form=wrap_create_initial_input_form(initial_input_form_generator), + target=Target.CREATE, +) +def create_trunk(): + + return ( + init + >> create_subscription + >> store_process_subscription(Target.CREATE) + >> initialize_subscription + >> provision_trunk_config_side + >> set_status(SubscriptionLifecycle.ACTIVE) + >> resync + >> done + ) -- GitLab