Last active
October 18, 2024 16:14
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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