Servicio del sistema gNOI
Use el servicio gNOI System para realizar operaciones del sistema en el dispositivo de red de destino, incluido el reinicio del dispositivo, la actualización del software y la solución de problemas de la red.
Descripción general
El servicio gNOI System proporciona RPC para realizar varias operaciones del sistema diferentes en un dispositivo de red, incluidas las siguientes operaciones:
- Reiniciar un dispositivo
- Ejecute comandos ping y traceroute para solucionar problemas de la red
- Actualice el software
- Realizar una conmutación del motor de enrutamiento
El archivo de definición de prototipo se encuentra en https://github.com/openconfig/gnoi/blob/master/system/system.proto.
El gnoi-system proceso se reinicia en caso de falla del sistema. Para reiniciarlo manualmente, use el restart gnoi-system comando.
Configuración de dispositivos de red
Antes de empezar:
- Configure los servicios de gRPC en el dispositivo de red como se describe en Configurar servicios de gRPC.
- Configure el sistema de administración de red para que admita las operaciones de gNOI como se describe en Configurar servicios de gNOI.
No se requiere ninguna configuración adicional para usar las RPC del System servicio.
ping y traceroute
Puede ejecutar comandos ping y traceroute en el dispositivo de red para solucionar problemas en su red.
| RPC | Descripción | Introducido en la versión |
|---|---|---|
Ping() |
Haga ping a un dispositivo. La Número predeterminado de paquetes: 5 |
Junos OS evolucionado 22.2R1 |
Traceroute() |
Ejecute el comando traceroute en el dispositivo de destino y transmita los resultados. Recuento de saltos predeterminado: 30 |
Junos OS evolucionado 22.2R1 |
Ejemplo: ping
En este ejemplo, el cliente ejecuta la gnoi_ping_request.py aplicación de Python. La aplicación envía la Ping() RPC al dispositivo de red, que luego hace ping al dispositivo especificado en la red.
La gnoi_ping_request.py aplicación importa el grpc_channel módulo para establecer el canal. El grpc_channel módulo se describe en Configurar servicios de gNOI. Los argumentos de la aplicación se almacenan en el archivo gnoi_ping_request_args.txt . Los archivos de aplicación y argumento se presentan aquí.
gnoi_ping_request.py
"""gRPC gNOI ping 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=32767,
help='The server port. Default is 32767')
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.')
# Ping request arguments
parser.add_argument('--destination',
dest='destination',
type=str,
default=None,
help='Destination IP. Default None')
parser.add_argument('--source',
dest='source',
type=str,
default=None,
help='Source IP. Default None')
parser.add_argument('--count',
dest='count',
type=int,
default=None,
help='Count of packets. Default None')
parser.add_argument('--interval',
dest='interval',
type=int,
default=None,
help='Interval of packets in nanoseconds. Default None')
parser.add_argument('--wait',
dest='wait',
type=int,
default=None,
help='Wait of packets in nanoseconds. Default None')
parser.add_argument('--size',
dest='size',
type=int,
default=None,
help='Size of packets. Default None')
parser.add_argument('--dnfragment',
dest='dnfragment',
type=int,
default=0,
help='Do not fragment. Default 0 (False)')
parser.add_argument('--dnresolve',
dest='dnresolve',
type=int,
default=0,
help='Do not resolve. Default 0 (False)')
parser.add_argument('--l3protocol',
dest='l3protocol',
type=int,
default=None,
help='L3 protocol (1=ipv4,2=ipv6). Default None')
parser.add_argument('--timeout',
dest='timeout',
type=int,
default=30,
help='Timeout for ping. Default: 30 seconds')
args = parser.parse_args()
return args
def send_rpc(channel, metadata, args):
stub = system_pb2_grpc.SystemStub(channel)
print("Executing GNOI::System::Ping Request RPC")
req = system_pb2.PingRequest()
if args.count != None:
req.count = args.count
if args.source != None:
req.source = args.source
if args.destination != None:
req.destination = args.destination
if args.interval != None:
req.interval = args.interval
if args.wait != None:
req.wait = args.wait
if args.size != None:
req.size = args.size
if args.dnfragment != 0:
req.do_not_fragment = args.dnfragment
if args.dnresolve != 0:
req.do_not_resolve = args.dnresolve
if args.l3protocol != None:
req.l3protocol = args.l3protocol
try:
print("Ping Request Response starts\n")
count = 1
for ping in stub.Ping(request=req, metadata=metadata, timeout=args.timeout):
print("Response Source%s: %s " % (count, ping.source))
print("Time%s: %s" % (count, ping.time))
print("Sent%s: %s" % (count, ping.sent))
print("Receive%s: %s" % (count, ping.received))
print("Mintime%s: %s" % (count, ping.min_time))
print("Avgtime%s: %s" % (count, ping.avg_time))
print("Stddev%s: %s" % (count, ping.std_dev))
print("Bytes%s: %s" % (count, ping.bytes))
print("Sequence%s: %s" % (count, ping.sequence))
print("TTL%s: %s" % (count, ping.ttl))
count += 1
print("Ping Request Response ends\n")
except Exception as e:
logging.error('Error: %s', e)
print(e)
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)
response = 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()
gnoi_ping_request_args.txt
--server=10.0.2.1 --port=32767 --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 --destination=10.0.3.1 --source=10.0.2.1 --count=5
Ejecute la aplicación
En el cliente, ejecute la aplicación, que solicita la contraseña del servidor para las credenciales de llamada RPC. Indica PingResponse que el dispositivo envió cinco pings. La respuesta final incluye las estadísticas de resumen de la solicitud de ping, que muestran que el dispositivo envió cinco pings y recibió cinco respuestas.
lab@gnoi-client:~/src/gnoi/proto$ python3 gnoi_ping_request.py @gnoi_ping_request_args.txt gRPC server password for executing RPCs: Creating channel Executing GNOI::System::Ping Request RPC Ping Request Response starts Response Source1: 10.0.3.1 Time1: 741000 Sent1: 0 Receive1: 0 Mintime1: 0 Avgtime1: 0 Stddev1: 0 Bytes1: 64 Sequence1: 1 TTL1: 59 Response Source2: 10.0.3.1 Time2: 734000 Sent2: 0 Receive2: 0 Mintime2: 0 Avgtime2: 0 Stddev2: 0 Bytes2: 64 Sequence2: 2 TTL2: 59 Response Source3: 10.0.3.1 Time3: 704000 Sent3: 0 Receive3: 0 Mintime3: 0 Avgtime3: 0 Stddev3: 0 Bytes3: 64 Sequence3: 3 TTL3: 59 Response Source4: 10.0.3.1 Time4: 767000 Sent4: 0 Receive4: 0 Mintime4: 0 Avgtime4: 0 Stddev4: 0 Bytes4: 64 Sequence4: 4 TTL4: 59 Response Source5: 10.0.3.1 Time5: 800000 Sent5: 0 Receive5: 0 Mintime5: 0 Avgtime5: 0 Stddev5: 0 Bytes5: 64 Sequence5: 5 TTL5: 59 Response Source6: 10.0.3.1 Time6: 4111000000 Sent6: 5 Receive6: 5 Mintime6: 704000 Avgtime6: 749000 Stddev6: 32000 Bytes6: 0 Sequence6: 0 TTL6: 0 Ping Request Response ends
Reiniciar un dispositivo
Utilice las RPC del System servicio para reiniciar un dispositivo de forma remota, comprobar el estado del reinicio y cancelarlo si es necesario. Puede ejecutar estas RPC en el dispositivo o en subcomponentes específicos. Los dispositivos Junos admiten los siguientes métodos de reinicio:
-
FRÍO (1): Disponible para todo tipo de reinicios.
-
APAGADO (2): Se utiliza para reinicios de FPC y del motor de enrutamiento (tarjeta controladora).
-
HALT (3): Utilícelo para reiniciar el procesador de control activo.
-
POWERUP (7): Se utiliza para reinicios de FPC y del motor de enrutamiento (tarjeta controladora).
A partir de Junos OS Evolved versión 25.2R1, puede usar las opciones POWERDOWN y POWERUP en los componentes del motor de enrutamiento. Solo puede apagar un motor de enrutamiento en un sistema de motor de enrutamiento dual y no puede apagar ambos motores de enrutamiento al mismo tiempo. Un motor de enrutamiento permanece apagado hasta el próximo reinicio.
Para apagar el motor de enrutamiento y mantener el estado incluso después de un reinicio, puede establecer la ruta de OpenConfig /components/component/controller-card/config/power-admin-state/ en POWER_DISABLED. Este cambio de estado es efectivo inmediatamente en el motor de enrutamiento de respaldo. El estado del motor de enrutamiento principal solo cambia después de un reinicio o una conmutación.
| RPC | Descripción | Introducido en la versión |
|---|---|---|
Reboot() |
Reinicie el destino. Solo puede ejecutar una solicitud de reinicio en un destino a la vez. Si lo desea, puede configurar un retraso para reiniciar en el futuro, reiniciar los subcomponentes individualmente y agregar un mensaje cuando se inicie el reinicio. El retraso se configura en nanosegundos. Los dispositivos Junos admiten los siguientes métodos de reinicio:
|
Junos OS evolucionado 22.2R1 |
RebootStatus() |
Devuelva el estado del reinicio. | Junos OS evolucionado 22.2R1 |
CancelReboot() |
Cancelar una solicitud de reinicio pendiente. | Junos OS evolucionado 22.2R1 |
Ejemplo: Reiniciar
En este ejemplo, el cliente ejecuta la gnoi_reboot_request.py aplicación de Python. La aplicación envía la solicitud de reinicio y, a continuación, comprueba el estado del reinicio.
La aplicación permite al usuario establecer el retraso de reinicio en segundos. RebootRequest() Dado que interpreta el retraso en nanosegundos, la aplicación convierte la entrada del usuario en nanosegundos para la solicitud. En este ejemplo, el cliente especifica un retraso de 60 segundos para la operación de reinicio.
La gnoi_reboot_request.py aplicación importa el grpc_channel módulo para establecer el canal. El grpc_channel módulo se describe en Configurar servicios de gNOI. Los argumentos de la aplicación se almacenan en el archivo reboot_status_request_args.txt . Los archivos de aplicación y argumento se presentan aquí.
gnoi_reboot_status_request.py
"""gRPC gNOI reboot request and reboot status utility."""
from __future__ import print_function
import argparse
import logging
from getpass import getpass
import types_pb2
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=32767,
help='The server port. Default is 32767')
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.')
# Arguments for RebootRequest
parser.add_argument('--method',
dest='method',
type=int,
default=1,
help='Reboot method. Valid value: 0 (UNKNOWN), 1 (COLD), 2 (POWERDOWN), 3 (HALT), 6 (reserved), 7 (POWERUP). Default 1')
parser.add_argument('--delay',
dest='delay',
type=int,
default=None,
help='Delay in seconds before rebooting. Default 0')
parser.add_argument('--message',
dest='message',
type=str,
default=None,
help='Message for rebooting.')
parser.add_argument('--force',
dest='force',
type=int,
default=None,
help='Force reboot. Valid value 0|1. Default 0')
parser.add_argument('--subcomponents',
dest='subcomponents',
type=str,
default='',
help='Subcomponents to reboot. Valid value re0,re1,fpc0,fpc8,etc. Default ""')
args = parser.parse_args()
return args
def send_rpc(channel, metadata, args):
# RebootRequest
stub = system_pb2_grpc.SystemStub(channel)
print("Executing GNOI::System::Reboot RPC")
req = system_pb2.RebootRequest()
# Add RebootRequest arguments
req.method = args.method
if args.delay != None:
# gNOI delay is in nanoseconds. Convert from seconds to nanoseconds.
req.delay = args.delay*(10**9)
if args.message != None:
req.message = args.message
if args.force != None:
req.force = args.force
for subcomponent in args.subcomponents.split(","):
if subcomponent == "":
continue
elem_key = {}
elem_key["%s" % subcomponent] = subcomponent
path_elem = [types_pb2.PathElem(
name="%s" % subcomponent, key=elem_key)]
path = types_pb2.Path(origin="origin", elem=path_elem)
req.subcomponents.extend([path])
# RebootStatus
print("Executing GNOI::System::Reboot Status RPC")
req_status = system_pb2.RebootStatusRequest()
try:
reboot_response = stub.Reboot(
request=req, metadata=metadata, timeout=60)
status_response = stub.RebootStatus(
request=req_status, metadata=metadata, timeout=60)
print("Reboot status response received. %s" % status_response)
except Exception as e:
logging.error('Error: %s', e)
print(e)
else:
logging.info('Received reboot status: %s', status_response)
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:
print(e)
logging.error('Received error: %s', 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()
reboot_status_request_args.txt
--server=10.0.2.1 --port=32767 --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 --message="Testing gNOI reboot" --delay=60
Ejecute la aplicación
Cuando el cliente ejecuta la aplicación, la aplicación solicita la contraseña del servidor para las credenciales de llamada RPC. A continuación, la aplicación reinicia el servidor después de un retraso de 60 segundos y devuelve los mensajes de estado de reinicio aplicables. El mensaje establecido en también aparece en reason el servidor inmediatamente antes de que se reinicie el servidor. En este ejemplo, cualquier usuario que haya iniciado sesión en el servidor ve "Probando el reinicio de gNOI" inmediatamente antes de reiniciarse.
lab@gnoi-client:~/src/gnoi/proto$ python3 gnoi_reboot_status_request.py @reboot_status_request_args.txt gRPC server password for executing RPCs: Creating channel Executing GNOI::System::Reboot RPC Executing GNOI::System::Reboot Status RPC Reboot status response received! active: true wait: 59266969677 when: 1651788480000000000 reason: "Testing gNOI reboot" count: 5
actualice el software
En la tabla 3 se enumeran las RPC de servicio del sistema que admiten actualizaciones de software.
| RPC | Descripción | Introducido en la versión |
|---|---|---|
SetPackage() |
Instale una imagen de software en el dispositivo de destino. |
Junos OS evolucionado 22.2R1 |
Puede usar RPC SetPackage() para copiar una imagen de software al dispositivo de destino e instalarla. La imagen del software de origen debe residir en el sistema de administración de red local. Si la operación de copia de archivos se realiza correctamente y ya existe un archivo con el mismo nombre en la ubicación de destino, el archivo se sobrescribe. La RPC devuelve un error si la ubicación de destino no existe o si hay un error al escribir los datos.
De forma predeterminada, SetPackage() no reinicia el dispositivo ni activa el software. Debe establecer explícitamente la activate opción en 1 en el SetPackageRequest mensaje para activar el nuevo software. Si activa el software, el dispositivo se reinicia y utiliza la imagen nueva de software. Si no activa el software, deberá reiniciar los nodos correspondientes para llevar a cabo la instalación y activar la imagen de software nueva.
Ejemplo: Instalación de un paquete de software
En este ejemplo, el cliente ejecuta la gnoi_system_set_package.py aplicación de Python, la cual realiza las siguientes operaciones:
- Copia el paquete de software del sistema de administración de red local al dispositivo de red.
- Instala el paquete en el dispositivo de red.
- Reinicia el dispositivo de red y, por lo tanto, activa la imagen de software nueva.
La aplicación construye el SetPackageRequest mensaje con los parámetros adecuados para definir la solicitud de las operaciones de copia e instalación. Luego, la aplicación llama a la SetPackage() RPC para enviar la solicitud al dispositivo de red. El SetPackageRequest mensaje contiene los siguientes componentes:
- Un mensaje inicial
Packageque contiene la ruta de acceso y la información del archivo de la imagen de software. Elactivateargumento se establece en 1 (True) para reiniciar el dispositivo y activar el software. - Una secuencia del contenido del archivo de imagen de software en mensajes secuenciales que no superen los 64 KB.
- Un mensaje final con la suma de comprobación del archivo para comprobar la integridad del contenido del archivo.
La gnoi_system_set_package.py aplicación importa el grpc_channel módulo para establecer el canal. El grpc_channel módulo se describe en Configurar servicios de gNOI. Los argumentos de la aplicación se almacenan en el args_system_set_package.txt archivo. Los archivos de aplicación y argumento son los siguientes:
gnoi_system_set_package.py
"""gRPC gNOI OS Upgrade Utility."""
from __future__ import print_function
import argparse
import hashlib
import logging
from functools import partial
from getpass import getpass
import system_pb2
import system_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=32767,
help='The server port. Default is 32767')
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('--activate',
dest='activate',
type=int,
default=0,
help='Reboot and activate the package. Default: 0 (Do not reboot/activate). Valid value: 1 (Reboot/activate).')
parser.add_argument('--filename',
dest='filename',
type=str,
default='',
help='Destination path and filename of the package. Default ""')
parser.add_argument('--source_package',
dest='source_package',
type=str,
default='',
help='Full path of the source file to send. Default ""')
parser.add_argument('--timeout',
dest='timeout',
type=int,
default=None,
help='Timeout in seconds.')
parser.add_argument('--version',
dest='version',
type=str,
default='',
help='Version of the package. Default ""')
args = parser.parse_args()
return args
def send_rpc(channel, metadata, args):
stub = system_pb2_grpc.SystemStub(channel)
print("Executing GNOI::System::SetPackage")
# Create request
# Add file information to request
req = system_pb2.SetPackageRequest()
req.package.activate = args.activate
req.package.filename = args.filename
it = []
it.append(req)
# Prepare hash generator
gen_hash = hashlib.sha256()
# Read source package and add to request
with open(args.source_package, "rb") as fd:
# Read data in 64 KB chunks and calculate checksum and data messages
for data in iter(partial(fd.read, MAX_BYTES), b''):
req = system_pb2.SetPackageRequest()
req.contents = data
it.append(req)
gen_hash.update(data)
# Add checksum to request
req = system_pb2.SetPackageRequest()
req.hash.hash = gen_hash.hexdigest().encode()
req.hash.method = 1
it.append(req)
# Install the package
try:
logging.info('Installing package %s', args.source_package)
print('SetPackage start.')
response = stub.SetPackage(
iter(it), metadata=metadata, timeout=args.timeout)
print('SetPackage complete.')
except Exception as e:
logging.error('Software install error: %s', e)
print(e)
else:
logging.info('SetPackage complete.')
return response
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)
response = send_rpc(channel, metadata, args)
except Exception as e:
logging.error('Error: %s', e)
print(e)
if __name__ == '__main__':
logging.basicConfig(filename='gnoi-install.log',
format='%(asctime)s %(levelname)-8s %(message)s',
level=logging.INFO,
datefmt='%Y-%m-%d %H:%M:%S')
main()
args_system_set_package.txt
--server=10.0.2.1 --port=32767 --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 --activate=1 --filename=/var/tmp/junos-evo-install-ptx-x86-64-22.2R1.13-EVO.iso --source_package=/home/lab/images/junos-evo-install-ptx-x86-64-22.2R1.13-EVO.iso --timeout=1800
Ejecute la aplicación
Cuando el cliente ejecuta la aplicación, esta copia el paquete del dispositivo local al dispositivo de red, lo instala y, a continuación, reinicia el dispositivo para completar la instalación.
lab@gnoi-client:~/src/gnoi/proto$ python3 gnoi_system_set_package.py @args_system_set_package.txt gRPC server password for executing RPCs: Creating channel Executing GNOI::System::SetPackage SetPackage start. SetPackage complete.
Conmutación del motor de enrutamiento
Puede utilizar RPC SwitchControlProcessor() para realizar un cambio de motor de enrutamiento.
Los eventos sucesivos de conmutación del motor de enrutamiento deben estar separados por un mínimo de 400 segundos después de que ambos motores de enrutamiento hayan aparecido.
| RPC | Descripción | Introducido en la versión |
|---|---|---|
SwitchControlProcessor() |
Cambie del motor de enrutamiento actual al motor de enrutamiento especificado. Si los motores de enrutamiento actuales y especificados son los mismos, es un NOOP. Si el destino no existe, la RPC devuelve un error.
Nota:
Los dispositivos Junos no admiten |
Junos OS evolucionado 22.2R1 |
Ejemplo: conmutación del motor de enrutamiento
En este ejemplo, el cliente gNOI ejecuta la gnoi_system_switch_control_processor.py aplicación para realizar un cambio de motor de enrutamiento. El cliente especifica qué procesador de control de conmutador, o motor de enrutamiento, debe ser el motor de enrutamiento principal mediante la inclusión del control_processor argumento. Si el motor de enrutamiento de destino no existe, la RPC devuelve un INVALID_ARGUMENT error.
La aplicación importa el grpc_channel módulo para establecer el canal. El grpc_channel módulo se describe en Configurar servicios de gNOI.
gnoi_system_switch_control_processor.py
"""gNOI Routing Engine switchover request utility."""
from __future__ import print_function
import argparse
import logging
from getpass import getpass
import system_pb2
import system_pb2_grpc
import types_pb2
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=32767,
help='The server port. Default is 32767')
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('--control_processor',
dest='control_processor',
type=str,
default='re1',
help='Control processor that will assume the role of primary. Default is re1. Valid values are re0,re1.')
args = parser.parse_args()
return args
def send_rpc(channel, metadata, processor):
stub = system_pb2_grpc.SystemStub(channel)
print("Executing GNOI::System::SwitchControlProcessor")
elem_key = {}
elem_key["%s" % processor] = processor
path_elem = [types_pb2.PathElem(name="%s" % processor, key=elem_key)]
path = types_pb2.Path(origin="origin", elem=path_elem)
req = system_pb2.SwitchControlProcessorRequest(control_processor=path)
# Send the request
try:
response = stub.SwitchControlProcessor(
req, metadata=metadata, timeout=60)
print("SwitchControlProcessor response:\n", response)
except Exception as e:
logging.error('Switchover error: %s', e)
print(e)
else:
logging.info('SwitchControlProcessor response:\n %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, args.control_processor)
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()
Ejecute la aplicación
El cliente ejecuta la aplicación y establece el control_processor argumento en re1 para que re1 se convierta en el motor de enrutamiento principal.
lab@gnoi-client:~/src/gnoi/proto$ python3 gnoi_system_switch_control_processor.py --server 10.0.2.1 --port 32767 --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 --control_processor re1 gRPC server password for executing RPCs: Creating channel Executing GNOI::System::SwitchControlProcessor SwitchControlProcessor response: version: "22.2R1.13-EVO" uptime: 1652478709000000000
Después de ejecutar la operación, re1 es el motor de enrutamiento principal en el dispositivo de destino.
{master}
lab@gnoi-server-re1>
Tabla de historial de cambios
La compatibilidad de la función depende de la plataforma y la versión que utilice. Utilice el Explorador de características para determinar si una característica es compatible con su plataforma.
Reboot() gNOI
System para encender y apagar un motor de enrutamiento (tarjeta controladora) en un dispositivo de motor de enrutamiento dual.