見出し画像

【全文無料】bashでVyOSのConfig作成を自動化してみたお話 - ②

前回の記事の続きです。
【全文無料】bashでVyOSのConfig作成を自動化してみたお話 - ①

続きものだと前書きを沢山書ける程、文章を書く力は養われていないので
早速、コンフィグを生成する準備に入ります。


例に漏れずパッケージの導入から。

expect のインストールになります。

$ sudo apt -y install expect

expect の詳細は色々な所で書かれているので省略しますが、
要するに対話式で行われる処理を自動化するパッケージです。
例えば「$」と言う文字が表示されたら「su -」を実行して
「 password 」と表示されたら「hoge」と入力させるとかそんな感じです。
これを利用します。
導入も、Debian , Ubuntu 系であれば apt、
RHEL 系であれば dnf にて導入可能ですので非常に簡単です。
前職の奴らにはこれすら通じませんでしたが・・・(毒)

まずは試しに

loopback アドレスに「1.1.1.1/32」と言う設定を投入します。
早速ですがこんな感じ

testscript.sh
#!/bin/bash

ID="vyos"
PW="vyos"

expect -c "
  set timeout 5
  spawn env LANG=C /usr/bin/ssh ${ID}@203.0.113.2
  expect \"assword:\"
  send \"${PW}\n\"
  expect \"$\"
  send \"configure\n\"
  expect \"#\"
  send \"set interfaces loopback lo address 1.1.1.1/32\n\"
  expect \"#\"
  send \"commit\n\"
  expect \"#\"
  send \"save\n\"
  expect \"#\"
  send \"exit\n\"
  expect \"$\"
  send \"exit\n\"
exit 0
"

" spawn ~"で SSH ログインを試み、
" assword: "と表示されたら変数化したパスワードを入力、
 ※大文字小文字判定もできなくはないけどこれでいいや、という事で
" $ "が表示されたら" configure "と実行し、
" # "が出たら" set interfaces ~ "を実行し
以下、" commit "、" save "して装置からログアウトしていく、
と言うのが大まかな流れです。
" expect "及び" send "の時に括っているダブルクォーテーションや
改行コードにはバックスラッシュを付けることをお忘れずに。
なお、「1.1.1.1/32」についてはそのままにしても
正規表現っぽく「1\.1\.1\.1\/32」と表記しても
「1.1.1.1/32」と実機には反映されましたが、
これはクライアントが VyOS だったからなのか、
どんなクライアントでも同様の挙動をするのかは実はよく解っていません。

ともあれ次はこの「1.1.1.1/32」と言うパラメーターを
外部ファイルから読み込ませるような挙動をしていきます。

考え方はシンプル

単純に変数化するだけです。
分りやすい様に、しろおび君のホームディレクトリ「/home/shiroobi/」に
" testdata.csv "と言う形で外部データがあるとします。
" testdata.csv "の中身はこんな感じ

/home/shiroobi/testdata.csv
hostname,lo_address,Static_Route1,nexthop1
host1,203.0.113.1/32,198.51.100.0/25,203.0.113.251
host2,203.0.113.2/32,198.51.100.128/25,
host3,203.0.113.3/32,,
host4,,,
host5

host2には Static ルートは存在しますがネクストホップは存在しません。
host3 には Static ルート、ネクストホップ共に存在しません、
また host4 には lo アドレスすら存在しません。
現実的な設計として同一システム内のルーターにて
lo アドレスを設定するルーターとしないルーターが混在する事は
あり得ないのですが、そこも含めて動作確認させていきます。
またhost5には「,」すら入力しないでおきましたが
これでも問題なく動作するのか確認したく実装しました。

各種変数設定

そもそも、スクリプトを実行する時に引数指定しないと
スクリプト自体が動かない様にする必要がありますが、それは後述します。

HOST名設定

確実に存在するパラメーターは
" hostname "だけですので、"HOST"と言う変数は
単純に以下の通りに定義できます。

HOST=`cat /home/shiroobi/testdata.csv | grep $1 | awk -F '[,]' '{print $1}'`

本来は「$()」で囲う方が良いらしいのですが筆者は余程の事がない限り、
バッククォートで囲う様にしています。
またわざわざ cat しなくても最初から" grep $1 ~.csv "としても一緒と言えば一緒なのですがなんか半分クセでこう書いちゃいます。
ぶっちゃけ個人的な好みです。

Loアドレス設定

lo アドレス以降の場合、値が存在していたら変数格納及びコマンド実行、
存在していなければ、変数には何も格納せず、コマンドも実行させない、
そんな作りにする必要があります。
というわけで if 文で実装してみます。

LO=`cat /home/shiroobi/testdata.csv | grep $1 | awk -F '[,]' '{print $2}'`
if [ -n "${LO}" ]; then
        LOCONF="set interfaces loopback lo address ${LO}"
else
        LOCONF=""
fi

「 -n 」演算子で空文字列をチェックする際は、
変数を必ずダブルクォートで囲む必要がある
事に注意してください。
ここで筆者はハマりました。ナンデコンナコトワスレテタンジャ・・・
また、「コマンドを実行させない」と言うクダリは空文字を変数として
設定する事で結果空エンターを実施させる方向で逃げました。
expectの中で改行コードとかは実装しているので、
ここは単純に空文字を入れるだけで良いです。

Staticルート設定

同様に Static ルート設定も同じ様な実装を試みます。
しかしながら、静的経路及びネクストホップが共に存在しなければ
コマンドとして成立しませんから、
両方存在する場合のみ変数化、コマンド実行させます。

SR=`cat /home/shiroobi/testdata.csv | grep $1 | awk -F '[,]' '{print $3}'`
NH=`cat /home/shiroobi/testdata.csv | grep $1 | awk -F '[,]' '{print $4}'`
if [ -n "${SR}" && -n "${NH}" ]; then
	STCONF="set protocol static route ${SR} next-hop ${NH}"
else
	STCONF=""
fi

ネクストホップ指定がアドレスとインターフェースの混在パターンだったら文字列判定が必要だよね、
とかそういう処理を追加でしなければいけない気もしますが、
そこまで作り込む気はないので省略します。

忘れていけないのが・・・

引数指定がなされなかった時に、処理そのものを中止する事です。
これはシンプルに実装します。

if [ $# -ne 1 ]; then
        echo "ちゅーし"
        exit 1
fi

とこんな感じになりました。
念のために捕捉しますと、「$#」にてコマンドラインから渡された引数の数の確認で使用しています。

結果こうなった

出来たスクリプトは以下の通りです。

#!/bin/bash

if [ $# -ne 1 ]; then
        echo "ちゅーし"
        exit 1
fi

ID="vyos"
PW="vyos"

HOST=`cat /home/shiroobi/testdata.csv | grep $1 | awk -F '[,]' '{print $1}'`

LO=`cat /home/shiroobi/testdata.csv | grep $1 | awk -F '[,]' '{print $2}'`
if [ -n "${LO}" ]; then
        LOCONF="set interfaces loopback lo address ${LO}"
else
        LOCONF=""
fi

SR=`cat /home/shiroobi/testdata.csv | grep $1 | awk -F '[,]' '{print $3}'`
NH=`cat /home/shiroobi/testdata.csv | grep $1 | awk -F '[,]' '{print $4}'`
if [[ -n "${SR}" && -n "${NH}" ]]; then
        SRCONF="set protocol static route ${SR} next-hop ${NH}"
else
        SRCONF=""
fi

expect -c "
  set timeout 5
  spawn env LANG=C /usr/bin/ssh ${ID}@203.0.113.2
  expect \"assword:\"
  send \"${PW}\n\"
  expect \"$\"
  send \"configure\n\"
  expect \"#\"
  send \"set system host-name ${HOST}\n\"
  expect \"#\"
  send \"${LOCONF}\n\"
  expect \"#\"
  send \"${SRCONF}\n\"
  expect \"#\"
  send \"commit\n\"
  expect \"#\"
  send \"save\n\"
  expect \"#\"
  send \"exit\n\"
  expect \"$\"
  send \"exit\n\"
exit 0
"
exit 0

一応筆者のテスト環境ではうまく動作してくれましたのでご参考になれば幸いです。

まとめ

今回のパターンだと出来る事は Loopback アドレスの設定と
Static Route の設定のみ、また削除自体の実装もままならないと
割と機能は限定的なものになります。
VyOS には他にも沢山機能は充実しています。

そこで次回以降、もう少し柔軟に色々設定出来る様にしたいと思います。
こちらのネタにもう少しお付き合い下さい。

最後まで読んでくれてありがとうございます。
よかったら「スキ❤️」を押してくれたり、
ご課金と言う名のお気持ち頂ければ嬉しいです。

ここから先は

0字

¥ 100

期間限定!Amazon Payで支払うと抽選で
Amazonギフトカード5,000円分が当たる

この記事が気に入ったらチップで応援してみませんか?