この製品のドキュメントセットは、偏向のない言語を使用するように配慮されています。このドキュメントセットでの偏向のない言語とは、年齢、障害、性別、人種的アイデンティティ、民族的アイデンティティ、性的指向、社会経済的地位、およびインターセクショナリティに基づく差別を意味しない言語として定義されています。製品ソフトウェアのユーザインターフェイスにハードコードされている言語、RFP のドキュメントに基づいて使用されている言語、または参照されているサードパーティ製品で使用されている言語によりドキュメントに例外が存在する場合があります。シスコのインクルーシブ ランゲージの取り組みの詳細は、こちらをご覧ください。
シスコは世界中のユーザにそれぞれの言語でサポート コンテンツを提供するために、機械と人による翻訳を組み合わせて、本ドキュメントを翻訳しています。ただし、最高度の機械翻訳であっても、専門家による翻訳のような正確性は確保されません。シスコは、これら翻訳の正確性について法的責任を負いません。原典である英語版(リンクからアクセス可能)もあわせて参照することを推奨します。
このドキュメントでは、REST APIを使用してデバイスの障害情報にアクセスする場合のEPNM通知のトラブルシューティング方法について説明します。
実装するクライアントは、通知を送信するためにEvolved Programmable Network Manager(EPNM)で使用される2つのメカニズムのいずれかを処理し、サブスクライブできる必要があります。
通知は、ネットワーク管理者とオペレータに、ネットワークに関連する重要なイベントや問題について警告します。 これらの通知により、潜在的な問題を迅速に検出して解決できるため、ダウンタイムが短縮され、ネットワーク全体のパフォーマンスが向上します。
EPNMは、電子メールによる通知、指定されたレシーバへのSimple Network Management Protocol(SNMP)トラップ、外部SyslogサーバへのSyslogメッセージなど、さまざまな方法を処理できます。これらのメソッドに加えて、EPNMはRepresentational State Transfer(REST)アプリケーションプログラミングインターフェイス(REST API)も提供します。REST APIを使用すると、インベントリ、アラーム、サービスアクティベーション、テンプレート実行、および高可用性に関する情報を取得できます。
現在、APIベースの通知は、次の2つの異なるメカニズムを使用してサポートされています。
すべての通知は同じスキーマを共有し、JSONまたはXML形式で取得できます。
デフォルトでは、アラームとインベントリの通知は無効になっています。これらを有効にするには、 restconf-config.properties
ファイルを次のように指定します(EPNMアプリケーションを再起動する必要はありません)。
/opt/CSCOlumos/conf/restconf/restconf-config.properties
epnm.restconf.inventory.notifications.enabled=true
epnm.restconf.alarm.notifications.enabled=true
この図では、クライアントマシンがWebSocketを実行し、事前定義済みのURL、基本認証、およびセキュアHTTPSチャネルを使用してEPNMに登録しています。
PythonのWebSocket-clientライブラリを使用して、クライアントマシンにWebSocketを作成できます。
import websocket
import time
import ssl
import base64
def on_message(ws, message):
print(message)
def on_error(ws, error):
print(error)
def on_close(ws, close_status_code, close_msg):
print("### closed \###")
def on_open(ws):
ws.send("Hello, Server!")
if __name__ == "__main__":
username = "username"
password = "password"
credentials = base64.b64encode(f"{username}:{password}".encode("utf-8")).decode("utf-8")
headers = {"Authorization": f"Basic {credentials}"}
websocket.enableTrace(True)
ws = websocket.WebSocketApp("wss://10.122.28.3/restconf/streams/v1/inventory.json",
on_message=on_message,
on_error=on_error,
on_close=on_close,
header=headers)
ws.on_open = on_open
ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})
このコードは、EPNMにサブスクライブするWebSocketクライアントを wss://10.122.28.3/restconf/streams/v1/inventory.json.
Pythonを使用する WebSocket
ライブラリを作成して、送受信メッセージの接続と処理を行います。サブスクリプションは、次の場合もあります(登録する通知の種類に基づいて)。
/restconf/streams/v1/alarm{.xml | .json}
/restconf/streams/v1/service-activation{.xml | .json}
/restconf/streams/v1/template-execution{.xml | .json}
/restconf/streams/v1/all{.xml | .json}
「 on_message
、 on_error
と on_close
関数は、WebSocket接続がメッセージを受信したとき、エラーに遭遇したとき、または閉じられたときに呼び出されるコールバック関数です。「 on_open
関数は、WebSocket接続が確立され、使用可能な状態になったときに呼び出されるコールバックである。
「 username
と password
変数には、リモートサーバへのアクセスに必要なログインクレデンシャルが設定されます。これらのクレデンシャルは、 base64
モジュールを追加し、WebSocket要求のヘッダーに追加します。
「 run_forever
メソッドは、接続を開始し、無制限に開き続け、サーバから送信されるメッセージをリッスンするためにWebSocketオブジェクトで呼び出されます。「 sslopt
パラメータは、接続のSSL/TLSオプションを設定するために使用されます。 「 CERT_NONE
フラグは証明書の検証を無効にします。
コードを実行します。WebSocketで通知を受信する準備を整えるには、次の手順を実行します。
(env) devasc@labvm:~/epnm$ python conn-oriented.py
--- request header ---
GET /restconf/streams/v1/inventory.json HTTP/1.1
Upgrade: websocket
Host: 10.122.28.3
Origin: https://10.122.28.3
Sec-WebSocket-Key: YYYYYYYYYYY
Sec-WebSocket-Version: 13
Connection: Upgrade
Authorization: Basic XXXXXXXXXXXX
-----------------------
--- response header ---
HTTP/1.1 101
Set-Cookie: JSESSIONID=5BFB68B0126226A0A13ABE595DC63AC9; Path=/restconf; Secure; HttpOnly
Strict-Transport-Security: max-age=31536000;includeSubDomains
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Upgrade: websocket
Connection: upgrade
Sec-WebSocket-Accept: Ozns7PGgHjrXj0nAgnlhbyVKPjc=
Date: Thu, 30 Mar 2023 16:18:19 GMT
Server: Prime
-----------------------
Websocket connected
++Sent raw: b'\x81\x8es\x99ry;\xfc\x1e\x15\x1c\xb5R*\x16\xeb\x04\x1c\x01\xb8'
++Sent decoded: fin=1 opcode=1 data=b'Hello, Server!'
++Rcv raw: b'\x81\x0eHello, Server!'
++Rcv decoded: fin=1 opcode=1 data=b'Hello, Server!'
Hello, Server!
次のDBクエリを使用して、サーバへの通知サブスクリプションを確認できます。
ade # ./sql_execution.sh "SELECT * from RstcnfNtfctnsSbscrptnMngr WHERE CONNECTIONTYPE = 'connection-oriented';" > /localdisk/sftp/conn-oriented.txt
ネットワークを可視化し、 conn-oriented.txt
ファイル(DBクエリの結果)をHTMLに変換するには、次のようなツールを使用します aha
(ここではUbuntuマシンでの使用例を示します)。
devasc@labvm:~/tmp$ sudo apt-get install aha
devasc@labvm:~/tmp$ cat conn-oriented.txt | aha > conn-oriented.html
次に、 conn-oriented.html
ブラウザ内のファイル:
EPNMのオンラインドキュメントでは、一度確立されると、アプリケーションのライフサイクルを通じて同じ接続が維持されます。
何らかの理由で特定のサブスクリプションを削除する必要がある場合は、 HTTP DELETE
要求を行います。 SUBSCRIPTIONID
URLで指定します。 https://
を参照。例:
devasc@labvm:~/tmp$ curl --location --insecure --request DELETE 'https://10.122.28.3/restconf/data/v1/cisco-notifications:subscription/3648313822269611499' \ > --header 'Accept: application/json' \ > --header 'Content-Type: application/json' \ > --header 'Authorization: Basic XXXXXXXX'
メッセージ、DEBUGエントリ、 show log
、使用するファイル名、SQL出力
コネクション型メカニズムを使用するクライアントが通知を適切に受信しない原因をトラブルシューティングするには、表示されたDBクエリを実行して、サブスクリプションが存在するかどうかを確認します。これが存在しない場合は、クライアントの所有者にサブスクリプションを発行するように依頼します。
それまでの間、DEBUGレベルは
com.cisco.nms.nbi.epnm.restconf.notifications.handler.NotificationsHandlerAdapter
そのため、サブスクリプションが送信されるたびに受信できます。
ade # sudo /opt/CSCOlumos/bin/setLogLevel.sh com.cisco.nms.nbi.epnm.restconf.notifications.handler.NotificationsHandlerAdapter DEBUG 2>/dev/null Loglevel set to DEBUG for com.cisco.nms.nbi.epnm.restconf.notifications.handler.NotificationsHandlerAdapter .
サブスクリプションの送信後、WebSocketクライアントのIPアドレスを持つエントリが
localhost_access_log.txt
:を入力します。
ade # zgrep -h '"GET /restconf/streams/.* HTTP/1.1" 101' $(ls -1t /opt/CSCOlumos/logs/localhost_access_log.txt*) 10.82.244.205 - - [28/Aug/2023:16:13:03 -0300] "GET /restconf/streams/v1/inventory.json HTTP/1.1" 101 - 10.82.244.205 - - [28/Aug/2023:22:17:05 -0300] "GET /restconf/streams/v1/inventory.json HTTP/1.1" 101 -
最後に、再度DBを確認します(タイムスタンプが
localhost_access_log.txt
).
次のログは、サブスクリプションのPOST要求がいつ送信されるかを示しています。
ade # grep -Eh 'DEBUG com.cisco.nms.nbi.epnm.restconf.notifications.handler.NotificationsHandlerAdapter - (Successfully subscribed a connection-oriented|Requested resource uuid)' $(ls -1t /opt/CSCOlumos/logs/restconf-nbi.log*) 2023-08-28 22:17:06,221: DEBUG com.cisco.nms.nbi.epnm.restconf.notifications.handler.NotificationsHandlerAdapter - Successfully subscribed a connection-oriented subscription with user: root and topic: inventory 2023-08-28 22:17:06,221: DEBUG com.cisco.nms.nbi.epnm.restconf.notifications.handler.NotificationsHandlerAdapter - Successfully subscribed a connection-oriented subscription with user: root and topic: inventory 2023-08-28 22:17:06,221: DEBUG com.cisco.nms.nbi.epnm.restconf.notifications.handler.NotificationsHandlerAdapter - Requested resource uuid 852a674a-e3d0-4ecc-8ea0-787af30f1305 2023-08-28 22:17:06,221: DEBUG com.cisco.nms.nbi.epnm.restconf.notifications.handler.NotificationsHandlerAdapter - Requested resource uuid 852a674a-e3d0-4ecc-8ea0-787af30f1305
接続が維持されている限り、push-change-updateタイプの通知がEPN-Mサーバから通知をサブスクライブしたすべてのクライアントに送信されます。この例は、NCS2kのホスト名が変更されたときにEPNMによって送信される通知の1つを示しています。
{ "push.push-change-update":{ "push.notification-id":2052931975556780123, "push.topic":"inventory", "push.time-of-update":"2023-03-31 13:50:36.608", "push.time-of-update-iso8601":"2023-03-31T13:50:39.681-03:00", "push.operation":"push:modify", "push.update-data":{ "nd.node":{ "nd.description":"SOFTWARE=ONS,IPADDR=10.10.1.222,IPMASK=255.255.255.0,DEFRTR=255.255.255.255,IPV6ENABLE=N,IIOPPORT=57790,NAME=\\"tcc222c\\",SWVER=11.1.23,LOAD=11.123-022-D2911-W,PROTSWVER=none,PROTLOAD=none,DEFDESC=\\"Factory Defaults\\",PLATFORM=NCS2KFS-M15,SECUMODE=NORMAL,SUPPRESSIP=NO,MODE=MULTISHELF,AUTOPM=NO,SERIALPORTECHO=N,OSIROUTINGMODE=IS1,OSIL1BUFSIZE=512,NET=39840F800000000000000000000E67AD8A01DE00,SYSTEMMODE=SONET,ALARMSUPPRESS=N,CVSTATUS=VERIFICATION_IDLE,DEGILTHR=1.5,FAILILTHR=4.0,LATITUDE=N381343,LONGITUDE=W1223808,LCDSETTING=ALLOW-CONFIGURATION,NODEID=AD8A01DE,NODECVSTATUS=TRUE,ENABLESOCKSPROXY=FALSE,PROXYPORT=1080,ALARMPROFILENAME=\\"Default\\",COOLINGPROFILECTRL=AUTO,MACADDR=0e-67-ffffffad-ffffff8a-01-ffffffde,SUBNETMASKLEN=24,FORWARDDHCPENABLE=N,UPTIME=\\"217days\/14hours\/40mins\/17secs\\",DISCARDOTDRALARM=YES,CVTIMEBTWRUN=360", "nd.equipment-list":"", "nd.fdn":"MD=CISCO_EPNM!ND=tcc222c", "nd.sys-up-time":"217 days, 14:40:170.00" } } } }
コネクションレス型通知
次に、次の場合のワークフローを示します
connectionless
通知:
REST WebサービスPythonクライアントの実行
ユーザは、XMLペイロードやJSONペイロードをPOST要求として受け入れることができるREST Webサービスを持っていることが想定されます。このRESTサービスは、 Cisco EPNMrestconf notifications frameworkは通知を発行します。これは リモートマシンにインストールされるREST Webサービスの例:
from flask import Flask, request, jsonify app = Flask(__name__) @ app.route('/api/posts', methods=['POST']) def create_post(): post_data = request.get_json() response = {'message': 'Post created successfully'} print(post_data) return jsonify(response), 201 if __name__ == '__main__': app.run(debug=True, host='10.122.28.2', port=8080)
これは、単一のエンドポイントを定義するPython Flask Webアプリケーションです
/api/posts
受け入れる HTTP POST
保持されます。「 create_post()
関数は常に呼び出されます。 HTTP POST
要求が行われます /api/posts
.
内部 create_post()
関数を呼び出した場合、要求からデータを取得するには、 request.get_json()
JSONペイロードのディクショナリを返します。次に、ペイロードに次の文字列が出力されます print(post_data)
デバッグに使用します。その後、キーを含む応答メッセージが作成されます message
および値 Post created successfully
(辞書形式)。この応答メッセージは、HTTPステータスコード201(作成済み)でクライアントに返されます。
「
if __name__ == '__main__':
blockは、スクリプトがモジュールとしてインポートされるのではなく、メインプログラムとして実行されているかどうかをチェックする標準のPythonコンストラクトです。スクリプトがメインプログラムとして実行される場合、Flaskアプリケーションが起動され、指定されたIPアドレスとポートで実行されます。「 debug=True
この引数はデバッグモードを有効にします。デバッグモードでは、詳細なエラーメッセージが表示され、コードに変更が加えられた際にサーバが自動的にリロードされます。
プログラムを実行して、
REST
webサービス:
(venv) [apinelli@centos8_cxlabs_spo app]$ python connectionless.py * Serving Flask app 'connectionless' (lazy loading) * Environment: production WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Debug mode: on * Running on http://10.122.28.2:8080/ (Press CTRL+C to quit) * Restarting with stat * Debugger is active! * Debugger PIN: 117-025-064
コネクションレス型クライアントのサブスクリプション
ユーザは通知をサブスクライブします。
REST
購読するトピックとともにサービスエンドポイントが送信されます。この場合、トピックは次のとおりです all
を参照。
[apinelli@centos8_cxlabs_spo ~]$ curl --location -X POST --insecure 'https://10.122.28.3/restconf/data/v1/cisco-notifications:subscription' \ > --header 'Accept: application/json' \ > --header 'Content-Type: application-json' \ > --header 'Authorization: Basic XXXXXXXXX' \ > --data '{ > "push.endpoint-url":"http://10.122.28.2:8080/api/posts", > "push.topic":"all", > "push.format": "json" > }'
予想される応答は201応答で、応答の本文のサブスクリプションからの詳細も含まれています。
{ "push.notification-subscription": { "push.subscription-id": 7969974728822328535, "push.subscribed-user": "root", "push.endpoint-url": "http:\/\/10.122.28.2:8080\/api\/posts", "push.topic": "all", "push.creation-time": "Tue Aug 29 10:02:05 BRT 2023", "push.creation-time-iso8601": "2023-08-29T10:02:05.887-03:00", "push.time-of-update": "Tue Aug 29 10:02:05 BRT 2023", "push.time-of-update-iso8601": "2023-08-29T10:02:05.887-03:00", "push.format": "json", "push.connection-type": "connection-less" } }
ユーザがGET要求でサブスクライブしている通知のリストを取得できます。
curl --location --insecure 'https://10.122.28.3/restconf/data/v1/cisco-notifications:subscription' \ --header 'Accept: application/json' \ --header 'Content-Type: application/json' \ --header 'Authorization: Basic XXXXXXXXXXX'
得られた応答は次のとおりです。
{ "com.response-message": { "com.header": { "com.firstIndex": 0, "com.lastIndex": 1 }, "com.data": { "push.notification-subscription": [ { "push.subscription-id": 2985507860170167151, "push.subscribed-user": "root", "push.endpoint-url": "http://10.122.28.2:8080/api/posts", "push.session-id": 337897630, "push.topic": "inventory", "push.creation-time": "Fri Mar 31 17:45:47 BRT 2023", "push.time-of-update": "Fri Mar 31 17:45:47 BRT 2023", "push.format": "json", "push.connection-type": "connection-less" }, { "push.subscription-id": 7969974728822328535, "push.subscribed-user": "root", "push.endpoint-url": "http://10.122.28.2:8080/api/posts", "push.session-id": 0, "push.topic": "all", "push.creation-time": "Tue Aug 29 10:02:05 BRT 2023", "push.time-of-update": "Tue Aug 29 10:02:05 BRT 2023", "push.format": "json", "push.connection-type": "connection-less" } ] } } }
メッセージ、DEBUGエントリ、 show log,
使用するファイル名、SQL出力
応答から、サブスクリプションが2つあることに注目してください。1つは
all ("push.topic": "all")
インベントリ用に1つ ("push.topic": "inventory")
を参照。データベースに対するクエリを使用して確認できます(サブスクリプションのタイプが「コネクションレス型」であり、 SUBSCRIPTIONID
フィールドは出力に一致します。 GET
コマンドを入力します(黄色で強調表示)。
ade # ./sql_execution.sh "SELECT * from RstcnfNtfctnsSbscrptnMngr WHERE CONNECTIONTYPE = 'connection-less';" > /localdisk/sftp/connectionless.txt
コネクションレス型サブスクリプションを削除する必要がある場合は、
HTTP DELETE
削除するサブスクリプションIDを指定して要求します。削除すると仮定します subscription-id 2985507860170167151
:を入力します。
curl --location --insecure --request DELETE 'https://10.122.28.3/restconf/data/v1/cisco-notifications:subscription/2985507860170167151' \ --header 'Accept: application/json' \ --header 'Content-Type: application-json' \ --header 'Authorization: Basic XXXXXXXXXX'
DBに再度クエリを実行すると、
SUBSCRIPTIONID
等しい 7969974728822328535
.
インベントリの変更が発生すると、クライアントは通知を印刷します(これは
connection-oriented
に関するセクションに表示される通知 connected-oriented
201応答が続きます。
(venv) [apinelli@centos8_cxlabs_spo app]$ python connectionless.py * Serving Flask app 'connectionless' (lazy loading) * Environment: production WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Debug mode: on * Running on http://10.122.28.2:8080/ (Press CTRL+C to quit) * Restarting with stat * Debugger is active! * Debugger PIN: 117-025-064 {'push.push-change-update': {'push.notification-id': -2185938612268228828, 'push.topic': 'inventory', 'push.time-of-update': '2023-03-31 17:47:04.865', 'push.time-of-update-iso8601': '2023-03-31T17:47:10.846-03:00', 'push.operation': 'push:modify', 'push.update-data': {'nd.node': {'nd.collection-status': 'Synchronizing', 'nd.equipment-list': '', 'nd.fdn': 'MD=CISCO_EPNM!ND=tcc221'}}}} 10.122.28.3 - - [31/Mar/2023 16:47:23] "POST /api/posts HTTP/1.1" 201 - {'push.push-change-update': {'push.notification-id': -1634959052215805274, 'push.topic': 'inventory', 'push.time-of-update': '2023-03-31 17:47:12.786', 'push.time-of-update-iso8601': '2023-03-31T17:47:14.935-03:00', 'push.operation': 'push:modify', 'push.update-data': {'nd.node': {'nd.equipment-list': '', 'nd.fdn': 'MD=CISCO_EPNM!ND=tcc221c', 'nd.name': 'tcc221c'}}}} 10.122.28.3 - - [31/Mar/2023 16:47:27] "POST /api/posts HTTP/1.1" 201 -
結論
このドキュメントでは、EPNM(
connectionless
と connection-oriented
)について説明し、シミュレーションのベースとして使用できるそれぞれのクライアントの例を示します。
関連情報
改定 | 発行日 | コメント |
---|---|---|
1.0 |
10-Apr-2023 |
初版 |