From a66f560e8f29963e59ceaa6e69e26258edccb909 Mon Sep 17 00:00:00 2001
From: Karel van Klink <karel.vanklink@geant.org>
Date: Fri, 16 Feb 2024 13:23:35 +0100
Subject: [PATCH] make typing of provisioning products more strict

---
 gso/products/product_blocks/router.py | 12 ++++++------
 gso/products/product_blocks/site.py   | 22 +++++++++++-----------
 gso/workflows/router/create_router.py | 11 +++++++----
 3 files changed, 24 insertions(+), 21 deletions(-)

diff --git a/gso/products/product_blocks/router.py b/gso/products/product_blocks/router.py
index d8e9996b..5d1a307d 100644
--- a/gso/products/product_blocks/router.py
+++ b/gso/products/product_blocks/router.py
@@ -68,12 +68,12 @@ class RouterBlockProvisioning(RouterBlockInactive, lifecycle=[SubscriptionLifecy
 
     router_fqdn: str
     router_ts_port: PortNumber
-    router_access_via_ts: bool | None = None
-    router_lo_ipv4_address: ipaddress.IPv4Address | None = None
-    router_lo_ipv6_address: ipaddress.IPv6Address | None = None
-    router_lo_iso_address: str | None = None
-    router_role: RouterRole | None = None
-    router_site: SiteBlockProvisioning | None
+    router_access_via_ts: bool
+    router_lo_ipv4_address: ipaddress.IPv4Address
+    router_lo_ipv6_address: ipaddress.IPv6Address
+    router_lo_iso_address: str
+    router_role: RouterRole
+    router_site: SiteBlockProvisioning
     vendor: RouterVendor
 
 
diff --git a/gso/products/product_blocks/site.py b/gso/products/product_blocks/site.py
index efe21c4b..1852b246 100644
--- a/gso/products/product_blocks/site.py
+++ b/gso/products/product_blocks/site.py
@@ -82,16 +82,16 @@ class SiteBlockInactive(
 class SiteBlockProvisioning(SiteBlockInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]):
     """A site that's currently being provisioned, see :class:`SiteBlock`."""
 
-    site_name: str | None = None
-    site_city: str | None = None
-    site_country: str | None = None
-    site_country_code: str | None = None
-    site_latitude: LatitudeCoordinate | None = None
-    site_longitude: LongitudeCoordinate | None = None
-    site_internal_id: int | None = None
-    site_bgp_community_id: int | None = None
-    site_tier: SiteTier | None = None
-    site_ts_address: str | None = None
+    site_name: str
+    site_city: str
+    site_country: str
+    site_country_code: str
+    site_latitude: LatitudeCoordinate
+    site_longitude: LongitudeCoordinate
+    site_internal_id: int
+    site_bgp_community_id: int
+    site_tier: SiteTier
+    site_ts_address: str
 
 
 class SiteBlock(SiteBlockProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]):
@@ -120,4 +120,4 @@ class SiteBlock(SiteBlockProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE])
     #:  The address of the terminal server that this router is connected to. The terminal server provides out of band
     #:  access. This is required in case a link goes down, or when a router is initially added to the network and it
     #:  does not have any IP trunks connected to it.
-    site_ts_address: str | None = None
+    site_ts_address: str
diff --git a/gso/workflows/router/create_router.py b/gso/workflows/router/create_router.py
index 3ea3e162..e42d2299 100644
--- a/gso/workflows/router/create_router.py
+++ b/gso/workflows/router/create_router.py
@@ -107,21 +107,24 @@ def initialize_subscription(
     subscription.router.vendor = vendor
     subscription.description = f"Router {fqdn}"
 
-    subscription = RouterProvisioning.from_other_lifecycle(subscription, SubscriptionLifecycle.PROVISIONING)
-
     return {"subscription": subscription}
 
 
 @step("Allocate loopback interfaces in IPAM")
-def ipam_allocate_loopback(subscription: RouterProvisioning) -> State:
+def ipam_allocate_loopback(subscription: RouterInactive) -> State:
     """Allocate :term:`IPAM` resources for the loopback interface."""
     fqdn = subscription.router.router_fqdn
+    if not fqdn:
+        msg = f"Router fqdn for subscription id {subscription.subscription_id} is missing!"
+        raise ValueError(msg)
     loopback_v4, loopback_v6 = infoblox.allocate_host(f"lo0.{fqdn}", "LO", [fqdn], str(subscription.subscription_id))
 
     subscription.router.router_lo_ipv4_address = loopback_v4
     subscription.router.router_lo_ipv6_address = loopback_v6
     subscription.router.router_lo_iso_address = iso_from_ipv4(subscription.router.router_lo_ipv4_address)
 
+    subscription = RouterProvisioning.from_other_lifecycle(subscription, SubscriptionLifecycle.PROVISIONING)
+
     return {"subscription": subscription}
 
 
@@ -130,7 +133,7 @@ def create_netbox_device(subscription: RouterProvisioning) -> State:
     """Create a new NOKIA device in Netbox."""
     NetboxClient().create_device(
         subscription.router.router_fqdn,
-        str(subscription.router.router_site.site_tier),  # type: ignore[union-attr]
+        str(subscription.router.router_site.site_tier),
     )
     return {"subscription": subscription}
 
-- 
GitLab