gNOI サービスを設定する
概要 ネットワークデバイス上でgNOI操作を実行できるgRPCクライアントとして、リモートネットワーク管理システムを設定します。
gRPC ネットワーク運用インターフェイス(gNOI)は、gRPC リモート プロシージャ コール(gRPC)フレームワークを使用して、ネットワーク デバイスで操作を実行します。ネットワーク管理システムには、gRPC スタックがインストールされている必要があります。
OpenConfig は、 gNOI サービスのプロトタイプ定義ファイルを定義します。プロトタイプ定義ファイルは、特定のサービスの操作 (RPC) とデータ構造 (メッセージ) を定義します。定義は言語に依存しません。gRPC では、さまざまな言語を使用してサービス操作を実行できます。選択した言語のプロト定義ファイルをコンパイルする必要があります。次に、コンパイル済みファイル内のオブジェクト(クラス、関数、メソッドなど)を使用してネットワークデバイス上のgRPCサーバーに接続し、目的の操作を実行するアプリケーションを作成します。
サポートされているさまざまな言語で gRPC を使用する方法については、 gRPC のドキュメントを参照してください。以下のセクションでは、gRPC クライアントをセットアップし、Python 用の gNOI プロト定義ファイルをダウンロードしてコンパイルするためのサンプル コマンドを提供します。オペレーティング システム、環境、および選択した gRPC 言語に適したコマンドを使用する必要があります。
gRPC クライアントを構成する前に、「 gRPC サービスの構成」で定義されているように gRPC サーバーを構成します。
gRPC クライアントを設定する
gNOI は、gRPC フレームワークを使用して、ネットワーク デバイス上で操作を実行します。gRPC では、さまざまな言語の使用がサポートされています。選択した言語を使用して gNOI 操作を実行する前に、ネットワーク管理システムに gRPC スタックをインストールする必要があります。
たとえば、Ubuntu 20.04 LTS を実行しているネットワーク管理システムに Python 用の gRPC スタックをインストールするには (必要に応じて使用 sudo ):
プロトタイプ定義ファイルのコンパイル
gRPC では、多くの言語の使用がサポートされています。ネットワーク デバイスで gRPC 操作を実行するには、選択した言語のそれぞれの proto 定義ファイルをコンパイルする必要があります。OpenConfig は、 OpenConfig GitHub リポジトリに必要なプロトタイプ定義ファイルを提供します。プロトコル バッファー コンパイラ (protoc または同等のアプリケーション) を使用してファイルを .proto コンパイルします。
この設定では、必要なすべての .proto ファイルをディレクトリにコピーし、相対インポートステートメントを使用するようにファイルを更新してから、ファイルをコンパイルするスクリプトを実行します。
Python 用の gNOI プロト定義ファイルをダウンロードしてコンパイルするには、次のようにします。
gNOI アプリケーションの作成
プロトタイプ定義ファイルをコンパイルした後、コンパイル済みファイル内のオブジェクトを使用するアプリケーションを作成します。アプリケーションは、ネットワーク デバイス上の gRPC サーバーに接続し、目的の操作を実行します。このセクションでは、2 つのサンプル Python モジュールをそれぞれのセクションで説明します。
grpc_channel.py
Python モジュールには grpc_channel.py 、選択した認証方法 (サーバーのみまたは相互) に指定された引数を使用して gRPC チャネルを作成するサンプル関数が用意されています。
import grpc
from os.path import isfile
def grpc_authenticate_channel_mutual(server, port, root_ca_cert="", client_key="", client_cert=""):
if not isfile(root_ca_cert):
raise Exception("Error: root_ca_cert file does not exist")
if (client_key == "") or (not isfile(client_key)):
raise Exception(
"Error: client_key option is missing or target file does not exist")
elif (client_cert == "") or (not isfile(client_cert)):
raise Exception(
"Error: client_cert option is empty or target file does not exist")
print("Creating channel")
creds = grpc.ssl_channel_credentials(open(root_ca_cert, 'rb').read(),
open(client_key, 'rb').read(),
open(client_cert, 'rb').read())
channel = grpc.secure_channel('%s:%s' % (server, port), creds)
return channel
def grpc_authenticate_channel_server_only(server, port, root_ca_cert=""):
if isfile(root_ca_cert):
print("Creating channel")
creds = grpc.ssl_channel_credentials(open(root_ca_cert, 'rb').read(),
None,
None)
channel = grpc.secure_channel('%s:%s' % (server, port), creds)
return channel
else:
raise Exception("root_ca_cert file does not exist")
gnoi_connect_cert_auth_mutual.py
gnoi_connect_cert_auth_mutual.py Python アプリケーションは、指定された gRPC サーバーと gRPC チャネルを確立し、単純な gNOI System サービス操作を実行します。ユーザーは、アプリケーションへの入力として、必要な接続と相互認証情報を提供します。アプリケーションは、grpc_channel.pyモジュール内の適切な関数を呼び出して、クライアントとサーバー間の gRPC チャネルを確立します。アプリケーションが gRPC チャネルを正常に確立すると、単純なシステム サービス RPC を実行して、ネットワーク デバイスから時刻を取得します。
"""gRPC gNOI Time request utility."""
from __future__ import print_function
import argparse
import logging
from getpass import getpass
import system_pb2
import system_pb2_grpc
from grpc_channel import grpc_authenticate_channel_mutual
def get_args(parser):
parser.add_argument('--server',
dest='server',
type=str,
default='localhost',
help='Server IP or name. Default is localhost')
parser.add_argument('--port',
dest='port',
nargs='?',
type=int,
default=50051,
help='The server port. Default is 50051')
parser.add_argument('--client_key',
dest='client_key',
type=str,
default='',
help='Full path of the client private key. Default ""')
parser.add_argument('--client_cert',
dest='client_cert',
type=str,
default='',
help='Full path of the client certificate. Default ""')
parser.add_argument('--root_ca_cert',
dest='root_ca_cert',
required=True,
type=str,
help='Full path of the Root CA certificate.')
parser.add_argument('--user_id',
dest='user_id',
required=True,
type=str,
help='User ID for RPC call credentials.')
args = parser.parse_args()
return args
def send_rpc(channel, metadata):
stub = system_pb2_grpc.SystemStub(channel)
print("Executing GNOI::System::Time RPC")
req = system_pb2.TimeRequest()
try:
response = stub.Time(request=req, metadata=metadata, timeout=60)
except Exception as e:
logging.error('Error executing RPC: %s', e)
print(e)
else:
logging.info('Received message: %s', response)
return response
def main():
parser = argparse.ArgumentParser()
args = get_args(parser)
grpc_server_password = getpass("gRPC server password for executing RPCs: ")
metadata = [('username', args.user_id),
('password', grpc_server_password)]
try:
# Establish grpc channel to network device
channel = grpc_authenticate_channel_mutual(
args.server, args.port, args.root_ca_cert, args.client_key, args.client_cert)
response = send_rpc(channel, metadata)
print("Response received: time since last epoch in nanoseconds is ", str(response))
except Exception as e:
logging.error('Received error: %s', e)
print(e)
if __name__ == '__main__':
logging.basicConfig(filename='gnoi-testing.log',
format='%(asctime)s %(levelname)-8s %(message)s',
level=logging.INFO,
datefmt='%Y-%m-%d %H:%M:%S')
main()
アプリケーションの実行
gNOI サービス操作を実行するアプリケーションを作成したら、アプリケーションを実行し、必要な引数を指定します。次の例では、前のセクションで提供したスクリプトを使用して、ネットワーク デバイス上の gRPC サーバーに接続し、時刻を要求します。gRPC サーバーは、クライアントの証明書を要求して検証するように構成されています。
-
相互認証の場合、クライアントは、サーバーのIPアドレス、gRPCポート、およびルートCA証明書に加えて、PEM形式の独自のキーとX.509公開キー証明書を提供します。クライアントは RPC 呼び出しの資格情報も提供します。引数は
user_idユーザー名を指定し、アプリケーションはユーザー パスワードの入力を求めます。lab@gnoi-client:~/src/proto$ python3 gnoi_connect_cert_auth_mutual.py --server 10.53.52.169 --port 50051 --root_ca_cert /etc/pki/certs/serverRootCA.crt --client_key /home/lab/certs/client.key --client_cert /home/lab/certs/client.crt --user_id gnoi-user gRPC server password for executing RPCs: Creating channel Executing GNOI::System::Time RPC Response received: time since last epoch in nanoseconds is time: 1650061065769701762