def getSSHInfoForHost(host): """ Inspired by: http://markpasc.typepad.com/blog/2010/04/loading-ssh-config-settings-for-fabric.html """ from os.path import expanduser from paramiko.config import SSHConfig key = None key_filename = None host = host def hostinfo(host, config): hive = config.lookup(host) if 'hostname' in hive: host = hive['hostname'] if 'user' in hive: host = '%s@%s' % (hive['user'], host) if 'port' in hive: host = '%s:%s' % (host, hive['port']) return host try: config_file = file(expanduser('~/.ssh/config')) except IOError: pass else: config = SSHConfig() config.parse(config_file) key = config.lookup(host).get('identityfile', None) if key != None: key_filename = expanduser(key) host = hostinfo(host, config) return key_filename, host
def _annotate_hosts_with_ssh_config_info(): from os.path import expanduser from paramiko.config import SSHConfig def hostinfo(host, config): hive = config.lookup(host) if 'hostname' in hive: host = hive['hostname'] if 'user' in hive: host = '%s@%s' % (hive['user'], host) if 'port' in hive: host = '%s:%s' % (host, hive['port']) return host try: config_file = file(expanduser('~/.ssh/config')) except IOError: pass else: config = SSHConfig() config.parse(config_file) keys = [config.lookup(host).get('identityfile', None) for host in env.hosts] env.key_filename = [expanduser(key) for key in keys if key is not None] env.hosts = [hostinfo(host, config) for host in env.hosts] for role, rolehosts in env.roledefs.items(): env.roledefs[role] = [hostinfo(host, config) for host in rolehosts]
def main(working_dir=None): if working_dir is None: return logentriesprovisioning.constants.set_working_dir(working_dir) logentriesprovisioning.constants.set_account_key(None) logentriesprovisioning.constants.set_logentries_logging() if working_dir is None: ssh_config_name = 'ssh_config' else: ssh_config_name = '%s/ssh_config'%working_dir env.use_ssh_config = True try: config_file = file(ssh_config_name) except IOError: pass else: config = SSHConfig() config.parse(config_file) env._ssh_config = config for i in range(0,len(config._config)): print str(i), ' - ' , config._config[i] list_hosts = [] for host_config in env._ssh_config._config: print host_config if host_config['host'][0]!='*': list_hosts.extend(host_config['host']) execute(sync,hosts=list_hosts)
def hosts(self): """Retrieve host instances from ssh config.""" config = SSHConfig() with Path(self.user_config).open() as fileobj: config.parse(fileobj) hostnames = [i for i in config.get_hostnames() if self.is_endhost(i)] return [self.transform_to_instances(i, config.lookup(i)) for i in hostnames]
def annotate_hosts_with_ssh_config_info(): """ Load settings from ~/.ssh/config NOTE: Need to define env.hosts first. Code from http://markpasc.typepad.com/blog/2010/04/loading-ssh-config-settings-for-fabric.html """ def hostinfo(host, config): hive = config.lookup(host) if 'user' in hive: host = '%s@%s' % (hive['user'], host) if 'port' in hive: host = '%s:%s' % (host, hive['port']) return host try: config_file = file(expanduser('~/.ssh/config')) except IOError: pass else: config = SSHConfig() config.parse(config_file) keys = [config.lookup(host).get('identityfile', None) for host in env.hosts] env.key_filename = [key for key in keys if key is not None] env.hosts = [hostinfo(host, config) for host in env.hosts]
def parse_ssh_config(file_obj): """ Provided only as a backward-compatible wrapper around L{SSHConfig}. """ config = SSHConfig() config.parse(file_obj) return config
def ssh_config(host): from os.path import expanduser from paramiko.config import SSHConfig def hostinfo(host, config): hive = config.lookup(host) if 'hostname' in hive: host = hive['hostname'] if 'user' in hive: host = '%s@%s' % (hive['user'], host) if 'port' in hive: host = '%s:%s' % (host, hive['port']) return host try: config_file = file(expanduser('~/.ssh/config')) except IOError: pass else: config = SSHConfig() config.parse(config_file) key = config.lookup(host).get('identityfile', None) key_filename = expanduser(key) env.key_filename = [key_filename] if key_filename else [] return hostinfo(host, config)
def loadSshConfig(self): if self._sshConfig is None: self._sshConfigStr = self._vagrant.ssh_config(vm_name=self.host) configObj = StringIO(self._sshConfigStr) self._sshConfig = SSHConfig() # noinspection PyTypeChecker self._sshConfig.parse(configObj) self._sshHostConfig = self._sshConfig.lookup(self.host)
def load_ssh_config(self, host): ssh_config = SSHConfig() for path in (os.path.expanduser('~/.ssh/config'), '/etc/ssh/ssh_config'): if os.path.isfile(path): with open(path) as fd: ssh_config.parse(fd) return ssh_config.lookup(host)
def parse_ssh_config(file_obj): """ Provided only as a backward-compatible wrapper around `.SSHConfig`. .. deprecated:: 2.7 Use `SSHConfig.from_file` instead. """ config = SSHConfig() config.parse(file_obj) return config
def _clone_init_kwargs(self, *args, **kw): # Parent kwargs kwargs = super(Config, self)._clone_init_kwargs(*args, **kw) # Transmit our internal SSHConfig via explicit-obj kwarg, thus # bypassing any file loading. (Our extension of clone() above copies # over other attributes as well so that the end result looks consistent # with reality.) new_config = SSHConfig() # TODO: as with other spots, this implies SSHConfig needs a cleaner # public API re: creating and updating its core data. new_config._config = copy.deepcopy(self.base_ssh_config._config) return dict(kwargs, ssh_config=new_config)
def from_ssh_config(cls, host, config_file=os.path.expanduser("~/.ssh/config")): if os.path.isfile(config_file): ssh_config = SSHConfig() with open(config_file) as f: ssh_config.parse(f) user_config = ssh_config.lookup(host) if 'proxycommand' in user_config: return cls(user_config['proxycommand']) return None
def __init__(self, containers_file, extra_ssh_config_file): with open(conf.containers_file()) as infile: containers = yaml.load(infile) self._containers = [] self._container_default_config = {} self._ssh_config = SSHConfig() if extra_ssh_config_file is not None: with open(extra_ssh_config_file) as ssh_config_file: self._ssh_config.parse(ssh_config_file) self._missing_host_key_policy = AutoAddPolicy() for container_config in containers: if container_config['Host'] == '*': self._container_default_config = container_config break for container_config in containers: if container_config['Host'] == '*': continue container_host = container_config['Host'] ssh_host_config = self._ssh_config.lookup(container_host) ip_address = self._get_hostname_option(container_config) container = { 'Hostname': container_host, 'Id': container_host, 'Name': container_host, 'Labels': { 'interface': container_config['Interface'], 'type': container_config['Type'] }, 'State': { 'Running': 'running' }, 'NetworkSettings': { 'IPAddress': ip_address, 'MacAddress': None, 'Ports': None }, 'Config': container_config } self._containers.append(container) self.next_exec_id = 0 self.ssh_connections = {} self.execs = {}
def __init__(self, gerrit_host_alias): ssh_config = SSHConfig() user_ssh_config_file = os.path.expanduser("~/.ssh/config") if os.path.exists(user_ssh_config_file): with open(user_ssh_config_file) as f: ssh_config.parse(f) gerrit_host_name = ssh_config.lookup(gerrit_host_alias).get("hostname") auth = HTTPBasicAuthFromNetrc("https://{}/".format(gerrit_host_alias)) self.gerrit_api_client = GerritRestAPI("https://{}/".format(gerrit_host_name), auth)
def __init__(self, host, credential=None, stdout_queue=None, stderr_queue=None): self._password = None self.host = host self.credential = credential self.stdout_queue = stdout_queue self.stderr_queue = stderr_queue self.client = SSHClient() self.client.set_missing_host_key_policy(AutoAddPolicy()) self.config = SSHConfig() self.forward_agent = False self.parse_config_if_exists()
def _annotate_hosts_with_ssh_config_info(): from os.path import expanduser from paramiko.config import SSHConfig def hostinfo(host, config): hive = config.lookup(host) if 'hostname' in hive: host = hive['hostname'] if 'user' in hive: host = '%s@%s' % (hive['user'], host) if 'port' in hive: host = '%s:%s' % (host, hive['port']) return host try: config_file = file(expanduser('~/.ssh/config')) except IOError: pass else: config = SSHConfig() config.parse(config_file) keys = [ config.lookup(host).get('identityfile', None) for host in env.hosts ] env.key_filename = [ expanduser(key) for key in keys if key is not None ] env.hosts = [hostinfo(host, config) for host in env.hosts]
def __init__(self, hostname, user = None, filename = None): #set defaults if filename == None: filename = os.path.expanduser('~/.ssh/config') #read config file ssh_config = SSHConfig() with open(filename) as config_file: ssh_config.parse(config_file) self.update(ssh_config.lookup(hostname)) self.defaults={'port': 22, 'user': getpass.getuser(), 'hostname': hostname, 'hostkeyalias': hostname} if user != None: self['user'] = user
def does_not_affect_explicit_object(self, method): sc = SSHConfig() c = Config(ssh_config=sc, overrides={"load_ssh_configs": False}) # Implicit loading still doesn't happen...sanity check assert not method.called # Real test: the obj we passed in is present as usual assert c.base_ssh_config is sc
def __init__(self, *args, **kwargs): """ Creates a new Fabric-specific config object. For most API details, see `invoke.config.Config.__init__`. Parameters new to this subclass are listed below. :param ssh_config: Custom/explicit `paramiko.config.SSHConfig` object. If given, prevents loading of any SSH config files. Default: ``None``. :param str runtime_ssh_path: Runtime SSH config path to load. Prevents loading of system/user files if given. Default: ``None``. :param str system_ssh_path: Location of the system-level SSH config file. Default: ``/etc/ssh/ssh_config``. :param str user_ssh_path: Location of the user-level SSH config file. Default: ``~/.ssh/config``. :param bool lazy: Has the same meaning as the parent class' ``lazy``, but additionally controls whether SSH config file loading is deferred (requires manually calling `load_ssh_config` sometime.) For example, one may need to wait for user input before calling `set_runtime_ssh_path`, which will inform exactly what `load_ssh_config` does. """ # Tease out our own kwargs. # TODO: consider moving more stuff out of __init__ and into methods so # there's less of this sort of splat-args + pop thing? Eh. ssh_config = kwargs.pop("ssh_config", None) lazy = kwargs.get("lazy", False) self.set_runtime_ssh_path(kwargs.pop("runtime_ssh_path", None)) system_path = kwargs.pop("system_ssh_path", "/etc/ssh/ssh_config") self._set(_system_ssh_path=system_path) self._set(_user_ssh_path=kwargs.pop("user_ssh_path", "~/.ssh/config")) # Record whether we were given an explicit object (so other steps know # whether to bother loading from disk or not) # This needs doing before super __init__ as that calls our post_init explicit = ssh_config is not None self._set(_given_explicit_object=explicit) # Arrive at some non-None SSHConfig object (upon which to run .parse() # later, in _load_ssh_file()) if ssh_config is None: ssh_config = SSHConfig() self._set(base_ssh_config=ssh_config) # Now that our own attributes have been prepared & kwargs yanked, we # can fall up into parent __init__() super(Config, self).__init__(*args, **kwargs) # And finally perform convenience non-lazy bits if needed if not lazy: self.load_ssh_config()
def _get_host_ip( host: str, ssh_config_path: str = "~/.ssh/config" ) -> Union[IPv4Address, IPv6Address]: """ 1. If host.name is a short alias, we assume there is a corresponding record in `~/.ssh/config`: 1.1 If the corresponding `HOSTNAME` value is an IP address, return it as the result. 1.2 If the corresponding `HOSTNAME` is a domain, return the IP of the domain, assuming the domain is accessible from the local machine. 2. If host.name is a domain, return its IP, assuming the domain is accessible from the local machine. 3. Else raise an ValueError. """ posix_path: PosixPath = PosixPath(ssh_config_path) path_with_user_expanded: PosixPath = posix_path.expanduser() config: SSHConfig = SSHConfig.from_path(str(path_with_user_expanded)) # If `host.name` does not exist in `~/.ssh/config`, # `config.lookup(host.name)['hostname']` returns `host.name` itself. hostname: str = config.lookup(host)["hostname"] ip: Union[IPv4Address, IPv6Address] try: ip = ip_address(hostname) except ValueError: return ip_address(socket.gethostbyname(hostname)) else: return ip
def __init__(self, hostname, configpath=None, dry_run=False): ssh_config = SSHConfig() if not hostname: print(red('"hostname" must be defined')) sys.exit(1) parsed = self.parse_host(hostname) hostname = parsed.get('hostname') username = parsed.get('username') if configpath: if not isinstance(configpath, (list, tuple)): configpath = [configpath] for path in configpath: self._load_config(path, hostname) with (Path.home() / '.ssh/config').open() as fd: ssh_config.parse(fd) ssh_config = ssh_config.lookup(hostname) self.dry_run = dry_run self.hostname = config.hostname or ssh_config['hostname'] self.username = (username or config.username or ssh_config.get('user', getuser())) self.formatter = Formatter() self.key_filenames = [] if config.key_filename: self.key_filenames.append(config.key_filename) if 'identityfile' in ssh_config: self.key_filenames.extend(ssh_config['identityfile']) self.sudo = '' self.cd = None self.screen = None self.env = {} self._sftp = None self.proxy_command = ssh_config.get('proxycommand', config.proxy_command) self.open()
def __init__(self, hostname, username=None, password=None, transport=None, port=None, ssh_config_file=None): self.hostname = hostname c_args = dict() c_args['username'] = os.getenv('EOS_USER') or os.getenv( 'USER') or username c_args['password'] = os.getenv('EOS_PASSWORD') or os.getenv( 'PASSWORD') or password if port: c_args['port'] = port ssh_config_file = ssh_config_file or os.getenv('EOS_SSH_CONFIG') if ssh_config_file: ssh_config = SSHConfig() ssh_config.parse(open(ssh_config_file)) found = ssh_config.lookup(hostname) if 'user' in found: c_args['username'] = found['user'] if 'hostname' in found: c_args['host'] = found['hostname'] if 'localforward' in found: port = int(first(found['localforward']).split()[0]) c_args['port'] = port c_args['host'] = 'localhost' else: c_args['host'] = hostname c_args['transport'] = transport or self.DEFAULT_TRANSPORT self.api = pyeapi.connect(**c_args)
def __init__(self, hostname, user=None, filename=None): #set defaults if filename == None: filename = os.path.expanduser('~/.ssh/config') #read config file ssh_config = SSHConfig() with open(filename) as config_file: ssh_config.parse(config_file) self.update(ssh_config.lookup(hostname)) self.defaults = { 'port': 22, 'user': getpass.getuser(), 'hostname': hostname, 'hostkeyalias': hostname } if user != None: self['user'] = user
def annotate_from_sshconfig(env): """ Adds support for reading the host names, users and ports from ~/ssh/config Replaces the hosts defined in ssh config with actual host names, so that Fabric can take the advantage from it .. IMPORTANT:: This does not support /etc/ssh/ssh_config yet! """ from os.path import expanduser from paramiko.config import SSHConfig def hostinfo(host, config): hive = config.lookup(host) if 'hostname' in hive: host = hive['hostname'] if 'user' in hive: host = '%s@%s' % (hive['user'], host) if 'port' in hive: host = '%s:%s' % (host, hive['port']) return host # Look for user config, if found, parse it and update roledefs. Otherwise just ignore it (it is not required at all) try: config_file = file(expanduser('~/.ssh/config')) except IOError: pass else: config = SSHConfig() config.parse(config_file) keys = [ config.lookup(host).get('identityfile', None) for host in api.env.hosts ] env.key_filename = [expanduser(key) for key in keys if key is not None] env.hosts = [hostinfo(host, config) for host in env.hosts] for role, rolehosts in env.roledefs.items(): env.roledefs[role] = [hostinfo(host, config) for host in rolehosts]
def __init__(self, hostname, configpath=None): ssh_config = SSHConfig() if not hostname: print(red('"hostname" must be defined')) sys.exit(1) parsed = self.parse_host(hostname) hostname = parsed.get('hostname') username = parsed.get('username') if configpath: if not isinstance(configpath, (list, tuple)): configpath = [configpath] for path in configpath: self._load_config(path, hostname) with (Path.home() / '.ssh/config').open() as fd: ssh_config.parse(fd) ssh_config = ssh_config.lookup(hostname) self.hostname = ssh_config['hostname'] self.username = username or ssh_config.get('user', getuser()) self.open() self.formatter = Formatter() self.sudo = '' self.cd = None self.screen = None self.env = {} self._sftp = None
def create_worker(host): config = SSHConfig() proxy = None if os.path.exists(os.path.expanduser('~/.ssh/config')): with open(os.path.expanduser('~/.ssh/config')) as f: config.parse(f) if host.hostname is not None and 'proxycommand' in config.lookup( host.hostname): proxy = ProxyCommand(config.lookup(host.hostname)['proxycommand']) worker = SSHClient() worker.load_system_host_keys() worker.set_missing_host_key_policy(AutoAddPolicy()) # store data for later reference worker.host = host.hostname worker.username = host.username worker.password = host.password worker.key_filename = host.key_filename worker.connect(hostname=host.hostname, username=host.username, password=host.password, key_filename=host.key_filename, sock=proxy) return worker
def ssh_hosts(): paths = [] configs = {} try: import pwd for pw in pwd.getpwall(): config_path = path.join(pw.pw_dir, '.ssh', 'config') if path.isfile(config_path): paths.append((pw.pw_name, config_path)) except ImportError: config_path = path.expanduser(path.join('~', '.ssh', 'config')) if path.isfile(config_path): import getpass paths = [(getpass.getuser(), config_path)] for user, config_path in paths: ssh_config = SSHConfig() try: with open(config_path) as config: ssh_config.parse(config) except OSError: continue configs[user] = { host: ssh_config.lookup(host) for host in ssh_config.get_hostnames() } configs.update(ssh_putty_hosts()) return configs
def create_worker(host): config = SSHConfig() proxy = None if os.path.exists(os.path.expanduser('~/.ssh/config')): config.parse(open(os.path.expanduser('~/.ssh/config'))) if host.hostname is not None and \ 'proxycommand' in config.lookup(host.hostname): proxy = ProxyCommand(config.lookup(host.hostname)['proxycommand']) # proxy = paramiko.ProxyCommand("ssh -o StrictHostKeyChecking=no [email protected] nc 118.138.239.241 22") worker = SSHClient() worker.load_system_host_keys() worker.set_missing_host_key_policy(AutoAddPolicy()) worker.hostname = host.hostname # store all this for later reference (e.g., logging, reconnection) worker.username = host.username worker.password = host.password worker.proxy = proxy if not host.key_filename is None: worker.pkey = RSAKey.from_private_key_file(host.key_filename, host.key_password) else: worker.pkey = None # time.sleep(4) # worker.connect(hostname=host.hostname, username=host.username, password=host.password, key_filename=host.key_filename, sock=proxy, timeout=3600) worker.connect(hostname=host.hostname, username=host.username, password=host.password, pkey=worker.pkey, sock=proxy) return worker
def open_gateway(self): """ Obtain a socket-like object from `gateway`. :returns: A ``direct-tcpip`` `paramiko.channel.Channel`, if `gateway` was a `.Connection`; or a `~paramiko.proxy.ProxyCommand`, if `gateway` was a string. .. versionadded:: 2.0 """ # ProxyCommand is faster to set up, so do it first. if isinstance(self.gateway, string_types): # Leverage a dummy SSHConfig to ensure %h/%p/etc are parsed. # TODO: use real SSH config once loading one properly is # implemented. ssh_conf = SSHConfig() dummy = "Host {}\n ProxyCommand {}" ssh_conf.parse(StringIO(dummy.format(self.host, self.gateway))) return ProxyCommand(ssh_conf.lookup(self.host)["proxycommand"]) # Handle inner-Connection gateway type here. # TODO: logging self.gateway.open() # TODO: expose the opened channel itself as an attribute? (another # possible argument for separating the two gateway types...) e.g. if # someone wanted to piggyback on it for other same-interpreter socket # needs... # TODO: and the inverse? allow users to supply their own socket/like # object they got via $WHEREEVER? # TODO: how best to expose timeout param? reuse general connection # timeout from config? return self.gateway.transport.open_channel( kind="direct-tcpip", dest_addr=(self.host, int(self.port)), # NOTE: src_addr needs to be 'empty but not None' values to # correctly encode into a network message. Theoretically Paramiko # could auto-interpret None sometime & save us the trouble. src_addr=("", 0), )
def __init__(self, hostname, port=22, username=None, config_path=None): self.hostname = hostname self.client = SSHClient() self.client.load_system_host_keys() self.client.set_missing_host_key_policy(AutoAddPolicy()) if config_path is None: config_path = os.path.join(os.path.expanduser('~'), '.ssh', 'config') self.config = SSHConfig() with open(config_path) as config_file: self.config.parse(config_file) if hostname in self.config.get_hostnames(): host_cfg = self.config.lookup(hostname) full_hostname = host_cfg.get('hostname', hostname) if username is None: username = host_cfg.get('user', None) # If none, it will try the user running the server. else: full_hostname = hostname self.client.connect(full_hostname, port, username=username)
def __init__(self, hostname: str, root: Path, port: int, username: str, password: str, key: Union[PathLike, Sequence[PathLike]]): ssh = SSHClient() ssh.load_system_host_keys() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) config_path = Path('~/.ssh/config').expanduser() if config_path.exists(): with open(config_path) as f: config = SSHConfig() config.parse(f) host = config.lookup(hostname) hostname = host.get('hostname', hostname) port = host.get('port', port) username = host.get('user', username) key = host.get('identityfile', key) [self.hostname, self.port, self.username, self.password, self.key] = hostname, port, username, password, key self.root = root self.ssh = ssh
def main(working_dir=None, cmd='', group_name='AWS'): """ Main function for the module. Calls other functions according to the parameters provided. """ constants.set_working_dir(working_dir) constants.set_account_key(None) constants.set_logentries_logging() if working_dir is None: ssh_config_name = 'ssh_config' else: ssh_config_name = '%s/ssh_config'%working_dir env.use_ssh_config = True try: config_file = file(ssh_config_name) except IOError: pass else: config = SSHConfig() config.parse(config_file) env._ssh_config = config list_hosts = [] for host_config in env._ssh_config._config: host_name = host_config['host'][0] if host_config['host'][0]!='*': ssh_config = host_config['config']['hostname'] logger.info('Found instance ssh config. instance=%s, ssh_config=%s', host_name, ssh_config) list_hosts.extend(host_config['host']) if cmd == 'deprovision': execute(deprovision,hosts=list_hosts) elif cmd == 'clean': execute(set_instance_host_keys,hosts=list_hosts) execute(remove_hosts,group_name,hosts=list_hosts) elif cmd == '': execute(sync,hosts=list_hosts)
def __power_off_linux(): cfg = SSHConfig.from_path(Path.home() / ".ssh" / "config")\ .lookup(SSH_INSTANCE) ssh = SSHClient() ssh.set_missing_host_key_policy(AutoAddPolicy()) ssh.connect( **{ "hostname": cfg.get("hostname"), "port": cfg.get("port") or 22, "username": cfg.get("user"), "password": cfg.get("password"), "key_filename": cfg.get("identityfile"), }) ssh.exec_command("sudo poweroff")
def config_parser(config_path: Union["Path", str]) -> SSHConfig: """Parses ssh config file. Parameters ---------- config_path : Path path to config file Returns ------- SSHConfig paramiko SSHConfig object that parses config file """ if isinstance(config_path, str): config_path = Path(config_path).expanduser() config = SSHConfig() try: config.parse(config_path.open()) except FileNotFoundError: pass return config
def annotate_from_sshconfig(env): """ Adds support for reading the host names, users and ports from ~/ssh/config Replaces the hosts defined in ssh config with actual host names, so that Fabric can take the advantage from it .. IMPORTANT:: This does not support /etc/ssh/ssh_config yet! """ from os.path import expanduser from paramiko.config import SSHConfig def hostinfo(host, config): hive = config.lookup(host) if "hostname" in hive: host = hive["hostname"] if "user" in hive: host = "%s@%s" % (hive["user"], host) if "port" in hive: host = "%s:%s" % (host, hive["port"]) return host # Look for user config, if found, parse it and update roledefs. Otherwise just ignore it (it is not required at all) try: config_file = file(expanduser("~/.ssh/config")) except IOError: pass else: config = SSHConfig() config.parse(config_file) keys = [config.lookup(host).get("identityfile", None) for host in api.env.hosts] env.key_filename = [expanduser(key) for key in keys if key is not None] env.hosts = [hostinfo(host, config) for host in env.hosts] for role, rolehosts in env.roledefs.items(): env.roledefs[role] = [hostinfo(host, config) for host in rolehosts]
def _annotate_hosts_with_ssh_config_info(): from os.path import expanduser from paramiko.config import SSHConfig def hostinfo(host, config): hive = config.lookup(host) if "hostname" in hive: host = hive["hostname"] if "user" in hive: host = "%s@%s" % (hive["user"], host) if "port" in hive: host = "%s:%s" % (host, hive["port"]) return host try: config_file = file(expanduser("~/.ssh/config")) except IOError: pass else: config = SSHConfig() config.parse(config_file) keys = [config.lookup(host).get("identityfile", None) for host in env.hosts] env.key_filename = [expanduser(key) for key in keys if key is not None] env.hosts = [hostinfo(host, config) for host in env.hosts]
def _annotate_hosts_with_ssh_config_info(path): from os.path import expanduser from paramiko.config import SSHConfig def hostinfo(host, config): hive = config.lookup(host) # if 'hostname' in hive: # host = hive['hostname'] if 'user' in hive: host = '%s@%s' % (hive['user'], host) if 'port' in hive: host = '%s:%s' % (host, hive['port']) #print 'hive',hive #print 'host',host return host try: config_file = file(expanduser(path)) except IOError: pass else: config = SSHConfig() config.parse(config_file) # add hosts from ssh config to env.host & sort + unique env.hosts.extend([h for h in config.get_hostnames() if len(h) > 1]) env.hosts = sorted(set(env.hosts)) keys = [config.lookup(host).get('identityfile', None) for host in env.hosts] # flatten keys = [item for sublist in keys if sublist is not None for item in sublist] env.key_filename = [expanduser(key) for key in keys if key is not None] env.hosts = [hostinfo(host, config) for host in env.hosts] for role, rolehosts in env.roledefs.items(): env.roledefs[role] = [hostinfo(host, config) for host in rolehosts]
def __init__(self, host): self.host = host config_file = open(expanduser('.tmp/ssh_config')) config = SSHConfig() config.parse(config_file) ip = config.lookup(host).get('hostname', None) port = config.lookup(host).get('port', 22) pk = config.lookup(host).get('identityfile', None) self.ssh = paramiko.SSHClient() self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) self.ssh.connect(hostname=ip, port=int(port), username=SSH_USERNAME, key_filename=pk) s = self.ssh.get_transport().open_session() paramiko.agent.AgentRequestHandler(s)
class SystemVM(object): def __init__(self, host="default", vagrantDir=None, controlVagrant=True): global _defaultVagrantDir self.host = host self._controlVagrant = controlVagrant if vagrantDir is None: vagrantDir = _defaultVagrantDir self._vagrant = Vagrant(root=vagrantDir) self._startedVagrant = False self._sshClient = None self._sshConfigStr = None self._sshConfig = None self._sshHostConfig = None def maybeUp(self): if not self._controlVagrant: return state = self._vagrant.status(vm_name=self.host)[0].state if state == Vagrant.NOT_CREATED: self._vagrant.up(vm_name=self.host) self._startedVagrant = True elif state in [Vagrant.POWEROFF, Vagrant.SAVED, Vagrant.ABORTED]: raise Exception("SystemVM testing does not support resume(), do not use vagrant suspend/halt") elif state == Vagrant.RUNNING: self._startedVagrant = False else: raise Exception("Unrecognized vagrant state %s" % state) def maybeDestroy(self): if not self._controlVagrant or not self._startedVagrant: return self._vagrant.destroy(vm_name=self.host) if self._sshClient is not None: self._sshClient.close() def loadSshConfig(self): if self._sshConfig is None: self._sshConfigStr = self._vagrant.ssh_config(vm_name=self.host) configObj = StringIO(self._sshConfigStr) self._sshConfig = SSHConfig() # noinspection PyTypeChecker self._sshConfig.parse(configObj) self._sshHostConfig = self._sshConfig.lookup(self.host) @property def sshConfig(self): if self._sshConfig is None: self.loadSshConfig() return self._sshConfig @property def sshConfigStr(self): if self._sshConfigStr is None: self.loadSshConfig() return self._sshConfigStr @property def sshClient(self): if self._sshClient is None: self.loadSshConfig() self._sshClient = SSHClient() self._sshClient.set_missing_host_key_policy(AutoAddPolicy()) self._sshClient.connect(self.hostname, self.sshPort, self.sshUser, key_filename=self.sshKey, timeout=10) return self._sshClient @property def hostname(self): return self._sshHostConfig.get("hostname", self.host) @property def sshPort(self): return int(self._sshHostConfig.get("port", 22)) @property def sshUser(self): return self._sshHostConfig.get("user", "root") @property def sshKey(self): return self._sshHostConfig.get("identityfile", "~/.ssh/id_rsa")
class SshClient(object): def __init__(self, containers_file, extra_ssh_config_file): with open(conf.containers_file()) as infile: containers = yaml.load(infile) self._containers = [] self._container_default_config = {} self._ssh_config = SSHConfig() if extra_ssh_config_file is not None: with open(extra_ssh_config_file) as ssh_config_file: self._ssh_config.parse(ssh_config_file) self._missing_host_key_policy = AutoAddPolicy() for container_config in containers: if container_config['Host'] == '*': self._container_default_config = container_config break for container_config in containers: if container_config['Host'] == '*': continue container_host = container_config['Host'] ip_address = self._get_hostname_option(container_config) container = { 'Hostname': container_host, 'Id': container_host, 'Name': container_host, 'Labels': { 'interface': container_config['Interface'], 'type': container_config['Type'] }, 'State': { 'Running': 'running' }, 'NetworkSettings': { 'IPAddress': ip_address, 'MacAddress': None, 'Ports': None }, 'Config': container_config } self._containers.append(container) self.next_exec_id = 0 self.ssh_connections = {} self.execs = {} def inspect_container(self, container_id): for container in self._containers: if container_id == container['Id']: return {'Name': container['Name'], 'Config': container, 'State': container['State'], 'NetworkSettings': container['NetworkSettings']} return None def containers(self, all=None): return self._containers def get_container_by_name(self, container_name): for container in self._containers: if container_name == str(container['Name']).translate(None, '/'): return container return None def exec_create(self, container_name, cmd, stdout=True, stderr=True, tty=False): LOG.info("Running command %s at container %s " % (cmd, container_name)) exec_id = self.next_exec_id self.next_exec_id += 1 self.execs[exec_id] = (container_name, cmd, None, None) return exec_id def exec_start(self, exec_id, detach=False, stream=False): container_name, cmd, stdout, stderr = self.execs[exec_id] ssh_connection = self._get_ssh_connection(container_name) stdin, stdout, stderr = ssh_connection.exec_command(cmd) if stream: self.execs[exec_id] = (container_name, cmd, stdout, stderr) return stdout else: return ''.join(stdout.readlines()) def exec_inspect(self, exec_id, detach=False, stream=False): container_name, cmd, stdout, stderr = self.execs[exec_id] if stdout.channel.exit_status_ready(): running = False exit_code = stdout.channel.recv_exit_status() else: running = True exit_code = "N/A" return {'Running': running, 'ProcessConfig': { 'entrypoint': cmd.split(' ')[0], 'arguments': cmd.split(' ')[1:]}, 'ExitCode': exit_code} def _get_option(self, container_config, option, paramiko_option, default): return container_config.get(option, self._container_default_config.get(option, self._ssh_config.lookup(container_config['Host']).get(paramiko_option, default))) def _get_hostname_option(self, container_config): hostname = self._get_option(container_config, 'HostName', 'hostname', 'localhost') return socket.gethostbyname(hostname) def _get_port_option(self, container_config): return int(self._get_option(container_config, 'Port', 'port', '22')) def _get_user_option(self, container_config): return self._get_option(container_config, 'User', 'user', 'root') def _get_password_option(self, container_config): return self._get_option(container_config, 'Password', 'password', None) def _get_identity_file_option(self, container_config): return self._get_option(container_config, 'IdentityFile', 'identityfile', '/dev/null') def _get_strict_host_key_checking_option(self, container_config): return self._get_option(container_config, 'StrictHostKeyChecking', 'stricthostkeychecking', 'yes') def _get_user_known_hosts_file(self, container_config): return self._get_option(container_config, 'UserKnownHostsFile', 'userknownhostsfile', '/dev/null') def _get_ssh_connection(self, container_name): if container_name in self.ssh_connections: return self.ssh_connections[container_name] config = self.get_container_by_name(container_name)['Config'] ssh_connection = paramiko.SSHClient() ssh_connection.load_system_host_keys() ssh_connection.set_missing_host_key_policy(self._missing_host_key_policy) try: ssh_connection.connect(self._get_hostname_option(config), port=self._get_port_option(config), username=self._get_user_option(config), password=self._get_password_option(config), key_filename=self._get_identity_file_option(config), look_for_keys=False, allow_agent=False ) except paramiko.ssh_exception.AuthenticationException: raise Exception("AuthenticationException while trying to " + ("connect to %s container: %s with config %s" % (container_name, container_name, config))) self.ssh_connections[container_name] = ssh_connection return self.ssh_connections[container_name]
def config_obj_prevents_loading_runtime_path_too(self, method): sc = SSHConfig() Config(ssh_config=sc, runtime_ssh_path=self._system_path) assert not method.called
def when_config_obj_given_default_paths_are_not_sought(self, method): sc = SSHConfig() Config(ssh_config=sc) assert not method.called