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

added additional ssh config params

parent ef8e0a0f
No related branches found
No related tags found
No related merge requests found
......@@ -168,6 +168,9 @@ def _juniper_main(router_fqdn: str, app_config_params: dict):
:return:
"""
if 'juniper' not in app_config_params:
raise ValueError('juniper ssh config is required')
if 'inventory' in app_config_params:
all_routers = {_ifc['router'] for _ifc in inventory.load_interfaces()}
if router_fqdn not in all_routers:
......@@ -177,7 +180,7 @@ def _juniper_main(router_fqdn: str, app_config_params: dict):
netconf_doc = juniper.get_interface_info_ncrpc(
router_fqdn,
ssh_config=app_config_params['ssh-config'])
ssh_params=app_config_params['juniper'])
netconf_timestamp = datetime.now()
influx_params = app_config_params['influx']['brian-counters']
......
{
"log": {
"level": "info",
"format": "json"
},
"juniper": {
"ssh_config": "~/.ssh/config"
},
"nokia": {
"username": "bogus-user",
"password": "bogus-password"
},
"ssh-config": "~/.ssh/config",
"inventory": ["http://blah"],
"influx": {
......
......@@ -8,11 +8,25 @@ logger = logging.getLogger(__name__)
DEFAULT_INFLUX_SSL = True
DEFAULT_INFLUX_PORT = 8086
DEFAULT_NETCONF_PORT = 830
DEFAULT_HOSTKEY_VERIFY = False
CONFIG_SCHEMA = {
'$schema': 'https://json-schema.org/draft/2020-12/schema',
'definitions': {
'ssh-params': {
'type': 'object',
'properties': {
'username': {'type': 'string'},
'password': {'type': 'string'},
'port': {'type': 'integer'},
'key_filename': {'type': 'string'},
'ssh_config': {'type': 'string'},
'hostkey_verify': {'type': 'boolean'}
},
'additionalProperties': False
},
'influx-db-measurement': {
'type': 'object',
'properties': {
......@@ -38,7 +52,8 @@ CONFIG_SCHEMA = {
'type': 'object',
'properties': {
'ssh-config': {'type': 'string'},
'juniper': {'$ref': '#/definitions/ssh-params'},
'nokia': {'$ref': '#/definitions/ssh-params'},
'inventory': {
'type': 'array',
'items': {'type': 'string', 'format': 'uri'},
......@@ -54,7 +69,7 @@ CONFIG_SCHEMA = {
'additionalProperties': False
},
},
'required': ['ssh-config', 'influx'],
'required': ['influx'],
'additionalProperties': False
}
......@@ -71,10 +86,26 @@ def load(config_file):
config = json.loads(config_file.read())
jsonschema.validate(config, CONFIG_SCHEMA)
# TODO: why is this necessary?
# (user is automatically expanded for me when running from pycharm, but not from cli???)
config['ssh-config'] = os.path.expanduser(config['ssh-config'])
assert os.path.exists(config['ssh-config']), f'{config["ssh-config"]} does not exist'
# set some defaults
for router_vendor in 'juniper', 'nokia':
ssh_params = config.setdefault(router_vendor, {})
ssh_params.setdefault('port', DEFAULT_NETCONF_PORT)
ssh_params.setdefault('hostkey_verify', DEFAULT_HOSTKEY_VERIFY)
# verify any declared files are present
for _k in 'key_filename', 'ssh_config':
if _k in ssh_params:
assert os.path.exists(ssh_params[_k]), f'{ssh_params[_k]} does not exist'
# TODO: why is this necessary?
# (user is automatically expanded for me when running from pycharm, but not from cli???)]
for _k in 'key_filename', 'ssh_config':
if _k in ssh_params:
ssh_params[_k] = os.path.expanduser(ssh_params[_k])
for db in config['influx'].values():
db.setdefault('ssl', DEFAULT_INFLUX_SSL)
......
......@@ -9,14 +9,13 @@ from brian_polling_manager.interface_stats.vendors import netconf
logger = logging.getLogger(__name__)
def get_interface_info_ncrpc(router_name, ssh_config, host_verify=False):
def get_interface_info_ncrpc(router_name, ssh_params, host_verify=False):
request = etree.Element('get-interface-information')
request.append(etree.Element('extensive'))
return netconf.rpc(
router_name=router_name,
ssh_config=ssh_config,
command=request,
host_verify=host_verify)
ssh_params=ssh_params,
command=request)
def _elem_int(node, name):
......
......@@ -17,15 +17,15 @@ def _remove_ns(rpc_response):
.remove_namespaces(rpc_response.xml)
def _connection(hostname, ssh_config, host_verify=True):
conn = ncclient.manager.connect(
host=hostname,
port=830,
ssh_config=ssh_config,
hostkey_verify=host_verify
def _connection(hostname: str, ssh_params: dict, port=830):
params = {
'host': hostname,
'port': port,
# device_params={'name': 'junos'}
)
}
params.update(ssh_params)
conn = ncclient.manager.connect(**params)
conn.async_mode = True
return conn
......@@ -43,10 +43,19 @@ def _rpc_response(router, command):
return obj.reply
def rpc(router_name, ssh_config, command, host_verify=True):
def rpc(
router_name: str,
ssh_params: dict,
command: 'lxml.etree'):
"""
:param router_name: router fqdn
:param ssh_params: 'juniper' element from app config
:param command: an lxml etree element
:return:
"""
with contextlib.closing(_connection(
hostname=router_name,
ssh_config=ssh_config,
host_verify=host_verify)) as router:
ssh_params=ssh_params)) as router:
reply = _rpc_response(router, command)
return _remove_ns(reply)
......@@ -198,7 +198,22 @@ def app_config_params(free_host_port):
with tempfile.NamedTemporaryFile() as f:
yield {
'ssh-config': f.name,
'juniper': {
'username': 'bogus',
'password': 'bogus',
'port': 123,
'key_filename': f.name,
'ssh_config': f.name,
'hostkey_verify': True
},
'nokia': {
'username': 'bogus',
'password': 'bogus',
'port': -1234,
'key_filename': f.name,
'ssh_config': f.name,
'hostkey_verify': False
},
'inventory': ['http://blah'],
'influx': {
'brian-counters': {
......@@ -439,15 +454,15 @@ def test_e2e(app_config_params, app_config_filename, ifc_netconf_rpc, testenv_co
with patch('brian_polling_manager.inventory.load_interfaces') as inventory:
inventory.return_value = poller_interfaces()
for router_fqdn in JUNIPER_ROUTERS:
# cli._main(router_fqdn=router_fqdn, app_config_params=app_config_params)
runner = CliRunner()
result = runner.invoke(
cli.main,
[
'--config', app_config_filename,
'--juniper', router_fqdn
])
assert result.exit_code == 0, str(result)
cli._juniper_main(router_fqdn=router_fqdn, app_config_params=app_config_params)
# runner = CliRunner()
# result = runner.invoke(
# cli.main,
# [
# '--config', app_config_filename,
# '--juniper', router_fqdn
# ])
# assert result.exit_code == 0, str(result)
def verify_influx_content(influx_config, expected_fields):
# for each expected field, verify that there's
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment