diff --git a/gso/workflows/device/create_device.py b/gso/workflows/device/create_device.py index 91b4374f14098227d74aba592386163f7d1a79b7..86a17d458b46c01c1ba75342907ca012c0a8a2db 100644 --- a/gso/workflows/device/create_device.py +++ b/gso/workflows/device/create_device.py @@ -1,7 +1,9 @@ import ipaddress from uuid import uuid4 +from orchestrator.db.models import ProductTable, SubscriptionTable from orchestrator.forms import FormPage +from orchestrator.forms.validators import Choice, choice_list from orchestrator.targets import Target from orchestrator.types import FormGenerator, State from orchestrator.types import SubscriptionLifecycle, UUIDstr @@ -9,25 +11,28 @@ from orchestrator.workflow import done, init, step, workflow from orchestrator.workflows.steps import resync, set_status from orchestrator.workflows.steps import store_process_subscription from orchestrator.workflows.utils import wrap_create_initial_input_form -from gso.products.product_types import device + from gso.products.product_blocks import device as device_pb -from orchestrator.db.models import ProductTable, SubscriptionTable -from orchestrator.forms.validators import Choice, choice_list +from gso.products.product_types import device +from gso.products.product_types.device import DeviceInactive, \ + DeviceProvisioning from gso.products.product_types.site import Site -# from gso.services import ipam, provisioning_proxy +from gso.services import provisioning_proxy +from gso.services.provisioning_proxy import await_pp_results, \ + confirm_pp_results def site_selector() -> list: site_subscriptions = {} for site_id, site_description in ( - SubscriptionTable.query.join(ProductTable) - .filter( - ProductTable.product_type == "Site", - SubscriptionTable.status == "active", - ) - .with_entities(SubscriptionTable.subscription_id, - SubscriptionTable.description) - .all() + SubscriptionTable.query.join(ProductTable) + .filter( + ProductTable.product_type == "Site", + SubscriptionTable.status == "active", + ) + .with_entities(SubscriptionTable.subscription_id, + SubscriptionTable.description) + .all() ): site_subscriptions[str(site_id)] = site_description @@ -73,8 +78,10 @@ def get_info_from_ipam(subscription: 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 = ipaddress.ip_address('10.10.10.10') - subscription.device.device_lo_ipv6_address = ipaddress.ip_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" @@ -85,13 +92,13 @@ def get_info_from_ipam(subscription: DeviceInactive) -> State: @step('Initialize subscription') def initialize_subscription( - subscription: device.DeviceInactive, - hostname: str, - ts_address: ipaddress.IPv4Address, - ts_port: str, - device_vendor: device_pb.DeviceVendor, - device_site: str, - device_role: device_pb.DeviceRole + subscription: device.DeviceInactive, + hostname: str, + ts_address: ipaddress.IPv4Address, + ts_port: str, + device_vendor: device_pb.DeviceVendor, + device_site: str, + device_role: device_pb.DeviceRole ) -> State: subscription.device.device_ts_address = str(ts_address) subscription.device.device_ts_port = str(ts_port) @@ -113,88 +120,27 @@ def initialize_subscription( return {"subscription": subscription, "fqdn": fqdn} -@step("Provision device [DRY RUN]") -def provision_device_dry( - subscription: device.DeviceProvisioning -) -> State: - import ansible_runner - - snmp_location = subscription.device.device_site.site_country_code - r = ansible_runner.run( - private_data_dir="/opt/geant-gap-ansible", - playbook="base_config.yaml", - inventory=subscription.device.device_fqdn, - extravars={ - "lo_ipv4_address": str(subscription.device.device_lo_ipv4_address), - "lo_ipv6_address": str(subscription.device.device_lo_ipv6_address), - "lo_iso_address": subscription.device.device_lo_iso_address, - "snmp_location": snmp_location, - "si_ipv4_network": str(subscription.device.device_si_ipv4_network), - "lt_ipv4_network": str(subscription.device.device_ias_lt_ipv4_network), - "lt_ipv6_network": str(subscription.device.device_ias_lt_ipv6_network), - "site_country_code": subscription.device.device_site.site_country_code, - "verb": "deploy", - }, - ) - 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} - # 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} - - -@inputstep("Confirm step", assignee="CHANGES") -def confirm_step() -> FormGenerator: - class ConfirmForm(FormPage): - confirm: Accept - - user_input = yield ConfirmForm - - return {"confirm": user_input.confirm} - - -@step("Provision device [FOR REAL]") -def provision_device_real( - subscription: device.DeviceProvisioning -) -> State: - import ansible_runner - - snmp_location = subscription.device.device_site.site_country_code - r = ansible_runner.run( - private_data_dir="/opt/geant-gap-ansible", - playbook="base_config.yaml", - inventory=subscription.device.device_fqdn, - extravars={ - "lo_ipv4_address": str(subscription.device.device_lo_ipv4_address), - "lo_ipv6_address": str(subscription.device.device_lo_ipv6_address), - "lo_iso_address": subscription.device.device_lo_iso_address, - "snmp_location": snmp_location, - "si_ipv4_network": str(subscription.device.device_si_ipv4_network), - "lt_ipv4_network": str(subscription.device.device_ias_lt_ipv4_network), - "lt_ipv6_network": str(subscription.device.device_ias_lt_ipv6_network), - "site_country_code": subscription.device.device_site.site_country_code, - "verb": "deploy", - "dryrun": "False", - "commit_comment": "Deployed with WFO and Ansible", - }, - ) - 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} - # 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} +@step('Provision device [DRY RUN]') +def provision_device_dry(subscription: DeviceProvisioning, + process_id: UUIDstr) -> State: + provisioning_proxy.provision_node( + subscription, + process_id + ) + + return {'subscription': subscription} + + +@step('Provision device [FOR REAL]') +def provision_device_real(subscription: DeviceProvisioning, + process_id: UUIDstr) -> State: + provisioning_proxy.provision_node( + subscription, + process_id, + False # No dry run this time, run it for real + ) + + return {'subscription': subscription} @workflow( 'Create device', @@ -208,7 +154,6 @@ def create_device(): >> create_subscription >> store_process_subscription(Target.CREATE) >> get_info_from_ipam - >> get_snmp_info >> initialize_subscription >> provision_device_dry >> await_pp_results