From 0c9107634082f28ae16d69c7914d46b03fae3599 Mon Sep 17 00:00:00 2001 From: Karel van Klink <karel.vanklink@geant.org> Date: Thu, 12 Sep 2024 16:24:34 +0200 Subject: [PATCH] =?UTF-8?q?Update=20edge=20port=20models,=20add=20translat?= =?UTF-8?q?ions,=20add=20domain=20model=20migration=20for=20G=C3=89ANT=20I?= =?UTF-8?q?P?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gso/__init__.py | 18 +- ...3d12_add_g\303\251ant_ip_domain_models.py" | 335 ++++++++++++++++++ gso/products/product_blocks/bgp_session.py | 12 +- gso/products/product_blocks/edge_port.py | 41 ++- gso/products/product_blocks/geant_ip.py | 17 +- .../product_blocks/service_binding_port.py | 22 +- gso/translations/en-GB.json | 7 +- gso/utils/types/bgp_session.py | 33 -- gso/workflows/edge_port/create_edge_port.py | 7 +- gso/workflows/edge_port/modify_edge_port.py | 15 +- gso/workflows/geant_ip/__init__.py | 1 + gso/workflows/geant_ip/create_geant_ip.py | 1 + 12 files changed, 417 insertions(+), 92 deletions(-) create mode 100644 "gso/migrations/versions/2024-09-16_aa6dcb493d12_add_g\303\251ant_ip_domain_models.py" delete mode 100644 gso/utils/types/bgp_session.py create mode 100644 gso/workflows/geant_ip/__init__.py create mode 100644 gso/workflows/geant_ip/create_geant_ip.py diff --git a/gso/__init__.py b/gso/__init__.py index 333891c3..478efc94 100644 --- a/gso/__init__.py +++ b/gso/__init__.py @@ -1,15 +1,13 @@ """The main entrypoint for :term:`GSO`, and the different ways in which it can be run.""" import os -from typing import Annotated import sentry_sdk -import strawberry import typer from celery import Celery from orchestrator import OrchestratorCore, app_settings from orchestrator.cli.main import app as cli_app -from orchestrator.graphql import DEFAULT_GRAPHQL_MODELS, SCALAR_OVERRIDES +from orchestrator.graphql import SCALAR_OVERRIDES from orchestrator.services.tasks import initialise_celery from orchestrator.settings import ExecutorType @@ -21,7 +19,6 @@ from gso.auth.oidc import oidc_instance from gso.auth.opa import graphql_opa_instance, opa_instance from gso.graphql_api.types import GSO_SCALAR_OVERRIDES from gso.settings import load_oss_params -from gso.utils.types.interfaces import LAGMember SCALAR_OVERRIDES.update(GSO_SCALAR_OVERRIDES) @@ -38,18 +35,7 @@ def init_gso_app() -> OrchestratorCore: app.register_authentication(oidc_instance) app.register_authorization(opa_instance) app.register_graphql_authorization(graphql_opa_instance) - - @strawberry.experimental.pydantic.type(model=LAGMember) - class LAGMemberGraphql: - self_reference_block: Annotated["LAGMemberGraphql", strawberry.lazy("gso.utils.types.interfaces")] | None = None - interface_name: str - interface_description: str - - updated_graphql_models = DEFAULT_GRAPHQL_MODELS | { - "LAGMemberGraphql": LAGMemberGraphql, - } - - app.register_graphql(graphql_models=updated_graphql_models) + app.register_graphql() app.include_router(api_router, prefix="/api") if app_settings.EXECUTOR == ExecutorType.WORKER: diff --git "a/gso/migrations/versions/2024-09-16_aa6dcb493d12_add_g\303\251ant_ip_domain_models.py" "b/gso/migrations/versions/2024-09-16_aa6dcb493d12_add_g\303\251ant_ip_domain_models.py" new file mode 100644 index 00000000..bb875384 --- /dev/null +++ "b/gso/migrations/versions/2024-09-16_aa6dcb493d12_add_g\303\251ant_ip_domain_models.py" @@ -0,0 +1,335 @@ +"""Add GÉANT IP domain models. + +Revision ID: aa6dcb493d12 +Revises: c466b64eccfd +Create Date: 2024-09-16 10:16:35.889496 + +""" +import sqlalchemy as sa +from alembic import op + +# revision identifiers, used by Alembic. +revision = 'aa6dcb493d12' +down_revision = 'c466b64eccfd' +branch_labels = None +depends_on = None + + +def upgrade() -> None: + conn = op.get_bind() + conn.execute(sa.text(""" +INSERT INTO products (name, description, product_type, tag, status) VALUES ('GeantIP', 'GÉANT IP service', 'GeantIP', 'G_IP', 'active') RETURNING products.product_id + """)) + conn.execute(sa.text(""" +INSERT INTO product_blocks (name, description, tag, status) VALUES ('EdgePortAEMemberBlock', 'Edge Port LAG Member', 'EDGEPORT_AE_MEMBER', 'active') RETURNING product_blocks.product_block_id + """)) + conn.execute(sa.text(""" +INSERT INTO product_blocks (name, description, tag, status) VALUES ('ServiceBindingPort', 'Service Binding Port', 'SBP', 'active') RETURNING product_blocks.product_block_id + """)) + conn.execute(sa.text(""" +INSERT INTO product_blocks (name, description, tag, status) VALUES ('BGPSession', 'BGP Session', 'BGP_SESSION', 'active') RETURNING product_blocks.product_block_id + """)) + conn.execute(sa.text(""" +INSERT INTO product_blocks (name, description, tag, status) VALUES ('GeantIPBlock', 'GÉANT IP service product block', 'G_IP_BLOCK', 'active') RETURNING product_blocks.product_block_id + """)) + conn.execute(sa.text(""" +INSERT INTO product_blocks (name, description, tag, status) VALUES ('NRENAccessPort', 'NREN Access Port', 'NREN_AP', 'active') RETURNING product_blocks.product_block_id + """)) + conn.execute(sa.text(""" +INSERT INTO resource_types (resource_type, description) VALUES ('authentication_key', 'BGP session authentication key') RETURNING resource_types.resource_type_id + """)) + conn.execute(sa.text(""" +INSERT INTO resource_types (resource_type, description) VALUES ('geant_sid', 'GÉANT Service ID') RETURNING resource_types.resource_type_id + """)) + conn.execute(sa.text(""" +INSERT INTO resource_types (resource_type, description) VALUES ('bfd_enabled', 'BFD enabled') RETURNING resource_types.resource_type_id + """)) + conn.execute(sa.text(""" +INSERT INTO resource_types (resource_type, description) VALUES ('send_default_route', 'Use default fallback route') RETURNING resource_types.resource_type_id + """)) + conn.execute(sa.text(""" +INSERT INTO resource_types (resource_type, description) VALUES ('nren_ap_type', 'Access Port type, primary, secondary or load balanced') RETURNING resource_types.resource_type_id + """)) + conn.execute(sa.text(""" +INSERT INTO resource_types (resource_type, description) VALUES ('multipath_enabled', 'Multipath enabled BGP session') RETURNING resource_types.resource_type_id + """)) + conn.execute(sa.text(""" +INSERT INTO resource_types (resource_type, description) VALUES ('peer_address', 'BGP Session peer address') RETURNING resource_types.resource_type_id + """)) + conn.execute(sa.text(""" +INSERT INTO resource_types (resource_type, description) VALUES ('sbp_type', 'Service Binding Port type, layer 2 or 3') RETURNING resource_types.resource_type_id + """)) + conn.execute(sa.text(""" +INSERT INTO resource_types (resource_type, description) VALUES ('has_custom_policies', 'This BGP session has custom policies') RETURNING resource_types.resource_type_id + """)) + conn.execute(sa.text(""" +INSERT INTO resource_types (resource_type, description) VALUES ('ipv4_address', 'IPv4 Address') RETURNING resource_types.resource_type_id + """)) + conn.execute(sa.text(""" +INSERT INTO resource_types (resource_type, description) VALUES ('is_multi_hop', 'This BGP session is multi hop') RETURNING resource_types.resource_type_id + """)) + conn.execute(sa.text(""" +INSERT INTO resource_types (resource_type, description) VALUES ('bfd_multiplier', 'Bi-directional Forwarding Detection multiplier') RETURNING resource_types.resource_type_id + """)) + conn.execute(sa.text(""" +INSERT INTO resource_types (resource_type, description) VALUES ('is_tagged', 'This SBP is tagged') RETURNING resource_types.resource_type_id + """)) + conn.execute(sa.text(""" +INSERT INTO resource_types (resource_type, description) VALUES ('families', 'Unicast / Multicast and IPv4 / IPv6') RETURNING resource_types.resource_type_id + """)) + conn.execute(sa.text(""" +INSERT INTO resource_types (resource_type, description) VALUES ('custom_firewall_filters', 'This SBP has custom firewall filters') RETURNING resource_types.resource_type_id + """)) + conn.execute(sa.text(""" +INSERT INTO resource_types (resource_type, description) VALUES ('ipv6_address', 'IPv6 address') RETURNING resource_types.resource_type_id + """)) + conn.execute(sa.text(""" +INSERT INTO resource_types (resource_type, description) VALUES ('bfd_interval', 'BFD interval') RETURNING resource_types.resource_type_id + """)) + conn.execute(sa.text(""" +INSERT INTO product_product_blocks (product_id, product_block_id) VALUES ((SELECT products.product_id FROM products WHERE products.name IN ('GeantIP')), (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('GeantIPBlock'))) + """)) + conn.execute(sa.text(""" +INSERT INTO product_block_relations (in_use_by_id, depends_on_id) VALUES ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('ServiceBindingPort')), (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession'))) + """)) + conn.execute(sa.text(""" +INSERT INTO product_block_relations (in_use_by_id, depends_on_id) VALUES ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('EdgePortBlock')), (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('EdgePortAEMemberBlock'))) + """)) + conn.execute(sa.text(""" +INSERT INTO product_block_relations (in_use_by_id, depends_on_id) VALUES ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('EdgePortBlock')), (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('ServiceBindingPort'))) + """)) + conn.execute(sa.text(""" +INSERT INTO product_block_relations (in_use_by_id, depends_on_id) VALUES ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('GeantIPBlock')), (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('NRENAccessPort'))) + """)) + conn.execute(sa.text(""" +INSERT INTO product_block_relations (in_use_by_id, depends_on_id) VALUES ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('NRENAccessPort')), (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('EdgePortBlock'))) + """)) + conn.execute(sa.text(""" +INSERT INTO product_block_resource_types (product_block_id, resource_type_id) VALUES ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('EdgePortAEMemberBlock')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('interface_description'))) + """)) + conn.execute(sa.text(""" +INSERT INTO product_block_resource_types (product_block_id, resource_type_id) VALUES ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('EdgePortAEMemberBlock')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('interface_name'))) + """)) + conn.execute(sa.text(""" +INSERT INTO product_block_resource_types (product_block_id, resource_type_id) VALUES ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('authentication_key'))) + """)) + conn.execute(sa.text(""" +INSERT INTO product_block_resource_types (product_block_id, resource_type_id) VALUES ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_enabled'))) + """)) + conn.execute(sa.text(""" +INSERT INTO product_block_resource_types (product_block_id, resource_type_id) VALUES ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('send_default_route'))) + """)) + conn.execute(sa.text(""" +INSERT INTO product_block_resource_types (product_block_id, resource_type_id) VALUES ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('multipath_enabled'))) + """)) + conn.execute(sa.text(""" +INSERT INTO product_block_resource_types (product_block_id, resource_type_id) VALUES ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('peer_address'))) + """)) + conn.execute(sa.text(""" +INSERT INTO product_block_resource_types (product_block_id, resource_type_id) VALUES ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('has_custom_policies'))) + """)) + conn.execute(sa.text(""" +INSERT INTO product_block_resource_types (product_block_id, resource_type_id) VALUES ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('is_multi_hop'))) + """)) + conn.execute(sa.text(""" +INSERT INTO product_block_resource_types (product_block_id, resource_type_id) VALUES ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_multiplier'))) + """)) + conn.execute(sa.text(""" +INSERT INTO product_block_resource_types (product_block_id, resource_type_id) VALUES ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('families'))) + """)) + conn.execute(sa.text(""" +INSERT INTO product_block_resource_types (product_block_id, resource_type_id) VALUES ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_interval'))) + """)) + conn.execute(sa.text(""" +INSERT INTO product_block_resource_types (product_block_id, resource_type_id) VALUES ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('ServiceBindingPort')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('vlan_id'))) + """)) + conn.execute(sa.text(""" +INSERT INTO product_block_resource_types (product_block_id, resource_type_id) VALUES ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('ServiceBindingPort')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('ipv4_address'))) + """)) + conn.execute(sa.text(""" +INSERT INTO product_block_resource_types (product_block_id, resource_type_id) VALUES ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('ServiceBindingPort')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('geant_sid'))) + """)) + conn.execute(sa.text(""" +INSERT INTO product_block_resource_types (product_block_id, resource_type_id) VALUES ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('ServiceBindingPort')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('is_tagged'))) + """)) + conn.execute(sa.text(""" +INSERT INTO product_block_resource_types (product_block_id, resource_type_id) VALUES ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('ServiceBindingPort')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('custom_firewall_filters'))) + """)) + conn.execute(sa.text(""" +INSERT INTO product_block_resource_types (product_block_id, resource_type_id) VALUES ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('ServiceBindingPort')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('ipv6_address'))) + """)) + conn.execute(sa.text(""" +INSERT INTO product_block_resource_types (product_block_id, resource_type_id) VALUES ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('ServiceBindingPort')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('sbp_type'))) + """)) + conn.execute(sa.text(""" +INSERT INTO product_block_resource_types (product_block_id, resource_type_id) VALUES ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('NRENAccessPort')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('nren_ap_type'))) + """)) + + +def downgrade() -> None: + conn = op.get_bind() + conn.execute(sa.text(""" +DELETE FROM product_block_resource_types WHERE product_block_resource_types.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('EdgePortAEMemberBlock')) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('interface_description')) + """)) + conn.execute(sa.text(""" +DELETE FROM subscription_instance_values USING product_block_resource_types WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.subscription_instance_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('EdgePortAEMemberBlock'))) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('interface_description')) + """)) + conn.execute(sa.text(""" +DELETE FROM product_block_resource_types WHERE product_block_resource_types.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('EdgePortAEMemberBlock')) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('interface_name')) + """)) + conn.execute(sa.text(""" +DELETE FROM subscription_instance_values USING product_block_resource_types WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.subscription_instance_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('EdgePortAEMemberBlock'))) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('interface_name')) + """)) + conn.execute(sa.text(""" +DELETE FROM product_block_resource_types WHERE product_block_resource_types.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession')) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('authentication_key')) + """)) + conn.execute(sa.text(""" +DELETE FROM subscription_instance_values USING product_block_resource_types WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.subscription_instance_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession'))) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('authentication_key')) + """)) + conn.execute(sa.text(""" +DELETE FROM product_block_resource_types WHERE product_block_resource_types.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession')) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_enabled')) + """)) + conn.execute(sa.text(""" +DELETE FROM subscription_instance_values USING product_block_resource_types WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.subscription_instance_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession'))) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_enabled')) + """)) + conn.execute(sa.text(""" +DELETE FROM product_block_resource_types WHERE product_block_resource_types.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession')) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('send_default_route')) + """)) + conn.execute(sa.text(""" +DELETE FROM subscription_instance_values USING product_block_resource_types WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.subscription_instance_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession'))) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('send_default_route')) + """)) + conn.execute(sa.text(""" +DELETE FROM product_block_resource_types WHERE product_block_resource_types.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession')) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('multipath_enabled')) + """)) + conn.execute(sa.text(""" +DELETE FROM subscription_instance_values USING product_block_resource_types WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.subscription_instance_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession'))) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('multipath_enabled')) + """)) + conn.execute(sa.text(""" +DELETE FROM product_block_resource_types WHERE product_block_resource_types.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession')) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('peer_address')) + """)) + conn.execute(sa.text(""" +DELETE FROM subscription_instance_values USING product_block_resource_types WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.subscription_instance_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession'))) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('peer_address')) + """)) + conn.execute(sa.text(""" +DELETE FROM product_block_resource_types WHERE product_block_resource_types.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession')) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('has_custom_policies')) + """)) + conn.execute(sa.text(""" +DELETE FROM subscription_instance_values USING product_block_resource_types WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.subscription_instance_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession'))) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('has_custom_policies')) + """)) + conn.execute(sa.text(""" +DELETE FROM product_block_resource_types WHERE product_block_resource_types.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession')) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('is_multi_hop')) + """)) + conn.execute(sa.text(""" +DELETE FROM subscription_instance_values USING product_block_resource_types WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.subscription_instance_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession'))) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('is_multi_hop')) + """)) + conn.execute(sa.text(""" +DELETE FROM product_block_resource_types WHERE product_block_resource_types.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession')) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_multiplier')) + """)) + conn.execute(sa.text(""" +DELETE FROM subscription_instance_values USING product_block_resource_types WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.subscription_instance_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession'))) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_multiplier')) + """)) + conn.execute(sa.text(""" +DELETE FROM product_block_resource_types WHERE product_block_resource_types.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession')) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('families')) + """)) + conn.execute(sa.text(""" +DELETE FROM subscription_instance_values USING product_block_resource_types WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.subscription_instance_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession'))) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('families')) + """)) + conn.execute(sa.text(""" +DELETE FROM product_block_resource_types WHERE product_block_resource_types.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession')) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_interval')) + """)) + conn.execute(sa.text(""" +DELETE FROM subscription_instance_values USING product_block_resource_types WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.subscription_instance_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession'))) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_interval')) + """)) + conn.execute(sa.text(""" +DELETE FROM product_block_resource_types 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 = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('vlan_id')) + """)) + conn.execute(sa.text(""" +DELETE FROM subscription_instance_values USING product_block_resource_types WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.subscription_instance_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 = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('vlan_id')) + """)) + conn.execute(sa.text(""" +DELETE FROM product_block_resource_types 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 = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('ipv4_address')) + """)) + conn.execute(sa.text(""" +DELETE FROM subscription_instance_values USING product_block_resource_types WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.subscription_instance_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 = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('ipv4_address')) + """)) + conn.execute(sa.text(""" +DELETE FROM product_block_resource_types 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 = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('geant_sid')) + """)) + conn.execute(sa.text(""" +DELETE FROM subscription_instance_values USING product_block_resource_types WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.subscription_instance_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 = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('geant_sid')) + """)) + conn.execute(sa.text(""" +DELETE FROM product_block_resource_types 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 = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('is_tagged')) + """)) + conn.execute(sa.text(""" +DELETE FROM subscription_instance_values USING product_block_resource_types WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.subscription_instance_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 = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('is_tagged')) + """)) + conn.execute(sa.text(""" +DELETE FROM product_block_resource_types 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 = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('custom_firewall_filters')) + """)) + conn.execute(sa.text(""" +DELETE FROM subscription_instance_values USING product_block_resource_types WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.subscription_instance_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 = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('custom_firewall_filters')) + """)) + conn.execute(sa.text(""" +DELETE FROM product_block_resource_types 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 = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('ipv6_address')) + """)) + conn.execute(sa.text(""" +DELETE FROM subscription_instance_values USING product_block_resource_types WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.subscription_instance_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 = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('ipv6_address')) + """)) + conn.execute(sa.text(""" +DELETE FROM product_block_resource_types 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 = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('sbp_type')) + """)) + conn.execute(sa.text(""" +DELETE FROM subscription_instance_values USING product_block_resource_types WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.subscription_instance_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 = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('sbp_type')) + """)) + conn.execute(sa.text(""" +DELETE FROM product_block_resource_types WHERE product_block_resource_types.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('NRENAccessPort')) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('nren_ap_type')) + """)) + conn.execute(sa.text(""" +DELETE FROM subscription_instance_values USING product_block_resource_types WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.subscription_instance_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('NRENAccessPort'))) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('nren_ap_type')) + """)) + conn.execute(sa.text(""" +DELETE FROM subscription_instance_values WHERE subscription_instance_values.resource_type_id IN (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('authentication_key', 'geant_sid', 'bfd_enabled', 'send_default_route', 'nren_ap_type', 'multipath_enabled', 'peer_address', 'sbp_type', 'has_custom_policies', 'ipv4_address', 'is_multi_hop', 'bfd_multiplier', 'is_tagged', 'families', 'custom_firewall_filters', 'ipv6_address', 'bfd_interval')) + """)) + conn.execute(sa.text(""" +DELETE FROM resource_types WHERE resource_types.resource_type IN ('authentication_key', 'geant_sid', 'bfd_enabled', 'send_default_route', 'nren_ap_type', 'multipath_enabled', 'peer_address', 'sbp_type', 'has_custom_policies', 'ipv4_address', 'is_multi_hop', 'bfd_multiplier', 'is_tagged', 'families', 'custom_firewall_filters', 'ipv6_address', 'bfd_interval') + """)) + 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 ('GeantIP')) AND product_product_blocks.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('GeantIPBlock')) + """)) + conn.execute(sa.text(""" +DELETE FROM product_block_relations WHERE product_block_relations.in_use_by_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('ServiceBindingPort')) AND product_block_relations.depends_on_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession')) + """)) + conn.execute(sa.text(""" +DELETE FROM product_block_relations WHERE product_block_relations.in_use_by_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('EdgePortBlock')) AND product_block_relations.depends_on_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('EdgePortAEMemberBlock')) + """)) + conn.execute(sa.text(""" +DELETE FROM product_block_relations WHERE product_block_relations.in_use_by_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('EdgePortBlock')) AND product_block_relations.depends_on_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('ServiceBindingPort')) + """)) + conn.execute(sa.text(""" +DELETE FROM product_block_relations WHERE product_block_relations.in_use_by_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('GeantIPBlock')) AND product_block_relations.depends_on_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('NRENAccessPort')) + """)) + conn.execute(sa.text(""" +DELETE FROM product_block_relations WHERE product_block_relations.in_use_by_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('NRENAccessPort')) AND product_block_relations.depends_on_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('EdgePortBlock')) + """)) + 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 ('EdgePortAEMemberBlock', 'GeantIPBlock', 'NRENAccessPort', 'ServiceBindingPort', 'BGPSession')) + """)) + conn.execute(sa.text(""" +DELETE FROM product_blocks WHERE product_blocks.name IN ('EdgePortAEMemberBlock', 'GeantIPBlock', 'NRENAccessPort', 'ServiceBindingPort', 'BGPSession') + """)) + conn.execute(sa.text(""" +DELETE FROM processes WHERE processes.pid IN (SELECT processes_subscriptions.pid FROM processes_subscriptions WHERE processes_subscriptions.subscription_id IN (SELECT subscriptions.subscription_id FROM subscriptions WHERE subscriptions.product_id IN (SELECT products.product_id FROM products WHERE products.name IN ('GeantIP')))) + """)) + conn.execute(sa.text(""" +DELETE FROM processes_subscriptions WHERE processes_subscriptions.subscription_id IN (SELECT subscriptions.subscription_id FROM subscriptions WHERE subscriptions.product_id IN (SELECT products.product_id FROM products WHERE products.name IN ('GeantIP'))) + """)) + conn.execute(sa.text(""" +DELETE FROM subscription_instances WHERE subscription_instances.subscription_id IN (SELECT subscriptions.subscription_id FROM subscriptions WHERE subscriptions.product_id IN (SELECT products.product_id FROM products WHERE products.name IN ('GeantIP'))) + """)) + conn.execute(sa.text(""" +DELETE FROM subscriptions WHERE subscriptions.product_id IN (SELECT products.product_id FROM products WHERE products.name IN ('GeantIP')) + """)) + conn.execute(sa.text(""" +DELETE FROM products WHERE products.name IN ('GeantIP') + """)) diff --git a/gso/products/product_blocks/bgp_session.py b/gso/products/product_blocks/bgp_session.py index 09d578cf..74083c04 100644 --- a/gso/products/product_blocks/bgp_session.py +++ b/gso/products/product_blocks/bgp_session.py @@ -1,13 +1,15 @@ """:term:`BGP` session product block.""" -from ipaddress import IPv4Address, IPv6Address - +import strawberry from orchestrator.domain.base import ProductBlockModel from orchestrator.types import SubscriptionLifecycle from pydantic import Field from pydantic_forms.types import strEnum +from gso.utils.types.ip_address import IPAddress + +@strawberry.enum class IPFamily(strEnum): """Possible :term:`IP` families of a :term:`BGP` peering.""" @@ -20,7 +22,7 @@ class IPFamily(strEnum): class BGPSessionInactive(ProductBlockModel, lifecycle=[SubscriptionLifecycle.INITIAL], product_block_name="BGPSession"): """A :term:`BGP` session that is currently inactive. See :class:`BGPSession`.""" - peer_address: IPv4Address | IPv6Address | None = None + peer_address: IPAddress | None = None bfd_enabled: bool | None = None bfd_interval: int | None = None bfd_multiplier: int | None = None @@ -35,7 +37,7 @@ class BGPSessionInactive(ProductBlockModel, lifecycle=[SubscriptionLifecycle.INI class BGPSessionProvisioning(BGPSessionInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]): """A :term:`BGP` session that is currently being provisioned. See :class:`BGPSession`.""" - peer_address: IPv4Address | IPv6Address + peer_address: IPAddress bfd_enabled: bool bfd_interval: int | None = None bfd_multiplier: int | None = None @@ -51,7 +53,7 @@ class BGPSession(BGPSessionProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE """A :term:`BGP` session that is currently deployed in the network.""" #: The peering address of the session. - peer_address: IPv4Address | IPv6Address + peer_address: IPAddress #: Whether :term:`BFD` is enabled. bfd_enabled: bool #: The :term:`BFD` interval, if enabled. diff --git a/gso/products/product_blocks/edge_port.py b/gso/products/product_blocks/edge_port.py index ffa5ea90..27e01558 100644 --- a/gso/products/product_blocks/edge_port.py +++ b/gso/products/product_blocks/edge_port.py @@ -6,9 +6,15 @@ domain still managed by GEANT. In other words, an Edge port determines where the from orchestrator.domain.base import ProductBlockModel from orchestrator.types import SubscriptionLifecycle, strEnum +from pydantic import Field from gso.products.product_blocks.router import RouterBlock, RouterBlockInactive, RouterBlockProvisioning -from gso.utils.types.interfaces import LAGMember, LAGMemberList, PhysicalPortCapacity +from gso.products.product_blocks.service_binding_port import ( + ServiceBindingPort, + ServiceBindingPortInactive, + ServiceBindingPortProvisioning, +) +from gso.utils.types.interfaces import LAGMemberList, PhysicalPortCapacity class EncapsulationType(strEnum): @@ -34,6 +40,29 @@ class EdgePortType(strEnum): RE_INTERCONNECT = "RE_INTERCONNECT" +class EdgePortAEMemberBlockInactive( + ProductBlockModel, lifecycle=[SubscriptionLifecycle.INITIAL], product_block_name="EdgePortAEMemberBlock" +): + """An inactive Edge Port AE interface.""" + + interface_name: str | None = None + interface_description: str | None = None + + +class EdgePortAEMemberBlockProvisioning(EdgePortAEMemberBlockInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]): + """A provisional Edge Port AE interface.""" + + interface_name: str + interface_description: str | None = None + + +class EdgePortAEMemberBlock(EdgePortAEMemberBlockProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]): + """An Edge Port AE interface.""" + + interface_name: str + interface_description: str | None = None + + class EdgePortBlockInactive( ProductBlockModel, lifecycle=[SubscriptionLifecycle.INITIAL], product_block_name="EdgePortBlock" ): @@ -50,7 +79,8 @@ class EdgePortBlockInactive( edge_port_type: EdgePortType | None = None edge_port_ignore_if_down: bool = False edge_port_geant_ga_id: str | None = None - edge_port_ae_members: LAGMemberList[LAGMember] + edge_port_ae_members: LAGMemberList[EdgePortAEMemberBlockInactive] + edge_port_sbp_list: list[ServiceBindingPortInactive] = Field(default_factory=list) class EdgePortBlockProvisioning(EdgePortBlockInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]): @@ -67,7 +97,8 @@ class EdgePortBlockProvisioning(EdgePortBlockInactive, lifecycle=[SubscriptionLi edge_port_type: EdgePortType edge_port_ignore_if_down: bool = False edge_port_geant_ga_id: str | None = None - edge_port_ae_members: LAGMemberList[LAGMember] + edge_port_ae_members: LAGMemberList[EdgePortAEMemberBlockProvisioning] # type: ignore[assignment] + edge_port_sbp_list: list[ServiceBindingPortProvisioning] # type: ignore[assignment] class EdgePortBlock(EdgePortBlockProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]): @@ -96,4 +127,6 @@ class EdgePortBlock(EdgePortBlockProvisioning, lifecycle=[SubscriptionLifecycle. #: The GEANT GA ID associated with this edge port, if any. edge_port_geant_ga_id: str | None = None #: A list of LAG members associated with this edge port. - edge_port_ae_members: LAGMemberList[LAGMember] + edge_port_ae_members: LAGMemberList[EdgePortAEMemberBlock] # type: ignore[assignment] + #: A list of Service Binding Ports associated with this Edge Port + edge_port_sbp_list: list[ServiceBindingPort] # type: ignore[assignment] diff --git a/gso/products/product_blocks/geant_ip.py b/gso/products/product_blocks/geant_ip.py index 7b7213a3..d57d2dd0 100644 --- a/gso/products/product_blocks/geant_ip.py +++ b/gso/products/product_blocks/geant_ip.py @@ -5,11 +5,6 @@ from orchestrator.types import SubscriptionLifecycle from pydantic import Field from gso.products.product_blocks.edge_port import EdgePortBlock, EdgePortBlockInactive, EdgePortBlockProvisioning -from gso.products.product_blocks.service_binding_port import ( - ServiceBindingPort, - ServiceBindingPortInactive, - ServiceBindingPortProvisioning, -) from gso.utils.shared_enums import APType @@ -18,22 +13,24 @@ class NRENAccessPortInactive( ): """An access port for an R&E :term:`NREN` service that is inactive.""" - nren_ap_sbp_list: list[ServiceBindingPortInactive] = Field(default_factory=list) nren_ap_type: APType | None = None + geant_ip_ep_list: list[EdgePortBlockInactive] = Field(default_factory=list) class NRENAccessPortProvisioning(NRENAccessPortInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]): """An access port for an R&E :term:`NREN` service that is being provisioned.""" - nren_ap_sbp_list: list[ServiceBindingPortProvisioning] # type: ignore[assignment] nren_ap_type: APType + geant_ip_ep_list: list[EdgePortBlockProvisioning] # type: ignore[assignment] class NRENAccessPort(NRENAccessPortProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]): """An access port for an R&E :term:`NREN` service.""" - nren_ap_sbp_list: list[ServiceBindingPort] # type: ignore[assignment] + #: The type of Access Port nren_ap_type: APType + #: The list of Edge Ports where this service terminates. + geant_ip_ep_list: list[EdgePortBlock] # type: ignore[assignment] class GeantIPBlockInactive( @@ -42,14 +39,12 @@ class GeantIPBlockInactive( """A GÉANT IP subscription that is currently inactive. See :class:`GeantIPBlock`.""" geant_ip_ap_list: list[NRENAccessPortInactive] = Field(default_factory=list) - geant_ip_ep_list: list[EdgePortBlockInactive] = Field(default_factory=list) class GeantIPBlockProvisioning(GeantIPBlockInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]): """A GÉANT IP subscription that is currently being provisioned. See :class:`GeantIPBlock`.""" geant_ip_ap_list: list[NRENAccessPortProvisioning] # type: ignore[assignment] - geant_ip_ep_list: list[EdgePortBlockProvisioning] # type: ignore[assignment] class GeantIPBlock(GeantIPBlockProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]): @@ -57,5 +52,3 @@ class GeantIPBlock(GeantIPBlockProvisioning, lifecycle=[SubscriptionLifecycle.AC #: The list of Access Points where this service is present. geant_ip_ap_list: list[NRENAccessPort] # type: ignore[assignment] - #: The list of Edge Ports where this service terminates. - geant_ip_ep_list: list[EdgePortBlock] # type: ignore[assignment] diff --git a/gso/products/product_blocks/service_binding_port.py b/gso/products/product_blocks/service_binding_port.py index a88c973b..1f031e52 100644 --- a/gso/products/product_blocks/service_binding_port.py +++ b/gso/products/product_blocks/service_binding_port.py @@ -3,15 +3,15 @@ A service binding port is used to logically attach an edge port to a customer service using a :term:`VLAN`. """ -from ipaddress import IPv4Address, IPv6Address from typing import Annotated from orchestrator.domain.base import ProductBlockModel from orchestrator.types import SubscriptionLifecycle from pydantic import Field +from gso.products.product_blocks.bgp_session import BGPSession, BGPSessionInactive, BGPSessionProvisioning from gso.utils.shared_enums import SBPType -from gso.utils.types.bgp_session import BGPSessionSet +from gso.utils.types.ip_address import IPv4AddressType, IPv6AddressType VLAN_ID = Annotated[int, Field(gt=0, lt=4096)] @@ -24,11 +24,11 @@ class ServiceBindingPortInactive( is_tagged: bool | None = None vlan_id: VLAN_ID | None = None sbp_type: SBPType | None = None - ipv4_address: IPv4Address | None = None - ipv6_address: IPv6Address | None = None + ipv4_address: IPv4AddressType | None = None + ipv6_address: IPv6AddressType | None = None custom_firewall_filters: bool | None = None geant_sid: str | None = None - sbp_bgp_session_list: BGPSessionSet | None = None + sbp_bgp_session_list: list[BGPSessionInactive] = Field(default_factory=list) class ServiceBindingPortProvisioning(ServiceBindingPortInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]): @@ -37,11 +37,11 @@ class ServiceBindingPortProvisioning(ServiceBindingPortInactive, lifecycle=[Subs is_tagged: bool vlan_id: VLAN_ID | None = None sbp_type: SBPType - ipv4_address: IPv4Address | None = None - ipv6_address: IPv6Address | None = None + ipv4_address: IPv4AddressType | None = None + ipv6_address: IPv6AddressType | None = None custom_firewall_filters: bool geant_sid: str - sbp_bgp_session_list: BGPSessionSet + sbp_bgp_session_list: list[BGPSessionProvisioning] # type: ignore[assignment] class ServiceBindingPort(ServiceBindingPortProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]): @@ -54,12 +54,12 @@ class ServiceBindingPort(ServiceBindingPortProvisioning, lifecycle=[Subscription #: Is this service binding port layer 2 or 3? sbp_type: SBPType #: If layer 3, IPv4 resources. - ipv4_address: IPv4Address | None = None + ipv4_address: IPv4AddressType | None = None #: If layer 3, IPv6 resources. - ipv6_address: IPv6Address | None = None + ipv6_address: IPv6AddressType | None = None #: 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 #: The :term:`BGP` sessions associated with this service binding port. - sbp_bgp_session_list: BGPSessionSet + sbp_bgp_session_list: list[BGPSession] # type: ignore[assignment] diff --git a/gso/translations/en-GB.json b/gso/translations/en-GB.json index f1ede053..63f9e9c2 100644 --- a/gso/translations/en-GB.json +++ b/gso/translations/en-GB.json @@ -32,8 +32,7 @@ "migrate_to_different_site": "Migrating to a different Site", "remove_configuration": "Remove configuration from the router", "clean_up_ipam": "Clean up related entries in IPAM", - "restore_isis_metric": "Restore ISIS metric to original value", - "confirm_info": "Please verify this form looks correct." + "restore_isis_metric": "Restore ISIS metric to original value" } }, "workflow": { @@ -44,6 +43,7 @@ "create_router": "Create Router", "create_site": "Create Site", "create_switch": "Create Switch", + "create_edge_port": "Create Edge Port", "deploy_twamp": "Deploy TWAMP", "migrate_iptrunk": "Migrate IP Trunk", "modify_isis_metric": "Modify the ISIS metric", @@ -51,10 +51,12 @@ "modify_trunk_interface": "Modify IP Trunk interface", "modify_connection_strategy": "Modify connection strategy", "modify_router_kentik_license": "Modify device license in Kentik", + "modify_edge_port": "Modify Edge Port", "terminate_iptrunk": "Terminate IP Trunk", "terminate_router": "Terminate Router", "terminate_site": "Terminate Site", "terminate_switch": "Terminate Switch", + "terminate_edge_port": "Terminate Edge Port", "redeploy_base_config": "Redeploy base config", "update_ibgp_mesh": "Update iBGP mesh", "create_imported_site": "NOT FOR HUMANS -- Import existing site", @@ -72,6 +74,7 @@ "validate_iptrunk": "Validate IP Trunk configuration", "validate_router": "Validate Router configuration", "validate_switch": "Validate Switch configuration", + "validate_edge_port": "Validate Edge Port", "task_validate_geant_products": "Validation task for GEANT products", "task_send_email_notifications": "Send email notifications for failed tasks", "task_create_partners": "Create partner task", diff --git a/gso/utils/types/bgp_session.py b/gso/utils/types/bgp_session.py deleted file mode 100644 index 681ab1c7..00000000 --- a/gso/utils/types/bgp_session.py +++ /dev/null @@ -1,33 +0,0 @@ -""":term:`BGP` session sets.""" - -from typing import Annotated, TypeVar - -from annotated_types import Len -from pydantic import AfterValidator - -from gso.products.product_blocks.bgp_session import BGPSession, BGPSessionInactive, BGPSessionProvisioning - -BGPSessionTypes = TypeVar("BGPSessionTypes", BGPSessionInactive, BGPSessionProvisioning, BGPSession) - - -def validate_bgp_session_set(bgp_session_set: list[BGPSessionTypes]) -> list[BGPSessionTypes]: - """:term:`BGP` sessions grouped together. - - It consists of either a single item, or a pair of IPv4 and v6 sessions. It is not allowed to have two IPv4 or IPv6 - :term:`BGP` sessions as part of a set. - """ - if any(bgp_session.peer_address is None for bgp_session in bgp_session_set): - msg = "BGP session is missing a peer address." - raise ValueError(msg) - if len(bgp_session_set) == 2 and bgp_session_set[0].peer_address.version == bgp_session_set[1].peer_address.version: # type: ignore[union-attr] # noqa: PLR2004 - msg = ( - "When defining two separate BGP sessions, IP families must differ. " - f"Both are IPv{bgp_session_set[0].peer_address.version}." # type: ignore[union-attr] - ) - raise ValueError(msg) - return bgp_session_set - - -BGPSessionSet = Annotated[ - list[BGPSessionTypes], Len(min_length=1, max_length=2), AfterValidator(validate_bgp_session_set) -] diff --git a/gso/workflows/edge_port/create_edge_port.py b/gso/workflows/edge_port/create_edge_port.py index c961cd7f..ce87d1f5 100644 --- a/gso/workflows/edge_port/create_edge_port.py +++ b/gso/workflows/edge_port/create_edge_port.py @@ -1,6 +1,7 @@ """A creation workflow for adding a new edge port to the network.""" from typing import Annotated, Any, Self +from uuid import uuid4 from annotated_types import Len from orchestrator import step, workflow @@ -16,7 +17,7 @@ from pydantic import AfterValidator, ConfigDict, model_validator from pydantic_forms.validators import validate_unique_list from pynetbox.models.dcim import Interfaces -from gso.products.product_blocks.edge_port import EdgePortType, EncapsulationType +from gso.products.product_blocks.edge_port import EdgePortAEMemberBlockInactive, EdgePortType, EncapsulationType from gso.products.product_blocks.router import RouterRole from gso.products.product_types.edge_port import EdgePortInactive, EdgePortProvisioning from gso.products.product_types.router import Router @@ -133,7 +134,9 @@ def initialize_subscription( subscription.description = f"Edge Port {name} on {router.router_fqdn}, {partner}, {geant_ga_id or ""}" subscription.edge_port.edge_port_description = description for member in ae_members: - subscription.edge_port.edge_port_ae_members.append(LAGMember(**member)) + subscription.edge_port.edge_port_ae_members.append( + EdgePortAEMemberBlockInactive.new(subscription_id=uuid4(), **member) + ) subscription = EdgePortProvisioning.from_other_lifecycle(subscription, SubscriptionLifecycle.PROVISIONING) return {"subscription": subscription} diff --git a/gso/workflows/edge_port/modify_edge_port.py b/gso/workflows/edge_port/modify_edge_port.py index 7e280198..0237b143 100644 --- a/gso/workflows/edge_port/modify_edge_port.py +++ b/gso/workflows/edge_port/modify_edge_port.py @@ -1,6 +1,7 @@ """Modify an existing edge port subscription.""" from typing import Annotated, Any, Self +from uuid import uuid4 from annotated_types import Len from orchestrator import workflow @@ -13,7 +14,7 @@ from pydantic import AfterValidator, ConfigDict, model_validator from pydantic_forms.types import FormGenerator, UUIDstr from pydantic_forms.validators import ReadOnlyField, validate_unique_list -from gso.products.product_blocks.edge_port import EncapsulationType +from gso.products.product_blocks.edge_port import EdgePortAEMemberBlock, EncapsulationType from gso.products.product_types.edge_port import EdgePort from gso.services.lso_client import execute_playbook, lso_interaction from gso.services.netbox_client import NetboxClient @@ -146,7 +147,7 @@ def modify_edge_port_subscription( ) subscription.edge_port.edge_port_ae_members.clear() for member in ae_members: - subscription.edge_port.edge_port_ae_members.append(LAGMember(**member)) + subscription.edge_port.edge_port_ae_members.append(EdgePortAEMemberBlock.new(subscription_id=uuid4(), **member)) subscription.save() return { @@ -159,19 +160,19 @@ def modify_edge_port_subscription( @step("Update interfaces in NetBox") def update_interfaces_in_netbox( subscription: EdgePort, - removed_ae_members: list[LAGMember], - previous_ae_members: list[LAGMember], + removed_ae_members: list[dict], + previous_ae_members: list[dict], ) -> dict[str, Any]: """Update the interfaces in NetBox.""" nbclient = NetboxClient() # Free removed interfaces - for member in removed_ae_members: - nbclient.free_interface(subscription.edge_port.edge_port_node.router_fqdn, member.interface_name) + for removed_member in removed_ae_members: + nbclient.free_interface(subscription.edge_port.edge_port_node.router_fqdn, removed_member["interface_name"]) # Attach physical interfaces to :term:`LAG` # Update interface description to subscription ID # Reserve interfaces for member in subscription.edge_port.edge_port_ae_members: - if any(prev_member.interface_name == member.interface_name for prev_member in previous_ae_members): + if any(prev_member["interface_name"] == member.interface_name for prev_member in previous_ae_members): continue nbclient.attach_interface_to_lag( device_name=subscription.edge_port.edge_port_node.router_fqdn, diff --git a/gso/workflows/geant_ip/__init__.py b/gso/workflows/geant_ip/__init__.py new file mode 100644 index 00000000..0a1739e2 --- /dev/null +++ b/gso/workflows/geant_ip/__init__.py @@ -0,0 +1 @@ +"""GÉANT IP workflows.""" diff --git a/gso/workflows/geant_ip/create_geant_ip.py b/gso/workflows/geant_ip/create_geant_ip.py new file mode 100644 index 00000000..651c602e --- /dev/null +++ b/gso/workflows/geant_ip/create_geant_ip.py @@ -0,0 +1 @@ +"""Create a new GÉANT IP subscription.""" -- GitLab