Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • 1048-service-config-backfilling
  • NAT-1154-import-edge-port-update
  • develop
  • feature/10GGBS-NAT-980
  • feature/NAT-1150-model-commecial-peers
  • feature/NAT-1182-rename-geant-plus-descriptions
  • feature/NAT-732-ias-to-re-interconnect
  • feature/add-moodi-wf-to-router
  • feature/mass-base-config-redeploy
  • feature/nat-1211-edgeport-lacp-xmit
  • feature/rename-geant-plus-descriptions
  • fix/NAT-1009/fix-redeploy-base-config-if-there-is-a-vprn
  • fix/l3-imports
  • fix/nat-1120-sdp-validation
  • master
  • update_change_log
  • 0.1
  • 0.2
  • 0.3
  • 0.4
  • 0.5
  • 0.6
  • 0.7
  • 0.8
  • 0.9
  • 1.0
  • 1.1
  • 1.4
  • 1.5
  • 2.0
  • 2.1
  • 2.10
  • 2.11
  • 2.12
  • 2.13
  • 2.14
  • 2.15
  • 2.16
  • 2.17
  • 2.18
  • 2.19
  • 2.2
  • 2.20
  • 2.21
  • 2.22
  • 2.23
  • 2.24
  • 2.25
  • 2.26
  • 2.27
  • 2.28
  • 2.29
  • 2.3
  • 2.31
  • 2.32
  • 2.33
  • 2.34
  • 2.35
  • 2.36
  • 2.37
  • 2.38
  • 2.39
  • 2.4
  • 2.40
  • 2.41
  • 2.42
  • 2.43
  • 2.44
  • 2.45
  • 2.46
  • 2.47
  • 2.48
  • 2.5
  • 2.6
  • 2.7
  • 2.8
  • 2.9
  • 3.0
  • 3.1
  • 3.2
  • 3.3
  • 3.4
  • 3.5
  • 3.6
  • 3.7
  • 3.8
  • Lime-Seal
87 results

Target

Select target project
  • goat/gap/geant-service-orchestrator
1 result
Select Git revision
  • 1048-service-config-backfilling
  • NAT-1154-import-edge-port-update
  • develop
  • feature/10GGBS-NAT-980
  • feature/NAT-1150-model-commecial-peers
  • feature/NAT-1182-rename-geant-plus-descriptions
  • feature/NAT-732-ias-to-re-interconnect
  • feature/add-moodi-wf-to-router
  • feature/mass-base-config-redeploy
  • feature/nat-1211-edgeport-lacp-xmit
  • feature/rename-geant-plus-descriptions
  • fix/NAT-1009/fix-redeploy-base-config-if-there-is-a-vprn
  • fix/l3-imports
  • fix/nat-1120-sdp-validation
  • master
  • update_change_log
  • 0.1
  • 0.2
  • 0.3
  • 0.4
  • 0.5
  • 0.6
  • 0.7
  • 0.8
  • 0.9
  • 1.0
  • 1.1
  • 1.4
  • 1.5
  • 2.0
  • 2.1
  • 2.10
  • 2.11
  • 2.12
  • 2.13
  • 2.14
  • 2.15
  • 2.16
  • 2.17
  • 2.18
  • 2.19
  • 2.2
  • 2.20
  • 2.21
  • 2.22
  • 2.23
  • 2.24
  • 2.25
  • 2.26
  • 2.27
  • 2.28
  • 2.29
  • 2.3
  • 2.31
  • 2.32
  • 2.33
  • 2.34
  • 2.35
  • 2.36
  • 2.37
  • 2.38
  • 2.39
  • 2.4
  • 2.40
  • 2.41
  • 2.42
  • 2.43
  • 2.44
  • 2.45
  • 2.46
  • 2.47
  • 2.48
  • 2.5
  • 2.6
  • 2.7
  • 2.8
  • 2.9
  • 3.0
  • 3.1
  • 3.2
  • 3.3
  • 3.4
  • 3.5
  • 3.6
  • 3.7
  • 3.8
  • Lime-Seal
87 results
Show changes
Commits on Source (88)
Showing
with 804 additions and 32 deletions
......@@ -15,7 +15,7 @@ run-tox-pipeline:
image: python:3.12
services:
- postgres:15.4
- postgres:14
# Change pip's cache directory to be inside the project directory since we can
# only cache local items.
......
# Changelog
## [2.5] - 2024-11-21
- Updated a trunk description when it is migrated.
- Made moodi steps indifferent about failure
- Added a router to Kentik when creating with a PE role
## [2.24] - 2024-11-07
- Add support for Moodi dashboard in Edge Port creation workflow
- Fix a bug where ISIS metric restoration did not work correctly
## [2.23] - 2024-11-05
- Added new workflows and updated the products of Swich and LAN Swith Interconnect
- Upgraded orchestrator-core to 2.8.0
## [2.22] - 2024-10-31
- Added EdgePort, IAS and GEANT IP products and required workflows
- Refactored pydantic models for maintainability
......
......@@ -116,3 +116,6 @@ Glossary of terms
WFO
`Workflow Orchestrator <https://workfloworchestrator.org/>`_
Moodi
A service that does monitoring on demand during a workflow execution.
\ No newline at end of file
``gso.workflows.l2_circuit.create_imported_layer_2_circuit``
============================================================
.. automodule:: gso.workflows.l2_circuit.create_imported_layer_2_circuit
:members:
:show-inheritance:
``gso.workflows.l2_circuit.create_layer_2_circuit``
===================================================
.. automodule:: gso.workflows.l2_circuit.create_layer_2_circuit
:members:
:show-inheritance:
``gso.workflows.l2_circuit.import_layer_2_circuit``
===================================================
.. automodule:: gso.workflows.l2_circuit.import_layer_2_circuit
:members:
:show-inheritance:
``gso.workflows.L2_circuit
==========================
.. automodule:: gso.workflows.L2_circuit
:members:
:show-inheritance:
Submodules
----------
.. toctree::
:maxdepth: 2
:titlesonly:
create_layer_2_circuit
modify_layer_2_circuit
terminate_layer_2_circuit
create_imported_layer_2_circuit
import_layer_2_circuit
``gso.workflows.l2_circuit.modify_layer_2_circuit``
===================================================
.. automodule:: gso.workflows.l2_circuit.modify_layer_2_circuit
:members:
:show-inheritance:
......@@ -21,10 +21,11 @@ from gso.products import ProductType
from gso.products.product_blocks.bgp_session import IPFamily
from gso.products.product_blocks.edge_port import EdgePortType, EncapsulationType
from gso.products.product_blocks.iptrunk import IptrunkType
from gso.products.product_blocks.layer_2_circuit import Layer2CircuitType
from gso.products.product_blocks.router import RouterRole
from gso.products.product_blocks.service_binding_port import VLAN_ID
from gso.products.product_blocks.switch import SwitchModel
from gso.products.product_types.nren_l3_core_service import NRENL3CoreServiceType
from gso.products.product_types.edge_port import EdgePort
from gso.products.product_types.layer_2_circuit import Layer2CircuitServiceType
from gso.services.partners import (
PartnerEmail,
PartnerName,
......@@ -39,7 +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.interfaces import LAGMember, LAGMemberList, PhysicalPortCapacity
from gso.utils.types.interfaces import BandwidthString, LAGMember, LAGMemberList, PhysicalPortCapacity
from gso.utils.types.ip_address import (
AddressSpace,
IPAddress,
......@@ -50,6 +51,7 @@ from gso.utils.types.ip_address import (
IPV6Netmask,
PortNumber,
)
from gso.utils.types.virtual_identifiers import VC_ID, VLAN_ID
app: typer.Typer = typer.Typer()
......@@ -243,10 +245,8 @@ class NRENL3CoreServiceImportModel(BaseModel):
"""Base BGP Peer model."""
bfd_enabled: bool = False
bfd_interval: int | None = None
bfd_multiplier: int | None = None
has_custom_policies: bool = False
authentication_key: str
authentication_key: str | None
multipath_enabled: bool = False
send_default_route: bool = False
is_passive: bool = False
......@@ -255,6 +255,14 @@ class NRENL3CoreServiceImportModel(BaseModel):
is_multi_hop: bool
rtbh_enabled: bool # whether Remote Triggered Blackhole is enabled
class BFDSettingsModel(BaseModel):
"""BFD Settings model."""
bfd_enabled: bool = False
bfd_interval_rx: int | None = None
bfd_interval_tx: int | None = None
bfd_multiplier: int | None = None
class ServiceBindingPort(BaseModel):
"""Service Binding model."""
......@@ -271,6 +279,8 @@ class NRENL3CoreServiceImportModel(BaseModel):
ipv6_mask: IPV6Netmask
is_multi_hop: bool = True
bgp_peers: list["NRENL3CoreServiceImportModel.BaseBGPPeer"]
v4_bfd_settings: "NRENL3CoreServiceImportModel.BFDSettingsModel"
v6_bfd_settings: "NRENL3CoreServiceImportModel.BFDSettingsModel"
partner: str
service_binding_ports: list[ServiceBindingPort]
......@@ -327,6 +337,49 @@ class LanSwitchInterconnectImportModel(BaseModel):
switch_side: LanSwitchInterconnectSwitchSideImportModel
class Layer2CircuitServiceImportModel(BaseModel):
"""Import Layer 2 Circuit Service model."""
class ServiceBindingPortInput(BaseModel):
"""Service Binding Port model."""
edge_port: UUIDstr
vlan_id: VLAN_ID
service_type: Layer2CircuitServiceType
partner: str
geant_sid: str
vc_id: VC_ID
layer_2_circuit_side_a: ServiceBindingPortInput
layer_2_circuit_side_b: ServiceBindingPortInput
layer_2_circuit_type: Layer2CircuitType
vlan_range_lower_bound: VLAN_ID | None = None
vlan_range_upper_bound: VLAN_ID | None = None
policer_enabled: bool = False
policer_bandwidth: BandwidthString | None = None
policer_burst_rate: BandwidthString | None = None
@field_validator("partner")
def check_if_partner_exists(cls, value: str) -> str:
"""Validate that the partner exists."""
try:
get_partner_by_name(value)
except PartnerNotFoundError as e:
msg = f"Partner {value} not found"
raise ValueError(msg) from e
return value
@model_validator(mode="after")
def check_if_edge_ports_exist(self) -> Self:
"""Check if the edge ports exist."""
for side in [self.layer_2_circuit_side_a, self.layer_2_circuit_side_b]:
if not EdgePort.from_subscription(side.edge_port):
msg = f"Edge Port {side.edge_port} not found"
raise ValueError(msg)
return self
T = TypeVar(
"T",
SiteImportModel,
......@@ -339,6 +392,7 @@ T = TypeVar(
EdgePortImportModel,
NRENL3CoreServiceImportModel,
LanSwitchInterconnectImportModel,
Layer2CircuitServiceImportModel,
)
common_filepath_option = typer.Option(
......@@ -608,7 +662,7 @@ def import_nren_l3_core_service(filepath: str = common_filepath_option) -> None:
for nren_l3_core_service in nren_l3_core_service_list:
partner = nren_l3_core_service["partner"]
service_type = NRENL3CoreServiceType(nren_l3_core_service["service_type"])
service_type = nren_l3_core_service["service_type"]
typer.echo(f"Creating imported {service_type} for {partner}")
try:
......@@ -650,3 +704,44 @@ def import_lan_switch_interconnect(filepath: str = common_filepath_option) -> No
"lan_switch_interconnect_description",
LanSwitchInterconnectImportModel,
)
@app.command()
def import_layer_2_circuit_service(filepath: str = common_filepath_option) -> None:
"""Import Layer 2 Circuit services into GSO."""
successfully_imported_data = []
layer_2_circuit_service_list = _read_data(Path(filepath))
for layer_2_circuit_service in layer_2_circuit_service_list:
partner = layer_2_circuit_service["partner"]
service_type = Layer2CircuitServiceType(layer_2_circuit_service["service_type"])
typer.echo(f"Creating imported {service_type} for {partner}")
try:
initial_data = Layer2CircuitServiceImportModel(**layer_2_circuit_service)
start_process("create_imported_layer_2_circuit", [initial_data.model_dump()])
successfully_imported_data.append(initial_data.vc_id)
typer.echo(
f"Successfully created imported {service_type} with virtual circuit ID {initial_data.vc_id}"
f" for {partner}"
)
except ValidationError as e:
typer.echo(f"Validation error: {e}")
typer.echo("Waiting for the dust to settle before importing new products...")
time.sleep(1)
# Migrate new products from imported to "full" counterpart.
imported_products = get_subscriptions(
product_types=[ProductType.IMPORTED_EXPRESSROUTE, ProductType.IMPORTED_GEANT_PLUS],
lifecycles=[SubscriptionLifecycle.ACTIVE],
includes=["subscription_id"],
)
for subscription_id in imported_products:
typer.echo(f"Importing {subscription_id}")
start_process("import_layer_2_circuit", [subscription_id])
if successfully_imported_data:
typer.echo("Successfully created imported Layer 2 Circuit services:")
for item in successfully_imported_data:
typer.echo(f"- {item}")
"""Add Layer 2 Cricuits services domain models..
Revision ID: 5132c463214d
Revises: 0e7e7d749617
Create Date: 2024-10-29 13:34:39.234303
"""
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision = '5132c463214d'
down_revision = '0e7e7d749617'
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 ('GÉANT Plus', 'GÉANT Plus', 'Layer2Circuit', 'G_PLUS', 'active') RETURNING products.product_id
"""))
conn.execute(sa.text("""
INSERT INTO products (name, description, product_type, tag, status) VALUES ('Imported GÉANT Plus', 'Imported GEANT Plus', 'ImportedLayer2Circuit', 'IMP_G_PLUS', 'active') RETURNING products.product_id
"""))
conn.execute(sa.text("""
INSERT INTO products (name, description, product_type, tag, status) VALUES ('Azure ExpressRoute', 'Azure ExpressRoute product', 'Layer2Circuit', 'ER', 'active') RETURNING products.product_id
"""))
conn.execute(sa.text("""
INSERT INTO products (name, description, product_type, tag, status) VALUES ('Imported Azure ExpressRoute', 'Imported Azure ExpressRoute', 'ImportedLayer2Circuit', 'IMP_ER', 'active') RETURNING products.product_id
"""))
conn.execute(sa.text("""
INSERT INTO fixed_inputs (name, value, product_id) VALUES ('layer_2_circuit_service_type', 'Azure ExpressRoute', (SELECT products.product_id FROM products WHERE products.name IN ('Azure ExpressRoute'))), ('layer_2_circuit_service_type', 'Imported Azure ExpressRoute', (SELECT products.product_id FROM products WHERE products.name IN ('Imported Azure ExpressRoute'))), ('layer_2_circuit_service_type', 'Imported GÉANT Plus', (SELECT products.product_id FROM products WHERE products.name IN ('Imported GÉANT Plus'))), ('layer_2_circuit_service_type', 'GÉANT Plus', (SELECT products.product_id FROM products WHERE products.name IN ('GÉANT Plus')))
"""))
conn.execute(sa.text("""
INSERT INTO product_blocks (name, description, tag, status) VALUES ('Layer2CircuitBlock', 'Layer 2 Circuit product block', 'L2_C_BLOCK', 'active') RETURNING product_blocks.product_block_id
"""))
conn.execute(sa.text("""
INSERT INTO product_blocks (name, description, tag, status) VALUES ('Layer2CircuitSideBlock', 'Layer 2 Circuit side product block', 'L2_C_SIDE_BLOCK', 'active') RETURNING product_blocks.product_block_id
"""))
conn.execute(sa.text("""
INSERT INTO resource_types (resource_type, description) VALUES ('policer_enabled', 'Whether this Layer 2 Circuit is policed.') RETURNING resource_types.resource_type_id
"""))
conn.execute(sa.text("""
INSERT INTO resource_types (resource_type, description) VALUES ('bandwidth', 'If policed, the bandwidth of the policer is stored.') RETURNING resource_types.resource_type_id
"""))
conn.execute(sa.text("""
INSERT INTO resource_types (resource_type, description) VALUES ('vlan_range_upper_bound', 'VLAN upper bound range') RETURNING resource_types.resource_type_id
"""))
conn.execute(sa.text("""
INSERT INTO resource_types (resource_type, description) VALUES ('vlan_range_lower_bound', 'VLAN lower bound range') RETURNING resource_types.resource_type_id
"""))
conn.execute(sa.text("""
INSERT INTO resource_types (resource_type, description) VALUES ('virtual_circuit_id', 'Virtual Circuit ID of this Layer 2 Circuit.') RETURNING resource_types.resource_type_id
"""))
conn.execute(sa.text("""
INSERT INTO resource_types (resource_type, description) VALUES ('layer_2_circuit_type', 'The type of circuit, can be tagged or untagged.') 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 ('Azure ExpressRoute')), (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('Layer2CircuitBlock'))), ((SELECT products.product_id FROM products WHERE products.name IN ('Imported Azure ExpressRoute')), (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('Layer2CircuitBlock'))), ((SELECT products.product_id FROM products WHERE products.name IN ('Imported GÉANT Plus')), (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('Layer2CircuitBlock'))), ((SELECT products.product_id FROM products WHERE products.name IN ('GÉANT Plus')), (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('Layer2CircuitBlock')))
"""))
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 ('Layer2CircuitBlock')), (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('Layer2CircuitSideBlock')))
"""))
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 ('Layer2CircuitSideBlock')), (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('ServiceBindingPort')))
"""))
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 ('Layer2CircuitBlock')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('virtual_circuit_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 ('Layer2CircuitBlock')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('layer_2_circuit_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 ('Layer2CircuitBlock')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('vlan_range_lower_bound')))
"""))
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 ('Layer2CircuitBlock')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('vlan_range_upper_bound')))
"""))
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 ('Layer2CircuitBlock')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('policer_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 ('Layer2CircuitBlock')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bandwidth')))
"""))
conn.execute(sa.text("""
INSERT INTO resource_types (resource_type, description) VALUES ('policer_burst_rate', 'Max burst rate of a policer') RETURNING resource_types.resource_type_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 ('Layer2CircuitBlock')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('policer_burst_rate')))
"""))
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 ('Layer2CircuitBlock')) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('policer_burst_rate'))
"""))
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 ('Layer2CircuitBlock'))) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('policer_burst_rate'))
"""))
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 ('policer_burst_rate'))
"""))
conn.execute(sa.text("""
DELETE FROM resource_types WHERE resource_types.resource_type IN ('policer_burst_rate')
"""))
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 ('Layer2CircuitBlock')) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('virtual_circuit_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 ('Layer2CircuitBlock'))) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('virtual_circuit_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 ('Layer2CircuitBlock')) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('layer_2_circuit_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 ('Layer2CircuitBlock'))) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('layer_2_circuit_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 ('Layer2CircuitBlock')) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('vlan_range_lower_bound'))
"""))
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 ('Layer2CircuitBlock'))) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('vlan_range_lower_bound'))
"""))
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 ('Layer2CircuitBlock')) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('vlan_range_upper_bound'))
"""))
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 ('Layer2CircuitBlock'))) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('vlan_range_upper_bound'))
"""))
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 ('Layer2CircuitBlock')) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('policer_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 ('Layer2CircuitBlock'))) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('policer_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 ('Layer2CircuitBlock')) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bandwidth'))
"""))
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 ('Layer2CircuitBlock'))) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bandwidth'))
"""))
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 ('policer_enabled', 'bandwidth', 'vlan_range_upper_bound', 'vlan_range_lower_bound', 'virtual_circuit_id', 'layer_2_circuit_type'))
"""))
conn.execute(sa.text("""
DELETE FROM resource_types WHERE resource_types.resource_type IN ('policer_enabled', 'bandwidth', 'vlan_range_upper_bound', 'vlan_range_lower_bound', 'virtual_circuit_id', 'layer_2_circuit_type')
"""))
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 ('Azure ExpressRoute', 'Imported Azure ExpressRoute', 'Imported GÉANT Plus', 'GÉANT Plus')) AND product_product_blocks.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('Layer2CircuitBlock'))
"""))
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 ('Layer2CircuitBlock')) AND product_block_relations.depends_on_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('Layer2CircuitSideBlock'))
"""))
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 ('Layer2CircuitSideBlock')) 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 fixed_inputs WHERE fixed_inputs.product_id IN (SELECT products.product_id FROM products WHERE products.name IN ('Azure ExpressRoute', 'Imported Azure ExpressRoute', 'Imported GÉANT Plus', 'GÉANT Plus')) AND fixed_inputs.name = 'layer_2_circuit_service_type'
"""))
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 ('Layer2CircuitSideBlock', 'Layer2CircuitBlock'))
"""))
conn.execute(sa.text("""
DELETE FROM product_blocks WHERE product_blocks.name IN ('Layer2CircuitSideBlock', 'Layer2CircuitBlock')
"""))
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 ('Azure ExpressRoute', 'Imported Azure ExpressRoute', 'Imported GÉANT Plus', 'GÉANT Plus'))))
"""))
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 ('Azure ExpressRoute', 'Imported Azure ExpressRoute', 'Imported GÉANT Plus', 'GÉANT Plus')))
"""))
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 ('Azure ExpressRoute', 'Imported Azure ExpressRoute', 'Imported GÉANT Plus', 'GÉANT Plus')))
"""))
conn.execute(sa.text("""
DELETE FROM subscriptions WHERE subscriptions.product_id IN (SELECT products.product_id FROM products WHERE products.name IN ('Azure ExpressRoute', 'Imported Azure ExpressRoute', 'Imported GÉANT Plus', 'GÉANT Plus'))
"""))
conn.execute(sa.text("""
DELETE FROM products WHERE products.name IN ('Azure ExpressRoute', 'Imported Azure ExpressRoute', 'Imported GÉANT Plus', 'GÉANT Plus')
"""))
"""Add L2Circuit workflows..
Revision ID: 72a4f7aa499d
Revises: 5132c463214d
Create Date: 2024-10-29 14:04:29.807253
"""
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision = '72a4f7aa499d'
down_revision = '5132c463214d'
branch_labels = None
depends_on = None
from orchestrator.migrations.helpers import create_workflow, delete_workflow
new_workflows = [
{
"name": "create_layer_2_circuit",
"target": "CREATE",
"description": "Create Layer 2 Circuit Service",
"product_type": "Layer2Circuit"
},
{
"name": "modify_layer_2_circuit",
"target": "MODIFY",
"description": "Modify Layer 2 Circuit Service",
"product_type": "Layer2Circuit"
},
{
"name": "terminate_layer_2_circuit",
"target": "TERMINATE",
"description": "Terminate Layer 2 Circuit Service",
"product_type": "Layer2Circuit"
},
{
"name": "create_imported_layer_2_circuit",
"target": "CREATE",
"description": "Create imported Layer 2 Circuit",
"product_type": "ImportedLayer2Circuit"
},
{
"name": "import_layer_2_circuit",
"target": "MODIFY",
"description": "Import Layer 2 Circuit",
"product_type": "ImportedLayer2Circuit"
},
]
def upgrade() -> None:
conn = op.get_bind()
for workflow in new_workflows:
create_workflow(conn, workflow)
def downgrade() -> None:
conn = op.get_bind()
for workflow in new_workflows:
delete_workflow(conn, workflow["name"])
"""Split BFD settings off into separate product block..
Revision ID: f6ceec1af371
Revises: 72a4f7aa499d
Create Date: 2024-11-18 09:40:50.214908
"""
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision = 'f6ceec1af371'
down_revision = '72a4f7aa499d'
branch_labels = None
depends_on = None
def upgrade() -> 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 ('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 ('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 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 ('bfd_interval'))
"""))
conn.execute(sa.text("""
DELETE FROM resource_types WHERE resource_types.resource_type IN ('bfd_interval')
"""))
conn.execute(sa.text("""
INSERT INTO product_blocks (name, description, tag, status) VALUES ('BFDSettings', 'A set of settings for BFD', 'BFD_SETTINGS', 'active') RETURNING product_blocks.product_block_id
"""))
conn.execute(sa.text("""
INSERT INTO resource_types (resource_type, description) VALUES ('bfd_interval_tx', 'the interval TX') RETURNING resource_types.resource_type_id
"""))
conn.execute(sa.text("""
INSERT INTO resource_types (resource_type, description) VALUES ('bfd_interval_rx', 'the interval RX') RETURNING resource_types.resource_type_id
"""))
conn.execute(sa.text("""
INSERT INTO resource_types (resource_type, description) VALUES ('ip_type', 'if it''s IPV4 or IPV6') RETURNING resource_types.resource_type_id
"""))
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 ('BFDSettings')))
"""))
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 ('ip_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 ('BFDSettings')), (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 ('BFDSettings')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_interval_tx')))
"""))
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 ('BFDSettings')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_interval_rx')))
"""))
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 ('BFDSettings')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_multiplier')))
"""))
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 ('BGPSession')) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('ip_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 ('BGPSession'))) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('ip_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 ('BFDSettings')) 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 ('BFDSettings'))) 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 ('BFDSettings')) 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_tx'))
"""))
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 ('BFDSettings'))) 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_tx'))
"""))
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 ('BFDSettings')) 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_rx'))
"""))
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 ('BFDSettings'))) 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_rx'))
"""))
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 ('BFDSettings')) 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 ('BFDSettings'))) 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 WHERE subscription_instance_values.resource_type_id IN (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_interval_tx', 'bfd_interval_rx', 'ip_type'))
"""))
conn.execute(sa.text("""
DELETE FROM resource_types WHERE resource_types.resource_type IN ('bfd_interval_tx', 'bfd_interval_rx', 'ip_type')
"""))
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 ('BFDSettings'))
"""))
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 ('BFDSettings'))
"""))
conn.execute(sa.text("""
DELETE FROM product_blocks WHERE product_blocks.name IN ('BFDSettings')
"""))
......@@ -125,6 +125,7 @@
"DSN": "https://sentry-dsn-url"
},
"MOODI": {
"host": "moodi.test.gap.geant.org"
"host": "moodi.test.gap.geant.org",
"moodi_enabled": false
}
}
......@@ -11,6 +11,7 @@ from pydantic_forms.types import strEnum
from gso.products.product_types.edge_port import EdgePort, ImportedEdgePort
from gso.products.product_types.iptrunk import ImportedIptrunk, Iptrunk
from gso.products.product_types.lan_switch_interconnect import ImportedLanSwitchInterconnect, LanSwitchInterconnect
from gso.products.product_types.layer_2_circuit import ImportedLayer2Circuit, Layer2Circuit, Layer2CircuitServiceType
from gso.products.product_types.nren_l3_core_service import ImportedNRENL3CoreService, NRENL3CoreService
from gso.products.product_types.office_router import ImportedOfficeRouter, OfficeRouter
from gso.products.product_types.opengear import ImportedOpengear, Opengear
......@@ -47,6 +48,10 @@ class ProductName(strEnum):
IMPORTED_GEANT_IP = "Imported GÉANT IP"
IAS = "IAS"
IMPORTED_IAS = "Imported IAS"
GEANT_PLUS = Layer2CircuitServiceType.GEANT_PLUS
IMPORTED_GEANT_PLUS = Layer2CircuitServiceType.IMPORTED_GEANT_PLUS
EXPRESSROUTE = Layer2CircuitServiceType.EXPRESSROUTE
IMPORTED_EXPRESSROUTE = Layer2CircuitServiceType.IMPORTED_EXPRESSROUTE
class ProductType(strEnum):
......@@ -75,6 +80,10 @@ class ProductType(strEnum):
IMPORTED_GEANT_IP = ImportedNRENL3CoreService.__name__
IAS = NRENL3CoreService.__name__
IMPORTED_IAS = ImportedNRENL3CoreService.__name__
GEANT_PLUS = Layer2Circuit.__name__
IMPORTED_GEANT_PLUS = ImportedLayer2Circuit.__name__
EXPRESSROUTE = Layer2Circuit.__name__
IMPORTED_EXPRESSROUTE = ImportedLayer2Circuit.__name__
SUBSCRIPTION_MODEL_REGISTRY.update(
......@@ -102,5 +111,11 @@ SUBSCRIPTION_MODEL_REGISTRY.update(
ProductName.IMPORTED_GEANT_IP.value: ImportedNRENL3CoreService,
ProductName.IAS.value: NRENL3CoreService,
ProductName.IMPORTED_IAS.value: ImportedNRENL3CoreService,
ProductName.GEANT_PLUS.value: Layer2Circuit,
ProductName.IMPORTED_GEANT_PLUS.value: ImportedLayer2Circuit,
ProductName.EXPRESSROUTE.value: Layer2Circuit,
ProductName.IMPORTED_EXPRESSROUTE.value: ImportedLayer2Circuit,
},
)
__all__ = ["ProductName", "ProductType"]
......@@ -13,19 +13,24 @@ from gso.utils.types.ip_address import IPAddress
class IPFamily(strEnum):
"""Possible IP families of a :term:`BGP` peering."""
V4UNICAST = "v4unicast"
V6UNICAST = "v6unicast"
V4MULTICAST = "v4multicast"
V6MULTICAST = "v6multicast"
V4UNICAST = "ipv4"
V6UNICAST = "ipv6"
V4MULTICAST = "mcast-ipv4"
V6MULTICAST = "mcast-ipv6"
@strawberry.enum
class IPTypes(strEnum):
"""Possible IP types of a :term:`BGP` peering."""
IPV4 = "ipv4"
IPV6 = "ipv6"
class BGPSessionInactive(ProductBlockModel, lifecycle=[SubscriptionLifecycle.INITIAL], product_block_name="BGPSession"):
"""A :term:`BGP` session that is currently inactive. See :class:`BGPSession`."""
peer_address: IPAddress | None = None
bfd_enabled: bool | None = None
bfd_interval: int | None = None
bfd_multiplier: int | None = None
families: list[IPFamily] = Field(default_factory=list)
has_custom_policies: bool | None = None
authentication_key: str | None = None
......@@ -34,23 +39,24 @@ class BGPSessionInactive(ProductBlockModel, lifecycle=[SubscriptionLifecycle.INI
is_multi_hop: bool = False
is_passive: bool = False
rtbh_enabled: bool = False
bfd_enabled: bool = False
ip_type: IPTypes | None = None
class BGPSessionProvisioning(BGPSessionInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]):
"""A :term:`BGP` session that is currently being provisioned. See :class:`BGPSession`."""
peer_address: IPAddress
bfd_enabled: bool
bfd_interval: int | None = None
bfd_multiplier: int | None = None
families: list[IPFamily]
has_custom_policies: bool
authentication_key: str
authentication_key: str | None
multipath_enabled: bool
send_default_route: bool
is_multi_hop: bool
is_passive: bool
rtbh_enabled: bool
bfd_enabled: bool
ip_type: IPTypes
class BGPSession(BGPSessionProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]):
......@@ -58,18 +64,12 @@ class BGPSession(BGPSessionProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE
#: The peering address of the session.
peer_address: IPAddress
#: Whether :term:`BFD` is enabled.
bfd_enabled: bool
#: The :term:`BFD` interval, if enabled.
bfd_interval: int | None = None
#: The :term:`BFD` multiplier, if enabled.
bfd_multiplier: int | None = None
#: The list of IP families enabled for this session.
families: list[IPFamily]
#: Whether any custom policies exist for this session.
has_custom_policies: bool
#: The authentication key of the :term:`BGP` session.
authentication_key: str
authentication_key: str | None
#: Whether multi-path is enabled.
multipath_enabled: bool
#: Whether we send a last resort route.
......@@ -80,3 +80,7 @@ class BGPSession(BGPSessionProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE
is_passive: bool
#: Whether Remote Triggered Blackhole is enabled
rtbh_enabled: bool
#: Settings for :term:`BFD`.
bfd_enabled: bool
#: The IP type of the session.
ip_type: IPTypes
"""Layer 2 Circuit product block."""
from collections.abc import Sequence
from typing import Annotated, TypeVar
from annotated_types import Len
from orchestrator.domain.base import ProductBlockModel
from orchestrator.types import SubscriptionLifecycle
from pydantic import AfterValidator
from pydantic_forms.types import strEnum
from pydantic_forms.validators import validate_unique_list
from typing_extensions import Doc
from gso.products.product_blocks.service_binding_port import (
ServiceBindingPort,
ServiceBindingPortInactive,
ServiceBindingPortProvisioning,
)
from gso.utils.types.interfaces import BandwidthString
from gso.utils.types.virtual_identifiers import VC_ID, VLAN_ID
class Layer2CircuitSideBlockInactive(
ProductBlockModel,
lifecycle=[SubscriptionLifecycle.INITIAL],
product_block_name="Layer2CircuitSideBlock",
):
"""One inactive side of a Layer 2 Circuit."""
sbp: ServiceBindingPortInactive
class Layer2CircuitSideBlockProvisioning(
Layer2CircuitSideBlockInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]
):
"""One provisioning side of a Layer 2 Circuit."""
sbp: ServiceBindingPortProvisioning
class Layer2CircuitSideBlock(Layer2CircuitSideBlockProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]):
"""One side of a Layer 2 Circuit."""
sbp: ServiceBindingPort
Layer2CircuitSideBlockType = TypeVar(
"Layer2CircuitSideBlockType",
"Layer2CircuitSideBlockInactive",
"Layer2CircuitSideBlockProvisioning",
"Layer2CircuitSideBlock",
)
Layer2CircuitSides = Annotated[
Sequence[Layer2CircuitSideBlockType],
AfterValidator(validate_unique_list),
Len(min_length=2, max_length=2),
Doc("A list of two Layer 2 Circuit sides."),
]
class Layer2CircuitType(strEnum):
"""The two types of Layer 2 Circuit."""
TAGGED = "TAGGED"
UNTAGGED = "UNTAGGED"
class Layer2CircuitBlockInactive(
ProductBlockModel, lifecycle=[SubscriptionLifecycle.INITIAL], product_block_name="Layer2CircuitBlock"
):
"""An inactive Layer 2 Circuit, see :class:`Layer2CircuitBlock`."""
layer_2_circuit_sides: Layer2CircuitSides[Layer2CircuitSideBlockInactive]
virtual_circuit_id: VC_ID | None = None
layer_2_circuit_type: Layer2CircuitType | None = None
vlan_range_lower_bound: VLAN_ID | None = None
vlan_range_upper_bound: VLAN_ID | None = None
policer_enabled: bool | None = None
policer_burst_rate: BandwidthString | None = None
bandwidth: BandwidthString | None = None
class Layer2CircuitBlockProvisioning(Layer2CircuitBlockInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]):
"""A provisioning Layer 2 Circuit, see :class:`Layer2CircuitBlock`."""
layer_2_circuit_sides: Layer2CircuitSides[Layer2CircuitSideBlockProvisioning]
virtual_circuit_id: VC_ID
layer_2_circuit_type: Layer2CircuitType
vlan_range_lower_bound: VLAN_ID | None
vlan_range_upper_bound: VLAN_ID | None
policer_enabled: bool
policer_burst_rate: BandwidthString | None
bandwidth: BandwidthString | None
class Layer2CircuitBlock(Layer2CircuitBlockProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]):
"""An active Layer 2 Circuit."""
#: The two sides that the Layer 2 Circuit is connected to.
layer_2_circuit_sides: Layer2CircuitSides[Layer2CircuitSideBlock]
#: Virtual Circuit ID of this Layer 2 Circuit.
virtual_circuit_id: VC_ID
#: The type of circuit, can be tagged or untagged.
layer_2_circuit_type: Layer2CircuitType
#: If tagged, the lower and upper bounds will set the :term:`VLAN` range.
vlan_range_lower_bound: VLAN_ID | None
#: Lower and Upper bounds are including.
vlan_range_upper_bound: VLAN_ID | None
#: Whether this Layer 2 Circuit is policed.
policer_enabled: bool
#: If policed, the burst rate of the policer
policer_burst_rate: BandwidthString | None
#: If policed, the bandwidth of the policer is stored.
bandwidth: BandwidthString | None
......@@ -3,18 +3,52 @@
A service binding port is used to logically attach an edge port to a customer service using a :term:`VLAN`.
"""
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.products.product_blocks.bgp_session import (
BGPSession,
BGPSessionInactive,
BGPSessionProvisioning,
)
from gso.products.product_blocks.edge_port import EdgePortBlock, EdgePortBlockInactive, EdgePortBlockProvisioning
from gso.utils.shared_enums import SBPType
from gso.utils.types.ip_address import IPv4AddressType, IPV4Netmask, IPv6AddressType, IPV6Netmask
from gso.utils.types.virtual_identifiers import VLAN_ID
class BFDSettingsInactive(
ProductBlockModel, lifecycle=[SubscriptionLifecycle.INITIAL], product_block_name="BFDSettings"
):
"""Settings for :term:`BFD`, see :class:`BFDSettings`."""
bfd_enabled: bool = False
bfd_interval_rx: int | None = None
bfd_interval_tx: int | None = None
bfd_multiplier: int | None = None
class BFDSettingsProvisioning(BFDSettingsInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]):
"""Settings for :term:`BFD`, see :class:`BFDSettings`."""
bfd_enabled: bool
bfd_interval_rx: int | None = None
bfd_interval_tx: int | None = None
bfd_multiplier: int | None
class BFDSettings(BFDSettingsProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]):
"""A set of settings for :term:`BFD`."""
VLAN_ID = Annotated[int, Field(gt=0, lt=4096)]
#: Whether :term:`BFD` is enabled.
bfd_enabled: bool
#: The :term:`BFD` interval RX, if enabled.
bfd_interval_rx: int | None
#: The :term:`BFD` interval TX, if enabled.
bfd_interval_tx: int | None
#: The :term:`BFD` multiplier, if enabled.
bfd_multiplier: int | None
class ServiceBindingPortInactive(
......@@ -33,6 +67,8 @@ class ServiceBindingPortInactive(
geant_sid: str | None = None
bgp_session_list: list[BGPSessionInactive] = Field(default_factory=list)
edge_port: EdgePortBlockInactive | None = None
v4_bfd_settings: BFDSettingsInactive
v6_bfd_settings: BFDSettingsInactive
class ServiceBindingPortProvisioning(ServiceBindingPortInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]):
......@@ -49,6 +85,8 @@ class ServiceBindingPortProvisioning(ServiceBindingPortInactive, lifecycle=[Subs
geant_sid: str
bgp_session_list: list[BGPSessionProvisioning] # type: ignore[assignment]
edge_port: EdgePortBlockProvisioning
v4_bfd_settings: BFDSettingsProvisioning
v6_bfd_settings: BFDSettingsProvisioning
class ServiceBindingPort(ServiceBindingPortProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]):
......@@ -76,3 +114,7 @@ class ServiceBindingPort(ServiceBindingPortProvisioning, lifecycle=[Subscription
bgp_session_list: list[BGPSession] # type: ignore[assignment]
#: The Edge Port on which this :term:`SBP` resides.
edge_port: EdgePortBlock
#: :term:`BFD` settings for IPv4
v4_bfd_settings: BFDSettings
#: :term:`BFD` settings for IPv6
v6_bfd_settings: BFDSettings
"""Product type for a Layer 2 circuit."""
from orchestrator.domain.base import SubscriptionModel
from orchestrator.types import SubscriptionLifecycle
from pydantic_forms.types import strEnum
from gso.products.product_blocks.layer_2_circuit import (
Layer2CircuitBlock,
Layer2CircuitBlockInactive,
Layer2CircuitBlockProvisioning,
)
class Layer2CircuitServiceType(strEnum):
"""Available types of Layer 2 Circuit services."""
GEANT_PLUS = "GÉANT Plus"
IMPORTED_GEANT_PLUS = "Imported GÉANT Plus"
EXPRESSROUTE = "Azure ExpressRoute"
IMPORTED_EXPRESSROUTE = "Imported Azure ExpressRoute"
class Layer2CircuitInactive(SubscriptionModel, is_base=True):
"""An inactive Layer 2 Circuit."""
layer_2_circuit_service_type: Layer2CircuitServiceType
layer_2_circuit: Layer2CircuitBlockInactive
class Layer2CircuitProvisioning(Layer2CircuitInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]):
"""A Layer 2 Circuit that is provisioning."""
layer_2_circuit_service_type: Layer2CircuitServiceType
layer_2_circuit: Layer2CircuitBlockProvisioning
class Layer2Circuit(Layer2CircuitProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]):
"""An active Layer 2 Circuit."""
layer_2_circuit_service_type: Layer2CircuitServiceType
layer_2_circuit: Layer2CircuitBlock
class ImportedLayer2CircuitInactive(SubscriptionModel, is_base=True):
"""An imported, inactive Layer 2 Circuit."""
layer_2_circuit_service_type: Layer2CircuitServiceType
layer_2_circuit: Layer2CircuitBlockInactive
class ImportedLayer2Circuit(
ImportedLayer2CircuitInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING, SubscriptionLifecycle.ACTIVE]
):
"""An imported Layer 2 Circuit."""
layer_2_circuit_service_type: Layer2CircuitServiceType
layer_2_circuit: Layer2CircuitBlock
......@@ -10,11 +10,11 @@ from typing import Any, Literal, TypedDict
import requests
from orchestrator import step
from orchestrator.config.assignee import Assignee
from orchestrator.forms import FormPage
from orchestrator.types import State
from orchestrator.utils.errors import ProcessFailureError
from orchestrator.workflow import Step, StepList, begin, callback_step, conditional, inputstep
from pydantic import ConfigDict
from pydantic_forms.core import FormPage
from pydantic_forms.types import FormGenerator
from pydantic_forms.validators import Label, LongText, ReadOnlyField
......
......@@ -287,3 +287,25 @@ def get_all_active_sites() -> list[dict[str, Any]]:
}
for subscription in get_active_site_subscriptions(includes=["subscription_id"])
]
def is_virtual_circuit_id_available(virtual_circuit_id: str) -> bool:
"""Check if the given virtual circuit ID is unique in the database.
This function verifies if the specified virtual circuit ID is not already
present in the core database.
:param virtual_circuit_id: The virtual circuit ID to check.
:type virtual_circuit_id: str
:return: True if the virtual circuit ID is unique (not found), False if it exists.
:rtype: bool
"""
exists = (
ResourceTypeTable.query.join(SubscriptionInstanceValueTable)
.filter(
ResourceTypeTable.resource_type == "virtual_circuit_id",
SubscriptionInstanceValueTable.value == virtual_circuit_id,
)
.scalar()
)
return exists is None