1- from typing import Any , Callable , Iterable
1+ from collections .abc import Iterable
2+
23from ironic_understack .inspected_port import InspectedPort
34
45
@@ -19,6 +20,8 @@ def vlan_group_names(
1920
2021 Assert that there are exactly two connections to each "network" switch.
2122
23+ Use the supplied mapping to categorise the connected switches.
24+
2225 If both switches are in the same rack, the vlan_group name looks like this:
2326
2427 ["a11-12-1", "a11-12-2"] => "a11-12-network"
@@ -27,17 +30,39 @@ def vlan_group_names(
2730 racks separated by a slash:
2831
2932 ["a11-12-1", "a11-13-1"] => "a11-12/a11-13-network"
30-
31- Non-network switches have a VLAN Group name of None.
3233 """
34+ assert_consistent_data_center (ports )
35+ assert_single_or_paired_racks (ports )
36+ assert_switch_names_have_known_suffixes (ports , mapping )
37+
38+ vlan_groups = group_by_switch_category (ports , mapping )
39+
40+ assert_redundant_network_connections (vlan_groups )
41+
42+ vlan_group_names = {}
43+ for switch_category , ports_in_group in vlan_groups .items ():
44+ rack_names = {p .rack_name for p in ports_in_group }
45+ vlan_group_name = "/" .join (sorted (rack_names )) + "-" + switch_category
46+ for p in ports_in_group :
47+ vlan_group_names [p .switch_system_name ] = vlan_group_name
48+ return vlan_group_names
49+
50+
51+ def assert_consistent_data_center (ports : Iterable [InspectedPort ]):
3352 data_centers = {p .data_center_name for p in ports }
3453 if len (data_centers ) > 1 :
3554 raise TopologyError ("Connected to switches in multiple data centers: %s" , ports )
3655
56+
57+ def assert_single_or_paired_racks (ports : Iterable [InspectedPort ]):
3758 network_rack_names = {p .rack_name for p in ports }
3859 if len (network_rack_names ) > 2 :
3960 raise TopologyError ("Connected to switches in more than two racks: %s" , ports )
4061
62+
63+ def assert_switch_names_have_known_suffixes (
64+ ports : Iterable [InspectedPort ], mapping : dict
65+ ):
4166 for port in ports :
4267 if port .switch_suffix not in mapping :
4368 raise TopologyError (
@@ -47,30 +72,28 @@ def vlan_group_names(
4772 f"Recognised suffixes are: { mapping .keys ()} "
4873 )
4974
50- vlan_groups = group_by (ports , lambda port : mapping [port .switch_suffix ])
5175
52- vlan_group_names = {}
53- for switch_category , ports_in_group in vlan_groups .items ():
54- switch_names = {p .switch_system_name for p in ports_in_group }
55- if switch_category == "network" and len (switch_names ) != 2 :
56- raise TopologyError (
57- "Expected connections to exactly two network switches, got %s" ,
58- ports_in_group ,
59- )
76+ def assert_redundant_network_connections ( vlan_groups : dict [ str , list [ InspectedPort ]]):
77+ network_ports = vlan_groups .get ( "network" , [])
78+ switch_names = {p .switch_system_name for p in network_ports }
79+ if len (switch_names ) != 2 :
80+ raise TopologyError (
81+ "Expected connections to exactly two network switches, got %s" ,
82+ network_ports ,
83+ )
6084
61- rack_names = {p .rack_name for p in ports_in_group }
62- vlan_group_name = "/" .join (sorted (rack_names )) + "-" + switch_category
6385
64- for p in ports_in_group :
65- vlan_group_names [p .switch_system_name ] = vlan_group_name
66- return vlan_group_names
86+ def group_by_switch_category (
87+ ports : list [InspectedPort ], mapping : dict [str , str ]
88+ ) -> dict [str , list [InspectedPort ]]:
89+ groups = {}
6790
91+ for port in ports :
92+ switch_category = mapping [port .switch_suffix ]
93+
94+ if switch_category not in groups :
95+ groups [switch_category ] = []
96+
97+ groups [switch_category ].append (port )
6898
69- def group_by (items : Iterable , f : Callable ) -> dict [Any , list ]:
70- groups = {}
71- for item in items :
72- key = f (item )
73- if key not in groups :
74- groups [key ] = []
75- groups [key ].append (item )
7699 return groups
0 commit comments