Prim Pro(X-Play)とPythonで楽するなにか



# Prim Pro(X-Play)とPythonで楽するなにか
* 本記事は[Nutanix Advent Calendar 2020](https://adventar.org/calendars/4998)の17日目の記事です。
* キーワード：Nutanix, python, X-Play, 自動化

## はじめに
* 最近、作業後にNutanixの正常性を取得するとか何かと同じコマンドを打つことが多かったのでスクリプト化していました。
* そのスクリプトとPrism ProのX-Playとを組み合わせてもっと楽しようという考えです。
* この内容を見てPrism Proとスクリプトの連携のイメージをもってもらえると嬉しいです

## やりたいこと
* Nutanixでアラートが発生したら自動でCVMから各種情報を取ってくる。
* つまりX-Playからスクリプトをキックする
* ↓こんな結果を自動で取って欲しいのです。どうせサポートに取れって言われるし

```
===========< id
uid=1000(nutanix) gid=1000(nutanix) groups=1000(nutanix),160(snmp),600(java),990(docker)context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

===========< uname -a
Linux ntnx-20sm6k250202-c-cvm 3.10.0-1062.12.1.el7.nutanix.20200216.cvm.x86_64 #1 SMP Sun Feb 16 07:02:50 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

===========< hostssh date
============= 10.55.87.27 ============
Sat Dec 12 11:17:09 UTC 2020
============= 10.55.87.25 ============
Sat Dec 12 11:17:10 UTC 2020
============= 10.55.87.26 ============
Sat Dec 12 11:17:10 UTC 2020

===========< hostssh uptime
============= 10.55.87.27 ============
 11:17:12 up 1 day,  9:40,  0 users,  load average: 1.90, 2.36, 2.38
============= 10.55.87.25 ============
 11:17:12 up 1 day,  9:41,  0 users,  load average: 6.04, 6.07, 5.98
============= 10.55.87.26 ============
 11:17:12 up 1 day,  9:41,  0 users,  load average: 1.47, 1.69, 1.80

===========< ncli cluster info
    Cluster Id                : 0005b626-72dd-8051-3f5b-ac1f6b3d7d4b::4565431898213285195
    Cluster Uuid              : 0005b626-72dd-8051-3f5b-ac1f6b3d7d4b
    Cluster Name              : RTP-POC087
    Cluster Version           : 5.15
    Cluster Full Version      : el7.3-release-euphrates-5.15-stable-4fbdd4d9de331230bb468b3549f530e80ab53bb9

・・・ 以下略
```

## X-Playとは
* その前に
* X-Playはお手軽なオートメーションを実現する運用支援機能の一つで、Prism Proライセンスにて提供される機能です
* Prism Proでは運用が楽になる機能が満載です。
* この図のような課題を解決してくれます。今日はその中の赤で囲った自動化について。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543420/7be3f648-0d83-a900-2726-31294752cf16.png)

## X-Playの設定方法イメージ
* X-Playの設定イメージについてはこのあたりの動画がデモとしてはイメージできるかも。ノンコーディングで自動化の仕組みを作れるのがいいですね。
  * https://www.youtube.com/watch?v=UmAWG0UHpuU
  * 英語分からなくてもなんとなくわかるのがNutanixのいいところ。


* X-PlayはNutanix上のアラートやスケジュールをトリガーにしていろいろなアクションを自動的に行うことができます。また、それを組み合わせることができます。
* いろいろとは（代表的なもの）。できることは日々増えています。さっき見たらまた増えてた。
  * VMの電源ON / Off
  * VMのSnapshot取得
  * リソースの追加や削除
  * メール送信 / Slackへの通知
  * レポート作成
  * などなど
* さらに下記にようにスクリプトも実行できるので組み合わせ次第でなんでもできますね。ですのでLinuxの場合はsshからコマンド。Windowsの場合はPowershellを実行できる感じなので、その中でpythonをキックすればよろし。
  * SSHしてコマンド実行
  * Powershellの実行
  * REST APIの実行
* 下図は「VMのCPU使用率のアラート」が上がったら「バックアップ（スナップショット）を取って」、「CPUを追加」して、「管理者へメール」するプレイブックとなります。

* こんなアクション一覧からポチポチするだけで
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543420/b7b680c4-18c2-bdaf-8230-36147b3f8d7b.png)

* こんなフローが出来ます。超簡単。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543420/564cef4d-11d9-38f3-89c3-68d4699f9b61.png)


## スクリプト連携（Powershell)
### 取得したいコマンド一覧
* では、スクリプト連携するスクリプトを作成しましょう。
* ここではよくAOSで実行するコマンドを、トリガーに合わせて取ってきたいと思います。
* 一気に取りたいコマンド （繰り返しですが）

```
id
uname -a
hostssh date
hostssh uptime
ncli cluster info
ncli host ls
ncli cluster get-domain-fault-tolerance-status type=node
ncli alert history duration=14
ncli license get-license
ncli license get-allowances
cluster status
zeus_config_printer
```

* 他にも取りたいものがあったがPythonのParamikoだと環境変数が取れない？のかうまく取れないコマンドもありました。`nodetool -h 0 ring`とか。
* フルパスで書かないといけないとか。
* うーん、未完全
* 結局フルパスで書いてこんなリスト。うーん。 まぁせっかくなので作っていきましょう

```
id
uname -a
/usr/local/nutanix/cluster/bin/hostssh date
/usr/local/nutanix/cluster/bin/hostssh uptime
/home/nutanix/prism/cli/ncli cluster info
/home/nutanix/prism/cli/ncli host ls
/home/nutanix/prism/cli/ncli cluster get-domain-fault-tolerance-status type=node
/home/nutanix/prism/cli/ncli alert history duration=14
/home/nutanix/prism/cli/ncli license get-license
/home/nutanix/prism/cli/ncli license get-allowances
/usr/local/nutanix/cluster/bin/cluster status
/usr/local/nutanix/bin/zeus_config_printer
```



### 実行するスクリプト
* スクリプト概要
  * リストに記載のコマンド一覧をNutanixのクラスターから取得してくる
* 以前作ったスクリプトを流用 https://qiita.com/matsumo2019/items/0713dd70bcdc91e2690f このページを参考に準備する。
* 準備項目（超省略）
  * Pythonのインストール
  * paramikoのインストール
  * 作成するスクリプト（上記の記事を参考に。スクリプトは最後に乗せてます。）
    * get-cvm.py   　			：メイン処理
    * my_command.py ：paramikoの処理をクラス化したもの
    * common.json   （設定ファイル。CVMのIP, ID, パスワード）
    * command_list.txt （実行するコマンド一覧を書く） ※基本的にこのファイルのみを編集する

* ちなみにPython触ったことが無かったのですが、この本見たら作れました。
  * たった 1日で基本が身に付く！ Python超入門 https://a.r10.to/hbHMiv

### 各種スクリプトの配置
* 今回はなぜかWindowsで確認しました。
* 下記の手順
  * Pythonのインストール
  * pipでparamikoのインストール
  * 各種スクリプトの配置（C:\scripts におきました）
* Windowsの場合はPowershellをリモートから実行できるようにしておいてください。

## X-Playの設定（Prism Central)
* 設定の流れ
  * Prism Centralから「メニュー」>「オペレーション」＞「プレイブック」
  * 「プレイブックの作成」
    * トリガーの選択・設定
    * アクションの選択・設定
    * アクションの追加を繰り返す
* 具体的な設定画面です。
    * 「プレイブックの作成」
        * デフォルトでいくつか作成されていますので参考にすることもできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543420/a0eed059-5923-c93f-286e-22eae7bd981c.png)
    * 「トリガーの選択」
        * 「Alerts Matching Criteria」を選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543420/79694e88-70b6-07c3-5c7a-603d6d0a3dff.png)
    * 「トリガーの選択」
        * 「Alerts Matching Criteria」を選びアラート条件を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543420/173e10f8-4de1-3e95-f295-2b436d0124a6.png)
    * 「アクションの選択」
        * 「VM Powershell」を選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543420/b0a417ac-9593-6e6e-95da-55956f6dad50.png)
    * 下記を設定します。
        * Target VM：スクリプトを実行するサーバ
        * Username
        * Password
        * Path to Script：実行するサーバ上のスクリプトをパスを含めた形式で指定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543420/cce0e886-3aed-859d-9a9c-a87fac34dc94.png)
    * 保存しプレイブック名を付けて保存します。
    * すぐに有効化する場合はステータスを有効にします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543420/d5f53393-157a-4884-6ebe-5d5ca5163631.png)

* 以上でX-Playの設定は完了です。




## X-PlayからPowershellを呼び出した結果
* アラートをトリガーにコマンド結果が取得できました。
* 実行結果（Prism Central側）
    * プレイブックの実行結果やエラーなどが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543420/cc588180-7b2e-dee0-c59b-d1ae9eec6d15.png)
    * エラーも見れます。このケースではうまく接続できてない（Windows Firewallでした。。。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543420/cf3c585d-75b8-c26d-2255-ae83de218f84.png)


* 実行結果（スクリプトサーバ側）
    * こんな感じでイベントが起きたら実行結果を自動で保存してくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543420/c013b1e5-7af5-e488-ca97-a1a22d9214b8.png)
    * その実行結果のファイルの中身（期待通り）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543420/360f79a8-6def-0c59-a8db-09b953bd4616.png)




## まとめ

* Prism ProのX-Playを使うとノンコーディングで自動化の仕組みが作れます。（ここで書いた内容よりもっともっと簡単です）
* 自前のスクリプトと組み合わせると処理は無限に広がります。
* みなさん、毎回手動でコマンド発行してませんか？私はしてませんPrism Proがあるから。



## おまけ。実際のスクリプト

* command_list.txt
  * このテキストを編集すればいろんなコマンドの結果が取得できます。

```
id
uname -a
/usr/local/nutanix/cluster/bin/hostssh date
/usr/local/nutanix/cluster/bin/hostssh uptime
/home/nutanix/prism/cli/ncli cluster info
/home/nutanix/prism/cli/ncli host ls
/home/nutanix/prism/cli/ncli cluster get-domain-fault-tolerance-status type=node
/home/nutanix/prism/cli/ncli alert history duration=14
/home/nutanix/prism/cli/ncli license get-license
/home/nutanix/prism/cli/ncli license get-allowances
/usr/local/nutanix/cluster/bin/cluster status
/usr/local/nutanix/bin/zeus_config_printer
```



* cvm_info.json
  * CVMへの接続情報をJSON形式で書いてます。おっとーID/パスワード直書き

```
{
	"cluster_address": "10.55.87.31",
	"user_name": "nutanix",
	"cvm_password": "nutanix/4u"
}
```

* get_cvm_cmd.py
  * メイン処理の子。この子を呼び出してください。コメントからなんとなく読み取ってください。

```python
import json
import my_command

# ファイルの読み込み
fin = open('command_list.txt', 'r')
json_open = open('cvm_info.json', 'r')

# コマンドリストの読み込み
fin = open('command_list.txt', 'r')
command = fin.readlines()
fin.close()

# サーバ情報の読み込み
sv_info = json.load(json_open)
cluster_ip = sv_info['cluster_address']
user_name = sv_info['user_name']
password = sv_info['cvm_password']

## コマンド実行（メイン処理）
def main():
	for name in command:
		print('===========<', name)
		remote_obj = my_command.RemoteCommand()
		ret = remote_obj.get_df(cluster_ip, user_name, password, name)
		print(ret)

## メイン処理（おまじない）
if __name__ == '__main__':
  main()


```



* my_command.py
  * paramiko（sshしてくるPythonのライブラリ）の処理をクラス化したもの。

```
import paramiko

class RemoteCommand:
	def get_df(self, 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, get_pty=True)
  		output = stdout.read().decode()
  		client.close()
   	
   	    return output
```



* get_cvm_cmd.ps1
  * X-Playからは Pythonが直接読めないのでpowershellで呼び出そうとしました。
  * がPowershellで日付操作がよくわからんかったのでさらにbatを読んでやりました。

```
cmd.exe /c "c:\scripts\get_cvm_cmd.bat"
```



* get_cvm_cmd.bat
  * 一意なログファイルに書き出したかったので
  * 結局最後のコマンド打ちたいだけ。

```
@echo off
set yyyy=%date:~0,4%
set mm=%date:~5,2%
set dd=%date:~8,2%
 
set time2=%time: =0%
 
set hh=%time2:~0,2%
set mn=%time2:~3,2%
set ss=%time2:~6,2%
 
set filename=%yyyy%-%mm%%dd%-%hh%%mn%%ss%
 
cmd.exe /c "c:\scripts\get_cvm_cmd.py > logs\log_%filename%.txt
```



* 配置場所
  * 同じところに置いただけです。


* 反省
    * 環境変数がセットできなかったので、フルパスで書いたり、allsshとか使えてなくて恥ずぃ。 
    * Powershellのあたり、手を抜いてしまった...。恥ずぃ
    * 誰か教えてー