zabbix apiで情報を取得

Pythonでのzabbix apiのコントロールにチャレンジ
今回は情報の取得をやってみようと思います

Pythonですと便利なpyzabbixなどもありますが、
会社のサーバ環境でインストールに抵抗がある事を想定して
jsonとurllib2を使ってみました
また、できる方はモジュールにまで落とし込みをしたうえで使うと思いますが、
今回はそこまで実施しません

Python初心者のため作成にあたって先人の方の内容を参考にさせて頂きました
[参考にさせていただきました]
http://www.zumwalt.info/blog/2012/11/pyhtonでzabbix-apiを触ってみる/

#今回試しにやる事と想定
- インベントリの情報で備考（メモ書き）を有効活用してみる(同僚がやっていたのでアイデア拝借)
 - サーバログイン前に何か共有するメモ（自分の備忘録）がないかを確認（メモ書きをしっかりやる事が前提になるので有能ではないかも）

#Pythonスクリプト
動作は、zabbix2.0系、zabbix2.4系にて確認しました

##設定について
clientのurl部分はListenしているアドレスに書き換えてください
あとhttp or httpsの設定も忘れずに

##今回の中身
```インベントリ取得.py:
#!/usr/bin/python
# coding: utf-8

import os
import sys
import getpass
import json
import urllib2

if len(sys.argv) != 2 :
  print ' ERROR : Please check Search hostname.'
  print '  Usage: ' + os.path.basename(__file__) + ' [search hostname]'
  sys.exit()

client = 'https://127.0.0.1/zabbix/api_jsonrpc.php'
postheader = {'Content-Type': 'application/json-rpc'}

userid = raw_input('Please Enter Zabbix Web Account : ')
passwd = getpass.getpass('PASSWORD :')
while userid == '':
  print 'type the account.'
  userid = raw_input('Please Enter Zabbix Web Account : ')
while passwd == '':
  print 'type the password'
  passwd = getpass.getpass('PASSWORD :')

# auth
authquery = json.dumps({'jsonrpc':'2.0', 'method':'user.login', 'params':{'user':userid, 'password':passwd}, 'auth':None, 'id': 1})
authreq = urllib2.Request(client, authquery, postheader)

try :
  getauthresult = urllib2.urlopen(authreq).read()
  authresult = json.loads(getauthresult)

except Exception as e :
  print ' %s %s' % ('ERROR :',e)
  print '         Please check zabbix URL Setting or Others.'
  sys.exit()

if 'error' in authresult :
  print ' %s %s' % ('API Error :',authresult['error']['data'])
  sys.exit()

# query
## メソッドとパラメータ
# host.get : ホスト情報取得のメソッド
# output : Object properties to be returned.今ドキュメント見たらdefaultがextend
# filter : 'status:0' = 監視有効のホスト, 'host:[hogehoge]' 指定したホスト名でフィルタする
# inventory : インベントリ情報の項目の出力指定 extend = 全部表示
# 特定ホストのインベントリの取得だけであればfilterのhost,select inventoryのみで良さそうである
postquery = json.dumps({'jsonrpc':'2.0', 'method':'host.get', 'params':{'output':'extend', 'filter':{'status':'0', 'host':sys.argv[1]}, 'selectInventory':'extend'}, 'auth':authresult['result'], 'id':1})
postreq = urllib2.Request(client, postquery, postheader)
getpostresult = urllib2.urlopen(postreq).read()
postresult = json.loads(getpostresult)

# result is empty
if not postresult['result'] :
  print 'no such host.'
  sys.exit()

# result data export
info=[]
for data in postresult['result'] :
  if not data['inventory'] :
    print 'no such inventory .'
    sys.exit()
  info = data['inventory']['notes']

print '--------------------------------------------------'
print '%s%s%s%s%s' % ('# INFO ->  ', sys.argv[1], ' : ', '\n', info)
```

#実行テスト
- 各参照権限がついたアカウントを用意します（Adminとかでokですが）
- テスト用にインベントリ情報を記載 今回は備考(notes)を使います
![スクリーンショット 2016-10-20 1.19.32.png](https://qiita-image-store.s3.amazonaws.com/0/90309/6b3f6e76-dbfc-88e7-55ab-5f975e2f736a.png)

- スクリプトを叩く
`$ scriptname.py [検索対象ホスト名（zabbixに設定している）]`

```実行:
$ ./get.py test
Please Enter Zabbix Web Account : test
PASSWORD :
--------------------------------------------------
# INFO ->  test :
test test test
テストだって
aaaaaaaaaaa
```

出力はダサいですが、こんな感じで抜き出しができます
サーバにログインする前に毎回確認する事を癖付けすると便利になるかなーとか思いましたがルール化は難しい

##このスクリプト実行時のエラー
```:URLの指定が間違ってたりする場合:
$ ./get.py test
Please Enter Zabbix Web Account : test
PASSWORD :
 ERROR : <urlopen error [Errno 111] Connection refused>
         Please check zabbix URL Setting or Others.


$ ./get.py test
Please Enter Zabbix Web Account : test
PASSWORD :
 ERROR : HTTP Error 404: Not Found
         Please check zabbix URL Setting or Others.
```

```:アカウントかパスワードミス:
$ ./get.py test
Please Enter Zabbix Web Account :a
PASSWORD :
 API Error : Login name or password is incorrect.
```

```:インベントリが無効になってる、ホストが存在しない（権限が無く参照できない）:
$ ./get.py test1
Please Enter Zabbix Web Account : test
PASSWORD :
no such host.

$ ./get.py test2
Please Enter Zabbix Web Account : test
PASSWORD :
no such inventory.
```

当然ですがメソッドやパラメータを変える事によって色々取得できます
あと今回のInventory情報はselectInventoryで取得する項目の指定も出来た気がしますが
なぜか私は失敗した記憶があるのでextendにしてデータ加工しています