|
8 | 8 | TagMissingException, |
9 | 9 | TagTooManyValuesException |
10 | 10 | ) |
| 11 | +from arista.tag.v2.services import ( |
| 12 | + TagAssignmentServiceStub, |
| 13 | + TagAssignmentStreamRequest |
| 14 | +) |
| 15 | +from arista.tag.v2.tag_pb2 import ( |
| 16 | + TagAssignment, |
| 17 | + ELEMENT_TYPE_DEVICE, |
| 18 | + CREATOR_TYPE_SYSTEM |
| 19 | +) |
11 | 20 | from .tags import Tag |
| 21 | +from .constants import ( |
| 22 | + MAINLINE_WS_ID, |
| 23 | + SYSTYPE_TAG_LABEL |
| 24 | +) |
12 | 25 |
|
13 | 26 |
|
14 | 27 | OLD_VEOS_REGEX = r'(v|c)EOS(-)*(Lab)*' |
@@ -431,6 +444,54 @@ def getInterfacesByTag(self, ctx, tag: Tag, inTopology: bool = True): |
431 | 444 | interfaces.append(Interface(name=intfId, device=self)) |
432 | 445 | return interfaces |
433 | 446 |
|
| 447 | + def getPrimaryManagementIntf(self, ctx): |
| 448 | + ''' |
| 449 | + Returns the primary management interface of the device. This would be Management0 for |
| 450 | + modular devices and Management1 for fixed systems. It also makes sure that the interface |
| 451 | + Management1/1 exists on the device. If not, returns the first management interface in the |
| 452 | + alphabetical sorted order. |
| 453 | + ''' |
| 454 | + mgmtIntfs = [] |
| 455 | + for intf in self.getInterfaces(): |
| 456 | + if intf.name.startswith("Management"): |
| 457 | + mgmtIntfs.append(intf.name) |
| 458 | + if not mgmtIntfs: |
| 459 | + # If the device mac is empty, it is an expected/pre-provisioned device. Should return a |
| 460 | + # default value to prevent errors. |
| 461 | + if not self.mac: |
| 462 | + return "Management1" |
| 463 | + return "" |
| 464 | + mgmtIntfs.sort() |
| 465 | + tagClient = ctx.getApiClient(TagAssignmentServiceStub) |
| 466 | + tagRequest = TagAssignmentStreamRequest() |
| 467 | + tagFilter = TagAssignment() |
| 468 | + tagFilter.tag_creator_type = CREATOR_TYPE_SYSTEM |
| 469 | + tagFilter.key.element_type = ELEMENT_TYPE_DEVICE |
| 470 | + tagFilter.key.workspace_id.value = MAINLINE_WS_ID |
| 471 | + tagFilter.key.label.value = SYSTYPE_TAG_LABEL |
| 472 | + tagFilter.key.device_id.value = self.id |
| 473 | + tagRequest.partial_eq_filter.append(tagFilter) |
| 474 | + systemType = "" |
| 475 | + primaryMgmtIntf = "" |
| 476 | + for resp in tagClient.GetAll(tagRequest): |
| 477 | + systemType = resp.value.key.value.value |
| 478 | + if systemType.lower() == "fixed": |
| 479 | + primaryMgmtIntf = "Management1" |
| 480 | + elif systemType.lower() == "modular": |
| 481 | + primaryMgmtIntf = "Management0" |
| 482 | + elif systemType: |
| 483 | + raise Exception("found unexpected systype tag for device") |
| 484 | + else: |
| 485 | + raise Exception("could not find systype tag for device") |
| 486 | + # There are cases where Mgmt0 and Mgmt1 are not present and a different primary interface |
| 487 | + # is needed. For example, devices with AWE sku have systype tag as fixed but don't have |
| 488 | + # management1 on the device but Management1/1 interface instead. |
| 489 | + # Checking this only for fixed systems as Management0 is not a physical interface |
| 490 | + # and is not returned by device object. |
| 491 | + if primaryMgmtIntf == "Management1" and primaryMgmtIntf not in mgmtIntfs: |
| 492 | + primaryMgmtIntf = mgmtIntfs[0] |
| 493 | + return primaryMgmtIntf |
| 494 | + |
434 | 495 |
|
435 | 496 | # Interfaces and devices are defined together to avoid circular imports |
436 | 497 | class Interface: |
|
0 commit comments