Junoscriptを使ってみよう #1 ConfigにCommitしたユーザを埋め込もう

# はじめに

Junoscriptを使ってみよう ということで、簡単なJunoscriptの例を紹介していきます。

Junoscriptとは、Junosルータ上で動作するスクリプト環境で、動作するタイミングによってCommit Script(設定のコミット時に動作)とOp Script(任意のタイミングで動作)、Event Script(何らかのイベントに応じて動作)に分かれます。
Junoscriptを記述する言語として、XSLTとSLAXという2つの言語が存在しますが、今後の記述はSLAXに統一して行います。
詳しくは、[公式ドキュメント](http://www.juniper.net/techpubs/en_US/junos15.1/information-products/pathway-pages/config-guide-automation/config-guide-automation.html)を参照してください。

さて、先日 Junosの自動バックアップ機能であるConfiguration Archival機能を[ご紹介しました](http://qiita.com/kazubu/items/c1b6a656a10a2e489142)。
普段、JunosのConfigを`show configurations`コマンド等で表示すると、Configの先頭に `## Last commit: 2015-12-31 00:23:45 JST by kazubu` などといった形で、コミットしたユーザ名が表示されます。しかしながら、Configuration ArchivalによってバックアップされるConfigには、この行は含まれません。
そこで、今回は、Commit Scriptを用いて、Configの中にCommitしたユーザ名をコメントとして埋め込む事により、Configの履歴管理をより使いやすくしていくことを考えます。

# 環境

今回紹介するスクリプトは、以下の環境にて動作確認を行っています。

 * SRX 12.1X46-D40
 * vMX 14.1R5.4
 * vMX 15.1F3.11
 * vMX 15.1F4.15

# SLAXについて

前述したとおり、JunoscriptはXSLTまたはSLAXによって記述されます。
歴史を遡ると、Junoscriptは当初、XSLTによってのみ記述が可能でした。しかし、XSLTはXMLによってXML文章を操作する為の言語であり、人間にとっては可読性が高くなく、記述しにくいという点がありました。そこで用意されたのがSLAXです。
SLAXは、Juniperによって開発された、XSLTと同等の操作をC/Perlライクな記述で可能にするためのXSLTのサブセットであり、XSLTと相互に変換が可能です。SLAXによって、比較的簡単にJunoscriptを記述することが可能になりました。

SLAXを学習するにあたっては、[This Week: Applying Junos Automation](http://forums.juniper.net/t5/Day-One-Books/This-Week-Applying-Junos-Automation/ba-p/52390) という入門書が用意されていますので、ご興味のある方はぜひ読んでみることをおすすめします(要Juniperアカウント)。

# ConfigにCommitしたユーザを埋め込もう

それでは早速、標題のスクリプトをご紹介します。
次のスクリプトでは、以下の処理を行います。

1. ユーザ名と(あれば)コミットコメント、バージョンを変数に格納
2. コミットコメントがない場合、"commiter: ユーザ名" というコメントをversion節に対して記載
3. コミットコメントがあった場合、"commiter: ユーザ名;comment: コメント" というコメントをversion節に対して記載

```slax:commit-user-annotate.slax
version 1.0;
/* Import namespaces */
ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
import "../import/junos.xsl";

/* For configuration script */
match configuration {
        var $cuser = $junos-context/user-context/login-name;
        var $ccomment = $junos-context/commit-context/commit-comment;
        var $version = version;

        /* Is commit comment empty? */
        if( jcs:empty ($ccomment)) {
                /* Create annotate which includes committer username */
                var $annotate = "committer:" _ $cuser;
                /* Make a change for configuration to include an annotate */
                <change> {
                        <junos:comment> $annotate;
                        <version> $version;
                }
        } else {
                /* Create annotate which includes committer username and commit comment */
                var $annotate = "committer:" _ $cuser _ ";comment:" _ $ccomment;

                /* Make a change for configuration to include an annotate */
                <change> {
                        <junos:comment> $annotate;
                        <version> $version;
                }
        }
}
```

実際に動かしてみるには、このスクリプトを、`/var/db/script/commit/`の中に`commit-user-annotate.slax`として配置し、以下の設定を投入します。

```
set system scripts commit file commit-user-annotate.slax
```

Commitを行った後にConfigを見てみると、

```
kazubu@r1> show configuration
## Last commit: 2015-12-31 03:25:49 JST by kazubu
/* committer:kazubu */
version 15.1F4.15;
system {
    host-name r1;
    domain-name lab.kazubu.jp;
...
```

といった感じで、設定の先頭行にコミットした人の名前が自動的に埋め込まれます。
コミット時にコメントを書いた場合は、以下のようになります。

```
kazubu@r1# commit comment "deleted interface ge-X/Y/Z"
commit complete

[edit]
kazubu@r1# show
## Last changed: 2015-12-31 04:08:09 JST
/* committer:kazubu;comment:deleted interface ge-X/Y/Z */
version 15.1F4.15;
system {
...
```

これにより、Git等でのConfigの履歴管理が捗ります。やったね！

# さいごに

今回は、極々簡単なJunoscriptを紹介してみました。Junoscriptを使うとこのように、簡単にJunosを拡張することが可能です。
ネタを思いついたら今後も書いてみようかと思いますので、良いネタを思いついた人は、是非コメントで教えてください。

それではまた！