お勉強としてZabbix APIを使ったログイン・ログアウトをするだけの実装をGoでやってみたので備忘録メモ程度に書いておきます。
環境
サーバ情報
項目 | 内容・バージョン |
---|---|
OS | CentOS 7.4 |
Zabbix | 3.0.13-2 |
開発情報
項目 | 内容・バージョン |
---|---|
Go | 1.8.1 |
Zabbix APIドキュメント
https://www.zabbix.com/documentation/3.0/manual/api/reference/user/login
https://www.zabbix.com/documentation/3.0/manual/api/reference/user/logout
ソース
zbxapi
に login
と logout
と postReuquest
のメソッドを実装しています。
package main
import (
"crypto/tls"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"log"
"net/http"
"strings"
)
const (
// URL Zabbix API URL.
URL = "http://IP or FQDN/zabbix/api_jsonrpc.php"
// User Zabbix Login User.
User = "admin"
// Passwd Zabbix Login User Password.
Passwd = "zabbix"
)
// Zabbix API構造体
type zbxapi struct {
URL string
User string
Passwd string
Token string
}
// login Zabbix API ログインメソッド
func (z *zbxapi) login() error {
// ログインリクエスト用構造体
type data struct {
JSONRPC string `json:"jsonrpc"`
Method string `json:"method"`
Params struct {
User string `json:"user"`
Passwd string `json:"password"`
} `json:"params"`
ID int32 `json:"id"`
}
// ログインリクエストのレスポンス用構造体
type rdata struct {
JSONRPC string `json:"jsonrpc"`
Result string `json:"result"`
ID int32 `json:"id"`
}
// ログイン情報
d := new(data)
d.JSONRPC = "2.0"
d.Method = "user.login"
d.Params.User = z.User
d.Params.Passwd = z.Passwd
d.ID = 1
// JSONへ変換してリクエストを実行
req, err := json.Marshal(d)
if err != nil {
return err
}
r, err := z.postReuquest(string(req))
if err != nil {
return err
}
// レスポンスJSONをパースしてTokenを取得
rbody := new(rdata)
err = json.Unmarshal([]byte(r), rbody)
if err != nil {
return err
}
if rbody.Result != "" {
z.Token = rbody.Result
return nil
}
return errors.New("Error token not set")
}
// logout Zabbix API ログアウトメソッド
func (z *zbxapi) logout() {
// ログアウト用構造体
type data struct {
JSONRPC string `json:"jsonrpc"`
Method string `json:"method"`
Params struct{} `json:"params"`
ID int32 `json:"id"`
Auth string `json:"auth"`
}
// ログアウト用のレスポンス用構造体
type rdata struct {
JSONRPC string `json:"jsonrpc"`
Result bool `json:"result"`
ID int32 `json:"id"`
}
// ログアウト情報
d := new(data)
d.JSONRPC = "2.0"
d.Method = "user.logout"
d.ID = 1
d.Auth = z.Token
// JSONへ変換してリクエストを実行
req, _ := json.Marshal(d)
r, _ := z.postReuquest(string(req))
// レスポンスJSONをパースして結果を取得
rbody := new(rdata)
if err := json.Unmarshal([]byte(r), rbody); err != nil {
log.Fatal(err)
}
// ログアウトが失敗した場合
if rbody.Result != true {
log.Fatal("Logout fail")
} else {
fmt.Println("Logout success")
}
}
// postReuquest Zabbixサーバに対してPOSTを実行するメソッド
func (z *zbxapi) postReuquest(b string) (body []byte, err error) {
// クライアントを作成
c := createHTTPClient()
req, err := http.NewRequest("POST", z.URL, strings.NewReader(b))
if err != nil {
return nil, err
}
// ヘッダを追加
req.Header.Add("Content-Type", "application/json-rpc")
// リクエストを実行
res, err := c.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
// リクエストボディを戻す
body, err = ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
return body, nil
}
// createHTTPClient クライアント作成関数
func createHTTPClient() http.Client {
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true},
},
}
return *client
}
func main() {
// Zabbix にログイン・ログアウトするだけの処理
zapi := new(zbxapi)
zapi.URL = URL
zapi.User = User
zapi.Passwd = Passwd
if err := zapi.login(); err != nil {
log.Fatal(err)
} else {
fmt.Printf("Login success\n")
fmt.Printf("Token: %s\n", zapi.Token)
}
defer zapi.logout()
}
実行してみる
実行すると取得したTokenを表示してログアウトします。
$ go run main.go
Login success
Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Logout success
後は getReuquest
メソッドを実装すれば値取得も出来そうだけどリクエストするJSONが複雑な場合、どう構造体を実装すればいいんだろ...が、課題かなぁ。
圧倒的Goの経験不足(´・_・`)