Skip to content

Instantly share code, notes, and snippets.

@XioNoX
Last active October 18, 2024 16:14
Show Gist options
  • Save XioNoX/42a61288c3f638ecd1bbd24b13d6c483 to your computer and use it in GitHub Desktop.
Save XioNoX/42a61288c3f638ecd1bbd24b13d6c483 to your computer and use it in GitHub Desktop.
Generate then download Juniper RSI and logs. Optionally uploads them to the matching JTAC case.
#!/usr/bin/env python3
# usage: autorsi.py [-h] [--username USERNAME] [--sshconf SSHCONF] [--case CASE]
# hostname
#
# Generate then download RSI and logs. Optionally upload them to the matching
# JTAC case.
#
# positional arguments:
# hostname Device to connect to
#
# optional arguments:
# -h, --help show this help message and exit
# --username USERNAME Juniper device username
# --sshconf SSHCONF SSH conf file (default: ~/.ssh/config)
# --case CASE JTAC case (2020-0123-0123)
import argparse
import datetime
import logging
from contextlib import contextmanager
from pathlib import Path
from jnpr.junos import Device
from jnpr.junos.utils.start_shell import StartShell
from paramiko import ProxyCommand, SFTPClient, SSHClient, SSHConfig, Transport
from scp import SCPClient
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger()
logging.getLogger("ncclient.transport").setLevel(logging.WARNING)
logging.getLogger("ncclient.operations.rpc").setLevel(logging.WARNING)
utc_date_time = datetime.datetime.utcnow().strftime("%Y-%m-%d-%H-%M")
logs_archive = 'LOGS-' + utc_date_time + '.tgz'
rsi_archive = 'RSI-' + utc_date_time + '.tgz'
class JuniperDevice():
@contextmanager
def connect(self):
logger.debug('Connecting to device with Junos PYEZ')
self.device.open()
try:
yield
finally:
self.device.close()
def __init__(self, args):
if 'username' in args:
username = args.username
else:
username = ''
self.device = Device(args.hostname, username, '', port=22)
def request_rsi(self):
with self.connect():
with StartShell(self.device) as sh:
logger.info('Generate RSI, this can take time.')
result = sh.run('cli -c "request support information | save /var/tmp/RSI-' + utc_date_time + '.txt"', timeout=600)
print(result)
logger.info('Compress RSI')
result = sh.run('cli -c "file archive compress source /var/tmp/RSI-' + utc_date_time + '.txt destination /var/tmp/' + rsi_archive + '"')
print(result)
def compress_logs(self):
with self.connect():
with StartShell(self.device) as sh:
logger.info('Compress logs')
result = sh.run('cli -c "file archive compress source /var/log/* destination /var/tmp/' + logs_archive + '"')
print(result)
class FileTransfer():
def __init__(self, args):
self.ssh_config = SSHConfig()
self.ssh_config.parse(open(args.sshconf))
self.ssh = SSHClient()
self.ssh.load_system_host_keys()
if 'username' in args:
self.username = args.username
else:
self.username = ''
self.hostname = args.hostname
def download(self):
ssh_conf_host = self.ssh_config.lookup(self.hostname)
# Assumes that everybody uses a proxycommand
proxy = ProxyCommand(ssh_conf_host['proxycommand'])
self.ssh.connect(self.hostname, username=self.username, key_filename=ssh_conf_host['identityfile'], sock=proxy)
with SCPClient(self.ssh.get_transport()) as scp:
logger.info('Download logs')
scp.get('/var/tmp/' + logs_archive)
logger.info('Download RSI')
scp.get('/var/tmp/' + rsi_archive)
def upload(self, case):
transport = Transport(('sftp.juniper.net', 22))
transport.connect(username='anonymous', password='anonymous')
sftp = SFTPClient.from_transport(transport)
remote_path = '/pub/incoming/' + case
try:
sftp.mkdir(remote_path)
except OSError: # Directory already exists
pass
logger.info('Upload logs to JTAC')
sftp.put(logs_archive, remote_path + '/' + logs_archive)
logger.info('Upload RSI to JTAC')
sftp.put(rsi_archive, remote_path + '/' + rsi_archive)
sftp.close()
transport.close()
def main():
arg_parser = argparse.ArgumentParser(description=('Generate then download RSI and logs.\
Optionally upload them to the matching JTAC case.'))
arg_parser.add_argument('hostname', help='Device to connect to')
arg_parser.add_argument('--username', help='Juniper device username')
default_ssh_conf = str(Path.home()) + '/.ssh/config'
arg_parser.add_argument('--sshconf', help='SSH conf file (default: ' + default_ssh_conf + ')', default=default_ssh_conf)
arg_parser.add_argument('--case', help='JTAC case (2020-0123-0123)')
args = arg_parser.parse_args()
juniper_device = JuniperDevice(args)
juniper_device.request_rsi()
juniper_device.compress_logs()
file_transfer = FileTransfer(args)
file_transfer.download()
if 'case' in args:
file_transfer.upload(args.case)
logger.info('https://casemanager.juniper.net/casemanager/#/cmdetails/' + args.case)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment