post Image
シスコルータのチャットを自動化する

NetOpsCoding Advent Calendar 2016 12/16分の記事です。

背景

もともとChatOps系のネタで何をやろうかと考えていたのですが、IOS自身にもチャットに近い機能(sendコマンド)があることを思い出しました。

送信側がこれを実行すると
Router#send *
Enter message, end with CTRL/Z; abort with CTRL/C:
test message
^Z
Send message? [confirm]
Router#
受信側でこれが表示される
***
***
*** Message from tty1 to all terminals:
***
test message

で、このsendコマンドがとても使いづらいんです。

  • 発言の度にログインするのが非常に手間である。
  • ログインしてないと発言を受けることができない。
  • 過去のメッセージが記録されない。
  • 日本語や絵文字が使えない。
  • チャットだったらGUIの方が使いやすい。
  • アバター画像があると親近感あって良い。

なので、これらの問題を自動化その他もろもろで何とかしてみました。

成果物(Web UI部分)

chat.png

全然sendコマンドの面影がありませんが、バックエンドでは重要な役割を担っています。
裏の仕組みについては後述します。

CLI部分を完全に自動化したので、非常に快適にチャットができるようになりました。

https://github.com/tanksuzuki/cchat

構成

構成.png

Router(as a Database)

標準のsendではログイン中のユーザにしか発言できず、過去の発言は保存されません。
そのため、データを保持できる何かしらの場所が必要となります。

案1: Flashにファイルを置く

Flashにファイルを作って、 IOS.shで発言内容を記録してく方法です。
Cisco IOS シェル CLI モジュールの設定例

echoやcatで繋げる例
Router#echo test1 > flash:file1

Router#echo test2 > flash:file2

Router#cat flash:file1 flash:file2
test1test2Router#

なんか普通すぎて面白みに欠けるため、この案は不採用になりました。

案2: bannerに記録する

banner motd的なところに発言内容を追記していく方式です。
容量的に懸念があったので、ちょっと検証してみました。

motd容量チェック
Router(config)#banner ^
Enter TEXT message.  End with the character '^'.
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
----- 省略 -----
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567
Maximum Banner size 3000 bytes reached. Banner message is truncated
Router(config)#$23456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
^
% Invalid input detected at '^' marker.

3000byteでアウト。容量的に辛いので、この案は不採用になりました。

案3: ログに記録する

sendは、ユーザに直接メッセージを送るだけでなく、ログに任意の文字列を出力させることもできます。

Router#send log hogehoge
Router#sh log | tail 1
Dec 12 2016 03:48:11: %SYS-7-USERLOG_DEBUG: Message from tty1(user id: hello@tanksuzuki.com): hogehoge

Router#

これは素晴らしい。

  • WriteもReadもコマンド化されてる。
  • バッファから溢れたログは自動破棄されるので管理が楽。
  • バッファを増やすことで、ある程度の量の発言を保持できる。

ということで、ログ領域をNoSQL的に使うことに決めました。
JSONを突っ込んでしまいましょう。

SSHクライアント

役割は2つです。

  • APIで渡されたメッセージを、ルータにログインしてsend logする。
  • APIでメッセージ取得要求を受けたら、ルータにログインしてsh logする。

メッセージ構造は下記の通り。
この構造体をJSON化してログに突っ込むんですが、send log時にダブルクォーテーションが削られてしまうため、全体をBase64化してJSON構文を保護しています。

cchat.go
type Message struct {
    ID    string `json:"id"`
    Date  string `json:"date"`
    Owner string `json:"owner"`
    Body  string `json:"body"`
}

下記は入れた結果です。

show_log
Dec 12 2016 04:28:35: %SYS-7-USERLOG_DEBUG: Message from tty1(user id: hello@tanksuzuki.com): eyJpZCI6IjZiN2YzZmQ2YTliZjM1ZWFkY2U5NjE1OGQ3YjEzYzI2ZjE0ZDM3ZDAiLCJkYXRlIjoiMjAxNi0xMi0xMlQwNDoyODozM1oiLCJvd25lciI6ImhlbGxvQHRhbmtzdXp1a2kuY29tIiwiYm9keSI6InRlc3QifQ==

API / Web UI

inputに入れた文章は、APIサーバのPOST /api/message経由で SSHクライアントに渡されます。
また、30秒ごとにAPIサーバのGET /api/messagesを叩いてメッセージ一覧を取得し、Riotで描画しています。

アバター画像はGravatarから取得しています。
Gravatarに登録しているメールアドレスを、SSHのユーザ名にすればOKです。

課題

大きなところで3点あります。

課題1: 発言データは揮発性

ログはメモリに乗っているだけなので、再起動すると揮発します。
ログ領域をDB化する以上、半ば最初から諦めていた部分ですが、できることなら何とかしたいです。

課題2: ログの文字数制限

ログ1行あたりの文字数上限が340文字でした。
それ以上の文字数をsend logしても、溢れた部分が削られるだけでコマンドとしては正常終了します。

長い文章を送るとJSONの後半部分が落ちて不良レコード化するため、現状だと半角40文字くらいまでがメッセージの上限になっています。

課題3: Read/Writeが遅すぎる

ストレスを感じるレベルで読み書きに時間がかかります。
ルータをDBにするのはやめた方が良いかもしれません。

今後について

まだ構想段階ですが、クライアントとDB(ルータ)の間に挟むコントローラ的なものがあれば劇的な改善が見込めそうです。

  • 複数のDB(ルータ)に対し、RAID5的にレコードを分散配置して耐障害性UP。
  • 長いレコードは1行に収まる程度に細切れにして分散配置し、コントローラ上で結合処理。
  • Writeを非同期化し、Readはコントローラ上のキャッシュで高速化する。

今度作ります。


『 Go 』Article List
Category List

Eye Catch Image
Read More

Androidに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

AWSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Bitcoinに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

CentOSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

dockerに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

GitHubに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Goに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Javaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

JavaScriptに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Laravelに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Pythonに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Rubyに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Scalaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Swiftに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Unityに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Vue.jsに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Wordpressに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

機械学習に関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。