シスコサポートコミュニティ
キャンセル
次の結果を表示 
次の代わりに検索 
もしかして: 

NSO: JSON-RPC API について

 

 

JSON-RPCとは

JSON-RPC は、NSO がサポートする Northbound APIs の一つで、クライアントはHTTP(S)  を使用して、NSOを操作することが出来ます。REST API と違い、一つのセッション(或いは、トランザクション) 内で複数のコマンドを実行することが可能です。

Remote Procedure Call (RPC) としては、歴史的に多くの方法が使用されてきました。XML-RPCが1990年代後半に使用され始め、その拡張としてSOAPが存在します。JSON-RPC は 2000年半ばに使われ始め、これら他のRPCと考え方は同じです。

JSON-RPC は、現在その仕様は バージョン 2.0 が最新となっています。詳細については、以下をご確認ください。

JSON-RPC 2.0 Specification

NSOにおけるJSON-RPC

JSON-RPC では、その Transport 層の仕様については定められていません。NSOで使用する JSON-RPC では、多くの実装でも使用されているように、HTTP(S) 上でPayloadの送受信が行います。

Payloadの中身は、一般的な JSON-RPC と同様、以下の様になります。

リクエスト:

{
"jsonrpc": "2.0",
"method": "XXXXX",
"params": {
"param1": XXXXX,
"param2": XXXXX
},
"id": XXXXX
}

 

レスポンス(正常時):

{
"jsonrpc": "2.0",
"result": XXXXX,
"id": XXXXX
}

レスポンス(エラー):

{
"jsonrpc": "2.0",
"error": {
"code": XXXXX,
"message": XXXXX,
"data": XXXXX,
"type": XXXXX
},
"id": XXXXX
}

type フィールドは、NSOが独自に決めたアプリケーションエラー(code = -32000) 発生時付加され、エラーの内容が含まれます。

WebUI

NSO はGUIからの操作を可能にするため、WebUIが実装されています。JSON-RPCを使用しているため、動作例として確認する場合には、ブラウザの開発機能を使用し動作を観察することも可能です。

JSON-RPCの使用例

あらゆるJSON-RPCリクエストに対しては、ユーザ認証されている必要があります。ただし、login method のみ認証されていない場合でもリクエストする事が可能で、それを実行することで、HTTP Cookie を受信し、以後のリクエストに使用します。

その後、NSOへのログインユーザの追加、削除を行います。また、action の実行方法についても説明しています。

session 作成 (login)

login method をNSOに対して実行し、ログインします。その際、HTTP Header にSet-Cookie が含まれますので、それに含まれる sessionid_[ポート番号] を以後のリクエストではCookieに含めて使用します。curl を使用する場合は、-i オプションを使用することで、それを確認できます。

$ curl -i -c cookie -X POST http://localhost:8080/jsonrpc -H 'Content-Type: application/json' -d '
{
"jsonrpc":"2.0",
"id":1,
"method":"login",
"params":{
"user":"admin",
"passwd":"admin"
}
}'
HTTP/1.1 200 OK
Server:
Date: Sat, 29 Apr 2017 03:56:28 GMT
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Cache-Control: private, no-cache, no-store, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
Content-Length: 36
Content-Type: application/json
Set-Cookie: sessionid_8080=sessjZtwG0ekhzDUZXwvrkW2rw==; path=/; HttpOnly
Vary: Accept-Encoding

{"jsonrpc":"2.0","result":{},"id":1}

なお、curl コマンドでは、取得した cookie を -c オプションで保存し、-b オプションで使用することが可能です。これにより、自動でセッション情報を継続して使用することが出来ます。

トランザクションの開始 (new_trans)

CDBへの操作など、データの取得・変更などを行う場合は、トランザクションの中で行います。ログイン直後は、有効なトランザクションが無いため、新たに開始します。

$ curl -b cookie -X POST http://localhost:8080/jsonrpc -H 'Content-Type: application/json' -d '
{
"jsonrpc":"2.0",
"id":1,
"method":"new_trans",
"params":{
"db": "running",
"mode": "read"
}
}'
{"jsonrpc":"2.0","result":{"th":1},"id":1}
$

mode には read または、read_write を指定出来ます。ここでは、read を指定して、読み取り専用のトランザクションが開始されました。トランザクションハンドル(th) =1 がアサインされていることがわかります。念のため、get_trans メソッドで確認してみます。

$ curl -b cookie -X POST http://localhost:8080/jsonrpc -H 'Content-Type: application/json' -d '
{
"jsonrpc":"2.0",
"id":1,
"method":"get_trans",
"params":{}
}'
{"jsonrpc":"2.0","result":{"trans":[{"th":1,"db":"running","mode":"read"}]},"id":1}
$

th=1 として、トランザクションが一つある事が確認出来ました。

config の取得 (show_config)

CLI 上での "show running" コマンドに相当するRPCです。show_config メソッドを使用します。以下では、"/aaa" を取得しています。これは、CLI上での "show running-config aaa"  相当です。

$ curl -b cookie -X POST http://localhost:8080/jsonrpc -H 'Content-Type: application/json' -d '
{
"jsonrpc":"2.0",
"id":1,
"method":"show_config",
"params":{
"th":1,
"path":"/aaa"
}
}'
{"jsonrpc":"2.0","result":{"config":"aaa {\n    authentication {\n        users {\n            user admin {\n                uid        65534;\n                gid        65534;\n                password   $6$EOlKr.zRujz34uPj$hHyfbMtbvcQWPwvwsmJ8VRaLn1mu/fdZAYKDRkHaL7UEm.WOxPafGr807a2hulfeJwrDSdr4YqLo/Kvg8KOrG0;\n                ssh_keydir /var/ncs/homes/admin/.ssh;\n                homedir    /var/ncs/homes/admin;\n            }\n            user oper {\n                uid        65534;\n                gid        65534;\n                password   $6$7kfOoClUgxfsrRyl$DBpyWaMkBzPQ2njtxfj9ysaSA7WeabDWaW9EfaaokpNGsSiGuu.Ek6VH12EzEiJghl7aCEFy9Sj24eAPxOcBP/;\n                ssh_keydir /var/ncs/homes/oper/.ssh;\n                homedir    /var/ncs/homes/oper;\n            }\n            user private {\n                uid        65534;\n                gid        65534;\n                password   $6$;\n                ssh_keydir /var/ncs/homes/private/.ssh;\n                homedir    /var/ncs/homes/private;\n            }\n            user public {\n                uid        65534;\n                gid        65534;\n                password   $6$;\n                ssh_keydir /var/ncs/homes/public/.ssh;\n                homedir    /var/ncs/homes/public;\n            }\n        }\n    }\n}\n"},"id":1}
$

"show running-config aaa" の結果がテキストで返って来ています。実際にこの形式でアプリケーションから使用する為には、これをparse する必要があり、プログラマビリティとしては、良いものではありません。具体的に、/aaa/authentication/users/user リストを取得してみます。

リストキーの取得 (get_list_keys)

/aaa/authentication/users/user はリストです。get_list_keys メソッドを使用して、このリストのキーを取得してみます。

$ curl -b cookie -X POST http://localhost:8080/jsonrpc -H 'Content-Type: application/json' -d '
{
"jsonrpc":"2.0",
"id":1,
"method":"get_list_keys",
"params":{
"th":1,
"path":"/aaa/authentication/users/user"
}
}'
{"jsonrpc":"2.0","result":{"keys":[["admin"],["oper"],["private"],["public"]],"total_count":4,"lh":-1},"id":1}
$

admin / oper / private / public の4ユーザが、このNSOには登録されている事がわかりました。

/aaa/authentication/users/user{test} の作成 (create)

JSON-RPC を使用して、ユーザ "test" を追加してみます。

これまでに使用してきたトランザクションは、読み取り専用でした。これでは、書き込みが出来ませんので、新たに、読み書き可能なトランザクションを作成します。

$ curl -b cookie -X POST http://localhost:8080/jsonrpc -H 'Content-Type: application/json' -d '
{
"jsonrpc":"2.0",
"id":1,
"method":"new_trans",
"params":{
"db": "running",
"mode": "read_write"
}
}'
{"jsonrpc":"2.0","result":{"th":2},"id":1}
$

th=2 のトランザクションが作成されました。これを使用して、ユーザの追加をしましょう。

user リストへ test ユーザを作成します。リストへ新しいエントリーを作成する場合は、create メソッドを使用します。

$ curl -b cookie -X POST http://localhost:8080/jsonrpc -H 'Content-Type: application/json' -d '
{
"jsonrpc":"2.0",
"id":1,
"method":"create",
"params":{
"th": 2,
"path": "/aaa/authentication/users/user{test}"
}
}'
{"jsonrpc":"2.0","result":{},"id":1}
$

これは、CLI 上で以下を行ったことと同等です。

admin@ncs# conf
admin@ncs(config)# aaa authentication users user test

user リストでは、uid / gid / password / ssh_keydir / homedir を同時に定義する必要がありますので、これらも設定します。

/aaa/authentication/users/user{test}/uid 等  leaf への値設定 (set_value / set_values)

以下の leaf に対して、設定を実施します。複数の leaf への設定を、それぞれの HTTP リクエストで行うことも可能ですが、ここでは Batch 機能を使用し、まとめて設定します。

また、uid/gid leaf は integer ですが、文字列を指定していることに注意して下さい。set_value が value として設定可能な値は、string または 配列です。(null を設定すると、当該 leaf を削除します)

$ curl -b cookie -X POST http://localhost:8080/jsonrpc -H 'Content-Type: application/json' -d '
[{
"jsonrpc":"2.0",
"id":1,
"method":"set_value",
"params":{
"th": 2,
"path": "/aaa/authentication/users/user{test}/uid",
"value": "0"
}
},
{
"jsonrpc":"2.0",
"id":1,
"method":"set_value",
"params":{
"th": 2,
"path": "/aaa/authentication/users/user{test}/gid",
"value": "0"
}
},
{
"jsonrpc":"2.0",
"id":1,
"method":"set_value",
"params":{
"th": 2,
"path": "/aaa/authentication/users/user{test}/password",
"value": "cisco"
}
},
{
"jsonrpc":"2.0",
"id":1,
"method":"set_value",
"params":{
"th": 2,
"path": "/aaa/authentication/users/user{test}/ssh_keydir",
"value": "/home/test/.ssh"
}
},
{
"jsonrpc":"2.0",
"id":1,
"method":"set_value",
"params":{
"th": 2,
"path": "/aaa/authentication/users/user{test}/homedir",
"value": "/home/test"
}
}]'
[{"jsonrpc":"2.0","result":{},"id":1},{"jsonrpc":"2.0","result":{},"id":1},{"jsonrpc":"2.0","result":{},"id":1},{"jsonrpc":"2.0","result":{},"id":1},{"jsonrpc":"2.0","result":{},"id":1}]

変更の実施 (validate_commit / commit)

これまでに、変更に必要なデータは全てトランザクション内に入りました。後は、CLIと同様、commit が必要です。

その際に、CLI では自動で行われますが、commit 前に、validate_commit を行う必要があります。これは、入力値のチェックを行い、不正があればエラーを表示します。validate されていないトランザクションは、commit する事が出来ません。

 

validate_commit

$ curl -b cookie -X POST http://localhost:8080/jsonrpc -H 'Content-Type: application/json' -d '
{
"jsonrpc":"2.0",
"id":1,
"method":"validate_commit",
"params":{
"th": 2
}
}'
{"jsonrpc":"2.0","result":{},"id":1}
$

以下は validate_commit に失敗した例です。user リストのエントリ作成では、homedir の設定が必須ですが、それをしていない場合には、以下の様なエラーが戻ります。

$ curl -b cookie -X POST http://localhost:8080/jsonrpc -H 'Content-Type: application/json' -d '
{
"jsonrpc":"2.0",
"id":1,
"method":"validate_commit",
"params":{
"th": 2
}
}'
{"jsonrpc":"2.0","error":{"type":"trans.validation_failed","code":-32000,"message":"Validation failed","data":{"errors":[{"reason":"is not configured","paths":["/aaa:aaa/authentication/users/user{test}/homedir"],"path":"/aaa:aaa/authentication/users/user{test}/homedir"}]}},"id":1}
$

commit

flags パラメータはオプションです。必要に応じて、dry-run=native, no-networking などを指定します。

例: flags = ["dry-run=native", "no-networking"]

$ curl -b cookie -X POST http://localhost:8080/jsonrpc -H 'Content-Type: application/json' -d '
{
"jsonrpc":"2.0",
"id":1,
"method":"commit",
"params":{
"th": 2,
"flags" : []
}
}'
{"jsonrpc":"2.0","result":{},"id":1}

値の取得 (get_value / get_values)

commit が完了しましたので、値を取得し、正しく commit が完了した事を確認します。また、get_list_keys を使用して、test が user リストに追加された事も確認します。

get_value は特定の leaf の値を取得します。複数のleaf の値をまとめて取得する get_values もありますので、以下例を示します。

test ユーザが追加された事を確認 (get_list_keys)

$ curl -b cookie -X POST http://localhost:8080/jsonrpc -H 'Content-Type: application/json' -d '
{
"jsonrpc":"2.0",
"id":1,
"method":"get_list_keys",
"params":{
"th":1,
"path":"/aaa/authentication/users/user"
}
}'
{"jsonrpc":"2.0","result":{"keys":[["admin"],["oper"],["private"],["public"],["test"]],"total_count":5,"lh":-1},"id":1}

user {test} / ssh_keydir を確認 (get_value)

$ curl -b cookie -X POST http://localhost:8080/jsonrpc -H 'Content-Type: application/json' -d '
{
"jsonrpc":"2.0",
"id":1,
"method":"get_value",
"params":{
"th": 1,
"path": "/aaa/authentication/users/user{test}/ssh_keydir"
}
}'
{"jsonrpc":"2.0","result":{"value":"/home/test/.ssh"},"id":1}

user {test} に設定された値をまとめて確認 (get_values)

$ curl -b cookie -X POST http://localhost:8080/jsonrpc -H 'Content-Type: application/json' -d '
{
"jsonrpc":"2.0",
"id":1,
"method":"get_values",
"params":{
"th": 1,
"path": "/aaa/authentication/users/user{test}",
"leafs": ["uid", "gid", "password", "ssh_keydir", "homedir"]
}
}'
{"jsonrpc":"2.0","result":{"values":[{"value":"0","access":{"read":true,"write":true}},{"value":"0","access":{"read":true,"write":true}},{"value":"$6$hXtiNxdt6ngFWZCO$MdOQfIe4cHEnzsZnVMkMIOH4eJ7ZGZEmNSUCYPO68SEHs2L/V9tZ1KbCIFFUfV52kl88JKbWmFCn2vrZNVuxA.","access":{"read":true,"write":true}},{"value":"/home/test/.ssh","access":{"read":true,"write":true}},{"value":"/home/test","access":{"read":true,"write":true}}]},"id":1}

 

/aaa/authentication/users/user{test} の削除 (delete)

作成した test ユーザを削除します。リストからエントリを削除するには、delete メソッドを使用します。

$ curl -b cookie -X POST http://localhost:8080/jsonrpc -H 'Content-Type: application/json' -d '
{
"jsonrpc":"2.0",
"id":1,
"method":"delete",
"params":{
"th": 2,
"path": "/aaa/authentication/users/user{test}"
}
}'
{"jsonrpc":"2.0","result":{},"id":1}

action の実行 (run_action)

アクションは、yang 上で定義された rpc です。当該ノードを「実行」することで、何らかの動作がNSO上で発生します。JSON-RPC では、run_action メソッドを実行する事で、NSO上でアクションを実行出来ます。

以下では、/devices/sync-from アクションを実施しています。このNSOでは、c0/c1 という二つのデバイスが登録されています。

$ curl -b cookie -X POST http://localhost:8080/jsonrpc -H 'Content-Type: application/json' -d '
{
"jsonrpc":"2.0",
"id":1,
"method":"run_action",
"params":{
"th": 1,
"path": "/devices/sync-from"
}
}'
{"jsonrpc":"2.0","result":[{"name":"sync-result/device","value":"c0"},{"name":"sync-result/result","value":"true"},{"name":"sync-result/device","value":"c1"},{"name":"sync-result/result","value":"true"}],"id":1}

スキーマ(モデル) の取得 (get_schema)

上記例では、/aaa 以下のモデルを既に知っていることから、user はリストであり、それ以下には pid, gid 等の leaf が存在している事がわかり、get_value 等を実行出来ました。しかしながら、知らない場合には、get_value 等でpath を指定することが出来ません。

一般のアプリケーションであれば、通常モデルを確認した上で作成するため、これは問題にはなりません。もし、ツリーを walk する様なアプリケーションを作成したい場合は、事前にモデルを知り得ませんので、get_value のようなことは出来ません。

JSON-RPCでは、get_schema メソッドによりモデルを取得出来ますので、そういったダイナミックなアプリケーションを作成することも可能です。

$ curl -b cookie -X POST http://localhost:8080/jsonrpc -H 'Content-Type: application/json' -d '
{
"jsonrpc":"2.0",
"id":1,
"method":"get_schema",
"params":{
"th": 1,
"path": "/aaa/authentication/users/user"
}
}'
{"jsonrpc":"2.0","result":{"meta":{"namespace":"http://tail-f.com/ns/aaa/1.1","keypath":"/aaa:aaa/authentication/users/user","prefix":"aaa","types":{"http://tail-f.com/ns/aaa/1.1:passwdStr":[{"name":"http://tail-f.com/ns/aaa/1.1:passwdStr"},
<< 出力が非常に長いため、省略しています >>

 

  • タグ付けされた記事をさらに検索:
256
閲覧回数
20
いいね!
0
コメント