-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathzone_bridge_client_class.py
More file actions
533 lines (451 loc) · 19.4 KB
/
Copy pathzone_bridge_client_class.py
File metadata and controls
533 lines (451 loc) · 19.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
#!/usr/bin/env python3
"""
This module defines the `ZoneBridgeClient` class to link Intersight and MDS clients.
Author:
Adrien LECHARNY - April 2025
"""
# Standard library imports
import sys
# Local application imports
from base_logger import logger
##############################################################################
# ZoneBridgeClient class #
##############################################################################
class ZoneBridgeClient:
"""
Class to link the Intersight and MDS clients.
This class provides various methods to interact with both clients.
Args:
intersight_client (IntersightClient): Instance of IntersightClient.
mds_client_a (MdsClient): Instance of MdsClient for Fabric A.
mds_client_b (MdsClient): Instance of MdsClient for Fabric B.
"""
# Class variables
def __init__(self, intersight_client, mds_client_a, mds_client_b):
"""
Initialize the ZoneBridgeClient class.
Args:
intersight_client (IntersightClient): Instance of IntersightClient.
mds_client_a (MdsClient): Instance of MdsClient for Fabric A.
mds_client_b (MdsClient): Instance of MdsClient for Fabric B.
"""
self.intersight_client = intersight_client
self.mds_client_a = mds_client_a
self.mds_client_b = mds_client_b
# Method to activate zonesets on each MDS of Fabric A and B
def activate_zonesets(
self, zoneset_name_a: str, vsan_id_a: str, zoneset_name_b: str, vsan_id_b: str
):
"""
Activate zonesets on each MDS of Fabric A and B.
This method activates the zonesets in the respective MDS clients.
It is assumed that the zonesets have already been created and configured.
Args:
zoneset_name_a (str): Name of the zoneset in Fabric A.
vsan_id_a (str): VSAN ID for the zoneset in Fabric A.
zoneset_name_b (str): Name of the zoneset in Fabric B.
vsan_id_b (str): VSAN ID for the zoneset in Fabric B.
Returns:
None
"""
# Activate the zoneset in Fabric A
logger.info(
"Activating zoneset '%s' of vsan `%s` in MDS '%s' (Fabric A).\n",
zoneset_name_a,
vsan_id_a,
self.mds_client_a.ip_address,
)
self.mds_client_a.activate_zoneset(
zoneset_name=zoneset_name_a, vsan_id=vsan_id_a
)
# Activate the zoneset in Fabric B
logger.info(
"Activating zoneset '%s' of vsan `%s` in MDS '%s' (Fabric B).\n",
zoneset_name_b,
vsan_id_b,
self.mds_client_b.ip_address,
)
self.mds_client_b.activate_zoneset(
zoneset_name=zoneset_name_b, vsan_id=vsan_id_b
)
# Method to fetch vHBAs attached to an Intersight Server Profile, and configure them as device aliases on each MDS of Fabric A and B
def add_device_aliases_from_server_profile_name_and_vhba(
self, server_profile_name: str, vhba_list: list
):
"""
Fetch vHBAs attached to an Intersight Server Profile, and configure them as device aliases on each MDS of Fabric A and B.
This method creates device aliases based on the Server Profile name, vHBA name and Fabric.
Args:
server_profile_name (str): Name of the Server Profile in Intersight.
vhba_list (list): A list of dictionaries containing vHBA WWPN, name and Fabric information.
Each dictionary contains the keys 'vhba_wwpn', 'vhba_name' and 'vhba_fabric'.
Example:
[
{
"vhba_wwpn": "20:00:00:00:00:00:00:01",
"vhba_name": "vHBA0",
"vhba_fabric": "A"
},
{
"vhba_wwpn": "20:00:00:00:00:00:00:02",
"vhba_name": "vHBA1",
"vhba_fabric": "B"
}
]
Returns:
None
"""
# Iterate over the VHBA list
for vhba in vhba_list:
# Create device alias from server profile name, vHBA name and Fabric
# It has format: <server_profile_name>-<vhba_fabric>-<vhba_name>
# Example: new-server-profile-A-vHBA0
device_alias = (
f"{server_profile_name}-{vhba['vhba_fabric']}-{vhba['vhba_name']}"
)
# Check if the vHBA is in Fabric A or B
if vhba["vhba_fabric"] == "A":
logger.info(
"Adding device alias '%s' with WWPN '%s' to MDS '%s' (Fabric A).\n",
device_alias,
vhba["vhba_wwpn"],
self.mds_client_a.ip_address,
)
# Add the device alias in Fabric A
self.mds_client_a.add_device_alias(
device_alias_name=device_alias,
wwpn=vhba["vhba_wwpn"],
)
elif vhba["vhba_fabric"] == "B":
logger.info(
"Adding device alias '%s' with WWPN '%s' to MDS '%s' (Fabric B).\n",
device_alias,
vhba["vhba_wwpn"],
self.mds_client_b.ip_address,
)
# Add the device alias in Fabric B
self.mds_client_b.add_device_alias(
device_alias_name=device_alias,
wwpn=vhba["vhba_wwpn"],
)
else:
logger.error(
"Unknown fabric type '%s' for vHBA '%s'.\n",
vhba["fabric"],
vhba["name"],
)
sys.exit(1)
# Method to add zones in zonesets on each MDS of Fabric A and B
def add_zones_to_zonesets(
self,
zoneset_name_a: str,
zone_name_a: str,
vsan_id_a: str,
zoneset_name_b: str,
zone_name_b: str,
vsan_id_b: str,
):
"""
Add zones in zonesets on each MDS of Fabric A and B.
This method adds the specified zones to the respective zonesets in the MDS clients.
Args:
zoneset_name_a (str): Name of the zoneset in Fabric A.
zone_name_a (str): Name of the zone to be added in Fabric A.
vsan_id_a (str): VSAN ID for the zone configuration in Fabric A.
zoneset_name_b (str): Name of the zoneset in Fabric B.
zone_name_b (str): Name of the zone to be added in Fabric B.
vsan_id_b (str): VSAN ID for the zone configuration in Fabric B.
Returns:
None
"""
# Add the zone to the zoneset in Fabric A
logger.info(
"Adding zone '%s' of vsan `%s` to zoneset '%s' in MDS '%s' (Fabric A).\n",
zone_name_a,
vsan_id_a,
zoneset_name_a,
self.mds_client_a.ip_address,
)
self.mds_client_a.add_zone_to_zoneset(
zone_name=zone_name_a,
zoneset_name=zoneset_name_a,
vsan_id=vsan_id_a,
)
# Add the zone to the zoneset in Fabric B
logger.info(
"Adding zone '%s' of vsan `%s` to zoneset '%s' in MDS '%s' (Fabric B)\n",
zone_name_b,
vsan_id_b,
zoneset_name_b,
self.mds_client_b.ip_address,
)
self.mds_client_b.add_zone_to_zoneset(
zone_name=zone_name_b,
zoneset_name=zoneset_name_b,
vsan_id=vsan_id_b,
)
# Method to fetch WWPNs attached to a Server Profile in Intersight, optionnaly configure device aliases and add them as members of a zone on each MDS of Fabric A and B
# It can also add the zones to zonesets and activate them
def configure_intersight_mds_zones(
self,
server_profile_name: str,
organization_name: str,
zone_name_a: str,
vsan_id_a: str,
zone_name_b: str,
vsan_id_b: str,
flag_configure_device_aliases: bool,
flag_add_zones_to_zonesets: bool,
flag_activate_zonesets: bool,
zoneset_name_a: str = None,
zoneset_name_b: str = None,
):
"""
Fetch vHBAs attached to an Intersight Server Profile, optionnaly configure device aliases, and add them as members of a zone on each MDS of Fabric A and B, then add the zones to zonesets and activate them.
This method is used to configure zones in MDS based on the vHBAs attached to a Server Profile in Intersight.
It fetches the vHBA information from Intersight and configures device aliases on MDS (if the flag is set to true).
It also adds the vHBA WWPNs or device aliases as members of the specified zones in MDS.
The method can also add the zones to zonesets and activate them if the respective flags are set to true.
Args:
server_profile_name (str): Name of the Server Profile in Intersight.
organization_name (str): Name of the organization in Intersight.
zoneset_name_a (str): Name of the zoneset in MDS.
zone_name_a (str): Name of the zone to be configured in MDS.
vsan_id_a (str): VSAN ID for the zone configuration.
zoneset_name_b (str): Name of the zoneset in MDS.
zone_name_b (str): Name of the zone to be configured in MDS.
vsan_id_b (str): VSAN ID for the zone configuration.
flag_configure_device_aliases (bool): Flag to configure device aliases on MDS.
If set to True, device aliases will be configured and will be used to add member in zone.
If set to False, WWPNs will be added directly to the zones.
flag_add_zones_to_zonesets (bool): Flag to add zones to zonesets.
If set to True, zones will be added to the zonesets.
If set to False, zones will not be added to the zonesets.
flag_activate_zonesets (bool): Flag to activate zonesets.
If set to True, zonesets will be activated.
If set to False, zonesets will not be activated.
Returns:
None
"""
# Log the start of the method
logger.info(
"Configuring Intersight MDS zoning from server profile '%s' in organization '%s'.\n",
server_profile_name,
organization_name,
)
# Check that all flags are provided
if flag_configure_device_aliases is None:
logger.error(
"Flag to configure device aliases is required to configure zones in MDS.\n"
)
sys.exit(1)
if flag_add_zones_to_zonesets is None:
logger.error(
"Flag to add zones to zonesets is required to configure zones in MDS.\n"
)
sys.exit(1)
if flag_activate_zonesets is None:
logger.error(
"Flag to activate zonesets is required to configure zones in MDS.\n"
)
sys.exit(1)
# Log all arguments with debug level
logger.debug(
"Arguments: server_profile_name=%s, organization_name=%s, zoneset_name_a=%s, zone_name_a=%s, vsan_id_a=%s, zoneset_name_b=%s, zone_name_b=%s, vsan_id_b=%s, flag_configure_device_aliases=%s, flag_add_zones_to_zonesets=%s, flag_activate_zonesets=%s\n",
server_profile_name,
organization_name,
zoneset_name_a,
zone_name_a,
vsan_id_a,
zoneset_name_b,
zone_name_b,
vsan_id_b,
flag_configure_device_aliases,
flag_add_zones_to_zonesets,
flag_activate_zonesets,
)
# Fetch the organization moid from Intersight
organization_moid = (
self.intersight_client.fetch_organization_moid_from_organization_name(
organization_name=organization_name,
)
)
# Fetch the server profile moid from Intersight
server_profile = self.intersight_client.fetch_server_profile_moid_from_server_profile_name_and_organization_moid(
server_profile_name=server_profile_name,
organization_moid=organization_moid,
)
# Fetch the VHBA list attached to the server profile
vhbas_list = self.intersight_client.fetch_vhba_from_server_profile_moid(
server_profile,
)
# Iterate over the VHBA list
for vhba in vhbas_list:
# Check if flag to configure device aliases is set to True
# If flag is set to True, device alias will be used for zoning
if flag_configure_device_aliases is True:
device_alias_name = (
f"{server_profile_name}-{vhba['vhba_fabric']}-{vhba['vhba_name']}"
)
# Add the device alias in MDS
logger.info(
"Adding device alias '%s' with WWPN '%s' to MDS '%s' (Fabric %s).\n",
device_alias_name,
vhba["vhba_wwpn"],
(
self.mds_client_a.ip_address
if vhba["vhba_fabric"] == "A"
else self.mds_client_b.ip_address
),
vhba["vhba_fabric"],
)
if vhba["vhba_fabric"] == "A":
self.mds_client_a.add_device_alias(
device_alias_name=device_alias_name,
wwpn=vhba["vhba_wwpn"],
)
elif vhba["vhba_fabric"] == "B":
self.mds_client_b.add_device_alias(
device_alias_name=device_alias_name,
wwpn=vhba["vhba_wwpn"],
)
else:
logger.error(
"Unknown fabric type '%s' for vHBA '%s'.\n",
vhba["fabric"],
vhba["name"],
)
sys.exit(1)
# If flag is set to False, do not configure device aliases
# WWPNs will be used for zoning
elif flag_configure_device_aliases is False:
# Set device alias name to None
device_alias_name = None
logger.info(
"Skipping device alias creation for vHBA '%s' with WWPN '%s'.\n",
vhba["vhba_name"],
vhba["vhba_wwpn"],
)
logger.info(
"Using WWPN '%s' directly for vHBA '%s' to configue zone member.\n",
vhba["vhba_wwpn"],
vhba["vhba_name"],
)
else:
logger.error(
"Unknown flag value '%s' for device alias configuration.\n",
flag_configure_device_aliases,
)
sys.exit(1)
# Check if the vHBA is in Fabric A or B
if vhba["vhba_fabric"] == "A":
logger.info(
"Adding vHBA '%s' to zone '%s' in vsan '%s' of MDS '%s' (Fabric A).\n",
vhba["vhba_wwpn"],
zone_name_a,
vsan_id_a,
self.mds_client_a.ip_address,
)
# Add the member to the zone in Fabric A
self.mds_client_a.configure_zone_and_add_member(
zone_name=zone_name_a,
vsan_id=vsan_id_a,
wwpn=vhba["vhba_wwpn"],
device_alias_name=device_alias_name,
)
elif vhba["vhba_fabric"] == "B":
logger.info(
"Adding vHBA '%s' to zone '%s' in vsan '%s' of MDS '%s' (Fabric B).\n",
vhba["vhba_wwpn"],
zone_name_b,
vsan_id_b,
self.mds_client_b.ip_address,
)
# Add the member to the zone in Fabric B
self.mds_client_b.configure_zone_and_add_member(
zone_name=zone_name_b,
vsan_id=vsan_id_b,
wwpn=vhba["vhba_wwpn"],
device_alias_name=device_alias_name,
)
else:
logger.error(
"Unknown fabric type '%s' for vHBA '%s'.\n",
vhba["fabric"],
vhba["name"],
)
sys.exit(1)
# Add zones to zonesets if the flag is set to True
if flag_add_zones_to_zonesets is True:
logger.info(
"Adding zones to zonesets in each MDS of Fabric A and B.\n",
)
# Check that zoneset names are provided
if zoneset_name_a is None or zoneset_name_b is None:
logger.error(
"Zoneset names are required to add zones to zonesets in MDS.\n"
)
sys.exit(1)
# Add the zone to the zoneset in Fabric A
logger.info(
"Adding zone '%s' of vsan `%s` to zoneset '%s' in MDS '%s' (Fabric A).\n",
zone_name_a,
vsan_id_a,
zoneset_name_a,
self.mds_client_a.ip_address,
)
self.mds_client_a.add_zone_to_zoneset(
zone_name=zone_name_a,
zoneset_name=zoneset_name_a,
vsan_id=vsan_id_a,
)
# Add the zone to the zoneset in Fabric B
logger.info(
"Adding zone '%s' of vsan `%s` to zoneset '%s' in MDS '%s' (Fabric B).\n",
zone_name_b,
vsan_id_b,
zoneset_name_b,
self.mds_client_b.ip_address,
)
self.mds_client_b.add_zone_to_zoneset(
zone_name=zone_name_b,
zoneset_name=zoneset_name_b,
vsan_id=vsan_id_b,
)
else:
logger.info(
"Skipping adding zones to zonesets in each MDS of Fabric A and B.\n"
)
# Activate zonesets if the flag is set to True
if flag_activate_zonesets is True:
# Check that zoneset names are provided
if zoneset_name_a is None or zoneset_name_b is None:
logger.error(
"Zoneset names are required to add zones to zonesets in MDS.\n"
)
sys.exit(1)
logger.info(
"Activating zonesets in each MDS of Fabric A and B.\n",
)
# Activate the zoneset in Fabric A
logger.info(
"Activating zoneset '%s' of vsan `%s` in MDS '%s' (Fabric A).\n",
zoneset_name_a,
vsan_id_a,
self.mds_client_a.ip_address,
)
self.mds_client_a.activate_zoneset(
zoneset_name=zoneset_name_a, vsan_id=vsan_id_a
)
# Activate the zoneset in Fabric B
logger.info(
"Activating zoneset '%s' of vsan `%s` in MDS '%s' (Fabric B).\n",
zoneset_name_b,
vsan_id_b,
self.mds_client_b.ip_address,
)
self.mds_client_b.activate_zoneset(
zoneset_name=zoneset_name_b, vsan_id=vsan_id_b
)
else:
logger.info("Skipping activating zonesets in each MDS of Fabric A and B.\n")