Skip to content
Snippets Groups Projects
Commit bb859c27 authored by Mohammad Torkashvand's avatar Mohammad Torkashvand
Browse files

Create migration scripts to port old L3 Core data to new models

Create new L3 models based on new design
parent 0ed62f34
No related branches found
No related tags found
No related merge requests found
Pipeline #92647 failed
This commit is part of merge request !383. Comments created here will be created in the context of that merge request.
"""Re-model L3CoreServices
GEANT_IP = "GÉANT IP"
IMPORTED_GEANT_IP = "IMPORTED GÉANT IP"
GWS = "GWS"
IMPORTED_GWS = "IMPORTED GWS"
LHCONE = "LHCONE"
IMPORTED_LHCONE = "IMPORTED LHCONE"
COPERNICUS = "COPERNICUS"
IMPORTED_COPERNICUS = "IMPORTED COPERNICUS"
Revision ID: e1afa3790f32
Revises: b96b0ecf6906
Create Date: 2025-03-17 10:23:45.917222
"""
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision = 'e1afa3790f32'
down_revision = 'b96b0ecf6906'
branch_labels = None
depends_on = None
def upgrade() -> None:
conn = op.get_bind()
conn.execute(
sa.text(
"""
DELETE FROM fixed_inputs
WHERE fixed_inputs.product_id IN (
SELECT products.product_id FROM products WHERE products.name IN ('IAS', 'Imported IAS')
)
AND fixed_inputs.name = 'l3_core_service_type'
"""
)
)
conn.execute(
sa.text(
"""
INSERT INTO product_blocks (name, description, tag, status)
VALUES ('IASProductBlock', 'An Internet Access Service for general internet access', 'IAS', 'active')
RETURNING product_blocks.product_block_id
"""
)
)
conn.execute(
sa.text(
"""
INSERT INTO resource_types (resource_type, description)
VALUES ('ias_flavor', 'The flavor of the IAS service')
RETURNING resource_types.resource_type_id
"""
)
)
conn.execute(
sa.text(
"""
INSERT INTO product_block_relations
VALUES (
(SELECT product_blocks.product_block_id FROM product_blocks WHERE name = 'IASProductBlock'),
(SELECT product_blocks.product_block_id FROM product_blocks WHERE name = 'L3CoreServiceBlock'),
NULL,
NULL
);
"""
)
)
conn.execute(
sa.text(
"""
UPDATE product_product_blocks
SET product_block_id = (
SELECT product_block_id FROM product_blocks WHERE name = 'IASProductBlock'
)
WHERE product_block_id = (
SELECT product_block_id FROM product_blocks WHERE name = 'L3CoreServiceBlock'
)
AND product_id IN (
SELECT product_id FROM products WHERE name IN ('IAS', 'Imported IAS')
);
"""
)
)
conn.execute(
sa.text(
"""
UPDATE products
SET product_type = 'IAS'
WHERE product_type = 'L3CoreService'
AND name = 'IAS';
"""
)
)
conn.execute(
sa.text(
"""
UPDATE products
SET product_type = 'ImportedIAS'
WHERE product_type = 'ImportedL3CoreService'
AND name = 'Imported IAS';
"""
)
)
conn.execute(
sa.text(
"""
-- Step 1: Insert new subscription_instances for 'IASProductBlock' and return their IDs
WITH inserted AS (
INSERT INTO subscription_instances (subscription_id, product_block_id)
SELECT
s.subscription_id,
(
SELECT product_block_id
FROM product_blocks
WHERE name = 'IASProductBlock'
) AS product_block_id
FROM subscriptions s
WHERE s.product_id = (
SELECT product_id
FROM products
WHERE products.name = 'IAS'
)
RETURNING subscription_instance_id, subscription_id
)
-- Step 2: Link newly inserted "IASProductBlock" instances to the existing "L3CoreServiceBlock" instance
INSERT INTO subscription_instance_relations (
in_use_by_id,
depends_on_id,
order_id,
domain_model_attr
)
SELECT
i.subscription_instance_id AS in_use_by_id,
e.subscription_instance_id AS depends_on_id,
0 AS order_id,
'l3_core' AS domain_model_attr
FROM inserted i
JOIN subscription_instances e
ON e.subscription_id = i.subscription_id
AND e.product_block_id = (
SELECT product_block_id
FROM product_blocks
WHERE name = 'L3CoreServiceBlock'
);
"""
)
)
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 ('IASProductBlock')),
(SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('ias_flavor'))
)
"""
)
)
conn.execute(
sa.text(
"""
WITH subscription_instance_ids AS (
SELECT subscription_instances.subscription_instance_id
FROM subscription_instances
WHERE subscription_instances.product_block_id IN (
SELECT product_blocks.product_block_id
FROM product_blocks
WHERE product_blocks.name = 'IASProductBlock'
)
)
INSERT INTO subscription_instance_values (subscription_instance_id, resource_type_id, value)
SELECT
subscription_instance_ids.subscription_instance_id,
resource_types.resource_type_id,
'None'
-- TODO we need to check this with Simone to see what the default value should be, in case it is empty string, this wont be show up in the GUI
FROM resource_types
CROSS JOIN subscription_instance_ids
WHERE resource_types.resource_type = 'ias_flavor'
"""
)
)
def downgrade() -> None:
conn = op.get_bind()
......@@ -8,12 +8,16 @@
from orchestrator.domain import SUBSCRIPTION_MODEL_REGISTRY
from pydantic_forms.types import strEnum
from gso.products.product_types.copernicus import Copernicus, ImportedCopernicus
from gso.products.product_types.edge_port import EdgePort, ImportedEdgePort
from gso.products.product_types.geant_ip import GeantIp, ImportedGeantIp
from gso.products.product_types.gws import GWS, ImportedGWS
from gso.products.product_types.ias import IAS, ImportedIAS
from gso.products.product_types.iptrunk import ImportedIptrunk, Iptrunk
from gso.products.product_types.l3_core_service import ImportedL3CoreService, L3CoreService
from gso.products.product_types.l3_core_service import L3CoreService
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.lhcone import ImportedLHCOne, LHCOne
from gso.products.product_types.office_router import ImportedOfficeRouter, OfficeRouter
from gso.products.product_types.opengear import ImportedOpengear, Opengear
from gso.products.product_types.pop_vlan import PopVlan
......@@ -107,14 +111,6 @@ class ProductType(strEnum):
IMPORTED_OPENGEAR = Opengear.__name__
EDGE_PORT = EdgePort.__name__
IMPORTED_EDGE_PORT = ImportedEdgePort.__name__
GEANT_IP = L3_CORE_SERVICE_PRODUCT_TYPE
IMPORTED_GEANT_IP = ImportedL3CoreService.__name__
GWS = L3_CORE_SERVICE_PRODUCT_TYPE
IMPORTED_GWS = ImportedL3CoreService.__name__
LHCONE = L3_CORE_SERVICE_PRODUCT_TYPE
IMPORTED_LHCONE = ImportedL3CoreService.__name__
COPERNICUS = L3_CORE_SERVICE_PRODUCT_TYPE
IMPORTED_COPERNICUS = ImportedL3CoreService.__name__
GEANT_PLUS = L2_CIRCUIT_PRODUCT_TYPE
IMPORTED_GEANT_PLUS = ImportedLayer2Circuit.__name__
EXPRESSROUTE = L2_CIRCUIT_PRODUCT_TYPE
......@@ -122,6 +118,14 @@ class ProductType(strEnum):
VRF = VRF.__name__
IAS = IAS.__name__
IMPORTED_IAS = ImportedIAS.__name__
GEANT_IP = GeantIp.__name__
IMPORTED_GEANT_IP = ImportedGeantIp.__name__
GWS = GWS.__name__
IMPORTED_GWS = ImportedGWS.__name__
LHCONE = LHCOne.__name__
IMPORTED_LHCONE = ImportedLHCOne.__name__
COPERNICUS = Copernicus.__name__
IMPORTED_COPERNICUS = ImportedCopernicus.__name__
SUBSCRIPTION_MODEL_REGISTRY.update(
......@@ -145,16 +149,16 @@ SUBSCRIPTION_MODEL_REGISTRY.update(
ProductName.IMPORTED_OPENGEAR.value: ImportedOpengear,
ProductName.EDGE_PORT.value: EdgePort,
ProductName.IMPORTED_EDGE_PORT.value: ImportedEdgePort,
ProductName.GEANT_IP.value: L3CoreService,
ProductName.IMPORTED_GEANT_IP.value: ImportedL3CoreService,
ProductName.GEANT_IP.value: GeantIp,
ProductName.IMPORTED_GEANT_IP.value: ImportedGeantIp,
ProductName.IAS.value: IAS,
ProductName.IMPORTED_IAS.value: ImportedIAS,
ProductName.GWS.value: L3CoreService,
ProductName.IMPORTED_GWS.value: ImportedL3CoreService,
ProductName.LHCONE.value: L3CoreService,
ProductName.IMPORTED_LHCONE.value: ImportedL3CoreService,
ProductName.COPERNICUS.value: L3CoreService,
ProductName.IMPORTED_COPERNICUS.value: ImportedL3CoreService,
ProductName.GWS.value: GWS,
ProductName.IMPORTED_GWS.value: ImportedGWS,
ProductName.LHCONE.value: LHCOne,
ProductName.IMPORTED_LHCONE.value: ImportedLHCOne,
ProductName.COPERNICUS.value: Copernicus,
ProductName.IMPORTED_COPERNICUS.value: ImportedCopernicus,
ProductName.GEANT_PLUS.value: Layer2Circuit,
ProductName.IMPORTED_GEANT_PLUS.value: ImportedLayer2Circuit,
ProductName.EXPRESSROUTE.value: Layer2Circuit,
......
"""Product blocks for Copernicus AS products."""
from orchestrator.domain.base import ProductBlockModel
from orchestrator.types import SubscriptionLifecycle
from gso.products.product_blocks.l3_core_service import (
L3CoreServiceBlock,
L3CoreServiceBlockInactive,
L3CoreServiceBlockProvisioning,
)
class CopernicusProductBlockInactive(
ProductBlockModel, lifecycle=[SubscriptionLifecycle.INITIAL], product_block_name="CopernicusProductBlock"
):
"""An inactive Copernicus product block. See `CopernicusProductBlock`."""
l3_core: L3CoreServiceBlockInactive | None = None
class CopernicusProductBlockProvisioning(
CopernicusProductBlockInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]
):
"""A provisioning Copernicus product block. See `CopernicusProductBlock`."""
l3_core: L3CoreServiceBlockProvisioning
class CopernicusProductBlock(CopernicusProductBlockProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]):
"""An active Copernicus product block."""
l3_core: L3CoreServiceBlock
"""Product blocks for GEANT IP products."""
from orchestrator.domain.base import ProductBlockModel
from orchestrator.types import SubscriptionLifecycle
from gso.products.product_blocks.l3_core_service import (
L3CoreServiceBlock,
L3CoreServiceBlockInactive,
L3CoreServiceBlockProvisioning,
)
class GeantIpProductBlockInactive(
ProductBlockModel, lifecycle=[SubscriptionLifecycle.INITIAL], product_block_name="GeantIpProductBlock"
):
"""An inactive GeantIp product block. See `GeantIpProductBlock`."""
l3_core: L3CoreServiceBlockInactive | None = None
class GeantIpProductBlockProvisioning(GeantIpProductBlockInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]):
"""A provisioning GeantIp product block. See `GeantIpProductBlock`."""
l3_core: L3CoreServiceBlockProvisioning
class GeantIpProductBlock(GeantIpProductBlockProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]):
"""An active GeantIp product block."""
l3_core: L3CoreServiceBlock
"""Product blocks for GWS products."""
from orchestrator.domain.base import ProductBlockModel
from orchestrator.types import SubscriptionLifecycle
from gso.products.product_blocks.l3_core_service import (
L3CoreServiceBlock,
L3CoreServiceBlockInactive,
L3CoreServiceBlockProvisioning,
)
class GWSProductBlockInactive(
ProductBlockModel, lifecycle=[SubscriptionLifecycle.INITIAL], product_block_name="GWSProductBlock"
):
"""A GWS product block. See `GWSProductBlock`."""
l3_core: L3CoreServiceBlockInactive | None = None
class GWSProductBlockProvisioning(GWSProductBlockInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]):
"""A provisioning GWS product block. See `GWSProductBlock`."""
l3_core: L3CoreServiceBlockProvisioning
class GWSProductBlock(GWSProductBlockProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]):
"""An active GWS product block."""
l3_core: L3CoreServiceBlock
"""Product blocks for IAS products."""
from orchestrator.domain.base import ProductBlockModel
from orchestrator.types import SubscriptionLifecycle
from gso.products.product_blocks.l3_core_service import L3CoreServiceBlockInactive
from gso.products.product_blocks.l3_core_service import (
L3CoreServiceBlock,
L3CoreServiceBlockInactive,
L3CoreServiceBlockProvisioning,
)
class IASProductBlockInactive(
L3CoreServiceBlockInactive, lifecycle=[SubscriptionLifecycle.INITIAL], product_block_name="IASProductBlock"
ProductBlockModel, lifecycle=[SubscriptionLifecycle.INITIAL], product_block_name="IASProductBlock"
):
"""An inactive IAS product block. See `IASProductBlock`."""
l3_core: L3CoreServiceBlockInactive | None = None
ias_flavor: str | None = None
class IASProductBlockProvisioning(IASProductBlockInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]):
"""A provisioning IAS product block. See `IASProductBlock`."""
l3_core: L3CoreServiceBlockProvisioning
ias_flavor: str | None = None
class IASProductBlock(IASProductBlockProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]):
"""An active IAS product block.
Attributes:
ap_list: The list of Access Points where this service is present.
"""
"""An active IAS product block."""
l3_core: L3CoreServiceBlock
ias_flavor: str | None = None
"""Product blocks for LHCONE AS products."""
from orchestrator.domain.base import ProductBlockModel
from orchestrator.types import SubscriptionLifecycle
from gso.products.product_blocks.l3_core_service import (
L3CoreServiceBlock,
L3CoreServiceBlockInactive,
L3CoreServiceBlockProvisioning,
)
class LHCOneProductBlockInactive(
ProductBlockModel, lifecycle=[SubscriptionLifecycle.INITIAL], product_block_name="LHCOneProductBlock"
):
"""An inactive LHCOne product block. See `LHCOneProductBlock`."""
l3_core: L3CoreServiceBlockInactive | None = None
class LHCOneProductBlockProvisioning(LHCOneProductBlockInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]):
"""A provisioning LHCOne product block. See `LHCOneProductBlock`."""
l3_core: L3CoreServiceBlockProvisioning
class LHCOneProductBlock(LHCOneProductBlockProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]):
"""An active LHCOne product block."""
l3_core: L3CoreServiceBlock
"""Product type for LHCONE."""
from orchestrator.domain.base import SubscriptionModel
from orchestrator.types import SubscriptionLifecycle
from gso.products.product_blocks.copernicus import (
CopernicusProductBlock,
CopernicusProductBlockInactive,
CopernicusProductBlockProvisioning,
)
class CopernicusInactive(SubscriptionModel, is_base=True):
"""A Copernicus product that is inactive."""
copernicus: CopernicusProductBlockInactive
class CopernicusProvisioning(CopernicusInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]):
"""A Copernicus product that is being provisioned."""
copernicus: CopernicusProductBlockProvisioning
class Copernicus(CopernicusProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]):
"""A Copernicus product that is active."""
copernicus: CopernicusProductBlock
class ImportedCopernicusInactive(SubscriptionModel, is_base=True):
"""An imported Copernicus product that is inactive."""
copernicus: CopernicusInactive
class ImportedCopernicus(
ImportedCopernicusInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING, SubscriptionLifecycle.ACTIVE]
):
"""An imported Copernicus product that is active."""
copernicus: CopernicusProductBlock
"""Product type for IAS."""
from orchestrator.domain.base import SubscriptionModel
from orchestrator.types import SubscriptionLifecycle
from gso.products.product_blocks.geant_ip import (
GeantIpProductBlock,
GeantIpProductBlockInactive,
GeantIpProductBlockProvisioning,
)
class GeantIpInactive(SubscriptionModel, is_base=True):
"""A GeantIp product that is inactive."""
geant_ip: GeantIpProductBlockInactive
class GeantIpProvisioning(GeantIpInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]):
"""A GeantIp product that is being provisioned."""
geant_ip: GeantIpProductBlockProvisioning
class GeantIp(GeantIpProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]):
"""A GeantIp product that is active."""
geant_ip: GeantIpProductBlock
class ImportedGeantIpInactive(SubscriptionModel, is_base=True):
"""An imported GeantIp product that is inactive."""
geant_ip: GeantIpInactive
class ImportedGeantIp(
ImportedGeantIpInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING, SubscriptionLifecycle.ACTIVE]
):
"""An imported GeantIp product that is active."""
geant_ip: GeantIpProductBlock
"""Product type for IAS."""
from orchestrator.domain.base import SubscriptionModel
from orchestrator.types import SubscriptionLifecycle
from gso.products.product_blocks.gws import GWSProductBlock, GWSProductBlockInactive, GWSProductBlockProvisioning
class GWSInactive(SubscriptionModel, is_base=True):
"""A GWS product that is inactive."""
gws: GWSProductBlockInactive
class GWSProvisioning(GWSInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]):
"""An GWS product that is being provisioned."""
gws: GWSProductBlockProvisioning
class GWS(GWSProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]):
"""An GWS product that is active."""
gws: GWSProductBlock
class ImportedGWSInactive(SubscriptionModel, is_base=True):
"""An imported GWS product that is inactive."""
gws: GWSProductBlockInactive
class ImportedGWS(ImportedGWSInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING, SubscriptionLifecycle.ACTIVE]):
"""An imported GWS product that is active."""
gws: GWSProductBlock
......@@ -17,7 +17,7 @@ class L3CoreServiceType(strEnum):
The core services offered include GÉANT IP for R&E access, and the Internet Access Service.
"""
GEANT_IP = "GÉANT IP"
GEANT_IP = "GÉANT IP" # TODO: PLEASE REMOVE ACCENT
"""GÉANT IP."""
IMPORTED_GEANT_IP = "IMPORTED GÉANT IP"
GWS = "GWS"
......
"""Product type for LHCONE."""
from orchestrator.domain.base import SubscriptionModel
from orchestrator.types import SubscriptionLifecycle
from gso.products.product_blocks.lhcone import (
LHCOneProductBlock,
LHCOneProductBlockInactive,
LHCOneProductBlockProvisioning,
)
class LHCOneInactive(SubscriptionModel, is_base=True):
"""A LHCOne product that is inactive."""
lhcone: LHCOneProductBlockInactive
class LHCOneProvisioning(LHCOneInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]):
"""A LHCOne product that is being provisioned."""
lhcone: LHCOneProductBlockProvisioning
class LHCOne(LHCOneProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]):
"""A LHCOne product that is active."""
lhcone: LHCOneProductBlock
class ImportedLHCOneInactive(SubscriptionModel, is_base=True):
"""An imported LHCOne product that is inactive."""
lhcone: LHCOneInactive
class ImportedLHCOne(
ImportedLHCOneInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING, SubscriptionLifecycle.ACTIVE]
):
"""An imported LHCOne product that is active."""
lhcone: LHCOneProductBlock
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment