diff --git a/gso/services/provisioning_proxy.py b/gso/services/provisioning_proxy.py index d7f89fcff24038987a598433bc570c5edf02af2d..8b170170a23275bace2d2e467f7d23d28e5c1dd4 100644 --- a/gso/services/provisioning_proxy.py +++ b/gso/services/provisioning_proxy.py @@ -1,23 +1,22 @@ -import enum import json import logging import requests from orchestrator import inputstep from orchestrator.config.assignee import Assignee -from orchestrator.domain.lifecycle import SubscriptionModel from orchestrator.forms import FormPage, ReadOnlyField from orchestrator.forms.validators import Accept, Label, LongText -from orchestrator.types import UUIDstr, State +from orchestrator.types import UUIDstr, State, strEnum from orchestrator.utils.json import json_dumps from gso import settings +from gso.products.product_types.device import DeviceProvisioning from gso.products.product_types.iptrunk import IptrunkProvisioning, Iptrunk logger = logging.getLogger(__name__) -class CUDOperation(str, enum.Enum): +class CUDOperation(strEnum): """ Enum for different C(R)UD operations that the provisioning proxy supports. Read is not applicable, hence these become CUD and not CRUD operations. @@ -32,6 +31,20 @@ class CUDOperation(str, enum.Enum): def _send_request(endpoint: str, parameters: dict, process_id: UUIDstr, operation: CUDOperation): + """ + Internal function for sending a request to LSO. The callback address is + derived using the process ID provided. + + :param str endpoint: The LSO-specific endpoint to call, depending on the + type of service object that is acted upon. + :param dict parameters: JSON body for the request, which will almost always + at least consist of a subscription object, and a boolean value to + indicate a dry run. + :param UUIDstr process_id: The process ID that this request is a part of, + used to call back to when the execution of the playbook is completed. + :param :class:`CUDOperation` operation: The specific operation that is + performed with the request. + """ oss = settings.load_oss_params() pp_params = oss.PROVISIONING_PROXY assert pp_params @@ -57,9 +70,18 @@ def _send_request(endpoint: str, parameters: dict, process_id: UUIDstr, def provision_device( - subscription: SubscriptionModel, + subscription: DeviceProvisioning, process_id: UUIDstr, dry_run: bool = True): + """ + Function that provisions a new device using LSO. + + :param :class:`DeviceProvisioning` subscription: The subscription object + that is to be provisioned. + :param UUIDstr process_id: The related process ID, used for callback. + :param bool dry_run: A boolean indicating whether this should be a dry run + or not, defaults to ``True``. + """ parameters = { 'dry_run': dry_run, 'subscription': json.loads(json_dumps(subscription)) @@ -71,6 +93,15 @@ def provision_device( def provision_ip_trunk(subscription: IptrunkProvisioning, process_id: UUIDstr, dry_run: bool = True): + """ + Function that provisions an IP trunk service using LSO. + + :param :class:`IptrunkProvisioning` subscription: The subscription object + that is to be provisioned. + :param UUIDstr process_id: The related process ID, used for callback. + :param bool dry_run: A boolean indicating whether this should be a dry run + or not, defaults to ``True``. + """ parameters = { 'subscription': json.loads(json_dumps(subscription)), 'dry_run': dry_run, @@ -85,6 +116,17 @@ def modify_ip_trunk(old_subscription: Iptrunk, new_subscription: Iptrunk, process_id: UUIDstr, dry_run: bool = True): + """ + Function that modifies an existing IP trunk subscription using LSO. + + :param :class:`Iptrunk` old_subscription: The subscription object, before + its modification. + :param :class:`Iptrunk` new_subscription: The subscription object, after + modifications have been made to it. + :param UUIDstr process_id: The related process ID, used for callback. + :param bool dry_run: A boolean indicating whether this should be a dry ryn + or not, defaults to ``True``. + """ parameters = { 'dry_run': dry_run, 'old_subscription': old_subscription, diff --git a/gso/workflows/device/create_device.py b/gso/workflows/device/create_device.py index 9ee1cafb8ab1d5242755865e00f8d4d496c99d64..f3a12ab7d8de4350acaa542098a3b7b884c31e82 100644 --- a/gso/workflows/device/create_device.py +++ b/gso/workflows/device/create_device.py @@ -25,19 +25,20 @@ from gso.services.provisioning_proxy import await_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 + # noinspection PyTypeChecker return choice_list( - Choice("site_selection", + Choice('site_selection', zip(site_subscriptions.keys(), site_subscriptions.items())), # type:ignore min_items=1, @@ -83,11 +84,11 @@ def get_info_from_ipam(subscription: DeviceInactive) -> State: 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" - subscription.device.device_ias_lt_ipv4_network = "192.168.1.0/31" - subscription.device.device_ias_lt_ipv6_network = "fc00:798:1::150/126" - return {"subscription": subscription} + = '49.51e5.0001.0620.4009.6047.00' + subscription.device.device_si_ipv4_network = '192.168.0.0/31' + subscription.device.device_ias_lt_ipv4_network = '192.168.1.0/31' + subscription.device.device_ias_lt_ipv6_network = 'fc00:798:1::150/126' + return {'subscription': subscription} @step('Initialize subscription') @@ -105,19 +106,19 @@ def initialize_subscription( subscription.device.device_vendor = device_vendor subscription.device.device_site \ = Site.from_subscription(device_site[0]).site - fqdn = str(hostname + "." + - subscription.device.device_site.site_name.lower() + "." + + fqdn = str(hostname + '.' + + subscription.device.device_site.site_name.lower() + '.' + subscription.device.device_site.site_country_code.lower() + - ".geant.net") + '.geant.net') subscription.device.device_fqdn = fqdn subscription.device.device_role = device_role - subscription.description = f"Device {fqdn} type \ - ({subscription.device_type})" + subscription.description = f'Device {fqdn} type \ + ({subscription.device_type})' subscription = device.DeviceProvisioning.from_other_lifecycle( subscription, SubscriptionLifecycle.PROVISIONING ) - return {"subscription": subscription, "fqdn": fqdn} + return {'subscription': subscription, 'fqdn': fqdn} @step('Provision device [DRY RUN]')