LoginSignup
3
0

More than 5 years have passed since last update.

Cisco IMC(CIMC)のエミュレータにGoでAPIを実行してみた

Last updated at Posted at 2017-10-09

Cisco IMC(CIMC)1 のEmulatorをインストールしてpythonからログイン・ログアウトのAPIを実行してみたのですが、XMLや構造体(メソッド)などの勉強としてGoでも同じことをやってみたので備忘録として書いておきます。

CIMC Emulatorインストールについて

CIMCやインストール方法については以下を参照ください。

CIMC API Document

CIMCのAPIを使いたかったきっかけ

CIMC経由でサーバの監視や管理を自動化したかった

GoでCIMCにログイン・ログアウト

ソース

package main

import (
    "crypto/tls"
    "encoding/xml"
    "fmt"
    "io/ioutil"
    "net/http"
    "os"
    "strings"

    "github.com/urfave/cli"
)

// ログインのXML構造体
type aaaLogin struct {
    InName     string `xml:"inName,attr"`
    InPassword string `xml:"inPassword,attr"`
}

// ログアウトのXML構造体
type aaaLogout struct {
    Cookie   string `xml:"cookie,attr"`
    InCookie string `xml:"inCookie,attr"`
}

// Login CIMCへログインしてCookieを取得するメソッド
func (data *aaaLogin) Login(url string) (cookie string, err error) {
    // ログインレスポンスのBodyで得られるXMLの構造体
    type aaaLogin struct {
        Cookie           string `xml:"cookie,attr"`
        Response         string `xml:"response,attr"`
        OutCookie        string `xml:"outCookie,attr"`
        OutRefreshPeriod int32  `xml:"outRefreshPreiod,attr"`
        OutPriv          string `xml:"outPriv,attr"`
        OutSessionID     int32  `xml:"outSessionId,attr"`
        OutVersion       string `xml:"outVersion,attr"`
    }

    // ログイン用XMLに変換
    reqXML, err := xml.Marshal(data)
    if err != nil {
        return "", err
    }

    // Bodyを取得
    body, err := PostRequest(url, reqXML)
    if err != nil {
        return "", err
    }

    // Cookieを戻す
    resData := new(aaaLogin)
    if err := xml.Unmarshal(body, resData); err != nil {
        return "", err
    }
    return resData.OutCookie, nil
}

// Logout CIMCからログアウトするメソッド
func (data *aaaLogout) Logout(url string) (status string, err error) {
    // ログアウトレスポンスのBodyで得られるXMLの構造体
    type aaaLogout struct {
        Cookie    string `xml:"cookie,attr"`
        Response  string `xml:"response,attr"`
        OutStatus string `xml:"outStatus,attr"`
    }

    // ログアウト用XMLに変換
    reqXML, err := xml.Marshal(data)
    if err != nil {
        return "", err
    }

    // Bodyを取得
    body, err := PostRequest(url, reqXML)
    if err != nil {
        return "", err
    }

    // OutStatusを戻す
    resData := new(aaaLogout)
    if err := xml.Unmarshal(body, resData); err != nil {
        return "", err
    }
    return resData.OutStatus, nil
}

// PostRequest CIMCにPostリクエストを実行する関数
func PostRequest(url string, reqXML []byte) (body []byte, err error) {
    // HTTPクライアントを作成、SSL証明書の検証はスキップ
    client := &http.Client{
        Transport: &http.Transport{
            TLSClientConfig: &tls.Config{
                InsecureSkipVerify: true},
        },
    }

    // リクエストを作成
    req, err := http.NewRequest("POST", url, strings.NewReader(string(reqXML)))
    if err != nil {
        return nil, err
    }
    // ヘッダ追加
    req.Header.Add("content-type", "application/x-www-form-urlencoded")

    // リクエストを実行
    res, err := client.Do(req)
    if err != nil {
        return nil, err
    }
    defer res.Body.Close()

    // 取得したBodyを戻す
    body, err = ioutil.ReadAll(res.Body)
    if err != nil {
        return nil, err
    }
    return body, nil
}

func doMain(c *cli.Context) {
    // CIMCへログイン
    login := new(aaaLogin)
    login.InName = c.String("user")
    login.InPassword = c.String("password")
    cookie, _ := login.Login(c.String("url"))
    fmt.Println("cookie: " + cookie)

    // CIMCからログアウト
    logout := new(aaaLogout)
    logout.Cookie = cookie
    logout.InCookie = cookie
    status, _ := logout.Logout(c.String("url"))
    fmt.Println("Logout: " + status)
}

func main() {
    app := cli.NewApp()
    app.Name = "cimc_login_logout"
    app.Usage = "CIMCログイン,ログアウトツール"
    app.UsageText = "cimc_login_logout [--url CIMC URL] [--user CIMC USER] [--password CIMC USER PASSWORD]"
    app.Version = "0.1"
    app.Flags = []cli.Flag{
        cli.StringFlag{
            Name:  "url",
            Value: "https://127.0.0.1/nuova",
            Usage: "CIMC URL",
        },
        cli.StringFlag{
            Name:  "user, u",
            Value: "admin",
            Usage: "CIMC Login User.",
        },
        cli.StringFlag{
            Name:  "password, p",
            Value: "password",
            Usage: "CIMC Login User Password.",
        },
    }
    app.Action = doMain
    app.Run(os.Args)
}

実行

[root@localhost ~]# go build -o cimc_login_logout main.go
[root@localhost ~]# ./cimc_login_logout --url https://192.168.1.54/nuova
cookie: 1507529279/7cd516ac-5b17-1b17-800d-ee768522e470
Logout: success

できた :-)

CIMCの管理構造について

CIMCの管理モデルはツリー構造化されています。
Emulatorで起動したUCS C220 M4の全ツリー構造については参考までに以下に保存してあります。

CIMC MIM XML構造

XMLだと見にくいのでJSONに変換してみました。

CIMC MIM JSON構造


  1. Cisco UCS Cシリーズの管理コントローラー、HPだとiLo 

3
0
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
3
0