このページの目次
gNOI ファイル サービス
概要 gNOI File
サービスを使用して、ネットワーク デバイス上のファイルを管理します。
File
サービス RPC を使用して、ファイルを転送および削除したり、ファイルに関する情報を取得したりします。プロトタイプ定義ファイルは https://github.com/openconfig/gnoi/blob/master/file/file.proto にあります。
対応する RPC
リリースで導入された | RPC | の説明 |
---|---|---|
Get() |
ターゲットからファイルの内容を読み取ってストリーミングします。 ファイルは順次メッセージによってストリーミングされ、各メッセージには最大 64KB のデータが含まれます。送信されたデータのハッシュを含むストリームを閉じる前に、最後のメッセージが送信されます。ファイルが存在しない場合、またはファイルの読み取り中にエラーが発生した場合、この操作はエラーを返します。 |
Junos OS Evolved 22.2R1 |
Put() |
ターゲット上のファイルにデータをストリーミングします。 ファイルは順次メッセージで送信され、各メッセージには最大 64KB のデータが含まれます。データのハッシュを含む最終メッセージを送信する必要があります。 場所が存在しない場合、またはデータの書き込み中にエラーがある場合、この操作はエラーを返します。チェックサムが受信されない場合、ターゲットは部分的に送信されたファイルを削除します。障害が発生しても、同じ名前の既存のファイルは変更されません。 |
Junos OS Evolved 22.2R1 |
Remove() |
指定したファイルをターゲットから削除します。ファイルが存在しない場合、ファイル パスがディレクトリに解決された場合、または削除操作でエラーが発生した場合、この操作はエラーを返します。 |
Junos OS Evolved 22.2R1 |
Stat() |
ターゲット デバイス上のファイルに関するメタデータを返します。この操作は、ファイルが存在しない場合、またはメタデータへのアクセス中にエラーがある場合にエラーを返します。 |
Junos OS Evolved 22.2R1 |
ネットワーク デバイスの設定
始める前に:
- 「gRPC サービスの構成」の説明に従って、ネットワーク デバイスで gRPC サービスを構成します。
- gNOI サービスの設定の説明に従って、gNOI 操作をサポートするようにネットワーク管理システムを設定します。
例: ファイルの取得
この例では、 gnoi_file_get.py
ターゲットデバイスからローカルネットワーク管理システムにファイルをダウンロードするためのシンプルなPythonアプリケーションを提供します。
アプリケーションはモジュール grpc_channel
をインポートしてチャネルを確立します。この grpc_channel
モジュールについては、 gNOI サービスの設定で説明しています。アプリケーションの引数はファイルに格納されます args_file_get.txt
。ここでは、アプリケーション ファイルと引数ファイルを示します。
gnoi_file_get.py
"""gNOI Get File utility.""" from __future__ import print_function import argparse import hashlib import logging from getpass import getpass import file_pb2 import file_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.') parser.add_argument('--dest_file', dest='dest_file', type=str, default='', help='Full path for destination file. Default ""') parser.add_argument('--source_file', dest='source_file', type=str, default='', help='Full path of source file to retrieve. Default ""') args = parser.parse_args() return args def send_rpc(channel, metadata, args): stub = file_pb2_grpc.FileStub(channel) print("Executing GNOI::File::Get") # Prepare hash generator gen_hash = hashlib.sha256() # Get File req = file_pb2.GetRequest() req.remote_file = args.source_file hashvalue = None hm = None count = 1 with open(args.dest_file, "wb") as file: # Read data in 64 KB chunks and calculate checksum and data messages print("Retrieving file") try: for msg in stub.Get(req, metadata=metadata, timeout=120): if msg.WhichOneof('response') == "contents": count = count + 1 file.write(msg.contents) gen_hash.update(msg.contents) else: hashvalue = msg.hash.hash hm = msg.hash.method print("File transfer complete: ", args.dest_file) except Exception as e: logging.error("Get() operation error. %s", e) print(e) else: file.close() ehashvalue = gen_hash.hexdigest().encode() if (ehashvalue != hashvalue): raise ValueError( 'Hash value mismatch. Expected "%s", got "%s"' % (ehashvalue, hashvalue)) if (hm != 1): raise ValueError( 'Hash method mismatch. Expected "1", got "%s"' % (hm)) logging.info("Downloaded file: %s", args.dest_file) def main(): parser = argparse.ArgumentParser(fromfile_prefix_chars='@') 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) send_rpc(channel, metadata, args) 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()
args_file_get.txt
--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 --source_file=/var/log/messages --dest_file=downloads/10.53.52.169-messages
アプリケーションの実行
クライアントは、アプリケーションを実行すると、指定されたファイルをターゲット デバイスからローカル デバイスに転送します。
lab@gnoi-client:~/src/gnoi/proto$ python3 gnoi_file_get.py @args_file_get.txt gRPC server password for executing RPCs: Creating channel Executing GNOI::File::Get Retrieving file File transfer complete: downloads/10.53.52.169-messages
例: ファイルの書き込み
この例では、 gnoi_file_put.py
ローカルネットワーク管理システムからターゲットデバイスにファイルをアップロードするための簡単なPythonアプリケーションを提供します。
アプリケーションはモジュール grpc_channel
をインポートしてチャネルを確立します。この grpc_channel
モジュールについては、 gNOI サービスの設定で説明しています。アプリケーションの引数はファイルに格納されます args_file_put.txt
。ここでは、アプリケーション ファイルと引数ファイルを示します。
gnoi_file_put.py
"""gNOI Put File utility.""" from __future__ import print_function import argparse import hashlib import logging import sys from functools import partial from getpass import getpass import file_pb2 import file_pb2_grpc from grpc_channel import grpc_authenticate_channel_mutual MAX_BYTES = 65536 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.') parser.add_argument('--dest_file', dest='dest_file', type=str, default='', help='Full path for destination file. Default ""') parser.add_argument('--dest_file_mode', dest='dest_file_mode', type=int, default=600, help='Destination file mode (file permissions in octal). Default 600') parser.add_argument('--hash_method', dest='hash_method', type=str, default='unspecified', help='Hash method. Valid values are md5, sha256, sha512, or unspecified. Default: unspecified') parser.add_argument('--source_file', dest='source_file', type=str, default='', help='Full path of source file to transfer. Default ""') args = parser.parse_args() return args def send_rpc(channel, metadata, args): stub = file_pb2_grpc.FileStub(channel) print("Executing GNOI::File::Put") # Prepare hash generator if args.hash_method == "sha256": gen_hash = hashlib.sha256() hm = 1 elif args.hash_method == "sha512": gen_hash = hashlib.sha512() hm = 2 elif args.hash_method == "md5": gen_hash = hashlib.md5() hm = 3 else: print("Unsupported hash method:", args.hash_method) sys.exit(1) # Put File req = file_pb2.PutRequest() req.open.remote_file = args.dest_file req.open.permissions = args.dest_file_mode it = [] it.append(req) # Read source file and add to request with open(args.source_file, "rb") as file: # Read data in 64 KB chunks and calculate checksum and data messages for data in iter(partial(file.read, MAX_BYTES), b''): req = file_pb2.PutRequest() req.contents = data it.append(req) gen_hash.update(data) # Checksum message req = file_pb2.PutRequest() req.hash.hash = gen_hash.hexdigest().encode() req.hash.method = hm it.append(req) # Send PutRequest try: print("Sending file.") response = stub.Put(iter(it), metadata=metadata, timeout=120) except Exception as e: logging.error("Error uploading source file %s to %s. Error: %s", args.source_file, args.dest_file, e) print(e) else: print("File transfer complete: ", args.dest_file) logging.info("Uploaded file: %s", args.dest_file) def main(): parser = argparse.ArgumentParser(fromfile_prefix_chars='@') 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) send_rpc(channel, metadata, args) 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()
args_file_put.txt
--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 --source_file=scripts/op/ospf-summary.slax --dest_file=/var/db/scripts/op/ospf-summary.slax --dest_file_mode=644 --hash_method=sha256
アプリケーションの実行
クライアントは、アプリケーションを実行すると、指定されたファイルをローカルデバイスからターゲットデバイスに転送し、その値に従って dest_file_mode
ファイルのアクセス許可を設定します。
lab@gnoi-client:~/src/gnoi/proto$ python3 gnoi_file_put.py @args_file_put.txt gRPC server password for executing RPCs: Creating channel Executing GNOI::File::Put Sending file. File transfer complete: /var/db/scripts/op/ospf-summary.slax