2020年12月14日月曜日

Pythonを使って、NutanixクラスタにVMイメージをUploadしてみる。

event_note12月 14, 2020 editBy m.o forumNo comments

はじめに

この記事はNutanix Advent Calendar 2020の12月15日分として執筆しました。

こんにちは!Nutanix Advent Calendar初参加です!今回はPythonを使ってNutanixクラスタ上にイメージをアップロードする手順のご紹介です。

Nutanixのクラスタへイメージのアップロード

Nutanix環境を使っていると、繰り返し行う作業をまとめて1回で実行したいシーンありますよね? 例えば、仮想マシンのベースイメージやISOファイルをまとめて、Image Congigurationにアップロードしたい! 私の場合、Foundation後に同じイメージをアップロードするケースが多々あるので、Pythonで少しだけ楽をしたいと思います。 そのような悩みをお持ちの皆様の助けになれば幸いです。



NutanixのREST APIの仕様確認

NutanixのサイトからREST APIの仕様を確認します。 今回は、API V2を利用します。以下、リンクより仕様の確認が可能です。

Nutanix RESTAPI V2

また、PrismからもAPIの仕様を確認することができます。 これは、超便利!!Prismの右上のユーザーをクリックすると表示されます。

Nutanix API V2

ImageをPOSTするには、Bodyに下記のパラメーターを埋め込む必要があります。

"name": "イメージの名前"

"annotation": ""

"image_type": "DISK_IMAGE or ISOイメージ"

"image_import_spec": {

"storage_container_uuid": コンテナのUUID

"url":  ”HTTP or NFS Target”

}

では、上記内容を元にコードの作り込みに入っていきたいと思います。



環境準備

今回実行した環境は以下の通りです。

・python 3.7

・Hypervisor AHV(20170830.453)

・AOS(5.15.3)

・Webサーバー(NFSも可)

コードの作成

必要なパラメータの中で、Foundation後に毎回変わるパラメータが、コンテナのUUIDになります。 今回は、defaultで作成されるコンテナに、VMイメージをアップロードしますので、そのUUIDを取得する必要があります。 コンテナのUUIDの取得方法については、一番簡単な、ncliから取得する形で実装しました。 REST APIから、取得する方法もありますが、コマンドで実装されている部分は、コマンドで取得した方が楽かなと思ったので、、、ここの選択には好みもあるかなーと。 コマンドの出力をjsonにて出力するため、オプションを追加します。


ncli container list --json=true


sshのアクセス方法として、paramikoモジュールを使いました。 では、コンテナのUUIDを取得してみます。 コードについては、下記の通りです。

コンテナUUIDの取得

import paramiko,json

#パラメーター
user = "admin"
new_password = "xxxxxxx"
IP = "172.29.161.60"


def exec_command(ip, user, password, command):
    client = paramiko.SSHClient()
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    client.connect(ip, username=user, password=password, timeout=3.0)
    (stdin, stdout, stderr) = client.exec_command(command)
    output = stdout.read().decode()
    client.close()
    return output

#ncliをjsonで出力
container = exec_command(IP, user, new_password,"source /etc/profile; ncli container list --json=true")
containerdict = json.loads(container)
containernames =  containerdict["data"]
for i in containernames:
    if "default" in i["name"]:
        container_name = i["name"]
        container_uuid = i["containerUuid"]
print(container_uuid)

無事UUIDゲットできましたー!

[root@localhost ~]#python3 Image_Post_v3.py
513cc828-3868-4eea-8349-xxxxxxxxxxxxx

イメージをUploadする方法

次に、イメージをUploadする方法です。 パラメータはコード内に組み込みました。 別ファイルに保存して読み込む形もありです。 urlには、イメージがdownload可能なURLを指定します。

import json,requests,urllib3
from urllib3.exceptions import InsecureRequestWarning
urllib3.disable_warnings(InsecureRequestWarning)

#パラメーター
user = "admin"
new_password = "xxxxxxxxxxx"
IP = "172.29.161.60"
centvm = "http://172.29.30.11/iso/centos7-1.qcow2"

#ImagePost_Body
centvm_dict = {
    "name": "CentOS7",
    "annotation": "",
    "image_type": "DISK_IMAGE",
    "image_import_spec": {
    "storage_container_uuid": container_uuid, ←取得したコンテナのUUID
    "url": centvm,←VMイメージがダウンロード可能なURL
    }
}

#make session 
session = requests.Session()
session.auth = (user, new_password)
session.verify = False                 
session.headers.update({'Content-Type': 'application/json; charset=utf-8'})

response = session.post('https://172.29.161.60:9440/api/nutanix/v2.0/images/',data=json.dumps(centvm_dict, indent=2))
if response.ok:
    print("centos7 Upload is ok")
else:
    print("centos7 Upload is fault")

以上で、VMののアップロードができました!

[root@localhost ~]#python3 Image_Post_v3.py
centos7 Upload is ok

GUIでも確認してみると、ちゃんとアップされていることが確認取れました。

手動でイメージをアップロードする際は、パラメータを複数入力する必要があるため、 同じようなイメージを何度も入れる場合は、是非こちらを使ってみてください。以上です! 最後まで、読んで頂きありがとうございました。