帮助我们改善您的体验。

让我们了解您的想法。

您是否能抽出两分钟的时间完成一份问卷调查?

close
keyboard_arrow_left
gRPC 网络服务用户指南
Table of Contents Expand all
list Table of Contents

机器翻译对您有帮助吗?

starstarstarstarstar
Go to English page
免责声明:

我们将使用第三方机器翻译软件翻译本页面。瞻博网络虽已做出相当大的努力提供高质量译文,但无法保证其准确性。如果对译文信息的准确性有任何疑问,请参阅英文版本. 可下载的 PDF 仅提供英文版.

gNOI 文件服务

date_range 12-Jul-23

总结 使用 gNOI File 服务管理网络设备上的文件。

使用 File 服务 RPC 传输和删除文件或检索有关文件的信息。proto 定义文件位于 https://github.com/openconfig/gnoi/blob/master/file/file.proto

支持的 RPC

表 1:支持的文件.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 操作
要在目标设备上执行文件操作,客户端必须具有与文件系统交互的相应权限。

示例:获取文件

此示例提供了一个简单的 Python 应用程序, gnoi_file_get.py用于将文件从目标设备下载到本地网络管理系统。

应用程序会导入模块grpc_channel以建立通道。配置 gNOI 服务中介绍了该grpc_channel模块。应用程序参数存储在文件中args_file_get.txt。此处显示应用程序和参数文件。

gnoi_file_get.py

content_copy zoom_out_map
          
         
               
"""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

content_copy zoom_out_map
--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

执行应用程序

客户端执行应用程序时,会将指定文件从目标设备传输到本地设备。

content_copy zoom_out_map
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

示例:放置文件

此示例提供了一个简单的 Python 应用程序, gnoi_file_put.py用于将文件从本地网络管理系统上传到目标设备。

应用程序会导入模块grpc_channel以建立通道。配置 gNOI 服务中介绍了该grpc_channel模块。应用程序参数存储在文件中args_file_put.txt。此处显示应用程序和参数文件。

gnoi_file_put.py

content_copy zoom_out_map
          
         
               
"""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

content_copy zoom_out_map
--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

content_copy zoom_out_map
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
external-footer-nav