From 7660911a849ffa8fcbccb993d378d35191618ccf Mon Sep 17 00:00:00 2001 From: Neda Moeini <neda.moeini@geant.org> Date: Wed, 4 Dec 2024 15:40:47 +0100 Subject: [PATCH 01/20] Add migration for removing additional products. --- ...4cc835c615fc_remove_additional_products.py | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 gso/migrations/versions/2024-12-04_4cc835c615fc_remove_additional_products.py diff --git a/gso/migrations/versions/2024-12-04_4cc835c615fc_remove_additional_products.py b/gso/migrations/versions/2024-12-04_4cc835c615fc_remove_additional_products.py new file mode 100644 index 00000000..969e1e0f --- /dev/null +++ b/gso/migrations/versions/2024-12-04_4cc835c615fc_remove_additional_products.py @@ -0,0 +1,33 @@ +"""remove additional products. + +Revision ID: 4cc835c615fc +Revises: 28c1723c6a00 +Create Date: 2024-12-04 14:54:22.167158 + +""" +import sqlalchemy as sa +from alembic import op + +# revision identifiers, used by Alembic. +revision = '4cc835c615fc' +down_revision = '28c1723c6a00' +branch_labels = None +depends_on = None + + +def upgrade() -> None: + conn = op.get_bind() + conn.execute(sa.text(""" +DELETE FROM product_product_blocks WHERE product_product_blocks.product_id IN (SELECT products.product_id FROM products WHERE products.name IN ('IAS', 'Imported IAS', 'Imported GÉANT IP', 'GÉANT IP')) AND product_product_blocks.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('NRENL3CoreServiceBlock')) + """)) + conn.execute(sa.text(""" +DELETE FROM subscription_instances WHERE subscription_instances.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('NRENAccessPort', 'NRENL3CoreServiceBlock')) + """)) + conn.execute(sa.text(""" +DELETE FROM product_blocks WHERE product_blocks.name IN ('NRENAccessPort', 'NRENL3CoreServiceBlock') + """)) + + +def downgrade() -> None: + conn = op.get_bind() + -- GitLab From 486239cc39ea4dacac654d5b187159967f8157ef Mon Sep 17 00:00:00 2001 From: Neda Moeini <neda.moeini@geant.org> Date: Wed, 4 Dec 2024 15:49:18 +0100 Subject: [PATCH 02/20] Rename Service IDs to GS or GA id. --- ...ename_iptrunk_and_iptrunk_side_sid_and_.py | 35 ++++++++++++++ ...5c_rename_edgeport_and_sbp_gs_and_ga_id.py | 47 +++++++++++++++++++ gso/products/product_blocks/edge_port.py | 6 +-- gso/products/product_blocks/iptrunk.py | 12 ++--- .../product_blocks/service_binding_port.py | 6 +-- 5 files changed, 94 insertions(+), 12 deletions(-) create mode 100644 gso/migrations/versions/2024-12-04_e358efe9ab03_rename_iptrunk_and_iptrunk_side_sid_and_.py create mode 100644 gso/migrations/versions/2024-12-04_e36b3bd8a45c_rename_edgeport_and_sbp_gs_and_ga_id.py diff --git a/gso/migrations/versions/2024-12-04_e358efe9ab03_rename_iptrunk_and_iptrunk_side_sid_and_.py b/gso/migrations/versions/2024-12-04_e358efe9ab03_rename_iptrunk_and_iptrunk_side_sid_and_.py new file mode 100644 index 00000000..63bc63a7 --- /dev/null +++ b/gso/migrations/versions/2024-12-04_e358efe9ab03_rename_iptrunk_and_iptrunk_side_sid_and_.py @@ -0,0 +1,35 @@ +"""Rename iptrunk and iptrunk side sid and gid. + +Revision ID: e358efe9ab03 +Revises: 4cc835c615fc +Create Date: 2024-12-04 15:05:46.356709 + +""" +import sqlalchemy as sa +from alembic import op + +# revision identifiers, used by Alembic. +revision = 'e358efe9ab03' +down_revision = '4cc835c615fc' +branch_labels = None +depends_on = None + + +def upgrade() -> None: + conn = op.get_bind() + conn.execute(sa.text(""" +UPDATE resource_types SET resource_type='ga_id' WHERE resource_types.resource_type = 'iptrunk_side_ae_geant_a_sid' + """)) + conn.execute(sa.text(""" +UPDATE resource_types SET resource_type='gs_id' WHERE resource_types.resource_type = 'geant_s_sid' + """)) + + +def downgrade() -> None: + conn = op.get_bind() + conn.execute(sa.text(""" +UPDATE resource_types SET resource_type='iptrunk_side_ae_geant_a_sid' WHERE resource_types.resource_type = 'ga_id' + """)) + conn.execute(sa.text(""" +UPDATE resource_types SET resource_type='geant_s_sid' WHERE resource_types.resource_type = 'gs_id' + """)) diff --git a/gso/migrations/versions/2024-12-04_e36b3bd8a45c_rename_edgeport_and_sbp_gs_and_ga_id.py b/gso/migrations/versions/2024-12-04_e36b3bd8a45c_rename_edgeport_and_sbp_gs_and_ga_id.py new file mode 100644 index 00000000..180c97ee --- /dev/null +++ b/gso/migrations/versions/2024-12-04_e36b3bd8a45c_rename_edgeport_and_sbp_gs_and_ga_id.py @@ -0,0 +1,47 @@ +"""Rename edgeport and sbp gs and ga id. + +Revision ID: e36b3bd8a45c +Revises: e358efe9ab03 +Create Date: 2024-12-04 15:08:30.512126 + +""" +import sqlalchemy as sa +from alembic import op + +# revision identifiers, used by Alembic. +revision = 'e36b3bd8a45c' +down_revision = 'e358efe9ab03' +branch_labels = None +depends_on = None + + +def upgrade() -> None: + conn = op.get_bind() + conn.execute(sa.text(""" +UPDATE product_block_resource_types SET resource_type_id=(SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('ga_id')) WHERE product_block_resource_types.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('EdgePortBlock')) AND product_block_resource_types.resource_type_id IN (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('geant_ga_id')) + """)) + conn.execute(sa.text(""" +UPDATE product_block_resource_types SET resource_type_id=(SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('gs_id')) WHERE product_block_resource_types.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('ServiceBindingPort')) AND product_block_resource_types.resource_type_id IN (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('geant_sid')) + """)) + conn.execute(sa.text(""" +UPDATE subscription_instance_values SET resource_type_id=(SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('ga_id')) WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('EdgePortBlock'))) AND subscription_instance_values.resource_type_id IN (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('geant_ga_id')) + """)) + conn.execute(sa.text(""" +UPDATE subscription_instance_values SET resource_type_id=(SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('gs_id')) WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('ServiceBindingPort'))) AND subscription_instance_values.resource_type_id IN (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('geant_sid')) + """)) + + +def downgrade() -> None: + conn = op.get_bind() + conn.execute(sa.text(""" +UPDATE product_block_resource_types SET resource_type_id=(SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('geant_ga_id')) WHERE product_block_resource_types.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('EdgePortBlock')) AND product_block_resource_types.resource_type_id IN (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('ga_id')) + """)) + conn.execute(sa.text(""" +UPDATE product_block_resource_types SET resource_type_id=(SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('geant_sid')) WHERE product_block_resource_types.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('ServiceBindingPort')) AND product_block_resource_types.resource_type_id IN (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('gs_id')) + """)) + conn.execute(sa.text(""" +UPDATE subscription_instance_values SET resource_type_id=(SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('geant_ga_id')) WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('EdgePortBlock'))) AND subscription_instance_values.resource_type_id IN (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('ga_id')) + """)) + conn.execute(sa.text(""" +UPDATE subscription_instance_values SET resource_type_id=(SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('geant_sid')) WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('ServiceBindingPort'))) AND subscription_instance_values.resource_type_id IN (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('gs_id')) + """)) diff --git a/gso/products/product_blocks/edge_port.py b/gso/products/product_blocks/edge_port.py index b3400e0f..8f5c4bb1 100644 --- a/gso/products/product_blocks/edge_port.py +++ b/gso/products/product_blocks/edge_port.py @@ -72,7 +72,7 @@ class EdgePortBlockInactive( minimum_links: int | None = None edge_port_type: EdgePortType | None = None ignore_if_down: bool = False - geant_ga_id: str | None = None + ga_id: str | None = None edge_port_ae_members: LAGMemberList[EdgePortAEMemberBlockInactive] @@ -89,7 +89,7 @@ class EdgePortBlockProvisioning(EdgePortBlockInactive, lifecycle=[SubscriptionLi minimum_links: int | None = None edge_port_type: EdgePortType ignore_if_down: bool = False - geant_ga_id: str | None = None + ga_id: str | None = None edge_port_ae_members: LAGMemberList[EdgePortAEMemberBlockProvisioning] # type: ignore[assignment] @@ -117,6 +117,6 @@ class EdgePortBlock(EdgePortBlockProvisioning, lifecycle=[SubscriptionLifecycle. #: If set to True, the edge port will be ignored if it is down. ignore_if_down: bool = False #: The GEANT GA ID associated with this edge port, if any. - geant_ga_id: str | None = None + ga_id: str | None = None #: A list of LAG members associated with this edge port. edge_port_ae_members: LAGMemberList[EdgePortAEMemberBlock] # type: ignore[assignment] diff --git a/gso/products/product_blocks/iptrunk.py b/gso/products/product_blocks/iptrunk.py index e68911dd..9ffaa788 100644 --- a/gso/products/product_blocks/iptrunk.py +++ b/gso/products/product_blocks/iptrunk.py @@ -67,7 +67,7 @@ class IptrunkSideBlockInactive( iptrunk_side_node: RouterBlockInactive iptrunk_side_ae_iface: str | None = None - iptrunk_side_ae_geant_a_sid: str | None = None + ga_id: str | None = None iptrunk_side_ae_members: LAGMemberList[IptrunkInterfaceBlockInactive] @@ -76,7 +76,7 @@ class IptrunkSideBlockProvisioning(IptrunkSideBlockInactive, lifecycle=[Subscrip iptrunk_side_node: RouterBlockProvisioning iptrunk_side_ae_iface: str - iptrunk_side_ae_geant_a_sid: str | None = None + ga_id: str | None = None iptrunk_side_ae_members: LAGMemberList[IptrunkInterfaceBlockProvisioning] # type: ignore[assignment] @@ -85,7 +85,7 @@ class IptrunkSideBlock(IptrunkSideBlockProvisioning, lifecycle=[SubscriptionLife iptrunk_side_node: RouterBlock iptrunk_side_ae_iface: str - iptrunk_side_ae_geant_a_sid: str | None = None + ga_id: str | None = None iptrunk_side_ae_members: LAGMemberList[IptrunkInterfaceBlock] # type: ignore[assignment] @@ -96,7 +96,7 @@ class IptrunkBlockInactive( ): """A trunk that's currently inactive, see ``IptrunkBlock``.""" - geant_s_sid: str | None = None + gs_id: str | None = None iptrunk_description: str | None = None iptrunk_type: IptrunkType | None = None iptrunk_speed: PhysicalPortCapacity | None = None @@ -110,7 +110,7 @@ class IptrunkBlockInactive( class IptrunkBlockProvisioning(IptrunkBlockInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]): """A trunk that's currently being provisioned, see ``IptrunkBlock``.""" - geant_s_sid: str | None = None + gs_id: str | None = None iptrunk_description: str | None = None iptrunk_type: IptrunkType | None = None iptrunk_speed: PhysicalPortCapacity | None = None @@ -125,7 +125,7 @@ class IptrunkBlock(IptrunkBlockProvisioning, lifecycle=[SubscriptionLifecycle.AC """A trunk that's currently deployed in the network.""" #: GÉANT service ID associated with this trunk. - geant_s_sid: str | None = None + gs_id: str | None = None #: A human-readable description of this trunk. iptrunk_description: str | None = None #: The type of trunk, can be either dark fibre or leased capacity. diff --git a/gso/products/product_blocks/service_binding_port.py b/gso/products/product_blocks/service_binding_port.py index 6fd7467c..5f10b33c 100644 --- a/gso/products/product_blocks/service_binding_port.py +++ b/gso/products/product_blocks/service_binding_port.py @@ -64,7 +64,7 @@ class ServiceBindingPortInactive( ipv6_address: IPv6AddressType | None = None ipv6_mask: IPV6Netmask | None = None custom_firewall_filters: bool | None = None - geant_sid: str | None = None + gs_id: str | None = None bgp_session_list: list[BGPSessionInactive] = Field(default_factory=list) edge_port: EdgePortBlockInactive | None = None v4_bfd_settings: BFDSettingsInactive @@ -82,7 +82,7 @@ class ServiceBindingPortProvisioning(ServiceBindingPortInactive, lifecycle=[Subs ipv6_address: IPv6AddressType | None = None ipv6_mask: IPV6Netmask | None = None custom_firewall_filters: bool - geant_sid: str + gs_id: str bgp_session_list: list[BGPSessionProvisioning] # type: ignore[assignment] edge_port: EdgePortBlockProvisioning v4_bfd_settings: BFDSettingsProvisioning @@ -109,7 +109,7 @@ class ServiceBindingPort(ServiceBindingPortProvisioning, lifecycle=[Subscription #: Any custom firewall filters that the partner may require. custom_firewall_filters: bool #: The GÉANT service ID of this binding port. - geant_sid: str + gs_id: str #: The BGP sessions associated with this service binding port. bgp_session_list: list[BGPSession] # type: ignore[assignment] #: The Edge Port on which this SBP resides. -- GitLab From 72e450c8c948c629ee56720bb2190f25132fe399 Mon Sep 17 00:00:00 2001 From: Neda Moeini <neda.moeini@geant.org> Date: Wed, 4 Dec 2024 15:50:01 +0100 Subject: [PATCH 03/20] Rename IPtrunk geant_s_id to gs_id in the entire project. --- gso/api/v1/network.py | 4 ++-- gso/cli/imports.py | 4 ++-- gso/utils/workflow_steps.py | 2 +- .../iptrunk/create_imported_iptrunk.py | 8 +++---- gso/workflows/iptrunk/create_iptrunk.py | 20 ++++++++--------- gso/workflows/iptrunk/migrate_iptrunk.py | 22 +++++++++---------- gso/workflows/iptrunk/modify_isis_metric.py | 4 ++-- .../iptrunk/modify_trunk_interface.py | 12 +++++----- gso/workflows/iptrunk/terminate_iptrunk.py | 4 ++-- test/fixtures/iptrunk_fixtures.py | 6 ++--- .../iptrunk/test_create_imported_iptrunk.py | 2 +- test/workflows/iptrunk/test_create_iptrunk.py | 4 ++-- .../iptrunk/test_modify_trunk_interface.py | 8 +++---- 13 files changed, 50 insertions(+), 50 deletions(-) diff --git a/gso/api/v1/network.py b/gso/api/v1/network.py index e4a19de9..81a209b7 100644 --- a/gso/api/v1/network.py +++ b/gso/api/v1/network.py @@ -64,7 +64,7 @@ class IptrunkBlock(OrchestratorBaseModel): iptrunk_capacity: str iptrunk_isis_metric: int iptrunk_sides: list[IptrunkSideBlock] - geant_s_sid: str + gs_id: str class IptrunkSchema(OrchestratorBaseModel): @@ -109,7 +109,7 @@ def network_topology() -> NetworkTopologyDomainModelSchema: "iptrunk_capacity": _calculate_iptrunk_capacity( extended_model["iptrunk"]["iptrunk_sides"], extended_model["iptrunk"]["iptrunk_speed"] ), - "geant_s_sid": extended_model["iptrunk"]["geant_s_sid"], + "gs_id": extended_model["iptrunk"]["gs_id"], "iptrunk_sides": [ { "subscription_instance_id": side["subscription_instance_id"], diff --git a/gso/cli/imports.py b/gso/cli/imports.py index 14a45ad0..9903d186 100644 --- a/gso/cli/imports.py +++ b/gso/cli/imports.py @@ -116,7 +116,7 @@ class IptrunkImportModel(BaseModel): """Required fields for importing an existing ``gso.products.product_types.iptrunk``.""" partner: str - geant_s_sid: str | None + gs_id: str | None iptrunk_type: IptrunkType iptrunk_description: str | None = None iptrunk_speed: PhysicalPortCapacity @@ -592,7 +592,7 @@ def import_iptrunks(filepath: str = common_filepath_option) -> None: try: initial_data = IptrunkImportModel( partner="GEANT", - geant_s_sid=trunk["id"], + gs_id=trunk["id"], iptrunk_type=trunk["config"]["common"]["type"], iptrunk_description=trunk["config"]["common"].get("description", ""), iptrunk_speed=trunk["config"]["common"]["link_speed"], diff --git a/gso/utils/workflow_steps.py b/gso/utils/workflow_steps.py index 721e1845..0250eb8c 100644 --- a/gso/utils/workflow_steps.py +++ b/gso/utils/workflow_steps.py @@ -318,7 +318,7 @@ def set_isis_to_max(subscription: Iptrunk, process_id: UUIDstr, tt_number: str) "verb": "deploy", "config_object": "isis_interface", "commit_comment": f"GSO_PROCESS_ID: {process_id} - TT_NUMBER: {tt_number} - Deploy config for " - f"{subscription.iptrunk.geant_s_sid}", + f"{subscription.iptrunk.gs_id}", } return { diff --git a/gso/workflows/iptrunk/create_imported_iptrunk.py b/gso/workflows/iptrunk/create_imported_iptrunk.py index 5cf9c5f8..77774049 100644 --- a/gso/workflows/iptrunk/create_imported_iptrunk.py +++ b/gso/workflows/iptrunk/create_imported_iptrunk.py @@ -30,7 +30,7 @@ def initial_input_form_generator() -> FormGenerator: model_config = ConfigDict(title="Import Iptrunk") partner: str - geant_s_sid: str | None = None + gs_id: str | None = None iptrunk_description: str | None = None iptrunk_type: IptrunkType iptrunk_speed: PhysicalPortCapacity @@ -71,7 +71,7 @@ def create_subscription(partner: str) -> State: @step("Initialize subscription") def initialize_subscription( subscription: ImportedIptrunkInactive, - geant_s_sid: str | None, + gs_id: str | None, iptrunk_type: IptrunkType, iptrunk_description: str, iptrunk_speed: PhysicalPortCapacity, @@ -87,7 +87,7 @@ def initialize_subscription( side_b_ae_members: LAGMemberList, ) -> State: """Take all input from the user, and store it in the database.""" - subscription.iptrunk.geant_s_sid = geant_s_sid + subscription.iptrunk.gs_id = gs_id subscription.iptrunk.iptrunk_description = iptrunk_description subscription.iptrunk.iptrunk_type = iptrunk_type subscription.iptrunk.iptrunk_speed = iptrunk_speed @@ -113,7 +113,7 @@ def initialize_subscription( subscription.iptrunk.iptrunk_sides[0].iptrunk_side_node.router_site.site_name, subscription.iptrunk.iptrunk_sides[1].iptrunk_side_node.router_site.site_name, ]) - subscription.description = f"IP trunk {side_names[0]} {side_names[1]}, geant_s_sid:{geant_s_sid}" + subscription.description = f"IP trunk {side_names[0]} {side_names[1]}, gs_id:{gs_id}" return {"subscription": subscription} diff --git a/gso/workflows/iptrunk/create_iptrunk.py b/gso/workflows/iptrunk/create_iptrunk.py index f8b54c61..c786f847 100644 --- a/gso/workflows/iptrunk/create_iptrunk.py +++ b/gso/workflows/iptrunk/create_iptrunk.py @@ -86,7 +86,7 @@ def initial_input_form_generator(product_name: str) -> FormGenerator: tt_number: TTNumber partner: ReadOnlyField("GEANT", default_type=str) # type: ignore[valid-type] - geant_s_sid: str | None = None + gs_id: str | None = None iptrunk_description: str | None = None iptrunk_type: IptrunkType iptrunk_speed: PhysicalPortCapacity @@ -196,7 +196,7 @@ def initial_input_form_generator(product_name: str) -> FormGenerator: ) summary_form_data = input_forms_data | {"side_a_node": router_a_fqdn, "side_b_node": router_b_fqdn} summary_fields = [ - "geant_s_sid", + "gs_id", "iptrunk_type", "iptrunk_speed", "iptrunk_description", @@ -322,7 +322,7 @@ def ping_all_hosts_v6(new_ipv6_network: str) -> State: @step("Initialize subscription") def initialize_subscription( subscription: IptrunkInactive, - geant_s_sid: str | None, + gs_id: str | None, iptrunk_type: IptrunkType, iptrunk_description: str | None, iptrunk_speed: PhysicalPortCapacity, @@ -340,7 +340,7 @@ def initialize_subscription( oss_params = load_oss_params() side_a = Router.from_subscription(side_a_node_id).router side_b = Router.from_subscription(side_b_node_id).router - subscription.iptrunk.geant_s_sid = geant_s_sid + subscription.iptrunk.gs_id = gs_id subscription.iptrunk.iptrunk_description = iptrunk_description subscription.iptrunk.iptrunk_type = iptrunk_type subscription.iptrunk.iptrunk_speed = iptrunk_speed @@ -363,7 +363,7 @@ def initialize_subscription( IptrunkInterfaceBlockInactive.new(subscription_id=uuid4(), **member), ) side_names = sorted([side_a.router_site.site_name, side_b.router_site.site_name]) - subscription.description = f"IP trunk {side_names[0]} {side_names[1]}, geant_s_sid:{geant_s_sid}" + subscription.description = f"IP trunk {side_names[0]} {side_names[1]}, gs_id:{gs_id}" return {"subscription": subscription} @@ -377,7 +377,7 @@ def provision_ip_trunk_iface_dry(subscription: IptrunkInactive, process_id: UUID "verb": "deploy", "config_object": "trunk_interface", "commit_comment": f"GSO_PROCESS_ID: {process_id} - TT_NUMBER: {tt_number} - Deploy config for " - f"{subscription.iptrunk.geant_s_sid}", + f"{subscription.iptrunk.gs_id}", } return { @@ -403,7 +403,7 @@ def provision_ip_trunk_iface_real(subscription: IptrunkInactive, process_id: UUI "verb": "deploy", "config_object": "trunk_interface", "commit_comment": f"GSO_PROCESS_ID: {process_id} - TT_NUMBER: {tt_number} - Deploy config for " - f"{subscription.iptrunk.geant_s_sid}", + f"{subscription.iptrunk.gs_id}", } return { @@ -441,7 +441,7 @@ def provision_ip_trunk_isis_iface_dry(subscription: IptrunkInactive, process_id: "verb": "deploy", "config_object": "isis_interface", "commit_comment": f"GSO_PROCESS_ID: {process_id} - TT_NUMBER: {tt_number} - Deploy config for " - f"{subscription.iptrunk.geant_s_sid}", + f"{subscription.iptrunk.gs_id}", } return { @@ -467,7 +467,7 @@ def provision_ip_trunk_isis_iface_real(subscription: IptrunkInactive, process_id "verb": "deploy", "config_object": "isis_interface", "commit_comment": f"GSO_PROCESS_ID: {process_id} - TT_NUMBER: {tt_number} - Deploy config for " - f"{subscription.iptrunk.geant_s_sid}", + f"{subscription.iptrunk.gs_id}", } return { @@ -574,7 +574,7 @@ def create_new_sharepoint_checklist(subscription: IptrunkProvisioning, tt_number new_list_item_url = SharePointClient().add_list_item( list_name="ip_trunk", fields={ - "Title": f"{subscription.description} - {subscription.iptrunk.geant_s_sid}", + "Title": f"{subscription.description} - {subscription.iptrunk.gs_id}", "TT_NUMBER": tt_number, "GAP_PROCESS_URL": f"{load_oss_params().GENERAL.public_hostname}/workflows/{process_id}", "ACTIVITY_TYPE": "Creation", diff --git a/gso/workflows/iptrunk/migrate_iptrunk.py b/gso/workflows/iptrunk/migrate_iptrunk.py index 5684dd2d..e0a42d19 100644 --- a/gso/workflows/iptrunk/migrate_iptrunk.py +++ b/gso/workflows/iptrunk/migrate_iptrunk.py @@ -50,7 +50,7 @@ def initial_input_form_generator(subscription_id: UUIDstr) -> FormGenerator: """Gather input from the operator on the new router that the IP trunk should connect to.""" subscription = Iptrunk.from_subscription(subscription_id) form_title = ( - f"Subscription {subscription.iptrunk.geant_s_sid} " + f"Subscription {subscription.iptrunk.gs_id} " f" from {subscription.iptrunk.iptrunk_sides[0].iptrunk_side_node.router_fqdn}" f" to {subscription.iptrunk.iptrunk_sides[1].iptrunk_side_node.router_fqdn}" ) @@ -298,7 +298,7 @@ def disable_old_config_dry( "config_object": "deactivate", "dry_run": True, "commit_comment": f"GSO_PROCESS_ID: {process_id} - TT_NUMBER: {tt_number} " - f"- Deploy config for {subscription.iptrunk.geant_s_sid}", + f"- Deploy config for {subscription.iptrunk.gs_id}", } return { @@ -337,7 +337,7 @@ def disable_old_config_real( "config_object": "deactivate", "dry_run": False, "commit_comment": f"GSO_PROCESS_ID: {process_id} - TT_NUMBER: {tt_number} " - f"- Deploy config for {subscription.iptrunk.geant_s_sid}", + f"- Deploy config for {subscription.iptrunk.gs_id}", } return { @@ -376,7 +376,7 @@ def deploy_new_config_dry( "config_object": "trunk_interface", "dry_run": True, "commit_comment": f"GSO_PROCESS_ID: {process_id} - TT_NUMBER: {tt_number} " - f"- Deploy config for {subscription.iptrunk.geant_s_sid}", + f"- Deploy config for {subscription.iptrunk.gs_id}", } return { @@ -415,7 +415,7 @@ def deploy_new_config_real( "config_object": "trunk_interface", "dry_run": False, "commit_comment": f"GSO_PROCESS_ID: {process_id} - TT_NUMBER: {tt_number} " - f"- Deploy config for {subscription.iptrunk.geant_s_sid}", + f"- Deploy config for {subscription.iptrunk.gs_id}", } return { @@ -564,7 +564,7 @@ def deploy_new_isis( "config_object": "isis_interface", "dry_run": False, "commit_comment": f"GSO_PROCESS_ID: {process_id} - TT_NUMBER: {tt_number} " - f"- Deploy config for {subscription.iptrunk.geant_s_sid}", + f"- Deploy config for {subscription.iptrunk.gs_id}", } return { @@ -629,7 +629,7 @@ def restore_isis_metric( "verb": "deploy", "config_object": "isis_interface", "commit_comment": f"GSO_PROCESS_ID: {process_id} - TT_NUMBER: {tt_number} - Deploy config for " - f"{subscription.iptrunk.geant_s_sid}", + f"{subscription.iptrunk.gs_id}", } return { @@ -668,7 +668,7 @@ def delete_old_config_dry( "config_object": "delete", "dry_run": True, "commit_comment": f"GSO_PROCESS_ID: {process_id} - TT_NUMBER: {tt_number} " - f"- Deploy config for {subscription.iptrunk.geant_s_sid}", + f"- Deploy config for {subscription.iptrunk.gs_id}", } return { @@ -707,7 +707,7 @@ def delete_old_config_real( "config_object": "delete", "dry_run": False, "commit_comment": f"GSO_PROCESS_ID: {process_id} - TT_NUMBER: {tt_number} " - f"- Deploy config for {subscription.iptrunk.geant_s_sid}", + f"- Deploy config for {subscription.iptrunk.gs_id}", } return { @@ -770,7 +770,7 @@ def update_subscription_model( subscription.iptrunk.iptrunk_sides[1].iptrunk_side_node.router_site.site_name, ]) subscription.description = ( - f"IP trunk {side_names[0]} {side_names[1]}, geant_s_sid:{subscription.iptrunk.geant_s_sid}" + f"IP trunk {side_names[0]} {side_names[1]}, gs_id:{subscription.iptrunk.gs_id}" ) return {"subscription": subscription} @@ -816,7 +816,7 @@ def create_new_sharepoint_checklist(subscription: Iptrunk, tt_number: str, proce new_list_item_url = SharePointClient().add_list_item( list_name="ip_trunk", fields={ - "Title": f"{subscription.description} - {subscription.iptrunk.geant_s_sid}", + "Title": f"{subscription.description} - {subscription.iptrunk.gs_id}", "TT_NUMBER": tt_number, "GAP_PROCESS_URL": f"{load_oss_params().GENERAL.public_hostname}/workflows/{process_id}", "ACTIVITY_TYPE": "Migration", diff --git a/gso/workflows/iptrunk/modify_isis_metric.py b/gso/workflows/iptrunk/modify_isis_metric.py index 61d2f090..80d97531 100644 --- a/gso/workflows/iptrunk/modify_isis_metric.py +++ b/gso/workflows/iptrunk/modify_isis_metric.py @@ -53,7 +53,7 @@ def provision_ip_trunk_isis_iface_dry(subscription: Iptrunk, process_id: UUIDstr "verb": "deploy", "config_object": "isis_interface", "commit_comment": f"GSO_PROCESS_ID: {process_id} - TT_NUMBER: {tt_number} - Deploy config for " - f"{subscription.iptrunk.geant_s_sid}", + f"{subscription.iptrunk.gs_id}", } return { @@ -79,7 +79,7 @@ def provision_ip_trunk_isis_iface_real(subscription: Iptrunk, process_id: UUIDst "verb": "deploy", "config_object": "isis_interface", "commit_comment": f"GSO_PROCESS_ID: {process_id} - TT_NUMBER: {tt_number} - Deploy config for " - f"{subscription.iptrunk.geant_s_sid}", + f"{subscription.iptrunk.gs_id}", } return { diff --git a/gso/workflows/iptrunk/modify_trunk_interface.py b/gso/workflows/iptrunk/modify_trunk_interface.py index 9c1be5cd..723a3246 100644 --- a/gso/workflows/iptrunk/modify_trunk_interface.py +++ b/gso/workflows/iptrunk/modify_trunk_interface.py @@ -86,7 +86,7 @@ def initial_input_form_generator(subscription_id: UUIDstr) -> FormGenerator: class ModifyIptrunkForm(FormPage): tt_number: TTNumber - geant_s_sid: str | None = subscription.iptrunk.geant_s_sid + gs_id: str | None = subscription.iptrunk.gs_id iptrunk_description: str | None = subscription.iptrunk.iptrunk_description iptrunk_type: IptrunkType = subscription.iptrunk.iptrunk_type warning_label: Label = ( @@ -254,7 +254,7 @@ def update_side_members(subscription: Iptrunk, side_index: int, new_members: lis @step("Update subscription") def modify_iptrunk_subscription( subscription: Iptrunk, - geant_s_sid: str | None, + gs_id: str | None, iptrunk_type: IptrunkType, iptrunk_description: str | None, iptrunk_speed: PhysicalPortCapacity, @@ -287,7 +287,7 @@ def modify_iptrunk_subscription( if ae_member["interface_name"] not in [m["interface_name"] for m in current_members] ]) # Update the subscription - subscription.iptrunk.geant_s_sid = geant_s_sid + subscription.iptrunk.gs_id = gs_id subscription.iptrunk.iptrunk_description = iptrunk_description subscription.iptrunk.iptrunk_type = iptrunk_type subscription.iptrunk.iptrunk_speed = iptrunk_speed @@ -302,7 +302,7 @@ def modify_iptrunk_subscription( subscription.iptrunk.iptrunk_sides[0].iptrunk_side_node.router_site.site_name, subscription.iptrunk.iptrunk_sides[1].iptrunk_side_node.router_site.site_name, ]) - subscription.description = f"IP trunk {side_names[0]} {side_names[1]}, geant_s_sid:{geant_s_sid}" + subscription.description = f"IP trunk {side_names[0]} {side_names[1]}, gs_id:{gs_id}" return { "subscription": subscription, @@ -323,7 +323,7 @@ def provision_ip_trunk_iface_dry( "config_object": "trunk_interface", "removed_ae_members": removed_ae_members, "commit_comment": f"GSO_PROCESS_ID: {process_id} - TT_NUMBER: {tt_number} - Deploy config for " - f"{subscription.iptrunk.geant_s_sid}", + f"{subscription.iptrunk.gs_id}", } return { @@ -352,7 +352,7 @@ def provision_ip_trunk_iface_real( "config_object": "trunk_interface", "removed_ae_members": removed_ae_members, "commit_comment": f"GSO_PROCESS_ID: {process_id} - TT_NUMBER: {tt_number} - Deploy config for " - f"{subscription.iptrunk.geant_s_sid}", + f"{subscription.iptrunk.gs_id}", } return { diff --git a/gso/workflows/iptrunk/terminate_iptrunk.py b/gso/workflows/iptrunk/terminate_iptrunk.py index d008ad88..24cb4271 100644 --- a/gso/workflows/iptrunk/terminate_iptrunk.py +++ b/gso/workflows/iptrunk/terminate_iptrunk.py @@ -70,7 +70,7 @@ def deprovision_ip_trunk_dry(subscription: Iptrunk, process_id: UUIDstr, tt_numb "verb": "terminate", "config_object": "trunk_deprovision", "commit_comment": f"GSO_PROCESS_ID: {process_id} - TT_NUMBER: {tt_number} " - f"- Remove config for {subscription.iptrunk.geant_s_sid}", + f"- Remove config for {subscription.iptrunk.gs_id}", } return { @@ -96,7 +96,7 @@ def deprovision_ip_trunk_real(subscription: Iptrunk, process_id: UUIDstr, tt_num "verb": "terminate", "config_object": "trunk_deprovision", "commit_comment": f"GSO_PROCESS_ID: {process_id} - TT_NUMBER: {tt_number} " - f"- Remove config for {subscription.iptrunk.geant_s_sid}", + f"- Remove config for {subscription.iptrunk.gs_id}", } return { diff --git a/test/fixtures/iptrunk_fixtures.py b/test/fixtures/iptrunk_fixtures.py index 5044a2e5..b297d07e 100644 --- a/test/fixtures/iptrunk_fixtures.py +++ b/test/fixtures/iptrunk_fixtures.py @@ -56,7 +56,7 @@ def iptrunk_subscription_factory(iptrunk_side_subscription_factory, faker, geant def subscription_create( description=None, start_date="2023-05-24T00:00:00+00:00", - geant_s_sid=None, + gs_id=None, iptrunk_description=None, iptrunk_type=IptrunkType.LEASED, iptrunk_speed=PhysicalPortCapacity.ONE_GIGABIT_PER_SECOND, @@ -84,7 +84,7 @@ def iptrunk_subscription_factory(iptrunk_side_subscription_factory, faker, geant ) description = description or faker.sentence() - geant_s_sid = geant_s_sid or faker.geant_sid() + gs_id = gs_id or faker.geant_sid() iptrunk_description = iptrunk_description or faker.sentence() iptrunk_isis_metric = iptrunk_isis_metric or faker.pyint() iptrunk_ipv4_network = iptrunk_ipv4_network or faker.ipv4_network(max_subnet=31) @@ -94,7 +94,7 @@ def iptrunk_subscription_factory(iptrunk_side_subscription_factory, faker, geant iptrunk_side_b = iptrunk_side_subscription_factory() iptrunk_sides = iptrunk_sides or [iptrunk_side_a, iptrunk_side_b] - iptrunk_subscription.iptrunk.geant_s_sid = geant_s_sid + iptrunk_subscription.iptrunk.gs_id = gs_id iptrunk_subscription.iptrunk.iptrunk_description = iptrunk_description iptrunk_subscription.iptrunk.iptrunk_type = iptrunk_type iptrunk_subscription.iptrunk.iptrunk_speed = iptrunk_speed diff --git a/test/workflows/iptrunk/test_create_imported_iptrunk.py b/test/workflows/iptrunk/test_create_imported_iptrunk.py index 25d68d8f..2e18e4bb 100644 --- a/test/workflows/iptrunk/test_create_imported_iptrunk.py +++ b/test/workflows/iptrunk/test_create_imported_iptrunk.py @@ -16,7 +16,7 @@ from test.workflows import ( def workflow_input_data(faker, router_subscription_factory): return { "partner": "GEANT", - "geant_s_sid": faker.geant_sid(), + "gs_id": faker.geant_sid(), "iptrunk_description": faker.sentence(), "iptrunk_type": IptrunkType.DARK_FIBER, "iptrunk_speed": PhysicalPortCapacity.FOUR_HUNDRED_GIGABIT_PER_SECOND, diff --git a/test/workflows/iptrunk/test_create_iptrunk.py b/test/workflows/iptrunk/test_create_iptrunk.py index cac63729..6345237f 100644 --- a/test/workflows/iptrunk/test_create_iptrunk.py +++ b/test/workflows/iptrunk/test_create_iptrunk.py @@ -65,7 +65,7 @@ def input_form_wizard_data(request, router_subscription_factory, faker): create_ip_trunk_step = { "tt_number": faker.tt_number(), - "geant_s_sid": faker.geant_sid(), + "gs_id": faker.geant_sid(), "iptrunk_type": IptrunkType.DARK_FIBER, "iptrunk_description": faker.sentence(), "iptrunk_speed": PhysicalPortCapacity.HUNDRED_GIGABIT_PER_SECOND, @@ -154,7 +154,7 @@ def test_successful_iptrunk_creation_with_standard_lso_result( ]) assert subscription.status == "provisioning" assert subscription.description == ( - f"IP trunk {sorted_sides[0]} {sorted_sides[1]}, geant_s_sid:{input_form_wizard_data[0]["geant_s_sid"]}" + f"IP trunk {sorted_sides[0]} {sorted_sides[1]}, gs_id:{input_form_wizard_data[0]["gs_id"]}" ) assert mock_execute_playbook.call_count == 6 diff --git a/test/workflows/iptrunk/test_modify_trunk_interface.py b/test/workflows/iptrunk/test_modify_trunk_interface.py index 2dcb23e2..ef3325fa 100644 --- a/test/workflows/iptrunk/test_modify_trunk_interface.py +++ b/test/workflows/iptrunk/test_modify_trunk_interface.py @@ -66,7 +66,7 @@ def input_form_iptrunk_data( {"subscription_id": product_id}, { "tt_number": faker.tt_number(), - "geant_s_sid": new_sid, + "gs_id": new_sid, "iptrunk_description": new_description, "iptrunk_type": new_type, "iptrunk_speed": new_speed, @@ -135,7 +135,7 @@ def test_iptrunk_modify_trunk_interface_success( assert subscription.status == "active" assert mock_provision_ip_trunk.call_count == lso_interaction_count # Assert all Netbox calls have been made - new_sid = input_form_iptrunk_data[1]["geant_s_sid"] + new_sid = input_form_iptrunk_data[1]["gs_id"] new_side_a_sid = input_form_iptrunk_data[3]["side_a_ae_geant_a_sid"] new_side_a_ae_members = input_form_iptrunk_data[3]["side_a_ae_members"] new_side_b_sid = input_form_iptrunk_data[4]["side_b_ae_geant_a_sid"] @@ -164,8 +164,8 @@ def test_iptrunk_modify_trunk_interface_success( subscription.iptrunk.iptrunk_sides[0].iptrunk_side_node.router_site.site_name, subscription.iptrunk.iptrunk_sides[1].iptrunk_side_node.router_site.site_name, ]) - assert subscription.description == f"IP trunk {side_names[0]} {side_names[1]}, geant_s_sid:{new_sid}" - assert subscription.iptrunk.geant_s_sid == input_form_iptrunk_data[1]["geant_s_sid"] + assert subscription.description == f"IP trunk {side_names[0]} {side_names[1]}, gs_id:{new_sid}" + assert subscription.iptrunk.gs_id == input_form_iptrunk_data[1]["gs_id"] assert subscription.iptrunk.iptrunk_description == input_form_iptrunk_data[1]["iptrunk_description"] assert subscription.iptrunk.iptrunk_type == input_form_iptrunk_data[1]["iptrunk_type"] assert subscription.iptrunk.iptrunk_speed == input_form_iptrunk_data[1]["iptrunk_speed"] -- GitLab From b2ea69cb45a3bf5de90ea11bf76301f93890dd6b Mon Sep 17 00:00:00 2001 From: Neda Moeini <neda.moeini@geant.org> Date: Wed, 4 Dec 2024 16:04:40 +0100 Subject: [PATCH 04/20] Rename IPtrunk side iptrunk_side_ae_geant_a_sid to ga_id --- gso/workflows/iptrunk/create_imported_iptrunk.py | 12 ++++++------ gso/workflows/iptrunk/create_iptrunk.py | 16 ++++++++-------- gso/workflows/iptrunk/modify_trunk_interface.py | 12 ++++++------ test/fixtures/iptrunk_fixtures.py | 4 ++-- .../iptrunk/test_modify_trunk_interface.py | 16 ++++++++-------- 5 files changed, 30 insertions(+), 30 deletions(-) diff --git a/gso/workflows/iptrunk/create_imported_iptrunk.py b/gso/workflows/iptrunk/create_imported_iptrunk.py index 77774049..db88b2b8 100644 --- a/gso/workflows/iptrunk/create_imported_iptrunk.py +++ b/gso/workflows/iptrunk/create_imported_iptrunk.py @@ -39,12 +39,12 @@ def initial_input_form_generator() -> FormGenerator: side_a_node_id: active_router_selector() # type: ignore[valid-type] side_a_ae_iface: str - side_a_ae_geant_a_sid: str | None = None + side_a_ga_id: str | None = None side_a_ae_members: Annotated[list[LAGMember], AfterValidator(validate_unique_list)] side_b_node_id: active_router_selector() # type: ignore[valid-type] side_b_ae_iface: str - side_b_ae_geant_a_sid: str | None = None + side_b_ga_id: str | None = None side_b_ae_members: Annotated[list[LAGMember], AfterValidator(validate_unique_list)] iptrunk_ipv4_network: ipaddress.IPv4Network @@ -79,11 +79,11 @@ def initialize_subscription( iptrunk_isis_metric: int, side_a_node_id: str, side_a_ae_iface: str, - side_a_ae_geant_a_sid: str | None, + side_a_ga_id: str | None, side_a_ae_members: LAGMemberList, side_b_node_id: str, side_b_ae_iface: str, - side_b_ae_geant_a_sid: str | None, + side_b_ga_id: str | None, side_b_ae_members: LAGMemberList, ) -> State: """Take all input from the user, and store it in the database.""" @@ -96,7 +96,7 @@ def initialize_subscription( subscription.iptrunk.iptrunk_sides[0].iptrunk_side_node = Router.from_subscription(side_a_node_id).router subscription.iptrunk.iptrunk_sides[0].iptrunk_side_ae_iface = side_a_ae_iface - subscription.iptrunk.iptrunk_sides[0].iptrunk_side_ae_geant_a_sid = side_a_ae_geant_a_sid + subscription.iptrunk.iptrunk_sides[0].ga_id = side_a_ga_id for member in side_a_ae_members: subscription.iptrunk.iptrunk_sides[0].iptrunk_side_ae_members.append( IptrunkInterfaceBlockInactive.new(subscription_id=uuid4(), **member), @@ -104,7 +104,7 @@ def initialize_subscription( subscription.iptrunk.iptrunk_sides[1].iptrunk_side_node = Router.from_subscription(side_b_node_id).router subscription.iptrunk.iptrunk_sides[1].iptrunk_side_ae_iface = side_b_ae_iface - subscription.iptrunk.iptrunk_sides[1].iptrunk_side_ae_geant_a_sid = side_b_ae_geant_a_sid + subscription.iptrunk.iptrunk_sides[1].ga_id = side_b_ga_id for member in side_b_ae_members: subscription.iptrunk.iptrunk_sides[1].iptrunk_side_ae_members.append( IptrunkInterfaceBlockInactive.new(subscription_id=uuid4(), **member), diff --git a/gso/workflows/iptrunk/create_iptrunk.py b/gso/workflows/iptrunk/create_iptrunk.py index c786f847..eefcd46c 100644 --- a/gso/workflows/iptrunk/create_iptrunk.py +++ b/gso/workflows/iptrunk/create_iptrunk.py @@ -144,7 +144,7 @@ def initial_input_form_generator(product_name: str) -> FormGenerator: model_config = ConfigDict(title=f"Provide subscription details for side A of the trunk. ({router_a_fqdn})") side_a_ae_iface: available_lags_choices(router_a) or str # type: ignore[valid-type] - side_a_ae_geant_a_sid: str | None + side_a_ga_id: str | None side_a_ae_members: ae_members_side_a_type user_input_side_a = yield CreateIptrunkSideAForm @@ -182,7 +182,7 @@ def initial_input_form_generator(product_name: str) -> FormGenerator: model_config = ConfigDict(title=f"Provide subscription details for side B of the trunk. ({router_b_fqdn})") side_b_ae_iface: available_lags_choices(router_b) or str # type: ignore[valid-type] - side_b_ae_geant_a_sid: str | None + side_b_ga_id: str | None side_b_ae_members: ae_members_side_b user_input_side_b = yield CreateIptrunkSideBForm @@ -204,11 +204,11 @@ def initial_input_form_generator(product_name: str) -> FormGenerator: "side_a_node", "side_a_ae_iface", "side_a_ae_members", - "side_a_ae_geant_a_sid", + "side_a_ga_id", "side_b_node", "side_b_ae_iface", "side_b_ae_members", - "side_b_ae_geant_a_sid", + "side_b_ga_id", ] yield from create_summary_form(summary_form_data, product_name, summary_fields) @@ -329,11 +329,11 @@ def initialize_subscription( iptrunk_minimum_links: int, side_a_node_id: str, side_a_ae_iface: str, - side_a_ae_geant_a_sid: str | None, + side_a_ga_id: str | None, side_a_ae_members: list[dict], side_b_node_id: str, side_b_ae_iface: str, - side_b_ae_geant_a_sid: str | None, + side_b_ga_id: str | None, side_b_ae_members: list[dict], ) -> State: """Take all input from the user, and store it in the database.""" @@ -349,7 +349,7 @@ def initialize_subscription( subscription.iptrunk.iptrunk_sides[0].iptrunk_side_node = side_a subscription.iptrunk.iptrunk_sides[0].iptrunk_side_ae_iface = side_a_ae_iface - subscription.iptrunk.iptrunk_sides[0].iptrunk_side_ae_geant_a_sid = side_a_ae_geant_a_sid + subscription.iptrunk.iptrunk_sides[0].ga_id = side_a_ga_id for member in side_a_ae_members: subscription.iptrunk.iptrunk_sides[0].iptrunk_side_ae_members.append( IptrunkInterfaceBlockInactive.new(subscription_id=uuid4(), **member), @@ -357,7 +357,7 @@ def initialize_subscription( subscription.iptrunk.iptrunk_sides[1].iptrunk_side_node = side_b subscription.iptrunk.iptrunk_sides[1].iptrunk_side_ae_iface = side_b_ae_iface - subscription.iptrunk.iptrunk_sides[1].iptrunk_side_ae_geant_a_sid = side_b_ae_geant_a_sid + subscription.iptrunk.iptrunk_sides[1].ga_id = side_b_ga_id for member in side_b_ae_members: subscription.iptrunk.iptrunk_sides[1].iptrunk_side_ae_members.append( IptrunkInterfaceBlockInactive.new(subscription_id=uuid4(), **member), diff --git a/gso/workflows/iptrunk/modify_trunk_interface.py b/gso/workflows/iptrunk/modify_trunk_interface.py index 723a3246..65fa452b 100644 --- a/gso/workflows/iptrunk/modify_trunk_interface.py +++ b/gso/workflows/iptrunk/modify_trunk_interface.py @@ -125,7 +125,7 @@ def initial_input_form_generator(subscription_id: UUIDstr) -> FormGenerator: subscription.iptrunk.iptrunk_sides[0].iptrunk_side_node.router_fqdn, default_type=str ) side_a_ae_iface: ReadOnlyField(subscription.iptrunk.iptrunk_sides[0].iptrunk_side_ae_iface, default_type=str) # type: ignore[valid-type] - side_a_ae_geant_a_sid: str | None = subscription.iptrunk.iptrunk_sides[0].iptrunk_side_ae_geant_a_sid + side_a_ga_id: str | None = subscription.iptrunk.iptrunk_sides[0].ga_id side_a_ae_members: ae_members_side_a = ( # type: ignore[valid-type] subscription.iptrunk.iptrunk_sides[0].iptrunk_side_ae_members if initial_user_input.iptrunk_speed == subscription.iptrunk.iptrunk_speed @@ -142,7 +142,7 @@ def initial_input_form_generator(subscription_id: UUIDstr) -> FormGenerator: subscription.iptrunk.iptrunk_sides[1].iptrunk_side_node.router_fqdn, default_type=str ) side_b_ae_iface: ReadOnlyField(subscription.iptrunk.iptrunk_sides[1].iptrunk_side_ae_iface, default_type=str) # type: ignore[valid-type] - side_b_ae_geant_a_sid: str | None = subscription.iptrunk.iptrunk_sides[1].iptrunk_side_ae_geant_a_sid + side_b_ga_id: str | None = subscription.iptrunk.iptrunk_sides[1].ga_id side_b_ae_members: ae_members_side_b = ( # type: ignore[valid-type] subscription.iptrunk.iptrunk_sides[1].iptrunk_side_ae_members if initial_user_input.iptrunk_speed == subscription.iptrunk.iptrunk_speed @@ -259,9 +259,9 @@ def modify_iptrunk_subscription( iptrunk_description: str | None, iptrunk_speed: PhysicalPortCapacity, iptrunk_minimum_links: int, - side_a_ae_geant_a_sid: str | None, + side_a_ga_id: str | None, side_a_ae_members: list[dict], - side_b_ae_geant_a_sid: str | None, + side_b_ga_id: str | None, side_b_ae_members: list[dict], ) -> State: """Modify the subscription in the service database, reflecting the changes to the newly selected interfaces.""" @@ -293,9 +293,9 @@ def modify_iptrunk_subscription( subscription.iptrunk.iptrunk_speed = iptrunk_speed subscription.iptrunk.iptrunk_minimum_links = iptrunk_minimum_links - subscription.iptrunk.iptrunk_sides[0].iptrunk_side_ae_geant_a_sid = side_a_ae_geant_a_sid + subscription.iptrunk.iptrunk_sides[0].ga_id = side_a_ga_id update_side_members(subscription, 0, side_a_ae_members) - subscription.iptrunk.iptrunk_sides[1].iptrunk_side_ae_geant_a_sid = side_b_ae_geant_a_sid + subscription.iptrunk.iptrunk_sides[1].ga_id = side_b_ga_id update_side_members(subscription, 1, side_b_ae_members) side_names = sorted([ diff --git a/test/fixtures/iptrunk_fixtures.py b/test/fixtures/iptrunk_fixtures.py index b297d07e..17715ebe 100644 --- a/test/fixtures/iptrunk_fixtures.py +++ b/test/fixtures/iptrunk_fixtures.py @@ -21,7 +21,7 @@ def iptrunk_side_subscription_factory(router_subscription_factory, faker): def subscription_create( iptrunk_side_node=None, iptrunk_side_ae_iface=None, - iptrunk_side_ae_geant_a_sid=None, + ga_id=None, iptrunk_side_ae_members=None, iptrunk_side_ae_members_description=None, ) -> IptrunkSideBlock: @@ -31,7 +31,7 @@ def iptrunk_side_subscription_factory(router_subscription_factory, faker): iptrunk_side_node or router_subscription_factory(vendor=Vendor.NOKIA) ).router, iptrunk_side_ae_iface=iptrunk_side_ae_iface or faker.pystr(), - iptrunk_side_ae_geant_a_sid=iptrunk_side_ae_geant_a_sid or faker.geant_sid(), + ga_id=ga_id or faker.geant_gid(), iptrunk_side_ae_members=iptrunk_side_ae_members or [ IptrunkInterfaceBlock.new( diff --git a/test/workflows/iptrunk/test_modify_trunk_interface.py b/test/workflows/iptrunk/test_modify_trunk_interface.py index ef3325fa..d88d805d 100644 --- a/test/workflows/iptrunk/test_modify_trunk_interface.py +++ b/test/workflows/iptrunk/test_modify_trunk_interface.py @@ -58,9 +58,9 @@ def input_form_iptrunk_data( new_speed = PhysicalPortCapacity.FOUR_HUNDRED_GIGABIT_PER_SECOND new_link_count = 2 - new_side_a_sid = faker.geant_sid() + new_side_a_gid = faker.geant_gid() - new_side_b_sid = faker.geant_sid() + new_side_b_gid = faker.geant_gid() return [ {"subscription_id": product_id}, @@ -74,11 +74,11 @@ def input_form_iptrunk_data( }, {}, { - "side_a_ae_geant_a_sid": new_side_a_sid, + "side_a_ae_geant_a_sid": new_side_a_gid, "side_a_ae_members": new_side_a_ae_members, }, { - "side_b_ae_geant_a_sid": new_side_b_sid, + "side_b_ae_geant_a_sid": new_side_b_gid, "side_b_ae_members": new_side_b_ae_members, }, ] @@ -136,9 +136,9 @@ def test_iptrunk_modify_trunk_interface_success( assert mock_provision_ip_trunk.call_count == lso_interaction_count # Assert all Netbox calls have been made new_sid = input_form_iptrunk_data[1]["gs_id"] - new_side_a_sid = input_form_iptrunk_data[3]["side_a_ae_geant_a_sid"] + new_side_a_gid = input_form_iptrunk_data[3]["side_a_ae_geant_a_sid"] new_side_a_ae_members = input_form_iptrunk_data[3]["side_a_ae_members"] - new_side_b_sid = input_form_iptrunk_data[4]["side_b_ae_geant_a_sid"] + new_side_b_gid = input_form_iptrunk_data[4]["side_b_ae_geant_a_sid"] new_side_b_ae_members = input_form_iptrunk_data[4]["side_b_ae_members"] # Only Nokia interfaces are checked @@ -170,7 +170,7 @@ def test_iptrunk_modify_trunk_interface_success( assert subscription.iptrunk.iptrunk_type == input_form_iptrunk_data[1]["iptrunk_type"] assert subscription.iptrunk.iptrunk_speed == input_form_iptrunk_data[1]["iptrunk_speed"] assert subscription.iptrunk.iptrunk_minimum_links == input_form_iptrunk_data[1]["iptrunk_number_of_members"] - 1 - assert subscription.iptrunk.iptrunk_sides[0].iptrunk_side_ae_geant_a_sid == new_side_a_sid + assert subscription.iptrunk.iptrunk_sides[0].ga_id == new_side_a_gid def _find_interface_by_name(interfaces: LAGMemberList, name: str): for interface in interfaces: @@ -185,7 +185,7 @@ def test_iptrunk_modify_trunk_interface_success( == _find_interface_by_name(new_side_a_ae_members, member.interface_name).interface_description ) - assert subscription.iptrunk.iptrunk_sides[1].iptrunk_side_ae_geant_a_sid == new_side_b_sid + assert subscription.iptrunk.iptrunk_sides[1].ga_id == new_side_b_gid for member in subscription.iptrunk.iptrunk_sides[1].iptrunk_side_ae_members: assert ( -- GitLab From bd9fc75c9472cbf423ec59566f9d15c19aee0c99 Mon Sep 17 00:00:00 2001 From: Neda Moeini <neda.moeini@geant.org> Date: Wed, 4 Dec 2024 16:09:13 +0100 Subject: [PATCH 05/20] Rename EdgePort geant_ga_id to ga_id --- gso/cli/imports.py | 2 +- gso/translations/en-GB.json | 2 +- gso/workflows/edge_port/create_edge_port.py | 10 +++++----- gso/workflows/edge_port/create_imported_edge_port.py | 8 ++++---- gso/workflows/edge_port/modify_edge_port.py | 8 ++++---- test/cli/test_imports.py | 2 +- test/fixtures/edge_port_fixtures.py | 4 ++-- test/workflows/edge_port/test_create_edge_port.py | 4 ++-- .../edge_port/test_create_imported_edge_port.py | 2 +- test/workflows/edge_port/test_modify_edge_port.py | 8 ++++---- 10 files changed, 25 insertions(+), 25 deletions(-) diff --git a/gso/cli/imports.py b/gso/cli/imports.py index 9903d186..72fe0d38 100644 --- a/gso/cli/imports.py +++ b/gso/cli/imports.py @@ -197,7 +197,7 @@ class EdgePortImportModel(BaseModel): encapsulation: EncapsulationType name: str minimum_links: int - geant_ga_id: str | None + ga_id: str | None mac_address: str | None partner: str enable_lacp: bool diff --git a/gso/translations/en-GB.json b/gso/translations/en-GB.json index f1f66f07..2328bba2 100644 --- a/gso/translations/en-GB.json +++ b/gso/translations/en-GB.json @@ -40,7 +40,7 @@ "enable_lacp": "Enable LACP", "mac_address": "MAC address", - "geant_ga_id": "GÉANT GA-ID" + "ga_id": "GÉANT GA-ID" } }, "workflow": { diff --git a/gso/workflows/edge_port/create_edge_port.py b/gso/workflows/edge_port/create_edge_port.py index 2005d7c2..ccd022f6 100644 --- a/gso/workflows/edge_port/create_edge_port.py +++ b/gso/workflows/edge_port/create_edge_port.py @@ -52,7 +52,7 @@ def initial_input_form_generator(product_name: str) -> FormGenerator: minimum_links: int mac_address: str | None = None ignore_if_down: bool = False - geant_ga_id: str | None = None + ga_id: str | None = None @model_validator(mode="after") def validate_number_of_members(self) -> Self: @@ -104,7 +104,7 @@ def initial_input_form_generator(product_name: str) -> FormGenerator: "minimum_links", "mac_address", "ignore_if_down", - "geant_ga_id", + "ga_id", "enable_lacp", "edge_port_name", "edge_port_description", @@ -134,7 +134,7 @@ def initialize_subscription( encapsulation: EncapsulationType, name: str, minimum_links: int, - geant_ga_id: str | None, + ga_id: str | None, mac_address: str | None, partner: str, enable_lacp: bool, # noqa: FBT001 @@ -152,10 +152,10 @@ def initialize_subscription( subscription.edge_port.edge_port_name = name subscription.edge_port.minimum_links = minimum_links subscription.edge_port.ignore_if_down = ignore_if_down - subscription.edge_port.geant_ga_id = geant_ga_id + subscription.edge_port.ga_id = ga_id subscription.edge_port.mac_address = mac_address partner_name = get_partner_by_id(partner).name - subscription.description = f"Edge Port {name} on {router.router_fqdn}, " f"{partner_name}, {geant_ga_id or ""}" + subscription.description = f"Edge Port {name} on {router.router_fqdn}, " f"{partner_name}, {ga_id or ""}" subscription.edge_port.edge_port_description = description for member in ae_members: subscription.edge_port.edge_port_ae_members.append( diff --git a/gso/workflows/edge_port/create_imported_edge_port.py b/gso/workflows/edge_port/create_imported_edge_port.py index 867965c7..07d4abf3 100644 --- a/gso/workflows/edge_port/create_imported_edge_port.py +++ b/gso/workflows/edge_port/create_imported_edge_port.py @@ -48,7 +48,7 @@ def initial_input_form_generator() -> FormGenerator: minimum_links: int mac_address: str | None = None ignore_if_down: bool = False - geant_ga_id: str | None = None + ga_id: str | None = None description: str | None = None name: str ae_members: Annotated[list[LAGMember], AfterValidator(validate_unique_list)] @@ -67,7 +67,7 @@ def initialize_subscription( encapsulation: EncapsulationType, name: str, minimum_links: int, - geant_ga_id: str | None, + ga_id: str | None, mac_address: str | None, partner: str, enable_lacp: bool, # noqa: FBT001 @@ -87,8 +87,8 @@ def initialize_subscription( subscription.edge_port.minimum_links = minimum_links subscription.edge_port.edge_port_type = service_type subscription.edge_port.ignore_if_down = ignore_if_down - subscription.edge_port.geant_ga_id = geant_ga_id - subscription.description = f"Edge Port {name} on {router.router_fqdn}, {partner}, {geant_ga_id or ""}" + subscription.edge_port.ga_id = ga_id + subscription.description = f"Edge Port {name} on {router.router_fqdn}, {partner}, {ga_id or ""}" for member in ae_members: subscription.edge_port.edge_port_ae_members.append( EdgePortAEMemberBlockInactive.new(subscription_id=uuid4(), **member) diff --git a/gso/workflows/edge_port/modify_edge_port.py b/gso/workflows/edge_port/modify_edge_port.py index bce56c74..94388984 100644 --- a/gso/workflows/edge_port/modify_edge_port.py +++ b/gso/workflows/edge_port/modify_edge_port.py @@ -43,7 +43,7 @@ def initial_input_form_generator(subscription_id: UUIDstr) -> FormGenerator: minimum_links: int | None = subscription.edge_port.minimum_links or None mac_address: str | None = subscription.edge_port.mac_address or None ignore_if_down: bool = subscription.edge_port.ignore_if_down - geant_ga_id: str | None = subscription.edge_port.geant_ga_id or None + ga_id: str | None = subscription.edge_port.ga_id or None @model_validator(mode="after") def validate_number_of_members(self) -> Self: @@ -117,7 +117,7 @@ def modify_edge_port_subscription( encapsulation: EncapsulationType, minimum_links: int, mac_address: str | None, - geant_ga_id: str | None, + ga_id: str | None, enable_lacp: bool, # noqa: FBT001 ae_members: list[dict[str, str]], ignore_if_down: bool, # noqa: FBT001 @@ -138,12 +138,12 @@ def modify_edge_port_subscription( subscription.edge_port.minimum_links = minimum_links subscription.edge_port.mac_address = mac_address subscription.edge_port.ignore_if_down = ignore_if_down - subscription.edge_port.geant_ga_id = geant_ga_id + subscription.edge_port.ga_id = ga_id subscription.edge_port.edge_port_description = description subscription.description = ( f"Edge Port {subscription.edge_port.edge_port_name} on" f" {subscription.edge_port.node.router_fqdn}," - f" {get_partner_by_id(subscription.customer_id).name}, {geant_ga_id or ""}" + f" {get_partner_by_id(subscription.customer_id).name}, {ga_id or ""}" ) subscription.edge_port.edge_port_ae_members.clear() partner_name = get_partner_by_id(subscription.customer_id).name diff --git a/test/cli/test_imports.py b/test/cli/test_imports.py index fa378703..60c8acee 100644 --- a/test/cli/test_imports.py +++ b/test/cli/test_imports.py @@ -270,7 +270,7 @@ def edge_port_data(temp_file, faker, router_subscription_factory, partner_factor "encapsulation": EncapsulationType.DOT1Q, "name": "lag34", "minimum_links": 2, - "geant_ga_id": faker.geant_gid(), + "ga_id": faker.geant_gid(), "mac_address": faker.mac_address(), "partner": partner_factory()["name"], "enable_lacp": True, diff --git a/test/fixtures/edge_port_fixtures.py b/test/fixtures/edge_port_fixtures.py index 669d42ff..7ea6b8b9 100644 --- a/test/fixtures/edge_port_fixtures.py +++ b/test/fixtures/edge_port_fixtures.py @@ -30,7 +30,7 @@ def edge_port_subscription_factory(faker, partner_factory, router_subscription_f member_speed=PhysicalPortCapacity.HUNDRED_GIGABIT_PER_SECOND, minimum_links=None, edge_port_type=EdgePortType.PUBLIC, - geant_ga_id=None, + ga_id=None, edge_port_ae_members=None, status: SubscriptionLifecycle | None = None, *, @@ -52,7 +52,7 @@ def edge_port_subscription_factory(faker, partner_factory, router_subscription_f ) edge_port_subscription.edge_port.edge_port_description = description or faker.text(max_nb_chars=30) - edge_port_subscription.edge_port.geant_ga_id = geant_ga_id or faker.geant_sid() + edge_port_subscription.edge_port.ga_id = ga_id or faker.geant_gid() edge_port_subscription.edge_port.node = node or node edge_port_subscription.edge_port.edge_port_name = name or f"lag-{faker.pyint(21, 50)}" edge_port_subscription.edge_port.edge_port_description = edge_port_description or faker.sentence() diff --git a/test/workflows/edge_port/test_create_edge_port.py b/test/workflows/edge_port/test_create_edge_port.py index 8066c5e0..35cf2613 100644 --- a/test/workflows/edge_port/test_create_edge_port.py +++ b/test/workflows/edge_port/test_create_edge_port.py @@ -50,7 +50,7 @@ def input_form_wizard_data(request, router_subscription_factory, partner_factory "node": router_subscription_factory(vendor=Vendor.NOKIA), "partner": partner_factory(name="GAAR", email=faker.email())["partner_id"], "service_type": EdgePortType.PUBLIC, - "geant_ga_id": faker.geant_gid(), + "ga_id": faker.geant_gid(), "enable_lacp": True, "speed": PhysicalPortCapacity.HUNDRED_GIGABIT_PER_SECOND, "encapsulation": EncapsulationType.DOT1Q, @@ -101,7 +101,7 @@ def test_successful_edge_port_creation( subscription = EdgePort.from_subscription(subscription_id) assert subscription.status == "active" - ga_id = input_form_wizard_data[0]["geant_ga_id"] + ga_id = input_form_wizard_data[0]["ga_id"] router_fqdn = Router.from_subscription(input_form_wizard_data[0]["node"]).router.router_fqdn assert subscription.description == f"Edge Port lag-21 on {router_fqdn}, GAAR, {ga_id}" assert len(subscription.edge_port.edge_port_ae_members) == 2 diff --git a/test/workflows/edge_port/test_create_imported_edge_port.py b/test/workflows/edge_port/test_create_imported_edge_port.py index c5590fe4..838d330d 100644 --- a/test/workflows/edge_port/test_create_imported_edge_port.py +++ b/test/workflows/edge_port/test_create_imported_edge_port.py @@ -17,7 +17,7 @@ def imported_edge_port_creation_input_form_data(router_subscription_factory, par "encapsulation": EncapsulationType.DOT1Q, "name": "lag34", "minimum_links": 2, - "geant_ga_id": faker.geant_gid(), + "ga_id": faker.geant_gid(), "mac_address": faker.mac_address(), "partner": partner_factory()["name"], "enable_lacp": True, diff --git a/test/workflows/edge_port/test_modify_edge_port.py b/test/workflows/edge_port/test_modify_edge_port.py index a7c82428..6e16f73a 100644 --- a/test/workflows/edge_port/test_modify_edge_port.py +++ b/test/workflows/edge_port/test_modify_edge_port.py @@ -21,7 +21,7 @@ def input_form_wizard_data(request, faker, edge_port_subscription_factory, partn {"subscription_id": subscription_id}, { "tt_number": faker.tt_number(), - "geant_ga_id": faker.geant_gid(), + "ga_id": faker.geant_gid(), "member_speed": PhysicalPortCapacity.FOUR_HUNDRED_GIGABIT_PER_SECOND, "number_of_members": 1, }, @@ -89,7 +89,7 @@ def test_modify_edge_port_with_changing_capacity( assert mocked_attach_interface_to_lag.call_count == 1 assert mocked_free_interface.call_count == 2 assert mocked_detach_interfaces_from_lag.call_count == 1 - assert subscription.edge_port.geant_ga_id == input_form_wizard_data[1]["geant_ga_id"] + assert subscription.edge_port.ga_id == input_form_wizard_data[1]["ga_id"] assert len(subscription.edge_port.edge_port_ae_members) == 1 @@ -100,7 +100,7 @@ def input_form_wizard_without_changing_capacity(request, faker, edge_port_subscr return [ {"subscription_id": subscription_id}, - {"tt_number": faker.tt_number(), "geant_ga_id": faker.geant_gid()}, + {"tt_number": faker.tt_number(), "ga_id": faker.geant_gid()}, { "description": faker.sentence(), "ae_members": [ @@ -163,6 +163,6 @@ def test_modify_edge_port_without_changing_capacity( assert mocked_free_interface.call_count == 0 assert mocked_detach_interfaces_from_lag.call_count == 0 - assert subscription.edge_port.geant_ga_id == input_form_wizard_without_changing_capacity[1]["geant_ga_id"] + assert subscription.edge_port.ga_id == input_form_wizard_without_changing_capacity[1]["ga_id"] assert len(subscription.edge_port.edge_port_ae_members) == 2 assert subscription.edge_port.edge_port_description == input_form_wizard_without_changing_capacity[2]["description"] -- GitLab From 7ef7177783f895474121f64a32415d5613bf4915 Mon Sep 17 00:00:00 2001 From: Neda Moeini <neda.moeini@geant.org> Date: Wed, 4 Dec 2024 16:44:16 +0100 Subject: [PATCH 06/20] IPTrunk side ga id renaming. --- test/workflows/iptrunk/test_create_imported_iptrunk.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/workflows/iptrunk/test_create_imported_iptrunk.py b/test/workflows/iptrunk/test_create_imported_iptrunk.py index 2e18e4bb..8b9c5d4d 100644 --- a/test/workflows/iptrunk/test_create_imported_iptrunk.py +++ b/test/workflows/iptrunk/test_create_imported_iptrunk.py @@ -24,13 +24,13 @@ def workflow_input_data(faker, router_subscription_factory): "iptrunk_isis_metric": 10000, "side_a_node_id": router_subscription_factory(), "side_a_ae_iface": faker.network_interface(), - "side_a_ae_geant_a_sid": faker.geant_sid(), + "side_a_ga_id": faker.geant_gid(), "side_a_ae_members": [ {"interface_name": faker.network_interface(), "interface_description": faker.sentence()} for _ in range(3) ], "side_b_node_id": router_subscription_factory(), "side_b_ae_iface": faker.network_interface(), - "side_b_ae_geant_a_sid": faker.geant_sid(), + "side_b_ga_id": faker.geant_gid(), "side_b_ae_members": [ {"interface_name": faker.network_interface(), "interface_description": faker.sentence()} for _ in range(3) ], -- GitLab From e746c51f67e41b9c9b7fb635e1e5f6a3af1eac99 Mon Sep 17 00:00:00 2001 From: Neda Moeini <neda.moeini@geant.org> Date: Wed, 4 Dec 2024 16:47:29 +0100 Subject: [PATCH 07/20] IPTrunk side ga id renaming. --- test/workflows/iptrunk/test_modify_trunk_interface.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/workflows/iptrunk/test_modify_trunk_interface.py b/test/workflows/iptrunk/test_modify_trunk_interface.py index d88d805d..801ce865 100644 --- a/test/workflows/iptrunk/test_modify_trunk_interface.py +++ b/test/workflows/iptrunk/test_modify_trunk_interface.py @@ -74,11 +74,11 @@ def input_form_iptrunk_data( }, {}, { - "side_a_ae_geant_a_sid": new_side_a_gid, + "side_a_ga_id": new_side_a_gid, "side_a_ae_members": new_side_a_ae_members, }, { - "side_b_ae_geant_a_sid": new_side_b_gid, + "side_b_ga_id": new_side_b_gid, "side_b_ae_members": new_side_b_ae_members, }, ] @@ -136,9 +136,9 @@ def test_iptrunk_modify_trunk_interface_success( assert mock_provision_ip_trunk.call_count == lso_interaction_count # Assert all Netbox calls have been made new_sid = input_form_iptrunk_data[1]["gs_id"] - new_side_a_gid = input_form_iptrunk_data[3]["side_a_ae_geant_a_sid"] + new_side_a_gid = input_form_iptrunk_data[3]["side_a_ga_id"] new_side_a_ae_members = input_form_iptrunk_data[3]["side_a_ae_members"] - new_side_b_gid = input_form_iptrunk_data[4]["side_b_ae_geant_a_sid"] + new_side_b_gid = input_form_iptrunk_data[4]["side_b_ga_id"] new_side_b_ae_members = input_form_iptrunk_data[4]["side_b_ae_members"] # Only Nokia interfaces are checked -- GitLab From 6a7a47c61d9eb5dd8e87a4bef123973acd8822ed Mon Sep 17 00:00:00 2001 From: Neda Moeini <neda.moeini@geant.org> Date: Thu, 5 Dec 2024 09:45:22 +0100 Subject: [PATCH 08/20] Replace geant_sid with gs_id --- gso/cli/imports.py | 12 ++++++------ .../l2_circuit/create_imported_layer_2_circuit.py | 6 +++--- gso/workflows/l2_circuit/create_layer_2_circuit.py | 6 +++--- .../create_imported_l3_core_service.py | 2 +- .../l3_core_service/create_l3_core_service.py | 2 +- .../l3_core_service/modify_l3_core_service.py | 6 +++--- test/cli/test_imports.py | 14 +++++++------- test/fixtures/l3_core_service_fixtures.py | 4 ++-- test/fixtures/layer_2_circuit_fixtures.py | 4 ++-- test/workflows/iptrunk/test_create_iptrunk.py | 4 ++-- .../test_create_imported_layer_2_circuit.py | 4 ++-- .../l2_circuit/test_create_layer_2_circuit.py | 6 +++--- .../test_create_imported_l3_core_service.py | 2 +- .../l3_core_service/test_create_l3_core_service.py | 2 +- .../l3_core_service/test_modify_l3_core_service.py | 6 +++--- 15 files changed, 40 insertions(+), 40 deletions(-) diff --git a/gso/cli/imports.py b/gso/cli/imports.py index 72fe0d38..ba33565e 100644 --- a/gso/cli/imports.py +++ b/gso/cli/imports.py @@ -124,11 +124,11 @@ class IptrunkImportModel(BaseModel): iptrunk_isis_metric: int side_a_node_id: str side_a_ae_iface: str - side_a_ae_geant_a_sid: str | None + side_a_ga_id: str | None side_a_ae_members: LAGMemberList[LAGMember] side_b_node_id: str side_b_ae_iface: str - side_b_ae_geant_a_sid: str | None + side_b_ga_id: str | None side_b_ae_members: LAGMemberList[LAGMember] iptrunk_ipv4_network: ipaddress.IPv4Network @@ -269,7 +269,7 @@ class L3CoreServiceImportModel(BaseModel): edge_port: str ap_type: str - geant_sid: str + gs_id: str sbp_type: SBPType = SBPType.L3 is_tagged: bool = False vlan_id: VLAN_ID @@ -349,7 +349,7 @@ class Layer2CircuitServiceImportModel(BaseModel): service_type: Layer2CircuitServiceType partner: str - geant_sid: str + gs_id: str vc_id: VC_ID layer_2_circuit_side_a: ServiceBindingPortInput layer_2_circuit_side_b: ServiceBindingPortInput @@ -600,11 +600,11 @@ def import_iptrunks(filepath: str = common_filepath_option) -> None: iptrunk_isis_metric=trunk["config"]["common"]["isis_metric"], side_a_node_id=_get_router_subscription_id(trunk["config"]["nodeA"]["name"]) or "", side_a_ae_iface=trunk["config"]["nodeA"]["ae_name"], - side_a_ae_geant_a_sid=trunk["config"]["nodeA"]["port_sid"], + side_a_ga_id=trunk["config"]["nodeA"]["port_ga_id"], side_a_ae_members=trunk["config"]["nodeA"]["members"], side_b_node_id=_get_router_subscription_id(trunk["config"]["nodeB"]["name"]) or "", side_b_ae_iface=trunk["config"]["nodeB"]["ae_name"], - side_b_ae_geant_a_sid=trunk["config"]["nodeB"]["port_sid"], + side_b_ga_id=trunk["config"]["nodeB"]["port_ga_id"], side_b_ae_members=trunk["config"]["nodeB"]["members"], iptrunk_ipv4_network=iptrunk_ipv4_network, iptrunk_ipv6_network=iptrunk_ipv6_network, diff --git a/gso/workflows/l2_circuit/create_imported_layer_2_circuit.py b/gso/workflows/l2_circuit/create_imported_layer_2_circuit.py index a0fc39cb..6102d86d 100644 --- a/gso/workflows/l2_circuit/create_imported_layer_2_circuit.py +++ b/gso/workflows/l2_circuit/create_imported_layer_2_circuit.py @@ -39,7 +39,7 @@ def initial_input_form_generator() -> FormGenerator: service_type: Layer2CircuitServiceType partner: str - geant_sid: str + gs_id: str vc_id: VC_ID layer_2_circuit_side_a: ServiceBindingPortInput layer_2_circuit_side_b: ServiceBindingPortInput @@ -91,7 +91,7 @@ def create_subscription(partner: str, service_type: Layer2CircuitServiceType) -> @step("Initialize subscription") def initialize_subscription( subscription: ImportedLayer2CircuitInactive, - geant_sid: str, + gs_id: str, layer_2_circuit_side_a: dict[str, Any], layer_2_circuit_side_b: dict[str, Any], layer_2_circuit_type: Layer2CircuitType, @@ -110,7 +110,7 @@ def initialize_subscription( edge_port=EdgePort.from_subscription(subscription_id=circuit_side_data["edge_port"]).edge_port, sbp_type=SBPType.L2, vlan_id=circuit_side_data["vlan_id"], - geant_sid=geant_sid, + gs_id=gs_id, is_tagged=layer_2_circuit_type == Layer2CircuitType.TAGGED, custom_firewall_filters=False, ) diff --git a/gso/workflows/l2_circuit/create_layer_2_circuit.py b/gso/workflows/l2_circuit/create_layer_2_circuit.py index 0a15fceb..7959a30b 100644 --- a/gso/workflows/l2_circuit/create_layer_2_circuit.py +++ b/gso/workflows/l2_circuit/create_layer_2_circuit.py @@ -69,7 +69,7 @@ def initial_input_generator(product_name: str) -> FormGenerator: vlan_divider: Divider = Field(None, exclude=True) policer_bandwidth: _policer_field(policer_enabled=initial_user_input.policer_enabled) # type: ignore[valid-type] policer_burst_rate: _policer_field(policer_enabled=initial_user_input.policer_enabled) # type: ignore[valid-type] - geant_sid: str + gs_id: str layer_2_circuit_side_a: Layer2CircuitSideSelection side_divider: Divider = Field(None, exclude=True) layer_2_circuit_side_b: Layer2CircuitSideSelection @@ -105,7 +105,7 @@ def initialize_subscription( policer_enabled: bool, # noqa: FBT001 policer_bandwidth: BandwidthString | None, policer_burst_rate: BandwidthString | None, - geant_sid: str, + gs_id: str, ) -> State: """Build a subscription object from all user input.""" layer_2_circuit_sides = [] @@ -115,7 +115,7 @@ def initialize_subscription( edge_port=EdgePort.from_subscription(subscription_id=circuit_side_data["edge_port"]).edge_port, sbp_type=SBPType.L2, vlan_id=circuit_side_data["vlan_id"], - geant_sid=geant_sid, + gs_id=gs_id, is_tagged=layer_2_circuit_type == Layer2CircuitType.TAGGED, custom_firewall_filters=False, ) diff --git a/gso/workflows/l3_core_service/create_imported_l3_core_service.py b/gso/workflows/l3_core_service/create_imported_l3_core_service.py index dd77021b..7862a47f 100644 --- a/gso/workflows/l3_core_service/create_imported_l3_core_service.py +++ b/gso/workflows/l3_core_service/create_imported_l3_core_service.py @@ -50,7 +50,7 @@ def initial_input_form_generator() -> FormGenerator: class ServiceBindingPort(BaseModel): edge_port: UUIDstr ap_type: str - geant_sid: str + gs_id: str sbp_type: SBPType = SBPType.L3 is_tagged: bool = False vlan_id: VLAN_ID diff --git a/gso/workflows/l3_core_service/create_l3_core_service.py b/gso/workflows/l3_core_service/create_l3_core_service.py index d4b085c1..04edd53f 100644 --- a/gso/workflows/l3_core_service/create_l3_core_service.py +++ b/gso/workflows/l3_core_service/create_l3_core_service.py @@ -113,7 +113,7 @@ def initial_input_form_generator(product_name: str) -> FormGenerator: exclude=True, ) - geant_sid: str + gs_id: str is_tagged: bool = False vlan_id: VLAN_ID custom_firewall_filters: bool = False diff --git a/gso/workflows/l3_core_service/modify_l3_core_service.py b/gso/workflows/l3_core_service/modify_l3_core_service.py index 7dbeb486..24b408ab 100644 --- a/gso/workflows/l3_core_service/modify_l3_core_service.py +++ b/gso/workflows/l3_core_service/modify_l3_core_service.py @@ -152,7 +152,7 @@ def initial_input_form_generator(subscription_id: UUIDstr) -> FormGenerator: exclude=True, ) - geant_sid: str = current_sbp.geant_sid + gs_id: str = current_sbp.gs_id is_tagged: bool = current_sbp.is_tagged # The SBP model does not require these five fields, but in the case of GÉANT IP or IAS this will never # occur since it's a layer 3 service. The ignore statements are there to put our type checker at ease. @@ -212,7 +212,7 @@ def initial_input_form_generator(subscription_id: UUIDstr) -> FormGenerator: exclude=True, ) - geant_sid: str + gs_id: str is_tagged: bool = False vlan_id: VLAN_ID ipv4_address: IPv4AddressType @@ -279,7 +279,7 @@ def modify_existing_sbp_blocks(subscription: L3CoreService, modified_sbp_list: l current_sbp.bgp_session_list = [v4_peer, v6_peer] current_sbp.vlan_id = modified_sbp_data["vlan_id"] - current_sbp.geant_sid = modified_sbp_data["geant_sid"] + current_sbp.gs_id = modified_sbp_data["gs_id"] current_sbp.is_tagged = modified_sbp_data["is_tagged"] current_sbp.ipv4_address = modified_sbp_data["ipv4_address"] current_sbp.ipv6_address = modified_sbp_data["ipv6_address"] diff --git a/test/cli/test_imports.py b/test/cli/test_imports.py index 60c8acee..475492a4 100644 --- a/test/cli/test_imports.py +++ b/test/cli/test_imports.py @@ -73,7 +73,7 @@ def iptrunk_data(temp_file, router_subscription_factory, faker) -> (Path, dict): "nodeA": { "name": side_a_node or Router.from_subscription(router_side_a).router.router_fqdn, "ae_name": side_a_ae_name or faker.network_interface(), - "port_sid": faker.geant_sid(), + "port_ga_id": faker.geant_gid(), "members": side_a_members or [ { @@ -88,7 +88,7 @@ def iptrunk_data(temp_file, router_subscription_factory, faker) -> (Path, dict): "nodeB": { "name": side_b_node or Router.from_subscription(router_side_b).router.router_fqdn, "ae_name": side_b_ae_name or faker.network_interface(), - "port_sid": faker.geant_sid(), + "port_ga_id": faker.geant_gid(), "members": side_b_members or [ { @@ -305,7 +305,7 @@ def l3_core_service_data(temp_file, faker, partner_factory, edge_port_subscripti { "edge_port": edge_port_subscription_factory(), "ap_type": "PRIMARY", - "geant_sid": faker.geant_sid(), + "gs_id": faker.geant_sid(), "vlan_id": faker.vlan_id(), "ipv4_address": faker.ipv4(), "ipv4_mask": faker.ipv4_netmask(), @@ -353,7 +353,7 @@ def l3_core_service_data(temp_file, faker, partner_factory, edge_port_subscripti { "edge_port": edge_port_subscription_factory(), "ap_type": "BACKUP", - "geant_sid": faker.geant_sid(), + "gs_id": faker.geant_sid(), "vlan_id": faker.vlan_id(), "ipv4_address": faker.ipv4(), "ipv4_mask": faker.ipv4_netmask(), @@ -414,7 +414,7 @@ def layer_2_circuit_data(temp_file, faker, partner_factory, edge_port_subscripti layer_2_circuit_input_data = { "partner": partner_factory()["name"], "service_type": Layer2CircuitServiceType.GEANT_PLUS, - "geant_sid": faker.geant_sid(), + "gs_id": faker.geant_sid(), "vc_id": generate_unique_vc_id(), "layer_2_circuit_side_a": { "edge_port": edge_port_subscription_factory(), @@ -697,7 +697,7 @@ def test_import_l3_core_service_with_invalid_edge_port( { "edge_port": fake_uuid, "ap_type": "PRIMARY", - "geant_sid": faker.geant_sid(), + "gs_id": faker.geant_sid(), "vlan_id": faker.vlan_id(), "ipv4_address": faker.ipv4(), "ipv4_mask": faker.ipv4_netmask(), @@ -737,7 +737,7 @@ def test_import_l3_core_service_with_invalid_edge_port( { "edge_port": edge_port_subscription_factory(), "ap_type": "BACKUP", - "geant_sid": faker.geant_sid(), + "gs_id": faker.geant_sid(), "vlan_id": faker.vlan_id(), "ipv4_address": faker.ipv4(), "ipv4_mask": faker.ipv4_netmask(), diff --git a/test/fixtures/l3_core_service_fixtures.py b/test/fixtures/l3_core_service_fixtures.py index da94298e..493ddc1c 100644 --- a/test/fixtures/l3_core_service_fixtures.py +++ b/test/fixtures/l3_core_service_fixtures.py @@ -84,7 +84,7 @@ def service_binding_port_factory( ): def create_service_binding_port( bgp_session_list: list[BGPSession] | None = None, - geant_sid: str | None = None, + gs_id: str | None = None, sbp_type: SBPType = SBPType.L3, ipv4_address: str | None = None, ipv4_mask: int | None = None, @@ -108,7 +108,7 @@ def service_binding_port_factory( ipv6_address=ipv6_address or faker.ipv6(), ipv6_mask=ipv6_mask or faker.ipv6_netmask(), custom_firewall_filters=custom_firewall_filters, - geant_sid=geant_sid or faker.geant_sid(), + gs_id=gs_id or faker.geant_sid(), bgp_session_list=bgp_session_list or [ bgp_session_subscription_factory(families=[IPFamily.V4UNICAST]), diff --git a/test/fixtures/layer_2_circuit_fixtures.py b/test/fixtures/layer_2_circuit_fixtures.py index 28fd88ae..e7c8c468 100644 --- a/test/fixtures/layer_2_circuit_fixtures.py +++ b/test/fixtures/layer_2_circuit_fixtures.py @@ -38,7 +38,7 @@ def layer_2_circuit_subscription_factory(faker, geant_partner, edge_port_subscri vlan_id_side_a: VLAN_ID | None = None, layer_2_circuit_side_b_edgeport: UUIDstr | None = None, vlan_id_side_b: VLAN_ID | None = None, - geant_sid: str | None = None, + gs_id: str | None = None, *, policer_enabled: bool = False, ) -> UUIDstr: @@ -82,7 +82,7 @@ def layer_2_circuit_subscription_factory(faker, geant_partner, edge_port_subscri edge_port=EdgePort.from_subscription(edge_port).edge_port, sbp_type=SBPType.L2, vlan_id=vlan_id, - geant_sid=geant_sid or faker.geant_sid(), + gs_id=gs_id or faker.geant_sid(), is_tagged=layer_2_circuit_type == Layer2CircuitType.TAGGED, custom_firewall_filters=False, ) diff --git a/test/workflows/iptrunk/test_create_iptrunk.py b/test/workflows/iptrunk/test_create_iptrunk.py index 6345237f..17c37388 100644 --- a/test/workflows/iptrunk/test_create_iptrunk.py +++ b/test/workflows/iptrunk/test_create_iptrunk.py @@ -75,7 +75,7 @@ def input_form_wizard_data(request, router_subscription_factory, faker): create_ip_trunk_side_a_router_name = {"side_a_node_id": router_side_a} create_ip_trunk_side_a_step = { "side_a_ae_iface": "lag-1", - "side_a_ae_geant_a_sid": None, + "side_a_ga_id": None, "side_a_ae_members": [ { "interface_name": f"Interface{interface}", @@ -87,7 +87,7 @@ def input_form_wizard_data(request, router_subscription_factory, faker): create_ip_trunk_side_b_router_name = {"side_b_node_id": router_side_b} create_ip_trunk_side_b_step = { "side_b_ae_iface": "lag-4", - "side_b_ae_geant_a_sid": faker.geant_sid(), + "side_b_ga_id": faker.geant_sid(), "side_b_ae_members": side_b_members, } summary_view_step = {} diff --git a/test/workflows/l2_circuit/test_create_imported_layer_2_circuit.py b/test/workflows/l2_circuit/test_create_imported_layer_2_circuit.py index 0e4e857e..1bc9884a 100644 --- a/test/workflows/l2_circuit/test_create_imported_layer_2_circuit.py +++ b/test/workflows/l2_circuit/test_create_imported_layer_2_circuit.py @@ -28,7 +28,7 @@ def test_create_imported_layer_2_circuit_success( "vc_id": generate_unique_vc_id(), "policer_bandwidth": faker.bandwidth() if policer_enabled else None, "policer_burst_rate": faker.bandwidth() if policer_enabled else None, - "geant_sid": faker.geant_sid(), + "gs_id": faker.geant_sid(), "layer_2_circuit_side_a": {"edge_port": edge_port_a, "vlan_id": faker.vlan_id()}, "layer_2_circuit_side_b": {"edge_port": edge_port_b, "vlan_id": faker.vlan_id()}, } @@ -44,7 +44,7 @@ def test_create_imported_layer_2_circuit_success( assert len(subscription.layer_2_circuit.layer_2_circuit_sides) == 2 assert subscription.layer_2_circuit.layer_2_circuit_sides[0].sbp.is_tagged is True assert ( - subscription.layer_2_circuit.layer_2_circuit_sides[0].sbp.geant_sid == creation_form_input_data[0]["geant_sid"] + subscription.layer_2_circuit.layer_2_circuit_sides[0].sbp.gs_id == creation_form_input_data[0]["gs_id"] ) assert ( str(subscription.layer_2_circuit.layer_2_circuit_sides[0].sbp.edge_port.owner_subscription_id) diff --git a/test/workflows/l2_circuit/test_create_layer_2_circuit.py b/test/workflows/l2_circuit/test_create_layer_2_circuit.py index c0d1b2df..edfab4dd 100644 --- a/test/workflows/l2_circuit/test_create_layer_2_circuit.py +++ b/test/workflows/l2_circuit/test_create_layer_2_circuit.py @@ -28,7 +28,7 @@ def layer_2_circuit_input(faker, partner_factory, edge_port_subscription_factory "vlan_range_upper_bound": faker.vlan_id(), "policer_bandwidth": faker.bandwidth() if policer_enabled else None, "policer_burst_rate": faker.bandwidth() if policer_enabled else None, - "geant_sid": faker.geant_sid(), + "gs_id": faker.geant_sid(), "layer_2_circuit_side_a": {"edge_port": edge_port_a, "vlan_id": faker.vlan_id()}, "layer_2_circuit_side_b": {"edge_port": edge_port_b, "vlan_id": faker.vlan_id()}, }, @@ -56,13 +56,13 @@ def test_create_layer_2_circuit_success( == layer_2_circuit_input[2]["layer_2_circuit_side_a"]["edge_port"] ) assert subscription.layer_2_circuit.layer_2_circuit_sides[0].sbp.is_tagged is True - assert subscription.layer_2_circuit.layer_2_circuit_sides[0].sbp.geant_sid == layer_2_circuit_input[2]["geant_sid"] + assert subscription.layer_2_circuit.layer_2_circuit_sides[0].sbp.gs_id == layer_2_circuit_input[2]["gs_id"] assert ( str(subscription.layer_2_circuit.layer_2_circuit_sides[1].sbp.edge_port.owner_subscription_id) == layer_2_circuit_input[2]["layer_2_circuit_side_b"]["edge_port"] ) assert subscription.layer_2_circuit.layer_2_circuit_sides[1].sbp.is_tagged is True - assert subscription.layer_2_circuit.layer_2_circuit_sides[1].sbp.geant_sid == layer_2_circuit_input[2]["geant_sid"] + assert subscription.layer_2_circuit.layer_2_circuit_sides[1].sbp.gs_id == layer_2_circuit_input[2]["gs_id"] assert subscription.layer_2_circuit.layer_2_circuit_type == Layer2CircuitType.TAGGED assert subscription.layer_2_circuit.vlan_range_lower_bound == layer_2_circuit_input[2]["vlan_range_lower_bound"] assert subscription.layer_2_circuit.vlan_range_upper_bound == layer_2_circuit_input[2]["vlan_range_upper_bound"] diff --git a/test/workflows/l3_core_service/test_create_imported_l3_core_service.py b/test/workflows/l3_core_service/test_create_imported_l3_core_service.py index 626c6237..0580bb5c 100644 --- a/test/workflows/l3_core_service/test_create_imported_l3_core_service.py +++ b/test/workflows/l3_core_service/test_create_imported_l3_core_service.py @@ -27,7 +27,7 @@ def test_create_imported_l3_core_service_success( { "edge_port": edge_port_subscription_factory(), "ap_type": "PRIMARY", - "geant_sid": faker.geant_sid(), + "gs_id": faker.geant_sid(), "sbp_type": SBPType.L3, "is_tagged": faker.boolean(), "vlan_id": faker.vlan_id(), diff --git a/test/workflows/l3_core_service/test_create_l3_core_service.py b/test/workflows/l3_core_service/test_create_l3_core_service.py index 149fdf20..2295e362 100644 --- a/test/workflows/l3_core_service/test_create_l3_core_service.py +++ b/test/workflows/l3_core_service/test_create_l3_core_service.py @@ -49,7 +49,7 @@ def test_create_l3_core_service_success( {"tt_number": faker.tt_number(), "partner": partner["partner_id"]}, {"edge_port": {"edge_port": edge_port_a, "ap_type": APType.PRIMARY}}, { - "geant_sid": faker.geant_sid(), + "gs_id": faker.geant_sid(), "is_tagged": faker.boolean(), "vlan_id": faker.vlan_id(), "ipv4_address": faker.ipv4(), diff --git a/test/workflows/l3_core_service/test_modify_l3_core_service.py b/test/workflows/l3_core_service/test_modify_l3_core_service.py index 67ff8880..333fc670 100644 --- a/test/workflows/l3_core_service/test_modify_l3_core_service.py +++ b/test/workflows/l3_core_service/test_modify_l3_core_service.py @@ -84,7 +84,7 @@ def test_modify_l3_core_service_add_new_edge_port_success( {}, # The existing SBPs are unchanged {}, { # Adding configuration for the new SBP - "geant_sid": faker.geant_sid(), + "gs_id": faker.geant_sid(), "vlan_id": faker.vlan_id(), "ipv4_address": faker.ipv4(), "ipv6_address": faker.ipv6(), @@ -115,7 +115,7 @@ def test_modify_l3_core_service_add_new_edge_port_success( def sbp_input_form_data(faker): def _generate_form_data(): return { - "geant_sid": faker.geant_sid(), + "gs_id": faker.geant_sid(), "is_tagged": True, "vlan_id": faker.vlan_id(), "ipv4_address": faker.ipv4(), @@ -198,7 +198,7 @@ def test_modify_l3_core_service_modify_edge_port_success( assert len(subscription.l3_core_service.ap_list) == 2 for i in range(2): - assert subscription.l3_core_service.ap_list[i].sbp.geant_sid == new_sbp_data[i]["geant_sid"] + assert subscription.l3_core_service.ap_list[i].sbp.gs_id == new_sbp_data[i]["gs_id"] assert subscription.l3_core_service.ap_list[i].sbp.is_tagged == new_sbp_data[i]["is_tagged"] assert subscription.l3_core_service.ap_list[i].sbp.vlan_id == new_sbp_data[i]["vlan_id"] assert str(subscription.l3_core_service.ap_list[i].sbp.ipv4_address) == new_sbp_data[i]["ipv4_address"] -- GitLab From f064efed78be7b3b53c4df4b578f9d079fa0d2ae Mon Sep 17 00:00:00 2001 From: Neda Moeini <neda.moeini@geant.org> Date: Thu, 5 Dec 2024 09:53:45 +0100 Subject: [PATCH 09/20] Make ruff happy --- gso/workflows/iptrunk/migrate_iptrunk.py | 4 +--- .../l2_circuit/test_create_imported_layer_2_circuit.py | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/gso/workflows/iptrunk/migrate_iptrunk.py b/gso/workflows/iptrunk/migrate_iptrunk.py index e0a42d19..03ee4465 100644 --- a/gso/workflows/iptrunk/migrate_iptrunk.py +++ b/gso/workflows/iptrunk/migrate_iptrunk.py @@ -769,9 +769,7 @@ def update_subscription_model( subscription.iptrunk.iptrunk_sides[0].iptrunk_side_node.router_site.site_name, subscription.iptrunk.iptrunk_sides[1].iptrunk_side_node.router_site.site_name, ]) - subscription.description = ( - f"IP trunk {side_names[0]} {side_names[1]}, gs_id:{subscription.iptrunk.gs_id}" - ) + subscription.description = f"IP trunk {side_names[0]} {side_names[1]}, gs_id:{subscription.iptrunk.gs_id}" return {"subscription": subscription} diff --git a/test/workflows/l2_circuit/test_create_imported_layer_2_circuit.py b/test/workflows/l2_circuit/test_create_imported_layer_2_circuit.py index 1bc9884a..2d4ed7a2 100644 --- a/test/workflows/l2_circuit/test_create_imported_layer_2_circuit.py +++ b/test/workflows/l2_circuit/test_create_imported_layer_2_circuit.py @@ -43,9 +43,7 @@ def test_create_imported_layer_2_circuit_success( assert subscription.layer_2_circuit.virtual_circuit_id == creation_form_input_data[0]["vc_id"] assert len(subscription.layer_2_circuit.layer_2_circuit_sides) == 2 assert subscription.layer_2_circuit.layer_2_circuit_sides[0].sbp.is_tagged is True - assert ( - subscription.layer_2_circuit.layer_2_circuit_sides[0].sbp.gs_id == creation_form_input_data[0]["gs_id"] - ) + assert subscription.layer_2_circuit.layer_2_circuit_sides[0].sbp.gs_id == creation_form_input_data[0]["gs_id"] assert ( str(subscription.layer_2_circuit.layer_2_circuit_sides[0].sbp.edge_port.owner_subscription_id) == creation_form_input_data[0]["layer_2_circuit_side_a"]["edge_port"] -- GitLab From 6f9601271f35c3ebd50c194aa40564792b0c5cee Mon Sep 17 00:00:00 2001 From: Neda Moeini <neda.moeini@geant.org> Date: Thu, 5 Dec 2024 12:43:25 +0100 Subject: [PATCH 10/20] Add the GA_ID and GS_ID sequence to manage automatic creation of GA and GS ids --- ...05_79192e72131c_add_gs_and_ga_sequences.py | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 gso/migrations/versions/2024-12-05_79192e72131c_add_gs_and_ga_sequences.py diff --git a/gso/migrations/versions/2024-12-05_79192e72131c_add_gs_and_ga_sequences.py b/gso/migrations/versions/2024-12-05_79192e72131c_add_gs_and_ga_sequences.py new file mode 100644 index 00000000..2fb7fc2d --- /dev/null +++ b/gso/migrations/versions/2024-12-05_79192e72131c_add_gs_and_ga_sequences.py @@ -0,0 +1,42 @@ +"""Add GS and GA sequences. + +Revision ID: 79192e72131c +Revises: e36b3bd8a45c +Create Date: 2024-12-05 11:11:41.048264 + +""" +import sqlalchemy as sa +from alembic import op + +# revision identifiers, used by Alembic. +revision = '79192e72131c' +down_revision = 'e36b3bd8a45c' +branch_labels = None +depends_on = None + + +def upgrade() -> None: + # Create GS ID sequence + op.execute(""" + CREATE SEQUENCE gs_id_seq + START WITH 50000 + INCREMENT BY 1 + MINVALUE 50000 + MAXVALUE 99999 + NO CYCLE; + """) + + # Create GA ID sequence + op.execute(""" + CREATE SEQUENCE ga_id_seq + START WITH 50000 + INCREMENT BY 1 + MINVALUE 50000 + MAXVALUE 99999 + NO CYCLE; + """) + + +def downgrade() -> None: + op.execute("DROP SEQUENCE gs_id_seq") + op.execute("DROP SEQUENCE ga_id_seq") -- GitLab From 28a66dea05e975e1eb1110a88bfaf96f7dc36cfa Mon Sep 17 00:00:00 2001 From: Neda Moeini <neda.moeini@geant.org> Date: Thu, 5 Dec 2024 12:46:13 +0100 Subject: [PATCH 11/20] Make GA and GS unique ids functionality --- gso/services/subscriptions.py | 38 +++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/gso/services/subscriptions.py b/gso/services/subscriptions.py index 9185265c..e5b3c8e7 100644 --- a/gso/services/subscriptions.py +++ b/gso/services/subscriptions.py @@ -19,6 +19,8 @@ from orchestrator.db import ( from orchestrator.domain import SubscriptionModel from orchestrator.services.subscriptions import query_in_use_by_subscriptions from orchestrator.types import SubscriptionLifecycle, UUIDstr +from sqlalchemy import text +from sqlalchemy.exc import SQLAlchemyError from gso.products import ProductName, ProductType from gso.products.product_types.site import Site @@ -329,3 +331,39 @@ def is_virtual_circuit_id_available(virtual_circuit_id: str) -> bool: True if the virtual circuit ID is unique (not found), False if it exists. """ return is_resource_type_value_unique("virtual_circuit_id", virtual_circuit_id) + + +def make_unique_gs_id() -> str: + """Generate a unique GS ID using the gs_id_seq database sequence. + + Returns: + str: A unique GS ID in the format `GS-<number>`. + + Raises: + ValueError: If there is an error generating the ID. + """ + try: + new_id = db.session.execute(text("SELECT nextval('gs_id_seq')")).scalar_one() + except SQLAlchemyError as exc: + error_message = f"Error generating GS ID: {exc}" + raise ValueError(error_message) from exc + else: + return f"GS-{new_id}" + + +def make_unique_ga_id() -> str: + """Generate a unique GA ID using the ga_id_seq database sequence. + + Returns: + str: A unique GA ID in the format `GA<number>`. + + Raises: + ValueError: If there is an error generating the ID. + """ + try: + new_id = db.session.execute(text("SELECT nextval('ga_id_seq')")).scalar_one() + except SQLAlchemyError as exc: + error_message = f"Error generating GA ID: {exc}" + raise ValueError(error_message) from exc + else: + return f"GA-{new_id}" -- GitLab From c0b3a84142bdc913fab4d862fd84b1fa62ad537d Mon Sep 17 00:00:00 2001 From: Neda Moeini <neda.moeini@geant.org> Date: Thu, 5 Dec 2024 12:48:19 +0100 Subject: [PATCH 12/20] Update create EdgePort WF --- gso/workflows/edge_port/create_edge_port.py | 5 ++--- test/workflows/edge_port/test_create_edge_port.py | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/gso/workflows/edge_port/create_edge_port.py b/gso/workflows/edge_port/create_edge_port.py index ccd022f6..a3ff763c 100644 --- a/gso/workflows/edge_port/create_edge_port.py +++ b/gso/workflows/edge_port/create_edge_port.py @@ -22,6 +22,7 @@ from gso.products.product_types.router import Router from gso.services.lso_client import LSOState, lso_interaction from gso.services.netbox_client import NetboxClient from gso.services.partners import get_partner_by_id +from gso.services.subscriptions import make_unique_ga_id from gso.utils.helpers import ( active_pe_router_selector, available_interfaces_choices, @@ -52,7 +53,6 @@ def initial_input_form_generator(product_name: str) -> FormGenerator: minimum_links: int mac_address: str | None = None ignore_if_down: bool = False - ga_id: str | None = None @model_validator(mode="after") def validate_number_of_members(self) -> Self: @@ -104,7 +104,6 @@ def initial_input_form_generator(product_name: str) -> FormGenerator: "minimum_links", "mac_address", "ignore_if_down", - "ga_id", "enable_lacp", "edge_port_name", "edge_port_description", @@ -134,7 +133,6 @@ def initialize_subscription( encapsulation: EncapsulationType, name: str, minimum_links: int, - ga_id: str | None, mac_address: str | None, partner: str, enable_lacp: bool, # noqa: FBT001 @@ -152,6 +150,7 @@ def initialize_subscription( subscription.edge_port.edge_port_name = name subscription.edge_port.minimum_links = minimum_links subscription.edge_port.ignore_if_down = ignore_if_down + ga_id = make_unique_ga_id() subscription.edge_port.ga_id = ga_id subscription.edge_port.mac_address = mac_address partner_name = get_partner_by_id(partner).name diff --git a/test/workflows/edge_port/test_create_edge_port.py b/test/workflows/edge_port/test_create_edge_port.py index 35cf2613..107dab95 100644 --- a/test/workflows/edge_port/test_create_edge_port.py +++ b/test/workflows/edge_port/test_create_edge_port.py @@ -50,7 +50,6 @@ def input_form_wizard_data(request, router_subscription_factory, partner_factory "node": router_subscription_factory(vendor=Vendor.NOKIA), "partner": partner_factory(name="GAAR", email=faker.email())["partner_id"], "service_type": EdgePortType.PUBLIC, - "ga_id": faker.geant_gid(), "enable_lacp": True, "speed": PhysicalPortCapacity.HUNDRED_GIGABIT_PER_SECOND, "encapsulation": EncapsulationType.DOT1Q, @@ -101,9 +100,9 @@ def test_successful_edge_port_creation( subscription = EdgePort.from_subscription(subscription_id) assert subscription.status == "active" - ga_id = input_form_wizard_data[0]["ga_id"] router_fqdn = Router.from_subscription(input_form_wizard_data[0]["node"]).router.router_fqdn - assert subscription.description == f"Edge Port lag-21 on {router_fqdn}, GAAR, {ga_id}" + assert subscription.edge_port.ga_id is not None + assert subscription.description == f"Edge Port lag-21 on {router_fqdn}, GAAR, {subscription.edge_port.ga_id}" assert len(subscription.edge_port.edge_port_ae_members) == 2 assert mock_execute_playbook.call_count == 2 -- GitLab From 66bf227e8ca3c510e855bb65ba67d96b07b436df Mon Sep 17 00:00:00 2001 From: Neda Moeini <neda.moeini@geant.org> Date: Thu, 5 Dec 2024 12:52:39 +0100 Subject: [PATCH 13/20] Update create EdgePort WF and rename generating GA and GS ids function --- gso/services/subscriptions.py | 4 ++-- gso/workflows/edge_port/create_edge_port.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gso/services/subscriptions.py b/gso/services/subscriptions.py index e5b3c8e7..e6781244 100644 --- a/gso/services/subscriptions.py +++ b/gso/services/subscriptions.py @@ -333,7 +333,7 @@ def is_virtual_circuit_id_available(virtual_circuit_id: str) -> bool: return is_resource_type_value_unique("virtual_circuit_id", virtual_circuit_id) -def make_unique_gs_id() -> str: +def generate_unique_gs_id() -> str: """Generate a unique GS ID using the gs_id_seq database sequence. Returns: @@ -351,7 +351,7 @@ def make_unique_gs_id() -> str: return f"GS-{new_id}" -def make_unique_ga_id() -> str: +def generate_unique_ga_id() -> str: """Generate a unique GA ID using the ga_id_seq database sequence. Returns: diff --git a/gso/workflows/edge_port/create_edge_port.py b/gso/workflows/edge_port/create_edge_port.py index a3ff763c..a62c7147 100644 --- a/gso/workflows/edge_port/create_edge_port.py +++ b/gso/workflows/edge_port/create_edge_port.py @@ -22,7 +22,7 @@ from gso.products.product_types.router import Router from gso.services.lso_client import LSOState, lso_interaction from gso.services.netbox_client import NetboxClient from gso.services.partners import get_partner_by_id -from gso.services.subscriptions import make_unique_ga_id +from gso.services.subscriptions import generate_unique_ga_id from gso.utils.helpers import ( active_pe_router_selector, available_interfaces_choices, @@ -150,7 +150,7 @@ def initialize_subscription( subscription.edge_port.edge_port_name = name subscription.edge_port.minimum_links = minimum_links subscription.edge_port.ignore_if_down = ignore_if_down - ga_id = make_unique_ga_id() + ga_id = generate_unique_ga_id() subscription.edge_port.ga_id = ga_id subscription.edge_port.mac_address = mac_address partner_name = get_partner_by_id(partner).name -- GitLab From f11acd44d7dd6acc52571187376875e307248a7f Mon Sep 17 00:00:00 2001 From: Neda Moeini <neda.moeini@geant.org> Date: Thu, 5 Dec 2024 13:25:32 +0100 Subject: [PATCH 14/20] Update create Iptrunk WF --- gso/workflows/iptrunk/create_iptrunk.py | 18 ++++++++---------- test/workflows/iptrunk/test_create_iptrunk.py | 6 ++---- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/gso/workflows/iptrunk/create_iptrunk.py b/gso/workflows/iptrunk/create_iptrunk.py index eefcd46c..8f24e333 100644 --- a/gso/workflows/iptrunk/create_iptrunk.py +++ b/gso/workflows/iptrunk/create_iptrunk.py @@ -57,7 +57,11 @@ from gso.services.lso_client import LSOState, lso_interaction from gso.services.netbox_client import NetboxClient from gso.services.partners import get_partner_by_name from gso.services.sharepoint import SharePointClient -from gso.services.subscriptions import get_non_terminated_iptrunk_subscriptions +from gso.services.subscriptions import ( + generate_unique_ga_id, + generate_unique_gs_id, + get_non_terminated_iptrunk_subscriptions, +) from gso.settings import load_oss_params from gso.utils.helpers import ( available_interfaces_choices, @@ -86,7 +90,6 @@ def initial_input_form_generator(product_name: str) -> FormGenerator: tt_number: TTNumber partner: ReadOnlyField("GEANT", default_type=str) # type: ignore[valid-type] - gs_id: str | None = None iptrunk_description: str | None = None iptrunk_type: IptrunkType iptrunk_speed: PhysicalPortCapacity @@ -144,7 +147,6 @@ def initial_input_form_generator(product_name: str) -> FormGenerator: model_config = ConfigDict(title=f"Provide subscription details for side A of the trunk. ({router_a_fqdn})") side_a_ae_iface: available_lags_choices(router_a) or str # type: ignore[valid-type] - side_a_ga_id: str | None side_a_ae_members: ae_members_side_a_type user_input_side_a = yield CreateIptrunkSideAForm @@ -182,7 +184,6 @@ def initial_input_form_generator(product_name: str) -> FormGenerator: model_config = ConfigDict(title=f"Provide subscription details for side B of the trunk. ({router_b_fqdn})") side_b_ae_iface: available_lags_choices(router_b) or str # type: ignore[valid-type] - side_b_ga_id: str | None side_b_ae_members: ae_members_side_b user_input_side_b = yield CreateIptrunkSideBForm @@ -196,7 +197,6 @@ def initial_input_form_generator(product_name: str) -> FormGenerator: ) summary_form_data = input_forms_data | {"side_a_node": router_a_fqdn, "side_b_node": router_b_fqdn} summary_fields = [ - "gs_id", "iptrunk_type", "iptrunk_speed", "iptrunk_description", @@ -204,11 +204,9 @@ def initial_input_form_generator(product_name: str) -> FormGenerator: "side_a_node", "side_a_ae_iface", "side_a_ae_members", - "side_a_ga_id", "side_b_node", "side_b_ae_iface", "side_b_ae_members", - "side_b_ga_id", ] yield from create_summary_form(summary_form_data, product_name, summary_fields) @@ -322,24 +320,22 @@ def ping_all_hosts_v6(new_ipv6_network: str) -> State: @step("Initialize subscription") def initialize_subscription( subscription: IptrunkInactive, - gs_id: str | None, iptrunk_type: IptrunkType, iptrunk_description: str | None, iptrunk_speed: PhysicalPortCapacity, iptrunk_minimum_links: int, side_a_node_id: str, side_a_ae_iface: str, - side_a_ga_id: str | None, side_a_ae_members: list[dict], side_b_node_id: str, side_b_ae_iface: str, - side_b_ga_id: str | None, side_b_ae_members: list[dict], ) -> State: """Take all input from the user, and store it in the database.""" oss_params = load_oss_params() side_a = Router.from_subscription(side_a_node_id).router side_b = Router.from_subscription(side_b_node_id).router + gs_id = generate_unique_gs_id() subscription.iptrunk.gs_id = gs_id subscription.iptrunk.iptrunk_description = iptrunk_description subscription.iptrunk.iptrunk_type = iptrunk_type @@ -349,6 +345,7 @@ def initialize_subscription( subscription.iptrunk.iptrunk_sides[0].iptrunk_side_node = side_a subscription.iptrunk.iptrunk_sides[0].iptrunk_side_ae_iface = side_a_ae_iface + side_a_ga_id = generate_unique_ga_id() subscription.iptrunk.iptrunk_sides[0].ga_id = side_a_ga_id for member in side_a_ae_members: subscription.iptrunk.iptrunk_sides[0].iptrunk_side_ae_members.append( @@ -357,6 +354,7 @@ def initialize_subscription( subscription.iptrunk.iptrunk_sides[1].iptrunk_side_node = side_b subscription.iptrunk.iptrunk_sides[1].iptrunk_side_ae_iface = side_b_ae_iface + side_b_ga_id = generate_unique_ga_id() subscription.iptrunk.iptrunk_sides[1].ga_id = side_b_ga_id for member in side_b_ae_members: subscription.iptrunk.iptrunk_sides[1].iptrunk_side_ae_members.append( diff --git a/test/workflows/iptrunk/test_create_iptrunk.py b/test/workflows/iptrunk/test_create_iptrunk.py index 17c37388..a45f3bf1 100644 --- a/test/workflows/iptrunk/test_create_iptrunk.py +++ b/test/workflows/iptrunk/test_create_iptrunk.py @@ -65,7 +65,6 @@ def input_form_wizard_data(request, router_subscription_factory, faker): create_ip_trunk_step = { "tt_number": faker.tt_number(), - "gs_id": faker.geant_sid(), "iptrunk_type": IptrunkType.DARK_FIBER, "iptrunk_description": faker.sentence(), "iptrunk_speed": PhysicalPortCapacity.HUNDRED_GIGABIT_PER_SECOND, @@ -75,7 +74,6 @@ def input_form_wizard_data(request, router_subscription_factory, faker): create_ip_trunk_side_a_router_name = {"side_a_node_id": router_side_a} create_ip_trunk_side_a_step = { "side_a_ae_iface": "lag-1", - "side_a_ga_id": None, "side_a_ae_members": [ { "interface_name": f"Interface{interface}", @@ -87,7 +85,6 @@ def input_form_wizard_data(request, router_subscription_factory, faker): create_ip_trunk_side_b_router_name = {"side_b_node_id": router_side_b} create_ip_trunk_side_b_step = { "side_b_ae_iface": "lag-4", - "side_b_ga_id": faker.geant_sid(), "side_b_ae_members": side_b_members, } summary_view_step = {} @@ -153,8 +150,9 @@ def test_successful_iptrunk_creation_with_standard_lso_result( subscription.iptrunk.iptrunk_sides[1].iptrunk_side_node.router_site.site_name, ]) assert subscription.status == "provisioning" + assert subscription.iptrunk.gs_id is not None assert subscription.description == ( - f"IP trunk {sorted_sides[0]} {sorted_sides[1]}, gs_id:{input_form_wizard_data[0]["gs_id"]}" + f"IP trunk {sorted_sides[0]} {sorted_sides[1]}, gs_id:{subscription.iptrunk.gs_id}" ) assert mock_execute_playbook.call_count == 6 -- GitLab From f4f004921d653d0568bef3173e4fb1226e59c06e Mon Sep 17 00:00:00 2001 From: Neda Moeini <neda.moeini@geant.org> Date: Thu, 5 Dec 2024 13:41:11 +0100 Subject: [PATCH 15/20] Update create L3 core service and L2 Circuit WFs --- gso/workflows/l2_circuit/create_layer_2_circuit.py | 4 ++-- gso/workflows/l3_core_service/create_l3_core_service.py | 4 +++- test/workflows/l2_circuit/test_create_layer_2_circuit.py | 7 ++++--- .../l3_core_service/test_create_l3_core_service.py | 1 - 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/gso/workflows/l2_circuit/create_layer_2_circuit.py b/gso/workflows/l2_circuit/create_layer_2_circuit.py index 7959a30b..acf5beef 100644 --- a/gso/workflows/l2_circuit/create_layer_2_circuit.py +++ b/gso/workflows/l2_circuit/create_layer_2_circuit.py @@ -19,6 +19,7 @@ from gso.products.product_blocks.service_binding_port import ServiceBindingPortI from gso.products.product_types.edge_port import EdgePort from gso.products.product_types.layer_2_circuit import Layer2Circuit, Layer2CircuitInactive from gso.services.partners import get_partner_by_name +from gso.services.subscriptions import generate_unique_gs_id from gso.utils.helpers import active_edge_port_selector, generate_unique_vc_id, partner_choice from gso.utils.shared_enums import SBPType from gso.utils.types.interfaces import BandwidthString @@ -69,7 +70,6 @@ def initial_input_generator(product_name: str) -> FormGenerator: vlan_divider: Divider = Field(None, exclude=True) policer_bandwidth: _policer_field(policer_enabled=initial_user_input.policer_enabled) # type: ignore[valid-type] policer_burst_rate: _policer_field(policer_enabled=initial_user_input.policer_enabled) # type: ignore[valid-type] - gs_id: str layer_2_circuit_side_a: Layer2CircuitSideSelection side_divider: Divider = Field(None, exclude=True) layer_2_circuit_side_b: Layer2CircuitSideSelection @@ -105,10 +105,10 @@ def initialize_subscription( policer_enabled: bool, # noqa: FBT001 policer_bandwidth: BandwidthString | None, policer_burst_rate: BandwidthString | None, - gs_id: str, ) -> State: """Build a subscription object from all user input.""" layer_2_circuit_sides = [] + gs_id = generate_unique_gs_id() for circuit_side_data in [layer_2_circuit_side_a, layer_2_circuit_side_b]: sbp = ServiceBindingPortInactive.new( uuid4(), diff --git a/gso/workflows/l3_core_service/create_l3_core_service.py b/gso/workflows/l3_core_service/create_l3_core_service.py index 04edd53f..cd42c761 100644 --- a/gso/workflows/l3_core_service/create_l3_core_service.py +++ b/gso/workflows/l3_core_service/create_l3_core_service.py @@ -20,6 +20,7 @@ from gso.products.product_types.edge_port import EdgePort from gso.products.product_types.l3_core_service import L3CoreService, L3CoreServiceInactive from gso.services.lso_client import LSOState, lso_interaction from gso.services.partners import get_partner_by_id +from gso.services.subscriptions import generate_unique_gs_id from gso.utils.helpers import ( active_edge_port_selector, partner_choice, @@ -113,7 +114,6 @@ def initial_input_form_generator(product_name: str) -> FormGenerator: exclude=True, ) - gs_id: str is_tagged: bool = False vlan_id: VLAN_ID custom_firewall_filters: bool = False @@ -165,6 +165,7 @@ def initialize_subscription( BGPSession.new(subscription_id=uuid4(), rtbh_enabled=True, is_multi_hop=True, **session) for session in binding_port_input["bgp_peers"] ] + sbp_gs_id = generate_unique_gs_id() service_binding_port = ServiceBindingPortInactive.new( subscription_id=uuid4(), v4_bfd_settings=BFDSettings.new(subscription_id=uuid4(), **(binding_port_input.pop("v4_bfd_settings"))), @@ -173,6 +174,7 @@ def initialize_subscription( bgp_session_list=sbp_bgp_session_list, sbp_type=SBPType.L3, edge_port=edge_port_subscription.edge_port, + gs_id=sbp_gs_id, ) subscription.l3_core_service.ap_list.append( AccessPortInactive.new( diff --git a/test/workflows/l2_circuit/test_create_layer_2_circuit.py b/test/workflows/l2_circuit/test_create_layer_2_circuit.py index edfab4dd..c14ab121 100644 --- a/test/workflows/l2_circuit/test_create_layer_2_circuit.py +++ b/test/workflows/l2_circuit/test_create_layer_2_circuit.py @@ -28,7 +28,6 @@ def layer_2_circuit_input(faker, partner_factory, edge_port_subscription_factory "vlan_range_upper_bound": faker.vlan_id(), "policer_bandwidth": faker.bandwidth() if policer_enabled else None, "policer_burst_rate": faker.bandwidth() if policer_enabled else None, - "gs_id": faker.geant_sid(), "layer_2_circuit_side_a": {"edge_port": edge_port_a, "vlan_id": faker.vlan_id()}, "layer_2_circuit_side_b": {"edge_port": edge_port_b, "vlan_id": faker.vlan_id()}, }, @@ -56,13 +55,15 @@ def test_create_layer_2_circuit_success( == layer_2_circuit_input[2]["layer_2_circuit_side_a"]["edge_port"] ) assert subscription.layer_2_circuit.layer_2_circuit_sides[0].sbp.is_tagged is True - assert subscription.layer_2_circuit.layer_2_circuit_sides[0].sbp.gs_id == layer_2_circuit_input[2]["gs_id"] + assert ( + subscription.layer_2_circuit.layer_2_circuit_sides[0].sbp.gs_id + == subscription.layer_2_circuit.layer_2_circuit_sides[1].sbp.gs_id + ) assert ( str(subscription.layer_2_circuit.layer_2_circuit_sides[1].sbp.edge_port.owner_subscription_id) == layer_2_circuit_input[2]["layer_2_circuit_side_b"]["edge_port"] ) assert subscription.layer_2_circuit.layer_2_circuit_sides[1].sbp.is_tagged is True - assert subscription.layer_2_circuit.layer_2_circuit_sides[1].sbp.gs_id == layer_2_circuit_input[2]["gs_id"] assert subscription.layer_2_circuit.layer_2_circuit_type == Layer2CircuitType.TAGGED assert subscription.layer_2_circuit.vlan_range_lower_bound == layer_2_circuit_input[2]["vlan_range_lower_bound"] assert subscription.layer_2_circuit.vlan_range_upper_bound == layer_2_circuit_input[2]["vlan_range_upper_bound"] diff --git a/test/workflows/l3_core_service/test_create_l3_core_service.py b/test/workflows/l3_core_service/test_create_l3_core_service.py index 2295e362..c26e6494 100644 --- a/test/workflows/l3_core_service/test_create_l3_core_service.py +++ b/test/workflows/l3_core_service/test_create_l3_core_service.py @@ -49,7 +49,6 @@ def test_create_l3_core_service_success( {"tt_number": faker.tt_number(), "partner": partner["partner_id"]}, {"edge_port": {"edge_port": edge_port_a, "ap_type": APType.PRIMARY}}, { - "gs_id": faker.geant_sid(), "is_tagged": faker.boolean(), "vlan_id": faker.vlan_id(), "ipv4_address": faker.ipv4(), -- GitLab From 4208ca006232bb368739e0c724c6ccf1424aeb6c Mon Sep 17 00:00:00 2001 From: Neda Moeini <neda.moeini@geant.org> Date: Thu, 5 Dec 2024 15:58:34 +0100 Subject: [PATCH 16/20] Update the relevant import WF --- gso/cli/imports.py | 13 ++--- gso/utils/types/geant_ids.py | 49 +++++++++++++++++++ .../edge_port/create_imported_edge_port.py | 5 +- .../iptrunk/create_imported_iptrunk.py | 13 ++--- test/cli/test_imports.py | 18 +++---- test/conftest.py | 18 +++++-- test/fixtures/edge_port_fixtures.py | 2 +- test/fixtures/iptrunk_fixtures.py | 4 +- test/fixtures/l3_core_service_fixtures.py | 2 +- test/fixtures/layer_2_circuit_fixtures.py | 2 +- .../test_create_imported_edge_port.py | 2 +- .../edge_port/test_modify_edge_port.py | 4 +- .../iptrunk/test_create_imported_iptrunk.py | 6 +-- .../iptrunk/test_modify_trunk_interface.py | 6 +-- .../test_create_imported_layer_2_circuit.py | 2 +- .../test_create_imported_l3_core_service.py | 2 +- .../test_modify_l3_core_service.py | 4 +- 17 files changed, 107 insertions(+), 45 deletions(-) create mode 100644 gso/utils/types/geant_ids.py diff --git a/gso/cli/imports.py b/gso/cli/imports.py index ba33565e..4c973ace 100644 --- a/gso/cli/imports.py +++ b/gso/cli/imports.py @@ -40,6 +40,7 @@ from gso.services.subscriptions import ( ) from gso.utils.shared_enums import SBPType, Vendor from gso.utils.types.base_site import BaseSiteValidatorModel +from gso.utils.types.geant_ids import IMPORTED_GA_ID, IMPORTED_GS_ID from gso.utils.types.interfaces import BandwidthString, LAGMember, LAGMemberList, PhysicalPortCapacity from gso.utils.types.ip_address import ( AddressSpace, @@ -116,7 +117,7 @@ class IptrunkImportModel(BaseModel): """Required fields for importing an existing ``gso.products.product_types.iptrunk``.""" partner: str - gs_id: str | None + gs_id: IMPORTED_GS_ID | None iptrunk_type: IptrunkType iptrunk_description: str | None = None iptrunk_speed: PhysicalPortCapacity @@ -124,11 +125,11 @@ class IptrunkImportModel(BaseModel): iptrunk_isis_metric: int side_a_node_id: str side_a_ae_iface: str - side_a_ga_id: str | None + side_a_ga_id: IMPORTED_GA_ID | None side_a_ae_members: LAGMemberList[LAGMember] side_b_node_id: str side_b_ae_iface: str - side_b_ga_id: str | None + side_b_ga_id: IMPORTED_GA_ID | None side_b_ae_members: LAGMemberList[LAGMember] iptrunk_ipv4_network: ipaddress.IPv4Network @@ -197,7 +198,7 @@ class EdgePortImportModel(BaseModel): encapsulation: EncapsulationType name: str minimum_links: int - ga_id: str | None + ga_id: IMPORTED_GA_ID | None mac_address: str | None partner: str enable_lacp: bool @@ -269,7 +270,7 @@ class L3CoreServiceImportModel(BaseModel): edge_port: str ap_type: str - gs_id: str + gs_id: IMPORTED_GS_ID sbp_type: SBPType = SBPType.L3 is_tagged: bool = False vlan_id: VLAN_ID @@ -349,7 +350,7 @@ class Layer2CircuitServiceImportModel(BaseModel): service_type: Layer2CircuitServiceType partner: str - gs_id: str + gs_id: IMPORTED_GS_ID vc_id: VC_ID layer_2_circuit_side_a: ServiceBindingPortInput layer_2_circuit_side_b: ServiceBindingPortInput diff --git a/gso/utils/types/geant_ids.py b/gso/utils/types/geant_ids.py new file mode 100644 index 00000000..adc3b19c --- /dev/null +++ b/gso/utils/types/geant_ids.py @@ -0,0 +1,49 @@ +"""Type definitions for the GA and GS IDs.""" + +from functools import partial +from typing import Annotated + +from pydantic import AfterValidator + +from gso.services.subscriptions import is_resource_type_value_unique + + +def validate_id(value: str, prefix: str, field_name: str) -> str: + """Validate that the ID is unique, has the correct prefix, and is within valid constraints. + + Args: + value (str): The ID value to validate. + prefix (str): The required prefix for the ID (e.g., "GA-" or "GS-"). + field_name (str): The database field name to check for uniqueness (e.g., "ga_id" or "gs_id"). + + Raises: + ValueError: If the ID is not valid. + + Returns: + str: The validated ID. + """ + min_range = 50000 + max_range = 99999 + if not value.startswith(prefix): + err = f"{field_name} must start with the prefix '{prefix}'." + raise ValueError(err) + + try: + numeric_part = int(value[len(prefix) :]) + except ValueError: + err = f"{field_name} must have a numeric part after the prefix '{prefix}'." + raise ValueError(err) from ValueError + + if min_range <= numeric_part < max_range: + err = f"{field_name} must not have a numeric part between 50000 and 99999." + raise ValueError(err) + + if not is_resource_type_value_unique(field_name, value): + err = f"{field_name} must be unique." + raise ValueError(err) + + return value + + +IMPORTED_GA_ID = Annotated[str, AfterValidator(partial(validate_id, prefix="GA-", field_name="ga_id"))] +IMPORTED_GS_ID = Annotated[str, AfterValidator(partial(validate_id, prefix="GS-", field_name="gs_id"))] diff --git a/gso/workflows/edge_port/create_imported_edge_port.py b/gso/workflows/edge_port/create_imported_edge_port.py index 07d4abf3..cd5f7a7b 100644 --- a/gso/workflows/edge_port/create_imported_edge_port.py +++ b/gso/workflows/edge_port/create_imported_edge_port.py @@ -20,6 +20,7 @@ from gso.products.product_types.router import Router from gso.services.partners import get_partner_by_name from gso.services.subscriptions import get_product_id_by_name from gso.utils.helpers import active_pe_router_selector +from gso.utils.types.geant_ids import IMPORTED_GA_ID from gso.utils.types.interfaces import LAGMember, PhysicalPortCapacity @@ -48,7 +49,7 @@ def initial_input_form_generator() -> FormGenerator: minimum_links: int mac_address: str | None = None ignore_if_down: bool = False - ga_id: str | None = None + ga_id: IMPORTED_GA_ID | None = None description: str | None = None name: str ae_members: Annotated[list[LAGMember], AfterValidator(validate_unique_list)] @@ -67,7 +68,7 @@ def initialize_subscription( encapsulation: EncapsulationType, name: str, minimum_links: int, - ga_id: str | None, + ga_id: IMPORTED_GA_ID | None, mac_address: str | None, partner: str, enable_lacp: bool, # noqa: FBT001 diff --git a/gso/workflows/iptrunk/create_imported_iptrunk.py b/gso/workflows/iptrunk/create_imported_iptrunk.py index db88b2b8..1feec505 100644 --- a/gso/workflows/iptrunk/create_imported_iptrunk.py +++ b/gso/workflows/iptrunk/create_imported_iptrunk.py @@ -20,6 +20,7 @@ from gso.products.product_types.router import Router from gso.services import subscriptions from gso.services.partners import get_partner_by_name from gso.utils.helpers import active_router_selector +from gso.utils.types.geant_ids import IMPORTED_GA_ID, IMPORTED_GS_ID from gso.utils.types.interfaces import LAGMember, LAGMemberList, PhysicalPortCapacity @@ -30,7 +31,7 @@ def initial_input_form_generator() -> FormGenerator: model_config = ConfigDict(title="Import Iptrunk") partner: str - gs_id: str | None = None + gs_id: IMPORTED_GS_ID | None = None iptrunk_description: str | None = None iptrunk_type: IptrunkType iptrunk_speed: PhysicalPortCapacity @@ -39,12 +40,12 @@ def initial_input_form_generator() -> FormGenerator: side_a_node_id: active_router_selector() # type: ignore[valid-type] side_a_ae_iface: str - side_a_ga_id: str | None = None + side_a_ga_id: IMPORTED_GA_ID | None = None side_a_ae_members: Annotated[list[LAGMember], AfterValidator(validate_unique_list)] side_b_node_id: active_router_selector() # type: ignore[valid-type] side_b_ae_iface: str - side_b_ga_id: str | None = None + side_b_ga_id: IMPORTED_GA_ID | None = None side_b_ae_members: Annotated[list[LAGMember], AfterValidator(validate_unique_list)] iptrunk_ipv4_network: ipaddress.IPv4Network @@ -71,7 +72,7 @@ def create_subscription(partner: str) -> State: @step("Initialize subscription") def initialize_subscription( subscription: ImportedIptrunkInactive, - gs_id: str | None, + gs_id: IMPORTED_GS_ID | None, iptrunk_type: IptrunkType, iptrunk_description: str, iptrunk_speed: PhysicalPortCapacity, @@ -79,11 +80,11 @@ def initialize_subscription( iptrunk_isis_metric: int, side_a_node_id: str, side_a_ae_iface: str, - side_a_ga_id: str | None, + side_a_ga_id: IMPORTED_GA_ID | None, side_a_ae_members: LAGMemberList, side_b_node_id: str, side_b_ae_iface: str, - side_b_ga_id: str | None, + side_b_ga_id: IMPORTED_GA_ID | None, side_b_ae_members: LAGMemberList, ) -> State: """Take all input from the user, and store it in the database.""" diff --git a/test/cli/test_imports.py b/test/cli/test_imports.py index 475492a4..571e64b6 100644 --- a/test/cli/test_imports.py +++ b/test/cli/test_imports.py @@ -62,7 +62,7 @@ def iptrunk_data(temp_file, router_subscription_factory, faker) -> (Path, dict): ipv6_network = ipv6_network or str(faker.ipv6_network(max_subnet=126)) iptrunk_data = { - "id": faker.geant_sid(), + "id": faker.imported_gs_id(), "config": { "common": { "link_speed": PhysicalPortCapacity.HUNDRED_GIGABIT_PER_SECOND, @@ -73,7 +73,7 @@ def iptrunk_data(temp_file, router_subscription_factory, faker) -> (Path, dict): "nodeA": { "name": side_a_node or Router.from_subscription(router_side_a).router.router_fqdn, "ae_name": side_a_ae_name or faker.network_interface(), - "port_ga_id": faker.geant_gid(), + "port_ga_id": faker.imported_ga_id(), "members": side_a_members or [ { @@ -88,7 +88,7 @@ def iptrunk_data(temp_file, router_subscription_factory, faker) -> (Path, dict): "nodeB": { "name": side_b_node or Router.from_subscription(router_side_b).router.router_fqdn, "ae_name": side_b_ae_name or faker.network_interface(), - "port_ga_id": faker.geant_gid(), + "port_ga_id": faker.imported_ga_id(), "members": side_b_members or [ { @@ -270,7 +270,7 @@ def edge_port_data(temp_file, faker, router_subscription_factory, partner_factor "encapsulation": EncapsulationType.DOT1Q, "name": "lag34", "minimum_links": 2, - "ga_id": faker.geant_gid(), + "ga_id": faker.imported_ga_id(), "mac_address": faker.mac_address(), "partner": partner_factory()["name"], "enable_lacp": True, @@ -305,7 +305,7 @@ def l3_core_service_data(temp_file, faker, partner_factory, edge_port_subscripti { "edge_port": edge_port_subscription_factory(), "ap_type": "PRIMARY", - "gs_id": faker.geant_sid(), + "gs_id": faker.imported_gs_id(), "vlan_id": faker.vlan_id(), "ipv4_address": faker.ipv4(), "ipv4_mask": faker.ipv4_netmask(), @@ -353,7 +353,7 @@ def l3_core_service_data(temp_file, faker, partner_factory, edge_port_subscripti { "edge_port": edge_port_subscription_factory(), "ap_type": "BACKUP", - "gs_id": faker.geant_sid(), + "gs_id": faker.imported_gs_id(), "vlan_id": faker.vlan_id(), "ipv4_address": faker.ipv4(), "ipv4_mask": faker.ipv4_netmask(), @@ -414,7 +414,7 @@ def layer_2_circuit_data(temp_file, faker, partner_factory, edge_port_subscripti layer_2_circuit_input_data = { "partner": partner_factory()["name"], "service_type": Layer2CircuitServiceType.GEANT_PLUS, - "gs_id": faker.geant_sid(), + "gs_id": faker.imported_gs_id(), "vc_id": generate_unique_vc_id(), "layer_2_circuit_side_a": { "edge_port": edge_port_subscription_factory(), @@ -697,7 +697,7 @@ def test_import_l3_core_service_with_invalid_edge_port( { "edge_port": fake_uuid, "ap_type": "PRIMARY", - "gs_id": faker.geant_sid(), + "gs_id": faker.imported_gs_id(), "vlan_id": faker.vlan_id(), "ipv4_address": faker.ipv4(), "ipv4_mask": faker.ipv4_netmask(), @@ -737,7 +737,7 @@ def test_import_l3_core_service_with_invalid_edge_port( { "edge_port": edge_port_subscription_factory(), "ap_type": "BACKUP", - "gs_id": faker.geant_sid(), + "gs_id": faker.imported_gs_id(), "vlan_id": faker.vlan_id(), "ipv4_address": faker.ipv4(), "ipv4_mask": faker.ipv4_netmask(), diff --git a/test/conftest.py b/test/conftest.py index da558c8a..4548fe0f 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -73,11 +73,21 @@ class FakerProvider(BaseProvider): return f"TT#{random_date}{random_int}" - def geant_gid(self) -> str: - return self.generator.numerify("GID-#####") + def ga_id(self) -> str: + random_int = self.generator.random_int(min=50000, max=99999) + return f"GA-{random_int}" - def geant_sid(self) -> str: - return self.generator.numerify("SID-#####") + def gs_id(self) -> str: + random_int = self.generator.random_int(min=50000, max=99999) + return f"GS-{random_int}" + + def imported_ga_id(self) -> str: + random_int = self.generator.random_int(min=00000, max=50000) + return f"GA-{random_int}" + + def imported_gs_id(self) -> str: + random_int = self.generator.random_int(min=00000, max=50000) + return f"GS-{random_int}" def site_name(self) -> str: site_name = "".join(self.generator.random_letter().upper() for _ in range(3)) diff --git a/test/fixtures/edge_port_fixtures.py b/test/fixtures/edge_port_fixtures.py index 7ea6b8b9..0ea87449 100644 --- a/test/fixtures/edge_port_fixtures.py +++ b/test/fixtures/edge_port_fixtures.py @@ -52,7 +52,7 @@ def edge_port_subscription_factory(faker, partner_factory, router_subscription_f ) edge_port_subscription.edge_port.edge_port_description = description or faker.text(max_nb_chars=30) - edge_port_subscription.edge_port.ga_id = ga_id or faker.geant_gid() + edge_port_subscription.edge_port.ga_id = ga_id or faker.ga_id() edge_port_subscription.edge_port.node = node or node edge_port_subscription.edge_port.edge_port_name = name or f"lag-{faker.pyint(21, 50)}" edge_port_subscription.edge_port.edge_port_description = edge_port_description or faker.sentence() diff --git a/test/fixtures/iptrunk_fixtures.py b/test/fixtures/iptrunk_fixtures.py index 17715ebe..742e974a 100644 --- a/test/fixtures/iptrunk_fixtures.py +++ b/test/fixtures/iptrunk_fixtures.py @@ -31,7 +31,7 @@ def iptrunk_side_subscription_factory(router_subscription_factory, faker): iptrunk_side_node or router_subscription_factory(vendor=Vendor.NOKIA) ).router, iptrunk_side_ae_iface=iptrunk_side_ae_iface or faker.pystr(), - ga_id=ga_id or faker.geant_gid(), + ga_id=ga_id or faker.ga_id(), iptrunk_side_ae_members=iptrunk_side_ae_members or [ IptrunkInterfaceBlock.new( @@ -84,7 +84,7 @@ def iptrunk_subscription_factory(iptrunk_side_subscription_factory, faker, geant ) description = description or faker.sentence() - gs_id = gs_id or faker.geant_sid() + gs_id = gs_id or faker.gs_id() iptrunk_description = iptrunk_description or faker.sentence() iptrunk_isis_metric = iptrunk_isis_metric or faker.pyint() iptrunk_ipv4_network = iptrunk_ipv4_network or faker.ipv4_network(max_subnet=31) diff --git a/test/fixtures/l3_core_service_fixtures.py b/test/fixtures/l3_core_service_fixtures.py index 493ddc1c..21ea6379 100644 --- a/test/fixtures/l3_core_service_fixtures.py +++ b/test/fixtures/l3_core_service_fixtures.py @@ -108,7 +108,7 @@ def service_binding_port_factory( ipv6_address=ipv6_address or faker.ipv6(), ipv6_mask=ipv6_mask or faker.ipv6_netmask(), custom_firewall_filters=custom_firewall_filters, - gs_id=gs_id or faker.geant_sid(), + gs_id=gs_id or faker.gs_id(), bgp_session_list=bgp_session_list or [ bgp_session_subscription_factory(families=[IPFamily.V4UNICAST]), diff --git a/test/fixtures/layer_2_circuit_fixtures.py b/test/fixtures/layer_2_circuit_fixtures.py index e7c8c468..2b93a370 100644 --- a/test/fixtures/layer_2_circuit_fixtures.py +++ b/test/fixtures/layer_2_circuit_fixtures.py @@ -82,7 +82,7 @@ def layer_2_circuit_subscription_factory(faker, geant_partner, edge_port_subscri edge_port=EdgePort.from_subscription(edge_port).edge_port, sbp_type=SBPType.L2, vlan_id=vlan_id, - gs_id=gs_id or faker.geant_sid(), + gs_id=gs_id or faker.gs_id(), is_tagged=layer_2_circuit_type == Layer2CircuitType.TAGGED, custom_firewall_filters=False, ) diff --git a/test/workflows/edge_port/test_create_imported_edge_port.py b/test/workflows/edge_port/test_create_imported_edge_port.py index 838d330d..ea5b024e 100644 --- a/test/workflows/edge_port/test_create_imported_edge_port.py +++ b/test/workflows/edge_port/test_create_imported_edge_port.py @@ -17,7 +17,7 @@ def imported_edge_port_creation_input_form_data(router_subscription_factory, par "encapsulation": EncapsulationType.DOT1Q, "name": "lag34", "minimum_links": 2, - "ga_id": faker.geant_gid(), + "ga_id": faker.imported_ga_id(), "mac_address": faker.mac_address(), "partner": partner_factory()["name"], "enable_lacp": True, diff --git a/test/workflows/edge_port/test_modify_edge_port.py b/test/workflows/edge_port/test_modify_edge_port.py index 6e16f73a..25adcd85 100644 --- a/test/workflows/edge_port/test_modify_edge_port.py +++ b/test/workflows/edge_port/test_modify_edge_port.py @@ -21,7 +21,7 @@ def input_form_wizard_data(request, faker, edge_port_subscription_factory, partn {"subscription_id": subscription_id}, { "tt_number": faker.tt_number(), - "ga_id": faker.geant_gid(), + "ga_id": faker.ga_id(), "member_speed": PhysicalPortCapacity.FOUR_HUNDRED_GIGABIT_PER_SECOND, "number_of_members": 1, }, @@ -100,7 +100,7 @@ def input_form_wizard_without_changing_capacity(request, faker, edge_port_subscr return [ {"subscription_id": subscription_id}, - {"tt_number": faker.tt_number(), "ga_id": faker.geant_gid()}, + {"tt_number": faker.tt_number(), "ga_id": faker.ga_id()}, { "description": faker.sentence(), "ae_members": [ diff --git a/test/workflows/iptrunk/test_create_imported_iptrunk.py b/test/workflows/iptrunk/test_create_imported_iptrunk.py index 8b9c5d4d..deaa2ddd 100644 --- a/test/workflows/iptrunk/test_create_imported_iptrunk.py +++ b/test/workflows/iptrunk/test_create_imported_iptrunk.py @@ -16,7 +16,7 @@ from test.workflows import ( def workflow_input_data(faker, router_subscription_factory): return { "partner": "GEANT", - "gs_id": faker.geant_sid(), + "gs_id": faker.imported_gs_id(), "iptrunk_description": faker.sentence(), "iptrunk_type": IptrunkType.DARK_FIBER, "iptrunk_speed": PhysicalPortCapacity.FOUR_HUNDRED_GIGABIT_PER_SECOND, @@ -24,13 +24,13 @@ def workflow_input_data(faker, router_subscription_factory): "iptrunk_isis_metric": 10000, "side_a_node_id": router_subscription_factory(), "side_a_ae_iface": faker.network_interface(), - "side_a_ga_id": faker.geant_gid(), + "side_a_ga_id": faker.imported_ga_id(), "side_a_ae_members": [ {"interface_name": faker.network_interface(), "interface_description": faker.sentence()} for _ in range(3) ], "side_b_node_id": router_subscription_factory(), "side_b_ae_iface": faker.network_interface(), - "side_b_ga_id": faker.geant_gid(), + "side_b_ga_id": faker.imported_ga_id(), "side_b_ae_members": [ {"interface_name": faker.network_interface(), "interface_description": faker.sentence()} for _ in range(3) ], diff --git a/test/workflows/iptrunk/test_modify_trunk_interface.py b/test/workflows/iptrunk/test_modify_trunk_interface.py index 801ce865..12f49b90 100644 --- a/test/workflows/iptrunk/test_modify_trunk_interface.py +++ b/test/workflows/iptrunk/test_modify_trunk_interface.py @@ -52,15 +52,15 @@ def input_form_iptrunk_data( product_id = iptrunk_subscription_factory(iptrunk_sides=[side_a_node, side_b_node]) - new_sid = faker.geant_sid() + new_sid = faker.gs_id() new_description = faker.sentence() new_type = IptrunkType.LEASED new_speed = PhysicalPortCapacity.FOUR_HUNDRED_GIGABIT_PER_SECOND new_link_count = 2 - new_side_a_gid = faker.geant_gid() + new_side_a_gid = faker.ga_id() - new_side_b_gid = faker.geant_gid() + new_side_b_gid = faker.ga_id() return [ {"subscription_id": product_id}, diff --git a/test/workflows/l2_circuit/test_create_imported_layer_2_circuit.py b/test/workflows/l2_circuit/test_create_imported_layer_2_circuit.py index 2d4ed7a2..3d0e7870 100644 --- a/test/workflows/l2_circuit/test_create_imported_layer_2_circuit.py +++ b/test/workflows/l2_circuit/test_create_imported_layer_2_circuit.py @@ -28,7 +28,7 @@ def test_create_imported_layer_2_circuit_success( "vc_id": generate_unique_vc_id(), "policer_bandwidth": faker.bandwidth() if policer_enabled else None, "policer_burst_rate": faker.bandwidth() if policer_enabled else None, - "gs_id": faker.geant_sid(), + "gs_id": faker.imported_gs_id(), "layer_2_circuit_side_a": {"edge_port": edge_port_a, "vlan_id": faker.vlan_id()}, "layer_2_circuit_side_b": {"edge_port": edge_port_b, "vlan_id": faker.vlan_id()}, } diff --git a/test/workflows/l3_core_service/test_create_imported_l3_core_service.py b/test/workflows/l3_core_service/test_create_imported_l3_core_service.py index 0580bb5c..48ac4b54 100644 --- a/test/workflows/l3_core_service/test_create_imported_l3_core_service.py +++ b/test/workflows/l3_core_service/test_create_imported_l3_core_service.py @@ -27,7 +27,7 @@ def test_create_imported_l3_core_service_success( { "edge_port": edge_port_subscription_factory(), "ap_type": "PRIMARY", - "gs_id": faker.geant_sid(), + "gs_id": faker.imported_gs_id(), "sbp_type": SBPType.L3, "is_tagged": faker.boolean(), "vlan_id": faker.vlan_id(), diff --git a/test/workflows/l3_core_service/test_modify_l3_core_service.py b/test/workflows/l3_core_service/test_modify_l3_core_service.py index 333fc670..dc7f3a51 100644 --- a/test/workflows/l3_core_service/test_modify_l3_core_service.py +++ b/test/workflows/l3_core_service/test_modify_l3_core_service.py @@ -84,7 +84,7 @@ def test_modify_l3_core_service_add_new_edge_port_success( {}, # The existing SBPs are unchanged {}, { # Adding configuration for the new SBP - "gs_id": faker.geant_sid(), + "gs_id": faker.gs_id(), "vlan_id": faker.vlan_id(), "ipv4_address": faker.ipv4(), "ipv6_address": faker.ipv6(), @@ -115,7 +115,7 @@ def test_modify_l3_core_service_add_new_edge_port_success( def sbp_input_form_data(faker): def _generate_form_data(): return { - "gs_id": faker.geant_sid(), + "gs_id": faker.gs_id(), "is_tagged": True, "vlan_id": faker.vlan_id(), "ipv4_address": faker.ipv4(), -- GitLab From dc51292181fad87680d520e3104861692f5b7e3a Mon Sep 17 00:00:00 2001 From: Neda Moeini <neda.moeini@geant.org> Date: Thu, 5 Dec 2024 16:05:37 +0100 Subject: [PATCH 17/20] Update the custom geant_ids --- gso/utils/types/geant_ids.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gso/utils/types/geant_ids.py b/gso/utils/types/geant_ids.py index adc3b19c..194f57b0 100644 --- a/gso/utils/types/geant_ids.py +++ b/gso/utils/types/geant_ids.py @@ -34,7 +34,7 @@ def validate_id(value: str, prefix: str, field_name: str) -> str: err = f"{field_name} must have a numeric part after the prefix '{prefix}'." raise ValueError(err) from ValueError - if min_range <= numeric_part < max_range: + if min_range <= numeric_part <= max_range: err = f"{field_name} must not have a numeric part between 50000 and 99999." raise ValueError(err) -- GitLab From 7fdced2db5abb26a81fcbd2c8290ff2771097ec3 Mon Sep 17 00:00:00 2001 From: Karel van Klink <karel.vanklink@geant.org> Date: Wed, 11 Dec 2024 10:08:05 +0100 Subject: [PATCH 18/20] Add input validation to modification workflows that contain GA- and GS-IDs --- gso/services/subscriptions.py | 2 +- gso/workflows/edge_port/modify_edge_port.py | 11 +++++++++-- .../iptrunk/create_imported_iptrunk.py | 2 +- gso/workflows/iptrunk/create_iptrunk.py | 2 +- gso/workflows/iptrunk/migrate_iptrunk.py | 2 +- .../iptrunk/modify_trunk_interface.py | 13 ++++++++++--- .../create_imported_layer_2_circuit.py | 3 ++- .../create_imported_l3_core_service.py | 3 ++- .../edge_port/test_modify_edge_port.py | 17 +++++++++++++++++ test/workflows/iptrunk/test_create_iptrunk.py | 4 +--- .../iptrunk/test_modify_trunk_interface.py | 19 ++++++++++++++++++- 11 files changed, 63 insertions(+), 15 deletions(-) diff --git a/gso/services/subscriptions.py b/gso/services/subscriptions.py index e6781244..83d88751 100644 --- a/gso/services/subscriptions.py +++ b/gso/services/subscriptions.py @@ -355,7 +355,7 @@ def generate_unique_ga_id() -> str: """Generate a unique GA ID using the ga_id_seq database sequence. Returns: - str: A unique GA ID in the format `GA<number>`. + str: A unique GA ID in the format `GA-<number>`. Raises: ValueError: If there is an error generating the ID. diff --git a/gso/workflows/edge_port/modify_edge_port.py b/gso/workflows/edge_port/modify_edge_port.py index 94388984..b176eafc 100644 --- a/gso/workflows/edge_port/modify_edge_port.py +++ b/gso/workflows/edge_port/modify_edge_port.py @@ -1,5 +1,6 @@ """Modify an existing edge port subscription.""" +from functools import partial from typing import Annotated, Any, Self from uuid import uuid4 @@ -10,7 +11,7 @@ from orchestrator.targets import Target from orchestrator.workflow import StepList, begin, conditional, done, step from orchestrator.workflows.steps import resync, store_process_subscription, unsync from orchestrator.workflows.utils import wrap_modify_initial_input_form -from pydantic import AfterValidator, ConfigDict, model_validator +from pydantic import AfterValidator, ConfigDict, Field, model_validator from pydantic_forms.types import FormGenerator, State, UUIDstr from pydantic_forms.validators import ReadOnlyField, validate_unique_list @@ -26,6 +27,7 @@ from gso.utils.helpers import ( ) from gso.utils.types.interfaces import LAGMember, PhysicalPortCapacity from gso.utils.types.tt_number import TTNumber +from gso.utils.types.unique_field import validate_field_is_unique def initial_input_form_generator(subscription_id: UUIDstr) -> FormGenerator: @@ -43,7 +45,12 @@ def initial_input_form_generator(subscription_id: UUIDstr) -> FormGenerator: minimum_links: int | None = subscription.edge_port.minimum_links or None mac_address: str | None = subscription.edge_port.mac_address or None ignore_if_down: bool = subscription.edge_port.ignore_if_down - ga_id: str | None = subscription.edge_port.ga_id or None + ga_id: ( + Annotated[ + str, AfterValidator(partial(validate_field_is_unique, subscription_id)), Field(pattern=r"^GA-\d{5}$") + ] + | None + ) = subscription.edge_port.ga_id or None @model_validator(mode="after") def validate_number_of_members(self) -> Self: diff --git a/gso/workflows/iptrunk/create_imported_iptrunk.py b/gso/workflows/iptrunk/create_imported_iptrunk.py index 1feec505..722121fe 100644 --- a/gso/workflows/iptrunk/create_imported_iptrunk.py +++ b/gso/workflows/iptrunk/create_imported_iptrunk.py @@ -114,7 +114,7 @@ def initialize_subscription( subscription.iptrunk.iptrunk_sides[0].iptrunk_side_node.router_site.site_name, subscription.iptrunk.iptrunk_sides[1].iptrunk_side_node.router_site.site_name, ]) - subscription.description = f"IP trunk {side_names[0]} {side_names[1]}, gs_id:{gs_id}" + subscription.description = f"IP trunk {side_names[0]} {side_names[1]}, {gs_id}" return {"subscription": subscription} diff --git a/gso/workflows/iptrunk/create_iptrunk.py b/gso/workflows/iptrunk/create_iptrunk.py index 8f24e333..962cc5d0 100644 --- a/gso/workflows/iptrunk/create_iptrunk.py +++ b/gso/workflows/iptrunk/create_iptrunk.py @@ -361,7 +361,7 @@ def initialize_subscription( IptrunkInterfaceBlockInactive.new(subscription_id=uuid4(), **member), ) side_names = sorted([side_a.router_site.site_name, side_b.router_site.site_name]) - subscription.description = f"IP trunk {side_names[0]} {side_names[1]}, gs_id:{gs_id}" + subscription.description = f"IP trunk {side_names[0]} {side_names[1]}, {gs_id}" return {"subscription": subscription} diff --git a/gso/workflows/iptrunk/migrate_iptrunk.py b/gso/workflows/iptrunk/migrate_iptrunk.py index 03ee4465..7e7f32b4 100644 --- a/gso/workflows/iptrunk/migrate_iptrunk.py +++ b/gso/workflows/iptrunk/migrate_iptrunk.py @@ -769,7 +769,7 @@ def update_subscription_model( subscription.iptrunk.iptrunk_sides[0].iptrunk_side_node.router_site.site_name, subscription.iptrunk.iptrunk_sides[1].iptrunk_side_node.router_site.site_name, ]) - subscription.description = f"IP trunk {side_names[0]} {side_names[1]}, gs_id:{subscription.iptrunk.gs_id}" + subscription.description = f"IP trunk {side_names[0]} {side_names[1]}, {subscription.iptrunk.gs_id}" return {"subscription": subscription} diff --git a/gso/workflows/iptrunk/modify_trunk_interface.py b/gso/workflows/iptrunk/modify_trunk_interface.py index 65fa452b..ea2309e4 100644 --- a/gso/workflows/iptrunk/modify_trunk_interface.py +++ b/gso/workflows/iptrunk/modify_trunk_interface.py @@ -7,6 +7,7 @@ necessary modifications will be applied. """ import json +from functools import partial from typing import Annotated from uuid import UUID, uuid4 @@ -18,7 +19,7 @@ from orchestrator.utils.json import json_dumps from orchestrator.workflow import StepList, begin, conditional, done, step, workflow from orchestrator.workflows.steps import resync, store_process_subscription, unsync from orchestrator.workflows.utils import wrap_modify_initial_input_form -from pydantic import ConfigDict +from pydantic import AfterValidator, ConfigDict, Field from pydantic_forms.validators import Label, ReadOnlyField from gso.products.product_blocks.iptrunk import ( @@ -39,6 +40,7 @@ from gso.utils.shared_enums import Vendor from gso.utils.types.interfaces import JuniperLAGMember, LAGMember, LAGMemberList, PhysicalPortCapacity from gso.utils.types.ip_address import IPv4AddressType, IPv6AddressType from gso.utils.types.tt_number import TTNumber +from gso.utils.types.unique_field import validate_field_is_unique from gso.workflows.iptrunk.migrate_iptrunk import check_ip_trunk_optical_levels_pre from gso.workflows.iptrunk.validate_iptrunk import check_ip_trunk_isis @@ -86,7 +88,12 @@ def initial_input_form_generator(subscription_id: UUIDstr) -> FormGenerator: class ModifyIptrunkForm(FormPage): tt_number: TTNumber - gs_id: str | None = subscription.iptrunk.gs_id + gs_id: ( + Annotated[ + str, AfterValidator(partial(validate_field_is_unique, subscription_id)), Field(pattern=r"^GS-\d{5}$") + ] + | None + ) = subscription.iptrunk.gs_id iptrunk_description: str | None = subscription.iptrunk.iptrunk_description iptrunk_type: IptrunkType = subscription.iptrunk.iptrunk_type warning_label: Label = ( @@ -302,7 +309,7 @@ def modify_iptrunk_subscription( subscription.iptrunk.iptrunk_sides[0].iptrunk_side_node.router_site.site_name, subscription.iptrunk.iptrunk_sides[1].iptrunk_side_node.router_site.site_name, ]) - subscription.description = f"IP trunk {side_names[0]} {side_names[1]}, gs_id:{gs_id}" + subscription.description = f"IP trunk {side_names[0]} {side_names[1]}, {gs_id}" return { "subscription": subscription, diff --git a/gso/workflows/l2_circuit/create_imported_layer_2_circuit.py b/gso/workflows/l2_circuit/create_imported_layer_2_circuit.py index 6102d86d..3e5e97c9 100644 --- a/gso/workflows/l2_circuit/create_imported_layer_2_circuit.py +++ b/gso/workflows/l2_circuit/create_imported_layer_2_circuit.py @@ -23,6 +23,7 @@ from gso.products.product_types.layer_2_circuit import ( from gso.services.partners import get_partner_by_name from gso.services.subscriptions import get_product_id_by_name from gso.utils.shared_enums import SBPType +from gso.utils.types.geant_ids import IMPORTED_GS_ID from gso.utils.types.interfaces import BandwidthString from gso.utils.types.virtual_identifiers import VC_ID, VLAN_ID @@ -39,7 +40,7 @@ def initial_input_form_generator() -> FormGenerator: service_type: Layer2CircuitServiceType partner: str - gs_id: str + gs_id: IMPORTED_GS_ID vc_id: VC_ID layer_2_circuit_side_a: ServiceBindingPortInput layer_2_circuit_side_b: ServiceBindingPortInput diff --git a/gso/workflows/l3_core_service/create_imported_l3_core_service.py b/gso/workflows/l3_core_service/create_imported_l3_core_service.py index 7862a47f..7280a225 100644 --- a/gso/workflows/l3_core_service/create_imported_l3_core_service.py +++ b/gso/workflows/l3_core_service/create_imported_l3_core_service.py @@ -21,6 +21,7 @@ from gso.products.product_types.l3_core_service import ImportedL3CoreServiceInac from gso.services.partners import get_partner_by_name from gso.services.subscriptions import get_product_id_by_name from gso.utils.shared_enums import SBPType +from gso.utils.types.geant_ids import IMPORTED_GS_ID from gso.utils.types.ip_address import IPAddress, IPv4AddressType, IPV4Netmask, IPv6AddressType, IPV6Netmask from gso.utils.types.virtual_identifiers import VLAN_ID @@ -50,7 +51,7 @@ def initial_input_form_generator() -> FormGenerator: class ServiceBindingPort(BaseModel): edge_port: UUIDstr ap_type: str - gs_id: str + gs_id: IMPORTED_GS_ID sbp_type: SBPType = SBPType.L3 is_tagged: bool = False vlan_id: VLAN_ID diff --git a/test/workflows/edge_port/test_modify_edge_port.py b/test/workflows/edge_port/test_modify_edge_port.py index 25adcd85..0f7ed140 100644 --- a/test/workflows/edge_port/test_modify_edge_port.py +++ b/test/workflows/edge_port/test_modify_edge_port.py @@ -1,6 +1,7 @@ from unittest.mock import patch import pytest +from pydantic_forms.exceptions import FormValidationError from gso.products.product_types.edge_port import EdgePort from gso.utils.types.interfaces import PhysicalPortCapacity @@ -37,6 +38,22 @@ def input_form_wizard_data(request, faker, edge_port_subscription_factory, partn ] +@pytest.mark.workflow() +@pytest.mark.parametrize("invalid_ga_id", ["GS-11111", "GA-1234", "GA_12345", "GA-100000"]) +def test_modify_edge_port_with_invalid_ga_id( + input_form_wizard_data, faker, invalid_ga_id, iptrunk_side_subscription_factory, iptrunk_subscription_factory +): + input_data = input_form_wizard_data + input_data[1]["ga_id"] = invalid_ga_id + iptrunk_subscription_factory( + iptrunk_sides=[iptrunk_side_subscription_factory(ga_id="GA-11111"), iptrunk_side_subscription_factory()] + ) + + # Run workflow + with pytest.raises(FormValidationError): + run_workflow("modify_edge_port", input_data) + + @pytest.mark.workflow() @patch("gso.services.lso_client._send_request") @patch("gso.services.netbox_client.NetboxClient.get_available_interfaces") diff --git a/test/workflows/iptrunk/test_create_iptrunk.py b/test/workflows/iptrunk/test_create_iptrunk.py index a45f3bf1..d0f9cfa5 100644 --- a/test/workflows/iptrunk/test_create_iptrunk.py +++ b/test/workflows/iptrunk/test_create_iptrunk.py @@ -151,9 +151,7 @@ def test_successful_iptrunk_creation_with_standard_lso_result( ]) assert subscription.status == "provisioning" assert subscription.iptrunk.gs_id is not None - assert subscription.description == ( - f"IP trunk {sorted_sides[0]} {sorted_sides[1]}, gs_id:{subscription.iptrunk.gs_id}" - ) + assert subscription.description == f"IP trunk {sorted_sides[0]} {sorted_sides[1]}, {subscription.iptrunk.gs_id}" assert mock_execute_playbook.call_count == 6 # We search for 6 hosts in total, 2 in a /31 and 4 in a /126 diff --git a/test/workflows/iptrunk/test_modify_trunk_interface.py b/test/workflows/iptrunk/test_modify_trunk_interface.py index 12f49b90..d8a96588 100644 --- a/test/workflows/iptrunk/test_modify_trunk_interface.py +++ b/test/workflows/iptrunk/test_modify_trunk_interface.py @@ -1,6 +1,7 @@ from unittest.mock import patch import pytest +from pydantic_forms.exceptions import FormValidationError from gso.products.product_blocks.iptrunk import IptrunkType from gso.products.product_types.iptrunk import Iptrunk @@ -164,7 +165,7 @@ def test_iptrunk_modify_trunk_interface_success( subscription.iptrunk.iptrunk_sides[0].iptrunk_side_node.router_site.site_name, subscription.iptrunk.iptrunk_sides[1].iptrunk_side_node.router_site.site_name, ]) - assert subscription.description == f"IP trunk {side_names[0]} {side_names[1]}, gs_id:{new_sid}" + assert subscription.description == f"IP trunk {side_names[0]} {side_names[1]}, {new_sid}" assert subscription.iptrunk.gs_id == input_form_iptrunk_data[1]["gs_id"] assert subscription.iptrunk.iptrunk_description == input_form_iptrunk_data[1]["iptrunk_description"] assert subscription.iptrunk.iptrunk_type == input_form_iptrunk_data[1]["iptrunk_type"] @@ -192,3 +193,19 @@ def test_iptrunk_modify_trunk_interface_success( member.interface_description == _find_interface_by_name(new_side_b_ae_members, member.interface_name).interface_description ) + + +@pytest.mark.workflow() +@pytest.mark.parametrize("invalid_ga_id", ["GA-11111", "GS-1234", "GS_12345", "GS-100000"]) +def test_modify_iptrunk_interface_with_invalid_ga_id( + input_form_iptrunk_data, faker, invalid_ga_id, iptrunk_side_subscription_factory, iptrunk_subscription_factory +): + input_data = input_form_iptrunk_data + input_data[3]["side_a_ga_id"] = invalid_ga_id + iptrunk_subscription_factory( + iptrunk_sides=[iptrunk_side_subscription_factory(ga_id="GA-11111"), iptrunk_side_subscription_factory()] + ) + + # Run workflow + with pytest.raises(FormValidationError): + run_workflow("modify_edge_port", input_data) -- GitLab From 73d830911ef348e49430fd7d2311aaf61ff44309 Mon Sep 17 00:00:00 2001 From: Karel van Klink <karel.vanklink@geant.org> Date: Wed, 11 Dec 2024 12:09:44 +0100 Subject: [PATCH 19/20] Update typing of ga and gs id validation method --- gso/utils/types/geant_ids.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/gso/utils/types/geant_ids.py b/gso/utils/types/geant_ids.py index 194f57b0..ec728bc0 100644 --- a/gso/utils/types/geant_ids.py +++ b/gso/utils/types/geant_ids.py @@ -1,20 +1,20 @@ """Type definitions for the GA and GS IDs.""" from functools import partial -from typing import Annotated +from typing import Annotated, Literal from pydantic import AfterValidator from gso.services.subscriptions import is_resource_type_value_unique -def validate_id(value: str, prefix: str, field_name: str) -> str: +def validate_id(value: str, prefix: Literal["GA", "GS"], field_name: str) -> str: """Validate that the ID is unique, has the correct prefix, and is within valid constraints. Args: - value (str): The ID value to validate. - prefix (str): The required prefix for the ID (e.g., "GA-" or "GS-"). - field_name (str): The database field name to check for uniqueness (e.g., "ga_id" or "gs_id"). + value: The ID value to validate. + prefix: The required prefix for the ID. + field_name: The database field name to check for uniqueness. Raises: ValueError: If the ID is not valid. @@ -29,21 +29,21 @@ def validate_id(value: str, prefix: str, field_name: str) -> str: raise ValueError(err) try: - numeric_part = int(value[len(prefix) :]) + numeric_part = int(value.split("-")[-1]) except ValueError: err = f"{field_name} must have a numeric part after the prefix '{prefix}'." raise ValueError(err) from ValueError if min_range <= numeric_part <= max_range: - err = f"{field_name} must not have a numeric part between 50000 and 99999." + err = f"{field_name} must not have a numeric part between 50000 and 99999, received {numeric_part}" raise ValueError(err) if not is_resource_type_value_unique(field_name, value): - err = f"{field_name} must be unique." + err = f"{field_name} must be unique, {value} is already in use." raise ValueError(err) return value -IMPORTED_GA_ID = Annotated[str, AfterValidator(partial(validate_id, prefix="GA-", field_name="ga_id"))] -IMPORTED_GS_ID = Annotated[str, AfterValidator(partial(validate_id, prefix="GS-", field_name="gs_id"))] +IMPORTED_GA_ID = Annotated[str, AfterValidator(partial(validate_id, prefix="GA", field_name="ga_id"))] +IMPORTED_GS_ID = Annotated[str, AfterValidator(partial(validate_id, prefix="GS", field_name="gs_id"))] -- GitLab From 96fa31fc046a516a04d22b7e0574ec2b8e677c32 Mon Sep 17 00:00:00 2001 From: Karel van Klink <karel.vanklink@geant.org> Date: Wed, 11 Dec 2024 13:49:39 +0000 Subject: [PATCH 20/20] Apply 1 suggestion(s) to 1 file(s) Co-authored-by: Mohammad Torkashvand <mohammad.torkashvand@geant.org> --- gso/utils/types/geant_ids.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gso/utils/types/geant_ids.py b/gso/utils/types/geant_ids.py index ec728bc0..72afc7f4 100644 --- a/gso/utils/types/geant_ids.py +++ b/gso/utils/types/geant_ids.py @@ -35,7 +35,7 @@ def validate_id(value: str, prefix: Literal["GA", "GS"], field_name: str) -> str raise ValueError(err) from ValueError if min_range <= numeric_part <= max_range: - err = f"{field_name} must not have a numeric part between 50000 and 99999, received {numeric_part}" + err = f"{field_name} must not have a numeric part between {min_range} and {max_range}, received {numeric_part}" raise ValueError(err) if not is_resource_type_value_unique(field_name, value): -- GitLab