diff --git a/gso/migrations/versions/2023-05-08_61f8e90581c5_add_terminate_device_workflow.py b/gso/migrations/versions/2023-05-08_61f8e90581c5_add_terminate_device_workflow.py new file mode 100644 index 0000000000000000000000000000000000000000..8b3f8398c9609c0de0ce56f2cb352aa2a335e1cc --- /dev/null +++ b/gso/migrations/versions/2023-05-08_61f8e90581c5_add_terminate_device_workflow.py @@ -0,0 +1,39 @@ +"""add Terminate device workflow. + +Revision ID: 61f8e90581c5 +Revises: 21e7bb0e5cad +Create Date: 2023-05-08 10:48:21.655880 + +""" +import sqlalchemy as sa +from alembic import op + +# revision identifiers, used by Alembic. +revision = '61f8e90581c5' +down_revision = '21e7bb0e5cad' +branch_labels = None +depends_on = None + + +from orchestrator.migrations.helpers import create_workflow, delete_workflow + +new_workflows = [ + { + "name": "terminate_device", + "target": "TERMINATE", + "description": "Terminate device", + "product_type": "Device" + } +] + + +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"]) diff --git a/gso/migrations/versions/2023-05-08_647e066bc99e_add_terminate_iptrunk_workflow.py b/gso/migrations/versions/2023-05-08_647e066bc99e_add_terminate_iptrunk_workflow.py new file mode 100644 index 0000000000000000000000000000000000000000..49cb67b43eed421e58df6a54a900bffe58e04a3a --- /dev/null +++ b/gso/migrations/versions/2023-05-08_647e066bc99e_add_terminate_iptrunk_workflow.py @@ -0,0 +1,39 @@ +"""add Terminate Iptrunk workflow. + +Revision ID: 647e066bc99e +Revises: 61f8e90581c5 +Create Date: 2023-05-08 18:59:01.309425 + +""" +import sqlalchemy as sa +from alembic import op + +# revision identifiers, used by Alembic. +revision = '647e066bc99e' +down_revision = '61f8e90581c5' +branch_labels = None +depends_on = None + + +from orchestrator.migrations.helpers import create_workflow, delete_workflow + +new_workflows = [ + { + "name": "terminate_iptrunk", + "target": "TERMINATE", + "description": "Terminate IPtrunk", + "product_type": "Iptrunk" + } +] + + +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"]) diff --git a/gso/products/product_blocks/iptrunk.py b/gso/products/product_blocks/iptrunk.py index f2c882bf9a68680c786f9c25ec00b2b838471d7d..40c0016dab7d0767e174de4a332098b185796008 100644 --- a/gso/products/product_blocks/iptrunk.py +++ b/gso/products/product_blocks/iptrunk.py @@ -27,14 +27,14 @@ class IptrunkBlockInactive(ProductBlockModel, iptrunk_sideA_node: DeviceBlockInactive iptrunk_sideA_ae_iface: Optional[str] = None iptrunk_sideA_ae_geant_a_sid: Optional[str] = None - iptrunk_sideA_ae_members: Optional[list] = None - iptrunk_sideA_ae_members_description: Optional[list] = None + iptrunk_sideA_ae_members: list[str] = Field(default_factory=list) + iptrunk_sideA_ae_members_description: list[str] = Field(default_factory=list) # iptrunk_sideB_node: DeviceBlockInactive iptrunk_sideB_ae_iface: Optional[str] = None iptrunk_sideB_ae_geant_a_sid: Optional[str] = None - iptrunk_sideB_ae_members: Optional[list] = None - iptrunk_sideB_ae_members_description: Optional[list] = None + iptrunk_sideB_ae_members: list[str] = Field(default_factory=list) + iptrunk_sideB_ae_members_description: list[str] = Field(default_factory=list) class IptrunkBlockProvisioning(IptrunkBlockInactive, diff --git a/gso/workflows/__init__.py b/gso/workflows/__init__.py index 1e11efa4d52a9a7270b4a48b0e757040c1e2e23b..268bada22e4b28b76ffc3e1371b1e23d2a8c2c47 100644 --- a/gso/workflows/__init__.py +++ b/gso/workflows/__init__.py @@ -5,4 +5,6 @@ LazyWorkflowInstance("gso.workflows.device.terminate_device", "terminate_device") LazyWorkflowInstance("gso.workflows.device.get_facts", "get_facts") LazyWorkflowInstance("gso.workflows.iptrunk.create_iptrunk", "create_iptrunk") +LazyWorkflowInstance("gso.workflows.iptrunk.terminate_iptrunk", + "terminate_iptrunk") LazyWorkflowInstance("gso.workflows.site.create_site", "create_site") diff --git a/gso/workflows/device/create_device.py b/gso/workflows/device/create_device.py index f501fe15317f0eb5a5d65ed75c45c562f6bbc552..3f9cddceeb80b40ef79a3e73e65e05b4dd4c8047 100644 --- a/gso/workflows/device/create_device.py +++ b/gso/workflows/device/create_device.py @@ -75,8 +75,8 @@ def get_info_from_ipam(subscription: device.DeviceInactive) -> State: # subscription.device.lo_ipv4_address = lo.v4 # subscription.device.lo_ipv6_address = lo.v6 # TODO: get info about how these should be generated - subscription.device.device_lo_ipv4_address = "10.10.10.10" - subscription.device.device_lo_ipv6_address = "fc00:798:10::10" + subscription.device.device_lo_ipv4_address = ipaddress.ip_address('10.10.10.10') + subscription.device.device_lo_ipv6_address = ipaddress.ip_address('fc00:798:10::10') subscription.device.device_lo_iso_address \ = "49.51e5.0001.0620.4009.6047.00" subscription.device.device_si_ipv4_network = "192.168.0.0/31" diff --git a/gso/workflows/device/terminate_device.py b/gso/workflows/device/terminate_device.py index 686128a19e0464a0d579b1370c21af3a746ba17b..d5de3c3d17f22d220da5001241f306e283d94d10 100644 --- a/gso/workflows/device/terminate_device.py +++ b/gso/workflows/device/terminate_device.py @@ -41,7 +41,7 @@ def deprovision_user(subscription: Device) -> None: initial_input_form_generator), target=Target.TERMINATE, ) -def terminate_user(): +def terminate_device(): return ( init >> store_process_subscription(Target.TERMINATE) diff --git a/gso/workflows/iptrunk/create_iptrunk.py b/gso/workflows/iptrunk/create_iptrunk.py index e4205e111c699e8fbf3992a02eb4732b628e3cc8..2b485a9b18f8444d528684069514c68eac7a4965 100644 --- a/gso/workflows/iptrunk/create_iptrunk.py +++ b/gso/workflows/iptrunk/create_iptrunk.py @@ -1,4 +1,4 @@ -# import ipaddress +import ipaddress from uuid import uuid4 from orchestrator.forms import FormPage @@ -19,6 +19,8 @@ from gso.products.product_types.device import Device # from gso.products.product_types import device from orchestrator.db.models import ProductTable, SubscriptionTable from orchestrator.forms.validators import Choice, choice_list +from orchestrator.utils.json import json_dumps + def device_selector(choice_value: str) -> list: @@ -91,8 +93,8 @@ def create_subscription(product: UUIDstr) -> State: @step("Get information from IPAM ") def get_info_from_ipam(subscription: iptrunk.IptrunkInactive) -> State: # TODO: get info about how these should be generated - subscription.iptrunk.iptrunk_ipv4_network = "192.168.1.0/31" - subscription.iptrunk.iptrunk_ipv6_network = "fc00:798:1::150/126" + subscription.iptrunk.iptrunk_ipv4_network = ipaddress.ip_network('192.168.255.0/31') + subscription.iptrunk.iptrunk_ipv6_network = ipaddress.ip_network('fc00:798:255::150/126') return {"subscription": subscription} @@ -153,35 +155,30 @@ def initialize_subscription( def provision_iptrunk_dry( subscription: iptrunk.IptrunkProvisioning, ) -> State: - # import ansible_runner - # - # r = ansible_runner.run( - # private_data_dir="/opt/geant-gap-ansible", - # playbook="base_config.yaml", - # inventory=subscription.iptrunk.fqdn, - # extravars={ - # "lo_ipv4_address": str(subscription.iptrunk.lo_ipv4_address), - # "lo_ipv6_address": str(subscription.iptrunk.lo_ipv6_address), - # "lo_iso_address": subscription.iptrunk.lo_iso_address, - # "snmp_location": subscription.iptrunk.snmp_location, - # "si_ipv4_network": str(subscription.iptrunk.si_ipv4_network), - # "lt_ipv4_network": str(subscription.iptrunk.ias_lt_ipv4_network), - # "lt_ipv6_network": str(subscription.iptrunk.ias_lt_ipv6_network), - # "site_country_code": subscription.iptrunk.site_country_code, - # "verb": "deploy", - # }, - # ) - # out = r.stdout.read() - # out_splitted = out.splitlines() + import ansible_runner + + r = ansible_runner.run( + private_data_dir="/opt/geant-gap-ansible", + playbook="iptrunks.yaml", + inventory= str(subscription.iptrunk.iptrunk_sideA_node.device_fqdn +"\n"+ + subscription.iptrunk.iptrunk_sideB_node.device_fqdn+"\n"), + extravars={ + "verb": "compile", + "wfo_trunk_json":json_dumps(subscription), + "config_object":"trunk_interface", + }, + ) + out = r.stdout.read() + out_splitted = out.splitlines() # # if r.rc != 0: # # raise ValueError("Ansible has failed") - # return {"dry_run_output": out_splitted, "return_code": r.rc} + return {"dry_run_output": out_splitted, "return_code": r.rc} # provisioning_proxy.provision_node( # node_subscription_params=subscription, # dry_run=True) # TODO: figure out what to return when we are suspending & waiting # for the provisioning-proxy to call back - return {"return_code": 0} + #return {"return_code": 0} @inputstep("Confirm step", assignee="CHANGES") diff --git a/gso/workflows/iptrunk/terminate_iptrunk.py b/gso/workflows/iptrunk/terminate_iptrunk.py new file mode 100644 index 0000000000000000000000000000000000000000..ddb65eacfd800868a76f2a5fe5b4f0a472035d42 --- /dev/null +++ b/gso/workflows/iptrunk/terminate_iptrunk.py @@ -0,0 +1,53 @@ +from orchestrator.forms import FormPage +from orchestrator.forms.validators import Label +from orchestrator.targets import Target +from orchestrator.types import InputForm, SubscriptionLifecycle, UUIDstr +from orchestrator.workflow import done, init, step, workflow +from orchestrator.workflows.steps import ( + resync, + set_status, + store_process_subscription, + unsync, +) +from orchestrator.workflows.utils import wrap_modify_initial_input_form + +from gso.products.product_types.iptrunk import Iptrunk + + +def initial_input_form_generator(subscription_id: UUIDstr) -> InputForm: + subscription = Iptrunk.from_subscription(subscription_id) + + class TerminateForm(FormPage): + are_you_sure: Label = ( + f"Are you sure you want to remove {subscription.description}?" + ) # type:ignore + + return TerminateForm + + +def _deprovision_in_user_management_system(fqdn: str) -> str: + pass + + +@step("Deprovision Iptrunk") +def deprovision_iptrunk(subscription: Iptrunk) -> None: + # _deprovision_in_user_management_system(subscription.user.user_id) + pass + + +@workflow( + "Terminate IPtrunk", + initial_input_form=wrap_modify_initial_input_form( + initial_input_form_generator), + target=Target.TERMINATE, +) +def terminate_iptrunk(): + return ( + init + >> store_process_subscription(Target.TERMINATE) + >> unsync + >> deprovision_iptrunk + >> set_status(SubscriptionLifecycle.TERMINATED) + >> resync + >> done + )