👀
GoでgRPCを使ってIOS XRのshowコマンドを実行する
前回はCiscoのModel Driven TelemetryのDial outを紹介したが、今回はDial inを紹介する。
Dial inはこのファイルを参照する。元のprotoファイルを参照すると、コンフィグ操作とshowコマンド系を実行するserviceが定義されていることがわかる(コメント等省略)。
service gRPCConfigOper {
rpc GetConfig(ConfigGetArgs) returns(stream ConfigGetReply) {};
rpc MergeConfig(ConfigArgs) returns(ConfigReply) {};
rpc DeleteConfig(ConfigArgs) returns(ConfigReply) {};
rpc ReplaceConfig(ConfigArgs) returns(ConfigReply) {};
rpc CliConfig(CliConfigArgs) returns(CliConfigReply) {};
rpc CommitReplace(CommitReplaceArgs) returns (CommitReplaceReply) {};
rpc CommitConfig(CommitArgs) returns(CommitReply) {};
rpc ConfigDiscardChanges(DiscardChangesArgs) returns(DiscardChangesReply) {};
rpc GetOper(GetOperArgs) returns(stream GetOperReply) {};
rpc CreateSubs(CreateSubsArgs) returns(stream CreateSubsReply) {};
}
service gRPCExec {
rpc ShowCmdTextOutput(ShowCmdArgs) returns(stream ShowCmdTextReply) {};
rpc ShowCmdJSONOutput(ShowCmdArgs) returns(stream ShowCmdJSONReply) {};
}
今回はshow run
を実行したいので、service gRPCExec
の方を使うことにする。
IOS XR側に必要な設定は以下の通り(portは適当)。
grpc
port 50051
no-tls
!
まず、実行したいコマンドを構造体ShowCmdArgs
として作成する。
command := "show run"
cli := dialin.ShowCmdArgs{Cli: command}
次に、gRPCのクライアントを定義。
conn, _ := grpc.Dial("192.168.1.10:50051", grpc.WithInsecure())
client := dialin.NewGRPCExecClient(conn)
GRPCExecClient
のShowCmdTextOutput
メソッドを実行するわけだが、ログイン認証という問題がある。
これはprotoファイルを眺めても全然やり方がわからないわけだが、pipelineのソースコードを眺めているとやり方がわかる。metadataを定義してコンテキストに埋め込んやればいい。
md := metadata.Pairs(
"username", "root",
"password", "password",
)
ctx := metadata.NewOutgoingContext(context.Background(), md)
reply, err := client.ShowCmdTextOutput(ctx, &cli)
というわけで全体像は以下のようになる。
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
dialin "github.com/cisco/bigmuddy-network-telemetry-proto/proto_go/mdt_grpc_dialin"
)
func main() {
md := metadata.Pairs(
"username", "root",
"password", "password",
)
command := "show run"
cli := dialin.ShowCmdArgs{Cli: command}
conn, _ := grpc.Dial("192.168.1.10:50051", grpc.WithInsecure())
client := dialin.NewGRPCExecClient(conn)
ctx := metadata.NewOutgoingContext(context.Background(), md)
reply, err := client.ShowCmdTextOutput(ctx, &cli)
if err != nil {
fmt.Println(err)
} else {
msg, _ := reply.Recv()
fmt.Println(msg.Output)
}
}
ちなみに、この内容をpythonで書くと以下のようになる。
import grpc
from mdt_grpc_dialin_pb2 import *
from mdt_grpc_dialin_pb2_grpc import *
_metadata = [('username', 'root'), ('password', 'password')]
channel = grpc.insecure_channel('192.168.1.10:50051')
exec_stub = gRPCExecStub(channel)
cli = ShowCmdArgs(cli="show run")
reply = exec_stub.ShowCmdTextOutput(cli, metadata=_metadata)
for r in reply:
print(r.output)
余談だが、Dial outのpackage名はmdt_dialout
なのに、Dial inのpackage名はIOSXRExtensibleManagabilityService
なのがなんかもやもやする...
次回はコンフィグ投入について書きます。
Discussion