Однажды у вас может возникнуть желание составить таблицу портов коммутаторов, к которым подключены ваши хосты.
Если у вас “гомогенное” окружение, состоящее из коммутаторов Cisco, то заморачиваться не нужно совсем (CDP настроен в Virtual Switch Standard/Distributed Virtual Switch по умолчанию).
Но если в окружении не только Cisco, то вам необходимо немного сильнее напрячься:
- использовать только распределенные коммутаторы;
- включать на них поддержку LLDP;
- с удивлением обнаружить, что в API опрос CDP и LLDP происходит по-разному.
Так получилось, что я решил для себя задачу опроса CDP/LLDP с помощью Python. Поэтому, когда возникла задача решения ее же через PoSh, я воспользовался уже имеющимися наработками.
Python
Передаем в переменную host результат использования pyvmomi-библиотеки:
Тут список хостов: connection.content.viewManager.CreateContainerView(datacenter, [vim.HostSystem], recursive=True).view
Хост – это один из объектов этого списка.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
cdp, host_network_system = {}, {}, host.configManager.networkSystem if (host_network_system is not None) and host_network_system.capabilities.supportsNetworkHints: for _ in host_network_system.QueryNetworkHint(): vmnic_name = vmnicConvert[_.device] if _.connectedSwitchPort is not None: cdp[vmnic_name] = {} cdp[vmnic_name]['switchName'] = _.connectedSwitchPort.systemName \ if len(_.connectedSwitchPort.systemName) > 6 else _.connectedSwitchPort.devId cdp[vmnic_name]['switchPort'] = _.connectedSwitchPort.portId elif _.lldpInfo is not None: cdp[vmnic_name] = {} cdp[vmnic_name]['switchPort'] = _.lldpInfo.portId for lldpParam in _.lldpInfo.parameter: if lldpParam.key == "System Name": cdp[vmnic_name]['switchName'] = lldpParam.value.split(".")[0] |
В результате выполнения этого куска кода в переменной cdp окажется с сетевыми интерфейсами, содержащие имена коммутаторов и портов.
PowerShell
PoSh-вариант представляет собой более законченное решение
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 |
param ($report_path) if ($report_path -eq $null) { $report_path = read-host -Prompt "Please set report name" } $VMHosts = Get-VMHost | Where-Object {($_.ConnectionState -eq 'Connected') -or ($_.ConnectionState -eq 'Maintenance')} | Sort-Object -Property Name $count = $VMHosts.count $i = 0 $Result = @() foreach ($VMHost in $VMHosts) { Write-Progress -PercentComplete (($i/$count*100)) -Activity Get_Discovery -Status "Gathering CDP/LLDP" $i++ $NetworkSystemConfigManager = Get-View -Id $VMHost.ExtensionData.ConfigManager.NetworkSystem [System.Object]$pnic = $NetworkSystemConfigManager.NetworkConfig.Pnic.Device | select -Unique foreach ($vmhostnic in $pnic){ $vmnic = $NetworkSystemConfigManager.QueryNetworkHint($vmhostnic)[0] if($vmnic.ConnectedSwitchPort -ne $null){ if(($vmnic.ConnectedSwitchPort.systemName).Length -gt 6){$switchName = $vmnic.ConnectedSwitchPort.systemName} else{$switchName = $vmnic.ConnectedSwitchPort.devId} $VMHostNetworkInfo = [PSCustomObject]@{ VMHost = $VMHost.Name Vmnic = $vmhostnic Switch = $switchName Port = $vmnic.ConnectedSwitchPort.PortId } $Result += $VMHostNetworkInfo } elseif($vmnic.LldpInfo -ne $null){ $switchName = "" foreach ($item in $vmnic.LldpInfo.parameter){ if($item.key -eq 'System Name'){$switchName = $item.value} } $VMHostNetworkInfo = [PSCustomObject]@{ VMHost = $VMHost.Name Vmnic = $vmhostnic Switch = $switchName Port = $vmnic.LldpInfo.PortId } $Result += $VMHostNetworkInfo } } } $Result | Export-Csv -NoTypeInformation -Path $report_path |
Надеюсь, данные куски кода будут кому-либо полезны.