|
61 | 61 | from marvin.codes import (PASS, FAILED, ISOLATED_NETWORK, VPC_NETWORK, |
62 | 62 | BASIC_ZONE, FAIL, NAT_RULE, STATIC_NAT_RULE, |
63 | 63 | RESOURCE_PRIMARY_STORAGE, RESOURCE_SECONDARY_STORAGE, |
64 | | - RESOURCE_CPU, RESOURCE_MEMORY) |
| 64 | + RESOURCE_CPU, RESOURCE_MEMORY, PUBLIC_TRAFFIC, |
| 65 | + GUEST_TRAFFIC, MANAGEMENT_TRAFFIC, STORAGE_TRAFFIC) |
65 | 66 | from marvin.lib.utils import (validateList, xsplit, get_process_status) |
66 | 67 | from marvin.lib.base import (PhysicalNetwork, |
67 | 68 | PublicIPAddress, |
|
80 | 81 | Host, |
81 | 82 | Resources, |
82 | 83 | Configurations, |
83 | | - Router) |
| 84 | + Router, |
| 85 | + PublicIpRange, |
| 86 | + StorageNetworkIpRange, |
| 87 | + TrafficType) |
84 | 88 | import random |
85 | | - |
86 | | - |
| 89 | +import re |
| 90 | +import itertools |
87 | 91 | # Import System modules |
88 | 92 | import time |
89 | 93 |
|
@@ -1417,3 +1421,251 @@ def verifyRouterState(apiclient, routerid, state, listall=True): |
1417 | 1421 | exceptionMessage = e |
1418 | 1422 | return [exceptionOccured, isRouterInDesiredState, exceptionMessage] |
1419 | 1423 | return [exceptionOccured, isRouterInDesiredState, exceptionMessage] |
| 1424 | + |
| 1425 | +def analyzeTrafficType(trafficTypes, trafficTypeToFilter): |
| 1426 | + """ Analyze traffic types for given type and return |
| 1427 | + switch name and vlan Id from the |
| 1428 | + vmwarenetworklabel string of trafficTypeToFilter |
| 1429 | + """ |
| 1430 | + |
| 1431 | + try: |
| 1432 | + filteredList = [trafficType for trafficType in trafficTypes |
| 1433 | + if trafficType.traffictype.lower() == |
| 1434 | + trafficTypeToFilter] |
| 1435 | + |
| 1436 | + if not filteredList: |
| 1437 | + return [PASS, filteredList, None, None] |
| 1438 | + |
| 1439 | + # Split string with , so as to extract the switch Name and |
| 1440 | + # vlan ID |
| 1441 | + splitString = str( |
| 1442 | + filteredList[0].vmwarenetworklabel).split(",") |
| 1443 | + switchName = splitString[0] |
| 1444 | + vlanSpecified = splitString[1] |
| 1445 | + |
| 1446 | + return [PASS, filteredList, switchName, vlanSpecified] |
| 1447 | + except Exception as e: |
| 1448 | + return [FAIL, e, None, None] |
| 1449 | + |
| 1450 | + |
| 1451 | +def getExpectedPortGroupNames( |
| 1452 | + api_client, |
| 1453 | + physical_network, |
| 1454 | + network_rate, |
| 1455 | + switch_name, |
| 1456 | + traffic_types, |
| 1457 | + switch_dict, |
| 1458 | + vcenter_conn, |
| 1459 | + specified_vlan, |
| 1460 | + traffic_type): |
| 1461 | + """ Return names of expected port groups that should be |
| 1462 | + present in vcenter |
| 1463 | +
|
| 1464 | + Parameters: |
| 1465 | + @physical_network: Physical Network of the @traffic_type |
| 1466 | + @network_rate: as defined by network.throttling.rate |
| 1467 | + @switch_name: Name of the switch used by the traffic in |
| 1468 | + vcenter |
| 1469 | + @traffic_types: List of all traffic types present in the physical |
| 1470 | + network |
| 1471 | + @switch_dict: Dictionary containing switch information in vcenter |
| 1472 | + @vcenter_conn: vcenter connection object used to fetch information |
| 1473 | + from vcenter |
| 1474 | + @specified_vlan: The vlan for @traffic_type |
| 1475 | + @traffic_type: Traffic type for which the port names are to be |
| 1476 | + returned |
| 1477 | +
|
| 1478 | + Return value: |
| 1479 | + [PASS/FAIL, exception object if FAIL else expected port group names |
| 1480 | + for @traffic_type] |
| 1481 | + """ |
| 1482 | + |
| 1483 | + try: |
| 1484 | + expectedDVPortGroupNames = [] |
| 1485 | + |
| 1486 | + if traffic_type == PUBLIC_TRAFFIC: |
| 1487 | + publicIpRanges = PublicIpRange.list( |
| 1488 | + api_client, |
| 1489 | + physicalnetworkid=physical_network.id |
| 1490 | + ) |
| 1491 | + if publicIpRanges is not None: |
| 1492 | + for publicIpRange in publicIpRanges: |
| 1493 | + vlanInIpRange = re.findall( |
| 1494 | + '\d+', |
| 1495 | + str(publicIpRange.vlan)) |
| 1496 | + if len(vlanInIpRange) > 0: |
| 1497 | + vlanId = vlanInIpRange[0] |
| 1498 | + expectedDVPortGroupName = "cloud" + "." + \ |
| 1499 | + PUBLIC_TRAFFIC + "." + vlanId + "." + \ |
| 1500 | + network_rate + "." + "1" + "-" + \ |
| 1501 | + switch_name |
| 1502 | + expectedDVPortGroupNames.append( |
| 1503 | + expectedDVPortGroupName) |
| 1504 | + |
| 1505 | + expectedDVPortGroupName = "cloud" + "." + PUBLIC_TRAFFIC + "." + \ |
| 1506 | + vlanId + "." + "0" + "." + "1" + "-" + switch_name |
| 1507 | + expectedDVPortGroupNames.append(expectedDVPortGroupName) |
| 1508 | + |
| 1509 | + if traffic_type == GUEST_TRAFFIC: |
| 1510 | + |
| 1511 | + networks = Network.list( |
| 1512 | + api_client, |
| 1513 | + physicalnetworkid=physical_network.id, |
| 1514 | + listall=True |
| 1515 | + ) |
| 1516 | + if networks is not None: |
| 1517 | + for network in networks: |
| 1518 | + networkVlan = re.findall( |
| 1519 | + '\d+', str(network.vlan)) |
| 1520 | + if len(networkVlan) > 0: |
| 1521 | + vlanId = networkVlan[0] |
| 1522 | + expectedDVPortGroupName = "cloud" + "." + GUEST_TRAFFIC + "." + \ |
| 1523 | + vlanId + "." + network_rate + "." + "1" + "-" + \ |
| 1524 | + switch_name |
| 1525 | + expectedDVPortGroupNames.append( |
| 1526 | + expectedDVPortGroupName) |
| 1527 | + |
| 1528 | + if traffic_type == STORAGE_TRAFFIC: |
| 1529 | + vlanId = "" |
| 1530 | + storageIpRanges = StorageNetworkIpRange.list( |
| 1531 | + api_client, |
| 1532 | + zoneid=physical_network.zoneid |
| 1533 | + ) |
| 1534 | + if storageIpRanges is not None: |
| 1535 | + for storageIpRange in storageIpRanges: |
| 1536 | + vlanInIpRange = re.findall( |
| 1537 | + '\d+', |
| 1538 | + str(storageIpRange.vlan)) |
| 1539 | + if len(vlanInIpRange) > 0: |
| 1540 | + vlanId = vlanInIpRange[0] |
| 1541 | + else: |
| 1542 | + vlanId = "untagged" |
| 1543 | + expectedDVPortGroupName = "cloud" + "." + STORAGE_TRAFFIC + \ |
| 1544 | + "." + vlanId + "." + "0" + "." + "1" + "-" + \ |
| 1545 | + switch_name |
| 1546 | + expectedDVPortGroupNames.append( |
| 1547 | + expectedDVPortGroupName) |
| 1548 | + |
| 1549 | + else: |
| 1550 | + response = analyzeTrafficType( |
| 1551 | + traffic_types, MANAGEMENT_TRAFFIC) |
| 1552 | + assert response[0] == PASS, response[1] |
| 1553 | + filteredList, switchName, vlanSpecified =\ |
| 1554 | + response[1], response[2], response[3] |
| 1555 | + |
| 1556 | + if not filteredList: |
| 1557 | + raise Exception("No Management traffic present and\ |
| 1558 | + Storage traffic does not have any IP range,\ |
| 1559 | + Invalid zone setting") |
| 1560 | + |
| 1561 | + if switchName not in switch_dict: |
| 1562 | + dvswitches = vcenter_conn.get_dvswitches( |
| 1563 | + name=switchName) |
| 1564 | + switch_dict[switchName] = dvswitches[0][ |
| 1565 | + 'dvswitch']['portgroupNameList'] |
| 1566 | + |
| 1567 | + if vlanSpecified: |
| 1568 | + vlanId = vlanSpecified |
| 1569 | + else: |
| 1570 | + vlanId = "untagged" |
| 1571 | + expectedDVPortGroupName = "cloud" + "." + STORAGE_TRAFFIC + \ |
| 1572 | + "." + vlanId + "." + "0" + "." + "1" + "-" + switchName |
| 1573 | + expectedDVPortGroupNames.append(expectedDVPortGroupName) |
| 1574 | + |
| 1575 | + if traffic_type == MANAGEMENT_TRAFFIC: |
| 1576 | + vlanId = "untagged" |
| 1577 | + if specified_vlan: |
| 1578 | + vlanId = specified_vlan |
| 1579 | + expectedDVPortGroupName = "cloud" + "." + "private" + "." + \ |
| 1580 | + vlanId + "." + "0" + "." + "1" + "-" + switch_name |
| 1581 | + expectedDVPortGroupNames.append(expectedDVPortGroupName) |
| 1582 | + |
| 1583 | + except Exception as e: |
| 1584 | + return [FAIL, e] |
| 1585 | + return [PASS, expectedDVPortGroupNames] |
| 1586 | + |
| 1587 | + |
| 1588 | +def verifyVCenterPortGroups( |
| 1589 | + api_client, |
| 1590 | + vcenter_conn, |
| 1591 | + zone_list, |
| 1592 | + traffic_types_to_validate): |
| 1593 | + |
| 1594 | + """ Generate expected port groups for given traffic types and |
| 1595 | + verify they are present in the vcenter |
| 1596 | +
|
| 1597 | + Parameters: |
| 1598 | + @api_client: API client of root admin account |
| 1599 | + @vcenter_conn: connection object for vcenter used to fetch data |
| 1600 | + using vcenterAPI |
| 1601 | + @zone_list: List of zones for which port groups are to be verified |
| 1602 | + traffic_types: Traffic types (public, guest, management, storage) for |
| 1603 | + which verification is to be done |
| 1604 | +
|
| 1605 | + Return value: |
| 1606 | + [PASS/FAIL, exception message if FAIL else None] |
| 1607 | + """ |
| 1608 | + try: |
| 1609 | + expectedDVPortGroupNames = [] |
| 1610 | + vcenterPortGroups = [] |
| 1611 | + config = Configurations.list( |
| 1612 | + api_client, |
| 1613 | + name="network.throttling.rate" |
| 1614 | + ) |
| 1615 | + networkRate = config[0].value |
| 1616 | + switchDict = {} |
| 1617 | + for zone in zone_list: |
| 1618 | + # Verify that there should be at least one physical |
| 1619 | + # network present in zone. |
| 1620 | + physicalNetworks = PhysicalNetwork.list( |
| 1621 | + api_client, |
| 1622 | + zoneid=zone.id |
| 1623 | + ) |
| 1624 | + assert validateList(physicalNetworks)[0] == PASS,\ |
| 1625 | + "listPhysicalNetworks returned invalid object in response." |
| 1626 | + |
| 1627 | + for physicalNetwork in physicalNetworks: |
| 1628 | + trafficTypes = TrafficType.list( |
| 1629 | + api_client, |
| 1630 | + physicalnetworkid=physicalNetwork.id) |
| 1631 | + |
| 1632 | + for trafficType in traffic_types_to_validate: |
| 1633 | + response = analyzeTrafficType( |
| 1634 | + trafficTypes, trafficType) |
| 1635 | + assert response[0] == PASS, response[1] |
| 1636 | + filteredList, switchName, vlanSpecified =\ |
| 1637 | + response[1], response[2], response[3] |
| 1638 | + |
| 1639 | + if not filteredList: |
| 1640 | + continue |
| 1641 | + |
| 1642 | + if switchName not in switchDict: |
| 1643 | + dvswitches = vcenter_conn.get_dvswitches( |
| 1644 | + name=switchName) |
| 1645 | + switchDict[switchName] = dvswitches[0][ |
| 1646 | + 'dvswitch']['portgroupNameList'] |
| 1647 | + |
| 1648 | + response = getExpectedPortGroupNames( |
| 1649 | + api_client, |
| 1650 | + physicalNetwork, |
| 1651 | + networkRate, |
| 1652 | + switchName, |
| 1653 | + trafficTypes, |
| 1654 | + switchDict, |
| 1655 | + vcenter_conn, |
| 1656 | + vlanSpecified, |
| 1657 | + trafficType) |
| 1658 | + assert response[0] == PASS, response[1] |
| 1659 | + dvPortGroups = response[1] |
| 1660 | + expectedDVPortGroupNames.extend(dvPortGroups) |
| 1661 | + |
| 1662 | + vcenterPortGroups = list(itertools.chain(*(switchDict.values()))) |
| 1663 | + |
| 1664 | + for expectedDVPortGroupName in expectedDVPortGroupNames: |
| 1665 | + assert expectedDVPortGroupName in vcenterPortGroups,\ |
| 1666 | + "Port group %s not present in VCenter DataCenter" %\ |
| 1667 | + expectedDVPortGroupName |
| 1668 | + |
| 1669 | + except Exception as e: |
| 1670 | + return [FAIL, e] |
| 1671 | + return [PASS, None] |
0 commit comments