Skip to content
Snippets Groups Projects
Commit b4fab396 authored by Erik Reid's avatar Erik Reid
Browse files

removed ssh-based juniper module

parent f7b6f253
No related branches found
No related tags found
No related merge requests found
import contextlib
import json
import logging
import re
import paramiko
from inventory_provider.constants import JUNIPER_LOGGER_NAME
def neighbors(
parsed_json_output,
routing_instances=["IAS"],
group_expression=r'^GEANT-IX(v6)?[\s-].*$'):
for config in parsed_json_output["configuration"]:
for ri in config["routing-instances"]:
for inst in ri["instance"]:
if inst["name"]["data"] not in routing_instances:
continue
for prot in inst["protocols"]:
for bgp in prot.get("bgp", []):
for g in bgp.get("group", []):
if group_expression and not \
re.match(
group_expression,
g["name"]["data"]):
continue
for n in g["neighbor"]:
yield n
def interfaces(parsed_json_output):
for ifc_info in parsed_json_output["interface-information"]:
for ifc_list in ifc_info["logical-interface"]:
for ifc in ifc_list:
yield {
"name": ifc["name"][0]["data"],
"status": "%s/%s" % (
ifc["admin-status"][0]["data"],
ifc["oper-status"][0]["data"]),
"description": ifc["description"][0]["data"],
"type": "logical"
}
@contextlib.contextmanager
def ssh_connection(hostname, ssh_params):
# TODO: remove this relative path logic!!
import os
key_filename = os.path.join(
os.path.dirname(__file__),
ssh_params["private-key"])
known_hosts = os.path.join(
os.path.dirname(__file__),
ssh_params["known-hosts"])
k = paramiko.DSSKey.from_private_key_file(key_filename)
with paramiko.SSHClient() as ssh:
ssh.load_host_keys(known_hosts)
ssh.connect(
hostname=hostname,
username=ssh_params['username'],
pkey=k)
yield ssh
def ssh_exec_commands(hostname, ssh_params, commands):
juniper_logger = logging.getLogger(JUNIPER_LOGGER_NAME)
with ssh_connection(hostname, ssh_params) as ssh:
_, stdout, _ = ssh.exec_command("set cli screen-length 0")
assert stdout.channel.recv_exit_status() == 0
for c in commands:
juniper_logger.debug("command: '%s'" % c)
_, stdout, _ = ssh.exec_command(c)
assert stdout.channel.recv_exit_status() == 0
# TODO: error handling
yield stdout.read().decode("utf-8")
def _loads(s, **args):
"""
the json text contains raw backslashes
:param s:
:param args:
:return:
"""
return json.loads(s.replace("\\", "\\\\"), **args)
_DISABLE_PAGING_COMMAND = r'set cli screen-length 0'
def fetch_bgp_config(hostname, ssh_params, **args):
commands = [
_DISABLE_PAGING_COMMAND,
('show configuration routing-instances'
' IAS protocols bgp | display json')
]
output = list(ssh_exec_commands(hostname, ssh_params, commands))
assert len(output) == len(commands)
if output[1]:
return list(neighbors(_loads(output[1]), **args))
else:
return {}
def fetch_vrr_config(hostname, ssh_params):
commands = [
_DISABLE_PAGING_COMMAND,
('show configuration logical-systems '
'VRR protocols bgp | display json')
]
output = list(ssh_exec_commands(hostname, ssh_params, commands))
assert len(output) == len(commands)
return _loads(output[1]) if output[1] else {}
def fetch_interfaces(hostname, ssh_params):
def _dups_to_list(pairs):
counter_map = {}
for k, v in pairs:
counter_map.setdefault(k, []).append(v)
result = {}
for k, v in counter_map.items():
if len(v) == 1:
result[k] = v[0]
else:
result[k] = v
return result
commands = [
_DISABLE_PAGING_COMMAND,
'show interfaces descriptions | display json'
]
output = list(ssh_exec_commands(hostname, ssh_params, commands))
assert len(output) == len(commands)
return _loads(
output[1],
object_pairs_hook=_dups_to_list) if output[1] else {}
"""
this utility runs the juniper shell commands from dashboard
v1 and v3 on all routers and saves them to local files as
reusable unit test data
"""
import logging
import os
import multiprocessing
from inventory_provider import juniper
OUTPUT_DIR = os.path.dirname(__file__)
SSH_DIR = os.path.join(
os.path.dirname(__file__),
"..",
"..",
"inventory_provider",
"ssh")
SSH_PARAMS = {
'username': 'Monit0r',
'private-key': os.path.join(SSH_DIR, 'monitor_dsa'),
'known-hosts': os.path.join(SSH_DIR, 'monitor_known_hosts')
}
SHELL_COMMANDS = []
for c in juniper.shell_commands():
SHELL_COMMANDS.append({"key": c["key"], "command": c["command"]})
SHELL_COMMANDS.append({
"key": "bgpv4",
"command": (r'show configuration routing-instances IAS '
r'protocols bgp | display set | match neighbor'
r' | match description'
r' | match "GEANT-IX | GEANT-IX-"')
})
SHELL_COMMANDS.append({
"key": "bgpv6",
"command": (r'show configuration routing-instances IAS'
r' protocols bgp | display set | match neighbor'
r' | match description'
r' | match "GEANT-IXv6 | GEANT-IXv6-"')
})
ROUTER_HOSTNAMES = [
'mx2.ath.gr.geant.net',
'mx1.tal.ee.geant.net',
'mx2.tal.ee.geant.net',
'mx2.rig.lv.geant.net',
'mx1.kau.lt.geant.net',
'mx2.kau.lt.geant.net',
'mx2.zag.hr.geant.net',
'mx2.lju.si.geant.net',
'mx1.bud.hu.geant.net',
'mx1.pra.cz.geant.net',
'mx2.bra.sk.geant.net',
'mx1.lon.uk.geant.net',
'mx1.vie.at.geant.net',
'mx2.bru.be.geant.net',
'mx1.poz.pl.geant.net',
'mx1.ams.nl.geant.net',
'mx1.fra.de.geant.net',
'mx1.par.fr.geant.net',
'mx1.gen.ch.geant.net',
'mx1.mil2.it.geant.net',
'mx1.lis.pt.geant.net',
'mx2.lis.pt.geant.net',
'mx1.mad.es.geant.net',
'mx1.sof.bg.geant.net',
'mx1.buc.ro.geant.net',
'mx1.ham.de.geant.net',
'mx1.dub.ie.geant.net',
'mx1.dub2.ie.geant.net',
'mx1.mar.fr.geant.net',
'mx1.lon2.uk.geant.net',
'mx1.ath2.gr.geant.net',
]
def ssh_exec_commands(hostname, ssh_params, commands, q):
logging.debug("[ENTER>>] ssh_exec_comands: %r" % hostname)
q.put(list(juniper.ssh_exec_commands(hostname, ssh_params, commands)))
logging.debug("[EXIT>>] ssh_exec_comands: %r" % hostname)
def main():
processes = []
for hostname in ROUTER_HOSTNAMES:
q = multiprocessing.Queue()
p = multiprocessing.Process(
target=ssh_exec_commands,
args=(
hostname,
SSH_PARAMS,
[c["command"] for c in SHELL_COMMANDS],
q))
p.start()
processes.append({"hostname": hostname, "process": p, "queue": q})
for p in processes:
logging.debug("waiting for shell results from %r" % p["hostname"])
for c, o in zip(SHELL_COMMANDS, p["queue"].get()):
if not c["key"]:
continue
filename = os.path.join(
OUTPUT_DIR,
"%s-%s.output" % (p["hostname"], c["key"]))
with open(filename, "w") as f:
f.write(o)
p["process"].join()
logging.debug("saved shell results from %r" % p["hostname"])
if __name__ == "__main__":
logging.basicConfig(level=logging.DEBUG)
main()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment