LoginSignup
0
1

More than 5 years have passed since last update.

zabbix APIを使ったログイン・ログアウトをGoで実装してみた

Last updated at Posted at 2017-11-24

お勉強として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

ソース

zbxapiloginlogoutpostReuquest のメソッドを実装しています。

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の経験不足(´・_・`)

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1