見出し画像

SNMPに代わるネットワーク管理技術gNMIを、いろいろ試しています

今朝は4時前に助手の猫さんが起こしてくれました。昨日、家の庭に、よその猫がやってきたらしく、うちの猫さんは混乱状態でした。今朝もまだ、引きずっているようです。静かにしてねと説得しておきました。

さて、昨日作ったgNMIのテスト環境を使って、いろいろ試しています。

外部からgNMIアクセス可能にした

まずは、開発用のマシンからgNMIでアクセスできるように、

で作ったContainerlabの定義ファイルを変更しました。

name: twsnmp

topology:
  nodes:
    srl:
      kind: nokia_srlinux
      image: ghcr.io/nokia/srlinux
      ports:
      - 57400:57400
    twsnmp:
      kind:  linux
      image: twsnmp/twsnmpfc
      binds:
      - datastore:/datastore
      ports:
      - 8080:8080

  links:
    - endpoints: ["srl:e1-1", "twsnmp:eth1"]

57400番ポートを外部からアクセスできるように変更しました。

MacにgNMIcをインストール

開発用のMacにもgNMIcをインストールして試してみました。インストールは

brew install gnmic

でできました。ちょっとだけ古いようです。

gNMIcの設定ファイルにパラメータを保存

設定をファイルに書いてコマンドのパラメータを少なくする方法も試してみました。

です。

# gNMI target address; CLI flag `--address`
address: "192.168.1.50:57400"
# gNMI target user name; CLI flag `--username`
username: admin
# gNMI target user password; CLI flag `--password`
password: NokiaSrl1!
# connection mode; CLI flag `--insecure`
skip-verify: true
# log file location; CLI flag `--log-file`
log-file: /tmp/gnmic.log

GO言語のプログラムからgNMIアクセス

のサンプルプログラムを一通り実行してみました。

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/openconfig/gnmic/pkg/api"
	"google.golang.org/protobuf/encoding/prototext"
)

func main() {
	// create a target
	tg, err := api.NewTarget(
		api.Name("srl1"),
		api.Address("192.168.1.50:57400"),
		api.Username("admin"),
		api.Password("NokiaSrl1!"),
		api.SkipVerify(true),
	)
	if err != nil {
		log.Fatal(err)
	}

	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	// create a gNMI client
	err = tg.CreateGNMIClient(ctx)
	if err != nil {
		log.Fatal(err)
	}
	defer tg.Close()

	// send a gNMI capabilities request to the created target
	capResp, err := tg.Capabilities(ctx)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(prototext.Format(capResp))
}

問題なく実行できました。

gNMIcの取得結果をファイル出力

のファイル出力を試してみました。

#File output
username: admin
password: NokiaSrl1!
skip-verify: true
encoding: json_ietf
log: true

targets:
  192.168.1.50:57400:

subscriptions:
  sub1:
    paths:
      - /interface/statistics
    stream-mode: sample
    sample-interval: 10s

outputs:
  file-output:
    type: file
    filename: /tmp/file-out.txt
    

のような設定ファイルを指定して

gnmic subscribe --config output_snmp.yaml

のように起動すると

{"source":"192.168.1.50:57400","subscription-name":"sub1","timestamp":1727296684417711520,"time":"2024-09-26T05:38:04.41771152+09:00","updates":[{"Path":"srl_nokia-interfaces:interface[name=ethernet-1/58]/statistics","values":{"srl_nokia-interfaces:interface/statistics":{}}},{"Path":"srl_nokia-interfaces:interface[name=mgmt0]/statistics","values":{"srl_nokia-interfaces:interface/statistics":{"carrier-transitions":"1","in-broadcast-packets":"0","in-discarded-packets":"22","in-error-packets":"0","in-fcs-error-packets":"0","in-multicast-packets":"0","in-octets":"295578","in-packets":"3383","in-unicast-packets":"3361","out-broadcast-packets":"7","out-discarded-packets":"0","out-error-packets":"0","out-mirror-octets":"0","out-mirror-packets":"0","out-multicast-packets":"41","out-octets":"571843","out-packets":"3288","out-unicast-packets":"3240"}}}]}

のようにファイルに出力されました。

gNMIcからSNMPのTARPを送信する

gNMIcで取得したデータを元にSNMPのTRAPを送信する機能があったので試してみました。

です。
設定を

username: admin
password: NokiaSrl1!
skip-verify: true
log: true

targets:
  192.168.1.50:57400:

subscriptions:
  sub1:
    paths:
      - /interface/admin-state
      - /interface/oper-state
      - /interface/ifindex
      - /system/name/host-name
    stream-mode: sample
    sample-interval: 10s
    # stream-mode: on-change
    encoding: ascii

outputs:
  snmp_trap:
    type: snmp
    address: 192.168.1.250
    port: 162
    community: public
    traps:
      - trigger:
          path: /interface/oper-state # static path
          oid: '".1.3.6.1.2.1.2.2.1.8"' # ifOperStatus
          type: int
          value: if (.values."/interface/oper-state" == "up") 
                  then 1 
                  else 2 
                  end
        bindings:         
          - path: '"/system/name/host-name"' # jq script
            oid: '".1.3.6.1.2.1.1.5"' # sysName
            type: octetString
            value: '.values."/system/name/host-name"'

          - path: '"/interface[name="+.tags.interface_name+"]/admin-state"' # jq script
            oid: '".1.3.6.1.2.1.2.2.1.7"' # ifAdminStatus
            type: int
            value: if (.values."/interface/admin-state" == "enable") 
                    then 1 
                    else 2 
                    end

          - path: '"/interface[name="+.tags.interface_name+"]/ifindex"' # jq script
            oid: '".1.3.6.1.2.1.2.2.1.1"' # ifIndex
            type: int
            value: '.values."/interface/ifindex" | tonumber' # jq script

のようにして実行するとTWSNMP FCにTRAPが送信されました。

のように受信はできますが、TRAPの内容はおかしいようです。
gNMIc側のログにもエラーが記録されています。

詳しく調べたいところですが、今朝は時間切れです。
いろいろ、やりすぎて、猫さんじゃないけど、頭が混乱しています。

明日に続く

いいなと思ったら応援しよう!

twsnmp
開発のための諸経費(機材、Appleの開発者、サーバー運用)に利用します。 ソフトウェアのマニュアルをnoteの記事で提供しています。 サポートによりnoteの運営にも貢献できるのでよろしくお願います。