From 70094e34db2d73a0fd668bc6ab2bfbaf497055fe Mon Sep 17 00:00:00 2001
From: Karel van Klink <karel.vanklink@geant.org>
Date: Fri, 6 Oct 2023 14:43:28 +0200
Subject: [PATCH] move exceptions into netbox_client, PHY port capacity into
 phy_port in utils.types

---
 gso/products/product_blocks/__init__.py | 19 +-------------
 gso/products/product_blocks/router.py   |  2 +-
 gso/services/netbox_client.py           | 34 ++++++++++++++++---------
 gso/utils/exceptions.py                 | 10 --------
 gso/utils/types/{port.py => ip_port.py} |  0
 gso/utils/types/phy_port.py             | 13 ++++++++++
 gso/workflows/router/create_router.py   |  2 +-
 gso/workflows/tasks/import_router.py    |  2 +-
 8 files changed, 39 insertions(+), 43 deletions(-)
 delete mode 100644 gso/utils/exceptions.py
 rename gso/utils/types/{port.py => ip_port.py} (100%)
 create mode 100644 gso/utils/types/phy_port.py

diff --git a/gso/products/product_blocks/__init__.py b/gso/products/product_blocks/__init__.py
index de5db46c..304dbd92 100644
--- a/gso/products/product_blocks/__init__.py
+++ b/gso/products/product_blocks/__init__.py
@@ -1,18 +1 @@
-"""Product blocks that store information about subscriptions.
-
-In this file, some enumerators may be declared that are available for use across all subscriptions.
-"""
-
-from orchestrator.types import strEnum
-
-
-class PhyPortCapacity(strEnum):
-    """Physical port capacity enumerator.
-
-    An enumerator that has the different possible capacities of ports that are available to use in subscriptions.
-    """
-
-    ONE_GIGABIT_PER_SECOND = "1G"
-    TEN_GIGABIT_PER_SECOND = "10G"
-    HUNDRED_GIGABIT_PER_SECOND = "100G"
-    FOUR_HUNDRED_GIGABIT_PER_SECOND = "400G"
+"""Product blocks that store information about subscriptions."""
diff --git a/gso/products/product_blocks/router.py b/gso/products/product_blocks/router.py
index 7a005907..e5bdc7d8 100644
--- a/gso/products/product_blocks/router.py
+++ b/gso/products/product_blocks/router.py
@@ -5,7 +5,7 @@ from orchestrator.domain.base import ProductBlockModel
 from orchestrator.types import SubscriptionLifecycle, strEnum
 
 from gso.products.product_blocks.site import SiteBlock, SiteBlockInactive, SiteBlockProvisioning
-from utils.types.port import PortNumber
+from gso.utils.types.ip_port import PortNumber
 
 
 class RouterVendor(strEnum):
diff --git a/gso/services/netbox_client.py b/gso/services/netbox_client.py
index 45b0906b..3ed80592 100644
--- a/gso/services/netbox_client.py
+++ b/gso/services/netbox_client.py
@@ -8,7 +8,18 @@ from pynetbox.models.dcim import Devices, DeviceTypes, Interfaces
 from gso.products import Router
 from gso.settings import load_oss_params
 from gso.utils.device_info import DEFAULT_SITE, FEASIBLE_IP_TRUNK_LAG_RANGE, ROUTER_ROLE, TierInfo
-from gso.utils.exceptions import NotFoundError, WorkflowStateError
+
+
+class NotFoundError(Exception):
+    """Exception raised for not found search."""
+
+    pass
+
+
+class WorkflowStateError(Exception):
+    """Exception raised on problems during workflow."""
+
+    pass
 
 
 # Define device models
@@ -22,8 +33,7 @@ class Manufacturer(pydantic.BaseModel):
 class DeviceType(pydantic.BaseModel):
     """Defines the device type.
 
-    The manufacturer should be created first to get the manufacturer id,
-    which is defined here as int.
+    The manufacturer should be created first to get the manufacturer id, which is defined here as int.
     """
 
     manufacturer: int
@@ -46,7 +56,7 @@ class Site(pydantic.BaseModel):
 
 
 class NetboxClient:
-    """Implement all methods to communicate with the NetBox API."""
+    """Implement all methods to communicate with the Netbox :term:`API`."""
 
     def __init__(self) -> None:
         self.netbox_params = load_oss_params().NETBOX
@@ -56,7 +66,7 @@ class NetboxClient:
         return list(self.netbox.dcim.devices.all())
 
     def get_device_by_name(self, device_name: str) -> Devices:
-        """Return the device object by name from netbox, or None if not found."""
+        """Return the device object by name from netbox, or ``None`` if not found."""
         return self.netbox.dcim.devices.get(name=device_name)
 
     def get_interfaces_by_device(self, device_name: str, speed: str) -> list[Interfaces]:
@@ -87,7 +97,7 @@ class NetboxClient:
         )
 
     def create_device_type(self, manufacturer: str, model: str, slug: str) -> DeviceTypes:
-        """Create a new device type in netbox."""
+        """Create a new device type in Netbox."""
 
         # First get manufacturer id
         manufacturer_id = int(self.netbox.dcim.manufacturers.get(name=manufacturer).id)
@@ -116,7 +126,7 @@ class NetboxClient:
         return None
 
     def create_device(self, router_name: str, site_tier: str) -> Devices:
-        """Create a new device in netbox."""
+        """Create a new device in Netbox."""
 
         # Get device type id
         tier_info = TierInfo().get_module_by_name(f"Tier{site_tier}")
@@ -159,7 +169,7 @@ class NetboxClient:
     def attach_interface_to_lag(
         self, device_name: str, lag_name: str, iface_name: str, description: str | None = None
     ) -> Interfaces:
-        """Assign a given interface to a LAG.
+        """Assign a given interface to a :term:`LAG`.
 
         Returns the interface object after assignment.
         """
@@ -225,20 +235,20 @@ class NetboxClient:
         return interface
 
     def get_available_lags(self, router_id: UUID) -> list[str]:
-        """Return all available lags not assigned to a device."""
+        """Return all available :term:`LAG`s not assigned to a device."""
 
         router_name = Router.from_subscription(router_id).router.router_fqdn
         device = self.get_device_by_name(router_name)
 
-        # Get the existing lag interfaces for the device
+        # Get the existing LAG interfaces for the device
         lag_interface_names = [
             interface["name"] for interface in self.netbox.dcim.interfaces.filter(device=device.name, type="lag")
         ]
 
-        # Generate all feasible lags
+        # Generate all feasible LAGs
         all_feasible_lags = [f"LAG-{i}" for i in FEASIBLE_IP_TRUNK_LAG_RANGE]
 
-        # Return available lags not assigned to the device
+        # Return available LAGs not assigned to the device
         return [lag for lag in all_feasible_lags if lag not in lag_interface_names]
 
     @staticmethod
diff --git a/gso/utils/exceptions.py b/gso/utils/exceptions.py
deleted file mode 100644
index 21c127e8..00000000
--- a/gso/utils/exceptions.py
+++ /dev/null
@@ -1,10 +0,0 @@
-class NotFoundError(Exception):
-    """Exception raised for not found search."""
-
-    pass
-
-
-class WorkflowStateError(Exception):
-    """Exception raised on problems during workflow."""
-
-    pass
diff --git a/gso/utils/types/port.py b/gso/utils/types/ip_port.py
similarity index 100%
rename from gso/utils/types/port.py
rename to gso/utils/types/ip_port.py
diff --git a/gso/utils/types/phy_port.py b/gso/utils/types/phy_port.py
new file mode 100644
index 00000000..50592c9a
--- /dev/null
+++ b/gso/utils/types/phy_port.py
@@ -0,0 +1,13 @@
+from orchestrator.types import strEnum
+
+
+class PhyPortCapacity(strEnum):
+    """Physical port capacity enumerator.
+
+    An enumerator that has the different possible capacities of ports that are available to use in subscriptions.
+    """
+
+    ONE_GIGABIT_PER_SECOND = "1G"
+    TEN_GIGABIT_PER_SECOND = "10G"
+    HUNDRED_GIGABIT_PER_SECOND = "100G"
+    FOUR_HUNDRED_GIGABIT_PER_SECOND = "400G"
\ No newline at end of file
diff --git a/gso/workflows/router/create_router.py b/gso/workflows/router/create_router.py
index ddda8b38..72d7d5e9 100644
--- a/gso/workflows/router/create_router.py
+++ b/gso/workflows/router/create_router.py
@@ -14,7 +14,7 @@ from pydantic import validator
 from gso.products.product_blocks.router import RouterRole, RouterVendor, generate_fqdn
 from gso.products.product_types.router import RouterInactive, RouterProvisioning
 from gso.products.product_types.site import Site
-from utils.types.port import PortNumber
+from utils.types.ip_port import PortNumber
 from gso.services import infoblox, provisioning_proxy, subscriptions
 from gso.services.netbox_client import NetboxClient
 from gso.services.provisioning_proxy import pp_interaction
diff --git a/gso/workflows/tasks/import_router.py b/gso/workflows/tasks/import_router.py
index 62fe1d6b..1a9c0656 100644
--- a/gso/workflows/tasks/import_router.py
+++ b/gso/workflows/tasks/import_router.py
@@ -13,7 +13,7 @@ from gso.products.product_blocks.router import RouterRole, RouterVendor
 from gso.products.product_types import router
 from gso.products.product_types.router import RouterInactive
 from gso.products.product_types.site import Site
-from utils.types.port import PortNumber
+from utils.types.ip_port import PortNumber
 from gso.products import ProductType
 from gso.services import subscriptions
 from gso.services.crm import get_customer_by_name
-- 
GitLab