diff --git a/gso/products/__init__.py b/gso/products/__init__.py index 319d1578b865217c83359a744274ac41d1e41f3e..b2b3e82946788a0ac336b03aab2ae571270735e6 100644 --- a/gso/products/__init__.py +++ b/gso/products/__init__.py @@ -1,5 +1,5 @@ """ -Module that updated the domain model of GSO. Should contain all types of +Module that updates the domain model of GSO. Should contain all types of subscriptions. """ from orchestrator.domain import SUBSCRIPTION_MODEL_REGISTRY diff --git a/gso/products/product_blocks/__init__.py b/gso/products/product_blocks/__init__.py index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..d1f718d83ec9df7d2b68374f4a7149168dac76b2 100644 --- a/gso/products/product_blocks/__init__.py +++ b/gso/products/product_blocks/__init__.py @@ -0,0 +1,8 @@ +from enum import IntEnum + + +class PhyPortCapacity(IntEnum): + ONE = 1 + TEN = 10 + HUNDRED = 100 + FOUR_HUNDRED = 400 diff --git a/gso/workflows/iptrunk/create_iptrunk.py b/gso/workflows/iptrunk/create_iptrunk.py index b33678d1422413daefbae90a445b464b91adedd4..425afc068794ce3ff2565377f4988be992c2e2c1 100644 --- a/gso/workflows/iptrunk/create_iptrunk.py +++ b/gso/workflows/iptrunk/create_iptrunk.py @@ -3,7 +3,7 @@ from uuid import uuid4 from orchestrator.db.models import ProductTable, SubscriptionTable # noinspection PyProtectedMember from orchestrator.forms import FormPage -from orchestrator.forms.validators import Choice, choice_list +from orchestrator.forms.validators import Choice from orchestrator.targets import Target from orchestrator.types import FormGenerator, State from orchestrator.types import SubscriptionLifecycle, UUIDstr @@ -12,6 +12,7 @@ from orchestrator.workflows.steps import resync, set_status from orchestrator.workflows.steps import store_process_subscription from orchestrator.workflows.utils import wrap_create_initial_input_form +from gso.products.product_blocks import PhyPortCapacity from gso.products.product_blocks.iptrunk import IptrunkType from gso.products.product_types.device import Device from gso.products.product_types.iptrunk import IptrunkInactive, \ @@ -22,11 +23,14 @@ from gso.services.provisioning_proxy import confirm_pp_results, \ await_pp_results -def device_selector(choice_value: str) -> list: - device_subscriptions = {} +def initial_input_form_generator(product_name: str) -> FormGenerator: + # TODO: we need additional validation: + # * interface names must be validated + + devices = {} for device_id, device_description in ( SubscriptionTable.query.join(ProductTable) - .filter( + .filter( ProductTable.product_type == 'Device', SubscriptionTable.status == 'active', ) @@ -34,18 +38,8 @@ def device_selector(choice_value: str) -> list: SubscriptionTable.description) .all() ): - device_subscriptions[str(device_id)] = device_description - - # noinspection PyTypeChecker - return choice_list( - Choice(choice_value, zip(device_subscriptions.keys(), - device_subscriptions.items())), # type:ignore - min_items=1, - max_items=1, - ) - + devices[str(device_id)] = device_description -def initial_input_form_generator(product_name: str) -> FormGenerator: class CreateIptrunkForm(FormPage): class Config: title = product_name @@ -53,31 +47,44 @@ def initial_input_form_generator(product_name: str) -> FormGenerator: geant_s_sid: str iptrunk_description: str iptrunk_type: IptrunkType - iptrunk_speed: str # This should be an enum: 1/10/100/400 + iptrunk_speed: PhyPortCapacity iptrunk_minimum_links: int - iptrunk_sideA_node_id: device_selector( - choice_value='DeviceEnumA') # noqa: F821 + initial_user_input = yield CreateIptrunkForm + + DeviceEnumA = Choice('Device A', zip(devices.keys(), devices.items())) + + class CreateIptrunkSideAForm(FormPage): + class Config: + title = 'Provide subscription details for side A of the trunk.' + + iptrunk_sideA_node_id: DeviceEnumA iptrunk_sideA_ae_iface: str iptrunk_sideA_ae_geant_a_sid: str iptrunk_sideA_ae_members: list[str] iptrunk_sideA_ae_members_descriptions: list[str] - iptrunk_sideB_node_id: device_selector( - choice_value='DeviceEnumB') # noqa: F821 + user_input_side_a = yield CreateIptrunkSideAForm + + # We remove the selected device for side A, to prevent any loops + devices.pop(str(user_input_side_a.iptrunk_sideA_node_id.name)) + DeviceEnumB = Choice('Device B', zip(devices.keys(), devices.items())) + + class CreateIptrunkSideBForm(FormPage): + class Config: + title = 'Provide subscription details for side B of the trunk.' + + iptrunk_sideB_node_id: DeviceEnumB iptrunk_sideB_ae_iface: str iptrunk_sideB_ae_geant_a_sid: str iptrunk_sideB_ae_members: list[str] iptrunk_sideB_ae_members_descriptions: list[str] - # TODO: we need additional validation: - # * sideA fqdn must be different from sideB fqdn - # * the length of iptrunk_sideA_ae_members should - # be the same as iptrunk_sideB_ae_members - # * interface names must be validated - user_input = yield CreateIptrunkForm + user_input_side_b = yield CreateIptrunkSideBForm - return user_input.dict() + return initial_user_input.dict() | \ + user_input_side_a.dict() | \ + user_input_side_b.dict() @step('Create subscription') diff --git a/setup.py b/setup.py index 7062c773b0d214c582e7c5b9db49da806d1eae59..333091fe42794a4d8d2118c0761dd53864872e3c 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ setup( author='GEANT', author_email='swd@geant.org', description='GEANT Service Orchestrator', - url=('https://gitlab.geant.org/goat/geant-service-orchestrator'), + url='https://gitlab.geant.org/goat/geant-service-orchestrator', packages=find_packages(), install_requires=[ 'orchestrator-core==1.0.0',