开发设备外 JET 应用程序
概述
您可以使用 JET 开发设备外运行的应用程序。这使您可以利用网络上所有设备上的 JET 优势。为方便开发,您可以使用自己选择的语言注销设备 JET 应用程序。要开发设备外应用程序:
下载和编译 IDL 文件。
使用您选择的语言开发应用程序。
打包应用程序。
在外部服务器上部署应用程序包或直接从 JET VM 运行应用程序。
图 1 显示了设备外应用程序开发工作流程。
准备部署您的应用程序
在外部服务器上或直接从 JET 虚拟机运行您的应用程序。在外部服务器上部署应用程序之前,您需要配置与 Junos OS 的 JET 交互。
配置与 Junos OS 的 JET 交互
要运行设备外应用程序,您需要启用 request-response
Junos OS 或 Junos OS Evolved 上的配置。使用 request-response 服务时,客户端应用程序会发出请求,并同步等待 Junos 服务器的响应。使用本节配置在安全套接字层 (SSL) 模式下运行的请求响应服务的 JET 服务进程 (jsd)。这提高了安全性并支持基于 SSL 的 API 连接。
目前,JET 支持传输层安全 (TLS) 版本 1.2 进行证书交换,并支持多种加密算法,但不支持相互身份验证。这意味着客户端可以对服务器进行身份验证,但服务器无法使用 SSL/TLS 证书对客户端进行身份验证。对于客户端身份验证,请使用身份验证服务 API 中的 LoginCheck() 过程。
-
通过在本地添加和配置证书名称,允许 jsd 使用 SSL。证书必须是 RSA 证书。不支持 ECDSA 和 DSA SSL 证书。
此方法与 Junos OS 中其他基于 SSL 的服务(如 xnm-ssl)相同。跟踪您在生成证书时指定的证书名称条目。您将将其用于下一
HOST_OVERRIDE
节 Python 应用程序示例中的选项。在此示例中,证书名称为router
。user@jet-vm:~ jet$ openssl genrsa -aes256 -out router.key.orig 2048 user@jet-vm:~ jet$ openssl req -new -key router.key.orig -out router.csr user@jet-vm:~ jet$ openssl rsa -in router.key.orig -out router.key user@jet-vm:~ jet$ openssl x509 -req -days 365 -in router.csr -signkey router.key -out router.crt user@jet-vm:~ jet$ cat router.crt router.key > router.pem
注意:如果证书更新了同一标识符,则不会对 jsd 进行更改。您需要使用 jsd 层次结构中的新标识符配置证书,或执行 jsd 重新启动以反映所做出的更改。
-
将 SSL 证书 .pem 文件复制到 Junos 设备。
user@device% scp pem-file-name device-name:/var/tmp
例如:
user@device% scp router.pem device:/var/tmp
-
将证书加载到 Junos 设备上的密钥链中。例如,如果 SSL 证书的本地名称为
sslcert
:[edit] user@device# set security certificates local sslcert load-key-file /var/tmp/router.pem
-
为加载证书启用 SSL 支持。
[edit system services extension-service request-response grpc] user@device# set ssl local-certificate cert-name
例如:
[edit system services extension-service request-response grpc] user@device# set ssl local-certificate sslcert
-
(可选)指定将使用 SSL 的特定 IP 地址或端口。SSL 使该地址或端口成为安全通道。
[edit system services extension-service request-response grpc] user@device# set ssl address address user@device# set ssl port port-number
如果将地址设置为 0.0.0.0,设备会在所有端口上使用 SSL。例如,要在所有端口的 gRPC 端点上启用 SSL 支持,以及默认 TCP 端口 51051:
[edit system services extension-service request-response grpc] user@device# set ssl address 0.0.0.0 user@device# set ssl port 51051
-
指定可连接到 jsd 的请求响应的最大同时连接数。数字越高,对客户端性能的影响就越高。
[edit system services extension-service request-response grpc] user@device# set max-connections 8
您已配置 jsd,用于在 SSL 模式下运行请求响应服务。您已准备好部署 JET 设备外应用程序。
-
指定要使用的脚本。
[edit] user@device# set system scripts language python3
注意:从 Junos OS 21.1R1 版和 Junos OS Evolved 版本 22.3R1 开始,Python 2.7 不再支持,
set system scripts language python
语句将弃用。请改为使用 语set system scripts language python3
句。
示例:Python JET 应用程序
使用此示例开发写在 Python 中的设备外 JET 应用程序。对于 gRPC 支持的其他语言,您可以遵循相同的指导。此 Python JET 应用程序以 XML 格式运行命令 get-system-uptime-information
。
在此示例中 HOST_OVERRIDE
,选项使用在证书生成期间指定的证书名称。请参阅 准备部署应用程序。
瞻博网络支持以下两种表格,用于解说 XML 打开和关闭标记: <xml-tag/>
和 <xml-tag></xml-tag>
。
Junos OS 版本 18.4R1 和更高版本
如果您使用 Junos OS 版本 18.4R1 或更高版本,请将本节中显示的 Python 应用程序示例用作指南。
如果您使用 Python 3 编写应用程序,请将 PASS 关键字包含在脚本的例外块中。
except Exception as tx: pass
#!/usr/bin/env python # A simple Python client to run XML OP command 'get-system-uptime-information' # Environment # Python 2.7.12 # grpcio (1.12.0) # grpcio-tools (1.12.0) # Following files should be available in current working directory # jnx_authentication_service_pb2_grpc.py # jnx_authentication_service_pb2.py # jnx_management_service_pb2_grpc.py # jnx_management_service_pb2.py import argparse import grpc import os import stat import jnx_authentication_service_pb2 import jnx_authentication_service_pb2_grpc import jnx_management_service_pb2 import jnx_management_service_pb2_grpc import jnx_common_base_types_pb2 _HOST_OVERRIDE = 'router' def Main(): try: parser = argparse.ArgumentParser() parser.add_argument('-d','--device', help='Input hostname', required=True) parser.add_argument('-t','--timeout', help='Input time_out value', required=True,type=int) parser.add_argument('-u', '--user', help='Input username', required=True) parser.add_argument('-pw', '--password', help='Input password', required=True) args = parser.parse_args() #Establish grpc channel to jet router creds = grpc.ssl_channel_credentials(open('/tmp/router.pem').read(), None, None) channel = grpc.secure_channel(args.device + ":32767", creds, options=(('grpc.ssl_target_name_override', _HOST_OVERRIDE,),)) #create stub for authentication services stub = jnx_authentication_service_pb2_grpc.AuthenticationStub(channel) #Authenticate login_request = jnx_authentication_service_pb2.LoginRequest( username=args.user, password=args.password, client_id="SampleApp") login_response = stub.Login(login_request, args.timeout) #Check if authentication is successful if login_response.status.code == jnx_common_base_types_pb2.SUCCESS: print "[INFO] Connected to gRPC Server" else: print "[ERROR] gRPC Server Connection failed:" print login_response.status.message #Create stub for management services stub = jnx_management_service_pb2_grpc.ManagementStub(channel) print "[INFO] Connected to management service" for i in range(1): #Provide API request details op_xml_command = "<get-system-uptime-information></get-system-uptime-information>" op = jnx_management_service_pb2.OpCommandGetRequest( xml_command=op_xml_command, out_format=2) # Invoke API op_response = stub.OpCommandGet(op, args.timeout) # Check API response like status and output for resp in op_response: if resp.status.code == jnx_common_base_types_pb2.SUCCESS: print "[INFO] Invoked OpCommandGetRequest succeeded" print "[INFO] Return output in CLI format = " print resp.data else: print "[ERROR] Invoked OpCommandGetRequest failed" print "[ERROR] " + resp.status.message except Exception as ex: print ex if __name__ == '__main__': Main()
user@jet-vm:~ jet$ python mgd_api_new_doc_example_ssl.py -d JUNOS_DEVICE -t TIMEOUT -u USER -pw PASSWORD [INFO] Connected to gRPC Server [INFO] Connected to management service [INFO] Invoked OpCommandGetRequest succeeded [INFO] Return output in CLI format = Current time: 2018-11-08 09:36:40 PST Time Source: NTP CLOCK System booted: 2018-10-09 17:02:56 PDT (4w1d 17:33 ago) Protocols started: 2018-10-09 17:05:09 PDT (4w1d 17:31 ago) Last configured: 2018-11-08 09:30:28 PST (00:06:12 ago) by root 9:36AM up 29 days, 17:34, 2 users, load averages: 1.05, 0.77, 0.57
Junos OS 版本 18.4R1 之前
如果您在 18.4R1 之前使用 Junos OS 版本,请将本部分中的 Python 应用程序示例用作指南。
#!/usr/bin/env python # A simple Python client to run XML OP command 'get-system-uptime-information' # Environment # Python 2.7.12 # grpcio (1.12.0) # grpcio-tools (1.12.0) # Following files should be available in current working directory # authentication_service_pb2_grpc.py # authentication_service_pb2.py # management_service_pb2_grpc.py # management_service_pb2.py import argparse import grpc import authentication_service_pb2 import authentication_service_pb2_grpc import management_service_pb2 import management_service_pb2_grpc _HOST_OVERRIDE = 'router' def Main(): try: parser = argparse.ArgumentParser() parser.add_argument('-d','-device', help='Input hostname', required=True) parser.add_argument('-t','-timeout', help='Input time_out value', required=True,type=int) parser.add_argument('-u', '-user', help='Input username', required=True) parser.add_argument('-pw', '-password', help='Input password', required=True) args = parser.parse_args() #Establish grpc channel to jet router creds = grpc.ssl_channel_credentials(open('/tmp/router.pem').read(), None, None) channel = grpc.secure_channel(args.device + ":51051", creds, options=(('grpc.ssl_target_name_override', _HOST_OVERRIDE,),)) #create stub for authentication services stub = authentication_service_pb2_grpc.LoginStub(channel) #Authenticate login_request = authentication_service_pb2.LoginRequest( user_name=args.user, password=args.password, client_id="SampleApp") login_response = stub.LoginCheck(login_request, args.timeout) #Check if authentication is successful if login_response.result == True: print "[INFO] Connected to gRPC Server:" print login_response.result else: print "[ERROR] gRPC Server Connection failed!!!" print login_response.result #Create stub for management services stub = management_service_pb2_grpc.ManagementRpcApiStub(channel) print "[INFO] Connected to JSD and created handle to mgd services" for i in range(1): #Provide API request details op_xml_command = "<get-system-uptime-information>" \ "</get-system-uptime-information>" op = management_service_pb2.ExecuteOpCommandRequest( xml_command=op_xml_command, out_format=2, request_id=1000) # Invoke API result = stub.ExecuteOpCommand(op, 100) # Check API response like status and output for i in result: print "[INFO] Invoked ExecuteOpCommand API return code = " print i.status print "[INFO] Return output in CLI format = " print i.data except Exception as ex: print ex if __name__ == '__main__': Main()
user@jet-vm:~ jet$ python mgd_api_doc_example_ssl.py -d JUNOS_DEVICE -t TIMEOUT_VAL -u USER -pw PASSWORD [INFO] Connected to gRPC Server: True [INFO] Connected to JSD and created handle to mgd services [INFO] Invoked ExecuteOpCommand API return code = 0 [INFO] Return output in CLI format = Current time: 2018-09-04 11:24:36 PDT Time Source: NTP CLOCK System booted: 2018-08-31 10:58:22 PDT (4d 00:26 ago) Protocols started: 2018-08-31 11:00:52 PDT (4d 00:23 ago) Last configured: 2018-08-31 14:21:32 PDT (3d 21:03 ago) by root 11:24AM up 4 days, 26 mins, 0 users, load averages: 1.20, 1.27, 1.10