gNOI 서비스 구성
요약 원격 네트워크 관리 시스템을 네트워크 디바이스에서 gNOI 작업을 실행할 수 있는 gRPC 클라이언트로 구성합니다.
gRPC 네트워크 작업 인터페이스(gNOI)는 gRPC 원격 프로시저 호출(gRPC) 프레임워크를 사용하여 네트워크 디바이스에서 작업을 수행합니다. 네트워크 관리 시스템에는 gRPC 스택이 설치되어 있어야 합니다.
OpenConfig는 gNOI 서비스에 대한 프로토 정의 파일을 정의합니다. 프로토 정의 파일은 주어진 서비스에 대한 작업(RPC) 및 데이터 구조(메시지)를 정의합니다. 정의는 언어에 구애받지 않습니다. gRPC는 다양한 언어를 사용하여 서비스 작업을 실행할 수 있도록 지원합니다. 선택한 언어에 대한 proto 정의 파일을 컴파일해야 합니다. 그런 다음 컴파일된 파일의 개체(클래스, 함수, 메서드 등)를 사용하여 네트워크 디바이스의 gRPC 서버에 연결하고 원하는 작업을 실행하는 애플리케이션을 만듭니다.
지원되는 다른 언어에서 gRPC를 사용하는 방법에 대한 자세한 내용은 gRPC 설명서를 참조하세요. 다음 섹션에서는 gRPC 클라이언트를 설정하고 Python용 gNOI proto 정의 파일을 다운로드 및 컴파일하기 위한 샘플 명령을 제공합니다. 선택한 운영 체제, 환경 및 gRPC 언어에 적합한 명령을 사용해야 합니다.
gRPC 클라이언트를 구성하기 전에 gRPC 서비스 구성에 정의된 대로 gRPC 서버를 구성합니다.
gRPC 클라이언트 설정
gNOI는 gRPC 프레임워크를 사용하여 네트워크 디바이스에서 작업을 수행합니다. gRPC는 다양한 언어 사용을 지원합니다. 선택한 언어를 사용하여 gNOI 작업을 수행하려면 먼저 네트워크 관리 시스템에 gRPC 스택을 설치해야 합니다.
예를 들어 Ubuntu 20.04 LTS를 실행하는 네트워크 관리 시스템에 Python용 gRPC 스택을 설치하려면(적절한 경우 사용 sudo
):
Proto Definiton 파일 컴파일
gRPC는 여러 언어 사용을 지원합니다. 네트워크 디바이스에서 gRPC 작업을 수행하려면 선택한 언어에 대한 각 프로토 정의 파일을 컴파일해야 합니다. OpenConfig는 OpenConfig GitHub 리포지토리에 필요한 프로토 정의 파일을 제공합니다. 프로토콜 버퍼 컴파일러(protoc
또는 동등한 응용 프로그램)를 사용하여 파일을 컴파일합니다 .proto
.
이 설정에서는 원하는 .proto
모든 파일을 디렉터리에 복사하고 상대 가져오기 문을 사용하도록 파일을 업데이트한 다음 파일을 컴파일하는 스크립트를 실행합니다.
Python용 gNOI proto 정의 파일을 다운로드하고 컴파일하려면:To download and compile the gNOI proto definition files for Python:
gNOI 응용 프로그램 만들기
proto 정의 파일을 컴파일한 후 컴파일된 파일의 개체를 사용하는 응용 프로그램을 만듭니다. 애플리케이션은 네트워크 디바이스의 gRPC 서버에 연결하고 원하는 작업을 수행합니다. 이 섹션에서는 해당 섹션에 설명된 두 개의 샘플 Python 모듈을 제공합니다.
grpc_channel.py
grpc_channel.py
Python 모듈은 선택한 인증 방법(서버 전용 또는 상호)에 제공된 인수를 사용하여 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
Python 애플리케이션은 gnoi_connect_cert_auth_mutual.py
지정된 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