メインコンテンツへスキップ
  1. Blogs/

pyvmomiで自動化2 -vCenterにアクセス-

·3692 文字·
Blog VMware VSphere Pyvmomi Python
hiroki
著者
hiroki
クラウドを作るお仕事をしてます。
目次
pyvmomi - 関連記事
2: << この記事 >>

はじめに
#

第1回では、pyvmomiを使う前準備としてManagement Object Browser(MOB)について解説しました。

今回は実際にpyvmomiを利用してvCenterにアクセス + 各オブジェクトを触ってみます。

1. pyvmomiとは?
#

pyvmomiはvSphereを操作できるSDKで、pythonを使用してvSphereの自動化を実施するにはこちらを使うことになります。

pyvmomiのメリットしては、

  • 利用ユーザーの多いpythonでvSphereの自動化を実施できる。
  • Ansible等の操作内容が定まっている自動化ツールよりも、pythonで自由にコードを記載できるので柔軟な操作できる。
  • 非常に広範囲のAPIをカバーしており、vSphereで実施するほぼ全ての作業がpyvmomiから実施できる。

があります。

特にpythonで自由にコードを記述できるのが便利で、膨大なVMのデータをpandas(pythonのデータ分析ライブラリ)で解析をよく実施しています。

vmware/pyvmomi

VMware vSphere API Python Bindings

Python
2204
766

2. pyvmomiのinstall
#

pipを使用してinstallだけでOKなので、非常に簡単です。

pip install pyvmomi
本記事ではpyvmomi>=7.0(vSphere7以上)を対象に解説します。 しかし後方互換性があるので最新のpyvmomi8.0を使用しても、vSphere6.5まではほとんどの機能が動きます。詳細はpyvmomiの公式HP を参照ください。

3. vCenterにアクセスする
#

まずはpyvmomiでvCenterに接続して、MOBのtopであるServiceInstanceを取得します。

vCenter接続用の関数pyVim.connect.SmartConnectを使います。問題なく接続できるとServiceInstanceのオブジェクト名vim.ServiceInstance:ServiceInstanceがprintされます。

# pyvmomiには2つのパッケージpyVimとpyVmomiが存在するが、今回はvCenterに接続するためのconnectパッケージが存在するpyVimをimport
from pyVim import connect

# ServiceInstanceはsiとよく略される
si = connect.SmartConnect(
    host="***",  # vCenter/ESXiのip, fqdn
    user="***",  # vCenterにloginするuser
    pwd="***",   # vCenterにloginするpassword
    disableSslCertValidation=True # 証明書チェックをしない(vCenterが発行したオレオレ証明書なので)
)
print(si)
# >>> 'vim.ServiceInstance:ServiceInstance'

pyvmomiでは900s経過すると自動でsessionがcloseします。その場合は再度connect.SmartConnectを使うか、connectionPoolTimeout=で指定しましょう。

si = connect.SmartConnect(
    host="***",  
    user="***",  
    pwd="***",   
    disableSslCertValidation=True
    connectionPoolTimeout=1200 # 単位は秒

pyvmomi<=7.0.3までは証明書確認skip専用のSmartConnectNoSSLも存在しましたが、pyvmomi>=8.0.0から削除されました。webで公開されているsampleにはこのSmartConnectNoSSLを使っている例も多いので注意してください。

もしvCenterにアクセスできないときは以下のエラーが出ますので、確認して対処をしましょう。

# login情報が間違っている
vim.fault.InvalidLogin:       Traceback (most recent call last)
   dynamicProperty = (vmodl.DynamicProperty) [],
   msg = 'Cannot complete login due to an incorrect user name or password.',
   faultCause = <unset>,
   faultMessage = (vmodl.LocalizableMessage) []

# vCenterに疎通できない場合(ip間違えなど)
OSError: [Errno 113] No route to host

4. ServiceInstanceを細かくみる
#

上記で取得したvim.ServiceInstance:ServiceInstanceですが、このままではオブジェクト名しか表示されないので以下コマンドを実行します。

print(dir(si))
# >> ['Array',
#     'CurrentTime',
#     'QueryVMotionCompatibility',
#     'RetrieveContent',
#     '__class__',
#     '__delattr__',
#     '__dict__',
#     '__dir__',
#     '__doc__',
#     '__eq__',
#     '__format__',
#     '__ge__',
#     '__getattribute__',
#     ...
#     '_version',
#     '_wsdlName',
#     'capability',
#     'content',
#     'serverClock']
dir()関数はpythonの標準ライブラリで、オブジェクトが持つ変数やメソッドをリストで出力してくれる。

これだと_から始まるprivateな変数も出力され分かりにくいので、publicな変数だけにするとMOBのProperties, Methodsと一致することがわかります。

public_attributes = [
    attr 
    for attr in dir(si)
    if not attr.startswith('_')
]
print(public_attributes) # MOBのSerivceInstanceと一致する!!
# >>> ['Array',
#     'CurrentTime',
#     'QueryVMotionCompatibility',
#     'RetrieveContent',
#     'RetrieveProductComponents',
#     'RetrieveServiceContent',
#     'ValidateMigration',
#     'capability',
#     'content',
#     'serverClock']

img001

このようにpyvmomiではMOBの情報を取得することができます。これが第1回でも紹介したMOBの重要性で「MOBで欲しい情報を見つける」→「pyvmomiで取得する」というのが基本のpyvmomiの扱い方になります。

5. 実際にデータを取得する
#

pyvmomiとMOBの繋がりが分かったので実際にMOBのデータをpyvmomiで取得してみます。

si
#

# MOBのPropertiesは変数なので、`si.serverClock`のように指定するだけOK
print(si.serverClock)
# >>> 2024-05-02 13:09:22.257361+00:00

# MOBのMethodsは関数なので、`si.CurrentTime()`のように`()`や引数が必要です。
print(si.CurrentTime())
# >>> 2024-05-02 13:20:26.999703+00:00

si.content
#

ServiceInstance → contentに進むと画像のように多くのPropertiesが確認できます。ここがMOBの中でも最重要なデータ群になり、基本的にどんな作業をするにもまずはsi.contentにアクセスすることになります。いくつか抜粋した項目が以下表です。

name pyvmomiのpath 説明
about si.content.about vCenterのverなど、vCenterに関するデータが記載
alarmManager si.content.alarmManager alarm定義や新規alarm作成など、alarmに関するデータ・関数が記載
rootFolder si.content.rootFolder 最重要 vCenterのインベントリーツリーのTOPに該当(ESXiやVMなどオブジェクトとTOPに該当)

img002

siと同様にpyvmomiでも同じPropertiesが取得できることが分かります。

public_attributes = [
    attr 
    for attr in dir(si.content)
    if not attr.startswith('_')
]
print(public_attributes)
# >>>['Array',
#     'about',
#     'accountManager',
#     'alarmManager',
#     'authorizationManager',
#     'certificateManager',

si.content.about
#

ServiceInstance → content → aboutと進むと先ほど解説したように、vCenterの情報が取得できるようになります。

print(si.content.about)

# >>>(vim.AboutInfo) {
#       dynamicType = <unset>,
#       dynamicProperty = (vmodl.DynamicProperty) [],
#       name = 'VMware vCenter Server',
#       fullName = 'VMware vCenter Server 7.0.3 build-20150588',
#       ### 省略 ###
#    }
si.content.aboutではprintすると中身が表示されように、pyvmomiでは「オブジェクトの名前だけ表示」、「オブジェクトの中身を表示」する2パターンが存在します。あまり法則性はなさそうなので、オブジェクトはこまめにprintして中身を確認すると良いでしょう。

img003

si.content.rootFolder
#

ServiceInstance → content → rootFolderと進むと、最重要オブジェクトであるrootFolderに辿り着くことができます。これはvCenterではインベントリツリーのTOPに該当し、VM,ESXi,Cluster,Datastore,Network等のオブジェクトにアクセスする際の入り口になります。

詳しくは第1回の「フォルダ階層を辿る」を参考ください。

pyvmomiで自動化1 -MOBを触ってみよう-
·2382 文字
Blog VMware VSphere Pyvmomi Python

6. ESXiを取得してみる
#

ここまでpyvmomiの使い方が分かったと思うので、ちょっと難解なESXiのオブジェクトの取得を実施してみます。

まずはrootFolderを経由して、Datacenterの1階層下(cluster)まで取得します。

ここからはcodeが各vCenterのインベントリーツリーに依存します。
from pyVim import connect

si = connect.SmartConnect(
    host=vc_ip,
    user=vc_usr,
    pwd=vc_pwd, 
    disableSslCertValidation=True
)

# まずはrootFolderにアクセス
print(si.content.rootFolder)
# >>> 'vim.Folder:group-d1'

# childEntityで1階層下がるとDatacenterが取得できる
print(si.content.rootFolder.childEntity)
# >>> (ManagedObject) [
#    'vim.Datacenter:datacenter-3'
# ]

# Datacenterを[0]で選び、その後ESXiを取得したいのでhostFolderを選択
print(si.content.rootFolder.childEntity[0].hostFolder)
# >>> 'vim.Folder:group-h5'

# hostFolderから1階層下がるとClusterが取得できた。(各vCenterのツリーに依存する)
print(si.content.rootFolder.childEntity[0].hostFolder.childEntity)
# >>>(ManagedObject) [
#    'vim.ClusterComputeResource:domain-c10',
#    'vim.ClusterComputeResource:domain-c8'
# ]

# moid(domain-c10)では分かりにくいので、<object>.nameで名前をprint (MOBにはnameも併記されているので分かりやすい。)
for cluster in si.content.rootFolder.childEntity[0].hostFolder.childEntity:
    print(f"{cluster}:{cluster.name}")
# >>>'vim.ClusterComputeResource:domain-c10':v_cluster
# >>>'vim.ClusterComputeResource:domain-c8':p_cluster


ここからv_cluster内のv10-nesxi-01.lab.localを取得します。

# clusterを[0]で選んで、その中のhostを表示する
print(si.content.rootFolder.childEntity[0].hostFolder.childEntity[0].host)
# >>> (ManagedObject) [
#    'vim.HostSystem:host-40',
#    'vim.HostSystem:host-43',
#    'vim.HostSystem:host-45'
# ]

# 同様にnameを表示
for host in si.content.rootFolder.childEntity[0].hostFolder.childEntity[0].host:
    print(f"{host}:{host.name}")
# >>>'vim.HostSystem:host-40':v10-nesxi-01.lab.local
# >>>'vim.HostSystem:host-43':v10-nesxi-02.lab.local
# >>>'vim.HostSystem:host-45':v10-nesxi-03.lab.local

# 取得したいhostを選んで、hostオブジェクトの取得完了
host = si.content.rootFolder.childEntity[0].hostFolder.childEntity[0].host[0]
print(host)
# >>>'vim.HostSystem:host-40'

img006

7. おわりに
#

pyvmomiの基礎である、vCenterへの接続、任意のオブジェクトの取得方法は分かりましたでしょうか?

  • 第3回はESXiオブジェクトに簡単な命令(ESXiにメンテナンスモード切り替え等)を実施する方法
  • 第4回はVMオブジェクトに簡単な命令(powerON/OFF)を実施する方法

について解説します。

またMOBの構造が複雑であるため、pyvmomiでも階層構造を地道に探索してオブジェクトの取得をするのが大変でした。更に特定のオブジェクトを取得するのではなく、状況に応じて動的に探す場合にはこの手法が使えません。

こちらも実用的な解決策があるので第5回で紹介したいと思います。

pyvmomi - 関連記事
2: << この記事 >>

Related

pyvmomiで自動化1 -MOBを触ってみよう-
·2382 文字
Blog VMware VSphere Pyvmomi Python
ansibleでvyosのclone
·1307 文字
Blog VMware VSphere Ansible Python
ESXiを自動でインストール
·3901 文字
Blog VMware VSphere RedfishAPI Python Kickstart Ansible