Entwicklung von Off-Device-JET-Anwendungen
Übersicht
Sie können JET verwenden, um Anwendungen zu entwickeln, die außerhalb des Geräts ausgeführt werden. Auf diese Weise können Sie die Vorteile von JET auf allen Geräten in Ihrem Netzwerk nutzen. Um die Entwicklung zu vereinfachen, können Sie JET-Anwendungen außerhalb des Geräts in der Sprache Ihrer Wahl schreiben. So entwickeln Sie eine Off-Device-Anwendung:
Laden Sie die IDL-Datei herunter und kompilieren Sie sie.
Entwickeln Sie die Anwendung in der Sprache Ihrer Wahl.
Verpacken Sie die Anwendung.
Stellen Sie das Anwendungspaket auf einem externen Server bereit, oder führen Sie die Anwendung direkt von der JET-VM aus aus.
Abbildung 1 zeigt den Workflow für die Entwicklung von Anwendungen außerhalb des Geräts.

Entwickeln und verpacken Sie Ihre Anwendung
Bevor Sie Ihre Anwendung entwickeln, stellen Sie sicher, dass Sie bereits die Anweisungen unter Einrichten der JET-VM befolgt haben, um die JET-VM einzurichten und die IDL-Datei herunterzuladen.
Siehe auch
Vorbereiten der Bereitstellung Ihrer Anwendung
Führen Sie Ihre Anwendung auf einem externen Server oder direkt von der JET-VM aus aus. Bevor Sie Ihre Anwendung auf einem externen Server bereitstellen, müssen Sie die JET-Interaktion mit Junos OS konfigurieren.
Konfigurieren der JET-Interaktion mit Junos OS
Um eine Anwendung außerhalb des Geräts auszuführen, müssen Sie die request-response
Konfiguration unter Junos OS oder Junos OS Evolved aktivieren. Bei Verwendung des Anforderungs-Antwort-Service gibt die Clientanwendung eine Anforderung aus und wartet synchron auf die Antwort vom Junos-Server. Verwenden Sie diesen Abschnitt, um den JET-Dienstprozess (jsd) für den Anforderungs-Antwort-Dienst so zu konfigurieren, dass er im SSL-Modus (Secure Sockets Layer) ausgeführt wird. Dies sorgt für erhöhte Sicherheit und ermöglicht SSL-basierte API-Verbindungen.
Derzeit unterstützt JET Transport Layer Security (TLS) Version 1.2 für den Zertifikataustausch und unterstützt mehrere Verschlüsselungsalgorithmen, jedoch keine gegenseitige Authentifizierung. Dies bedeutet, dass Clients den Server authentifizieren können, der Server jedoch keine Clients mit SSL/TLS-Zertifikaten authentifizieren kann. Verwenden Sie für die Clientauthentifizierung die LoginCheck()-Prozedur aus der Authentifizierungsdienst-API.
-
Aktivieren Sie jsd für die Verwendung von SSL, indem Sie den Zertifikatsnamen lokal hinzufügen und konfigurieren. Bei dem Zertifikat muss es sich um ein RSA-Zertifikat handeln. ECDSA- und DSA-SSL-Zertifikate werden nicht unterstützt.
Diese Methode ist identisch mit anderen SSL-basierten Diensten in Junos OS wie xnm-ssl. Verfolgen Sie den Zertifikatnameneintrag, den Sie während der Zertifikatgenerierung angeben. Sie werden es für die
HOST_OVERRIDE
Option in der Python-Beispielanwendung im nächsten Abschnitt verwenden. In diesem Beispiel lautetrouter
der Zertifikatname .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
Hinweis:Wenn ein Zertifikat mit demselben Bezeichner aktualisiert wird, werden die Änderungen für jsd nicht widergespiegelt. Sie müssen das Zertifikat entweder mit einem neuen Bezeichner in der jsd-Hierarchie konfigurieren oder einen jsd-Neustart durchführen, um die vorgenommenen Änderungen widerzuspiegeln.
-
Kopieren Sie die PEM-Datei des SSL-Zertifikats auf das Junos-Gerät.
user@device% scp pem-file-name device-name:/var/tmp
Zum Beispiel:
user@device% scp router.pem device:/var/tmp
-
Laden Sie das Zertifikat in den Schlüsselbund auf dem Junos-Gerät. Wenn der lokale Name des SSL-Zertifikats beispielsweise lautet
sslcert
:[edit] user@device# set security certificates local sslcert load-key-file /var/tmp/router.pem
-
Aktivieren Sie die SSL-Unterstützung für das geladene Zertifikat.
[edit system services extension-service request-response grpc] user@device# set ssl local-certificate cert-name
Zum Beispiel:
[edit system services extension-service request-response grpc] user@device# set ssl local-certificate sslcert
-
(Optional) Geben Sie die spezifische IP-Adresse oder den Port an, der SSL verwenden soll. SSL macht diese Adresse oder diesen Port zu einem sicheren Kanal.
[edit system services extension-service request-response grpc] user@device# set ssl address address user@device# set ssl port port-number
Wenn Sie die Adresse auf 0.0.0.0 festlegen, verwendet das Gerät SSL auf allen Ports. So aktivieren Sie beispielsweise die Unterstützung für SSL auf dem gRPC-Endpunkt auf allen Ports und dem TCP-Standardport 51051:
[edit system services extension-service request-response grpc] user@device# set ssl address 0.0.0.0 user@device# set ssl port 51051
-
Geben Sie die maximale Anzahl gleichzeitiger Verbindungen für Request-Response an, die an jsd angehängt werden können. Je höher die Zahl, desto höher die Auswirkungen auf die Leistung des Kunden.
[edit system services extension-service request-response grpc] user@device# set max-connections 8
Sie haben jsd für den Anforderungsantwortdienst so konfiguriert, dass er im SSL-Modus ausgeführt wird. Sie sind bereit, Ihre JET-Anwendung außerhalb des Geräts bereitzustellen.
-
Geben Sie die zu verwendenden Skripts an.
[edit] user@device# set system scripts language python3
Hinweis:Ab Junos OS Version 21.1R1 und Junos OS Evolved Version 22.3R1 wird Python 2.7 nicht mehr unterstützt und die
set system scripts language python
Anweisung ist veraltet. Verwenden Sie stattdessen dieset system scripts language python3
Anweisung.
Beispiel: Python JET-Anwendung
Verwenden Sie dieses Beispiel, um eine geräteunabhängige JET-Anwendung zu entwickeln, die in Python geschrieben wurde. Sie können die gleiche Anleitung für andere Sprachen befolgen, die von gRPC unterstützt werden. Diese Python JET-Anwendung führt den Befehl get-system-uptime-information
im XML-Format aus.
In diesem Beispiel verwendet die HOST_OVERRIDE
Option den Zertifikatnamen, den Sie bei der Zertifikatgenerierung angegeben haben. Weitere Informationen finden Sie unter Vorbereiten der Bereitstellung Ihrer Anwendung.
Juniper Networks unterstützt die beiden folgenden Formen zum Bezeichnen von öffnenden und schließenden XML-Tags: <xml-tag/>
und <xml-tag></xml-tag>
.
Junos OS Version 18.4R1 und höher
Verwenden Sie die in diesem Abschnitt gezeigte Python-Beispielanwendung als Leitfaden, wenn Sie Junos OS Version 18.4R1 oder höher verwenden.
Wenn Sie Ihre Anwendung mit Python 3 schreiben, fügen Sie das Schlüsselwort PASS in den Exception-Block des Skripts ein.
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
Vor Junos OS Version 18.4R1
Verwenden Sie die Python-Beispielanwendung in diesem Abschnitt als Leitfaden, wenn Sie Junos OS-Versionen vor 18.4R1 verwenden.
#!/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