Если вы захотите собирать информацию о версии драйвера и прошивки сетевого интерфейса ESXi, то можете воспользоваться пакетом от VMware, который нужно поставить на Linux. Есть отдельные версии для 7.0 и 6.7.
После этого Вам потребуется:
- подключить к Python библиотеку Subprocess;
- если vCenter использует недоверенный сертификат, то вам потребуется игнорировать эту ошибку. Один из вариантов – указать в команде отпечаток (thumbprint) сертификата vCenter, к которому подключены сервера ESXi (оптимально собирать информацию через него). Можно выполнить “esxcli -s <vcenter> -u <vcenter_login> -p <vcenter_password> -h <esxi>”, чтобы получить отпечаток.
Для вывода списка сетевых адаптеров с используемым драйвером и красивым названием воспользуемся командой esxcli -s <vcenter> -u <vcenter_login> -p <vcenter_password> -h <esxi> --thumbprint <vcenter_thumbprint> network nic list
Для вывода подробной информации по адаптеру, из которой можно взять версию драйвера и прошивки воспользуемся похожей командой ESXCLI network nic get -n vmnic7
, например.
Вот пример скрипта, который делает “что-то похожее”:
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 |
<span id="LC130" class="line" lang="python">def get_esxi_drv_version(vcenter_name,username,password,hostname,thumbprint): <span class="n">command_line</span> <span class="o">=</span> <span class="s">'esxcli -s '</span> <span class="o">+</span> <span class="n">vcenter_name</span> <span class="o">+</span> <span class="s">' -u '</span> <span class="o">+</span> <span class="n">username</span> <span class="o">+</span> <span class="s">" -p '"</span> <span class="o">+</span> <span class="n">password</span> <span class="o">+</span> <span class="s">"' -h "</span> <span class="o">+</span> <span class="n">host</span><span class="n">name</span> <span class="o">+</span> <span class="n">thumbprint</span></span> <span id="LC131" class="line" lang="python"> <span class="k">try</span><span class="p">:</span></span> <span id="LC132" class="line" lang="python"> <span class="n">nics_result</span> <span class="o">=</span> <span class="n">run</span><span class="p">(</span><span class="n">command_line</span> <span class="o">+</span> <span class="s">' network nic list'</span><span class="p">,</span> <span class="n">text</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">capture_output</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">check</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span></span><span id="LC133" class="line" lang="python"><span class="n">shell</span><span class="o">=</span><span class="bp">True</span><span class="p">).</span><span class="n">stdout</span></span> <span id="LC134" class="line" lang="python"> <span class="k">except</span> <span class="n">CalledProcessError</span><span class="p">:</span></span> <span id="LC135" class="line" lang="python"> <span class="n">logging</span><span class="p">.</span><span class="n">error</span><span class="p">(</span><span class="s">"ESXCLI network nic list error"</span><span class="p">,</span> <span class="n">exc_info</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span></span> <span id="LC136" class="line" lang="python"> <span class="k">return</span></span> <span id="LC137" class="line" lang="python"> <span class="n">start_position_nic_name</span> <span class="o">=</span> <span class="n">nics_result</span><span class="p">.</span><span class="n">splitlines</span><span class="p">()[</span><span class="mi">0</span><span class="p">].</span><span class="n">find</span><span class="p">(</span><span class="s">'Description'</span><span class="p">)</span></span> <span id="LC138" class="line" lang="python"> <span class="n">vmnic_dict</span><span class="p">,</span> <span class="n">i</span> <span class="o">=</span> <span class="p">{},</span> <span class="mi">0</span></span> <span id="LC139" class="line" lang="python"> <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="n">nics_result</span><span class="p">.</span><span class="n">splitlines</span><span class="p">():</span></span> <span id="LC140" class="line" lang="python"> <span class="k">if</span> <span class="n">i</span> <span class="o">></span> <span class="mi">1</span><span class="p">:</span></span> <span id="LC141" class="line" lang="python"> <span class="n">vmnic_dict</span><span class="p">[</span><span class="n">_</span><span class="p">[</span><span class="mi">0</span><span class="p">:</span><span class="mi">6</span><span class="p">]]</span> <span class="o">=</span> <span class="n">i</span></span> <span id="LC142" class="line" lang="python"> <span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span></span> <span id="LC143" class="line" lang="python"> <span class="n">logging</span><span class="p">.</span><span class="n">info</span><span class="p">(</span><span class="n">vmnic_dict</span><span class="p">)</span></span> <span id="LC144" class="line" lang="python"> <span class="k">for</span> <span class="n">pnic</span> <span class="ow">in</span> <span class="n">host</span><span class="p">.</span><span class="n">config</span><span class="p">.</span><span class="n">network</span><span class="p">.</span><span class="n">pnic</span><span class="p">:</span></span> <span id="LC146" class="line" lang="python"> <span class="n">nics</span><span class="p">[</span><span class="n">pnic</span><span class="p">.</span><span class="n">device</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span></span> <span id="LC147" class="line" lang="python"> <span class="k">try</span><span class="p">:</span></span> <span id="LC148" class="line" lang="python"> <span class="n">result</span> <span class="o">=</span> <span class="n">run</span><span class="p">(</span><span class="n">command_line</span> <span class="o">+</span> <span class="s">' network nic get -n '</span> <span class="o">+</span> <span class="n">pnic</span><span class="p">.</span><span class="n">device</span><span class="p">,</span> <span class="n">text</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">capture_output</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">check</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span></span> <span id="LC149" class="line" lang="python"> <span class="n">shell</span><span class="o">=</span><span class="bp">True</span><span class="p">).</span><span class="n">stdout</span></span> <span id="LC150" class="line" lang="python"> <span class="k">except</span> <span class="n">CalledProcessError</span><span class="p">:</span></span> <span id="LC151" class="line" lang="python"> <span class="n">logging</span><span class="p">.</span><span class="n">error</span><span class="p">(</span><span class="s">"ESXCLI network nic get -n vmnic"</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">nic_id</span><span class="p">),</span> <span class="n">exc_info</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span></span> <span id="LC152" class="line" lang="python"> <span class="k">return</span></span> <span id="LC153" class="line" lang="python"> <span class="n">driver_name</span> <span class="o">=</span> <span class="n">result</span><span class="p">.</span><span class="n">splitlines</span><span class="p">()[</span><span class="mi">7</span><span class="p">].</span><span class="n">split</span><span class="p">(</span><span class="s">'Driver: '</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span></span> <span id="LC154" class="line" lang="python"> <span class="k">if</span> <span class="n">driver_name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">nics_result</span><span class="p">.</span><span class="n">splitlines</span><span class="p">()[</span><span class="n">vmnic_dict</span><span class="p">[</span><span class="n">pnic</span><span class="p">.</span><span class="n">device</span><span class="p">]]:</span></span> <span id="LC155" class="line" lang="python"> <span class="n">logging</span><span class="p">.</span><span class="n">error</span><span class="p">(</span><span class="s">'ESXCLI error: driver name mismatch for '</span> <span class="o">+</span> <span class="n">host</span><span class="n">name</span><span class="p">)</span></span> <span id="LC156" class="line" lang="python"> <span class="k">return</span></span> <span id="LC157" class="line" lang="python"> <span class="n">nics</span><span class="p">[</span><span class="n">pnic</span><span class="p">.</span><span class="n">device</span><span class="p">][</span><span class="s">'name'</span><span class="p">]</span> <span class="o">=</span> <span class="n">nics_result</span><span class="p">.</span><span class="n">splitlines</span><span class="p">()[</span><span class="n">vmnic_dict</span><span class="p">[</span><span class="n">pnic</span><span class="p">.</span><span class="n">device</span><span class="p">]][</span><span class="n">start_position_nic_name</span><span class="p">:]</span> \</span> <span id="LC158" class="line" lang="python"> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">nics_result</span><span class="p">.</span><span class="n">splitlines</span><span class="p">()[</span><span class="n">vmnic_dict</span><span class="p">[</span><span class="n">pnic</span><span class="p">.</span><span class="n">device</span><span class="p">]][</span><span class="n">start_position_nic_name</span><span class="p">:])</span> <span class="o"><=</span> <span class="mi">50</span> \</span> <span id="LC159" class="line" lang="python"> <span class="k">else</span> <span class="n">nics_result</span><span class="p">.</span><span class="n">splitlines</span><span class="p">()[</span><span class="n">vmnic_dict</span><span class="p">[</span><span class="n">pnic</span><span class="p">.</span><span class="n">device</span><span class="p">]][</span><span class="n">start_position_nic_name</span><span class="p">:][</span><span class="mi">0</span><span class="p">:</span><span class="mi">49</span><span class="p">].</span><span class="n">rstrip</span><span class="p">()</span></span> <span id="LC160" class="line" lang="python"> <span class="n">nics</span><span class="p">[</span><span class="n">pnic</span><span class="p">.</span><span class="n">device</span><span class="p">][</span><span class="s">'driver'</span><span class="p">]</span> <span class="o">=</span> <span class="n">driver_name</span> <span class="o">+</span> <span class="n">result</span><span class="p">.</span><span class="n">splitlines</span><span class="p">()[</span><span class="mi">9</span><span class="p">].</span><span class="n">split</span><span class="p">(</span><span class="s">'Version:'</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="s">'['</span> <span class="o">+</span> <span class="n">pnic</span><span class="p">.</span><span class="n">device</span> <span class="o">+</span> <span class="s">']'</span></span> <span id="LC161" class="line" lang="python"> <span class="n">nics</span><span class="p">[</span><span class="n">pnic</span><span class="p">.</span><span class="n">device</span><span class="p">][</span><span class="s">'firmware'</span><span class="p">]</span> <span class="o">=</span> <span class="n">result</span><span class="p">.</span><span class="n">splitlines</span><span class="p">()[</span><span class="mi">8</span><span class="p">].</span><span class="n">split</span><span class="p">(</span><span class="s">'Firmware Version: '</span><span class="p">)[</span><span class="mi">1</span><span class="p">] </span></span><span id="LC130" class="line" lang="python"> return nics</span> |
В результате работы функции будет возвращен словарь, содержащий набор сетевых карт хоста и версий прошивок/драйверов.
Главный минус скрипта: если VMware решит изменить порядковый номер строки, в которых она выводит драйвер и прошивку сетевого адаптера, скрипт сломается.
UPD: пример XML для самостоятельных пинков ESXi:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <soapenv:Header> <operationID versionId="4.0">esxcli-39</operationID> </soapenv:Header> <soapenv:Body> <VimEsxCLInetworknicget xmlns="urn:vim25"> <_this versionId="4.0" type="VimEsxCLInetworknic">ha-cli-handler-network-nic</_this> <nicname versionId="4.0">vmnic5</nicname> </VimEsxCLInetworknicget> </soapenv:Body> </soapenv:Envelope> |
Через PowerCLI как-то попроще:
https://communities.vmware.com/t5/VMware-PowerCLI-Discussions/Looking-for-a-PowerCLI-script-to-get-the-ESXi-hosts-all-the-NIC/td-p/465467
Естественно, так как в PowerCLI для ESXCLI придумали готовую обертку. Вжух – и у вас готов результат выполнения команды, уже оформленный в объект со свойствами.
Тут же вы самостоятельно “парсите” вывод командной строки.
Впрочем, Вячеслав (наш старый соавтор aka virus) подсказывает, что при желании можно запрашивать XML с хоста с выводом esxcli на нем.
Все текущие реализации ESXcli делают в хост POST на URL https://1.1.1.1/sdk/webService с XML’кой, которую я добавил в пост.
В ответ вы получаете XML, содержащий искомую информацию (результат запуска esxcli network nic get -n vmnic5).
Существующие реализации vmomi/automation sdk на python не содержат средств работы с ESXcli, а хочется 🙂
esxcli сама по себе и есть обёртка. Чтоб не было “главного минуса скрипта” с нумерацией срок, достаточно глянуть help и увидеть:
–formatter=FORMATTER
Override the formatter to use for a given command.
Available formatter: xml, csv, keyvalue
Ну и других “оберток” можно на гитхабе найти…
Круто, не знал.