def _process_ssh_config(self, ssh_config_file: str) -> None: """ Method to parse ssh config file Ensure ssh_config_file is valid (if providing a string path to config file), or resolve config file if passed True. Search config file for any private key, if ANY matching key is found and user has not provided a private key, set `auth_private_key` to the value of the found key. This is because we prefer to use `open_pipes` over `open_pty`! Args: ssh_config_file: string path to ssh config file; passed down from `Scrape`, or the `NetworkDriver` or subclasses of it, in most cases. Returns: N/A # noqa: DAR202 Raises: N/A """ ssh = SSHConfig(ssh_config_file=ssh_config_file) self.ssh_config_file = ssh.ssh_config_file host_config = ssh.lookup(host=self.host) if not self.auth_private_key and host_config.identity_file: self.auth_private_key = os.path.expanduser( host_config.identity_file.strip())
def _process_ssh_config( host: str, ssh_config_file: str) -> Tuple[Optional[int], str, str]: """ Method to parse ssh config file In the future this may move to be a 'helper' function as it should be very similar between asyncssh and and paramiko/ssh2-python... for now it can be a static method as there may be varying supported args between the transport drivers. Args: host: host to lookup in ssh config file ssh_config_file: string path to ssh config file; passed down from `Scrape`, or the `NetworkDriver` or subclasses of it, in most cases. Returns: Tuple: port to use for ssh, username to use for ssh, identity file (private key) to use for ssh auth Raises: N/A """ ssh = SSHConfig(ssh_config_file) host_config = ssh.lookup(host) return host_config.port, host_config.user or "", host_config.identity_file or ""
def test_host_lookup_merged_data(): ssh_conf = SSHConfig(f"{TEST_DATA_DIR}/files/_ssh_config") host = ssh_conf.lookup("scrapli") assert repr(host) == ( "Host {'hosts': 'scrapli', 'hostname': None, 'port': None, 'user': '******', 'address_family': None, " "'bind_address': None, 'connect_timeout': None, 'identities_only': None, 'identity_file': " f"'{os.path.expanduser('~')}/.ssh/lastresortkey', 'keyboard_interactive': None, 'password_authentication': None, " "'preferred_authentication': None}")
def test_host_lookup_host_fuzzy_multi_match(): ssh_conf = SSHConfig(f"{TEST_DATA_DIR}/files/_ssh_config") host = ssh_conf.lookup("someswitch9999") assert repr(host) == ( "Host {'hosts': 'someswitch?', 'hostname': 'someswitch1.bogus.com', 'port': " "1234, 'user': '******', 'address_family': None, 'bind_address': None, 'connect_timeout': " f"None, 'identities_only': 'yes', 'identity_file': '{os.path.expanduser('~')}/.ssh/mysshkey', " "'keyboard_interactive': None, 'password_authentication': None, 'preferred_authentication': " "None}")
def test_host_lookup_exact_host_in_list(): ssh_conf = SSHConfig(f"{UNIT_TEST_DIR}_ssh_config") host = ssh_conf.lookup("someswitch1") assert repr(host) == ( "Host {'hosts': '1.2.3.4 someswitch1', 'hostname': 'someswitch1.bogus.com', 'port': " "1234, 'user': '******', 'address_family': None, 'bind_address': None, 'connect_timeout': " f"None, 'identities_only': 'yes', 'identity_file': '{os.path.expanduser('~')}/.ssh/mysshkey', " "'keyboard_interactive': None, 'password_authentication': None, 'preferred_authentication':" " None}")
def _update_ssh_args_from_ssh_config(self) -> None: """ Update ssh args based on ssh config file data Args: N/A Returns: None Raises: N/A """ ssh = SSHConfig(self.ssh_config_file) host_config = ssh.lookup(self.host) if host_config.port: self.logger.info( f"found port for host in ssh configuration file, using this value " f"'{host_config.port}' for port!" ) # perhaps this should not override already set port because we dont know if the user # provided the port or we just are accepting the default port value... in any case for # port, if it is in the ssh config file we will override whatever we currently have self.port = host_config.port if host_config.user and not self.auth_username: self.logger.info( f"found username for host in ssh configuration file, using this value " f"'{host_config.user}' for auth_username!" ) # only override auth_username if it is not truthy self.auth_username = host_config.user if host_config.identity_file and not self.auth_private_key: self.logger.info( f"found identity file for host in ssh configuration file, using this value " f"'{host_config.identity_file}' for auth_private_key!" ) # only override auth_private_key if it is not truthy self.auth_private_key = host_config.identity_file