def ssh_to_host(hostname, remote_command=None): """ Compose cmd string of ssh and execute Uses Ansible to parse inventory file, gets ssh connection options :param hostname: str. Hostname from inventory """ workspace_manager = CoreServices.workspace_manager() workspace = workspace_manager.get_active_workspace() if workspace is None: raise exceptions.IRNoActiveWorkspaceFound() inventory_file = workspace.inventory invent = inventory.Inventory(DataLoader(), VariableManager(), host_list=inventory_file) host = invent.get_host(hostname) if host is None: raise exceptions.IRSshException( "Host {} is not in inventory {}".format(hostname, inventory_file)) if _get_magic_var(host, "connection") == "local": raise exceptions.IRSshException("Only ssh transport acceptable.") cmd = " ".join([ "ssh {priv_key} {comm_args}", "{extra_args} -p {port} -t {user}@{host}" ]) cmd_fields = {} cmd_fields["user"] = _get_magic_var(host, "remote_user", default="root") cmd_fields["port"] = _get_magic_var(host, "port", default=22) cmd_fields["host"] = _get_magic_var(host, "remote_addr") priv_key = _get_magic_var(host, "private_key_file") # NOTE(yfried): # ssh client needs key to be in the directory you're running one from # ('ssh -i id_rsa ...') or to be provided by absolute path. # assume paths are relative to inventory file. abspath = os.path.join(os.path.abspath(os.path.dirname(inventory_file)), priv_key) priv_key = abspath if os.path.exists(abspath) else priv_key cmd_fields["priv_key"] = "-i {}".format(priv_key if priv_key else "") cmd_fields["comm_args"] = _get_magic_var(host, "ssh_common_args") cmd_fields["extra_args"] = _get_magic_var(host, "ssh_extra_args") LOG.debug("Establishing ssh connection to {}".format(cmd_fields["host"])) compiled_cmd = cmd.format(**cmd_fields) if remote_command is not None: compiled_cmd = " ".join([compiled_cmd, '"{}"'.format(remote_command)]) result = os.WEXITSTATUS(os.system(compiled_cmd)) LOG.debug("Connection to {} closed".format(cmd_fields["host"])) return result
def _fetch_inventory(self, name): """fetch inventory file for workspace. if no active workspace found - create a new workspace """ if name: wkspc = self.workspace_manager.get(name) else: wkspc = self.workspace_manager.get_active_workspace() if not wkspc: raise exceptions.IRNoActiveWorkspaceFound() print(wkspc.inventory)
def ssh_to_host(hostname, remote_command=None): """ Compose cmd string of ssh and execute Uses Ansible to parse inventory file, gets ssh connection options :param hostname: str. Hostname from inventory """ workspace_manager = CoreServices.workspace_manager() workspace = workspace_manager.get_active_workspace() if workspace is None: raise exceptions.IRNoActiveWorkspaceFound() inventory_file = workspace.inventory invent = inventory.Inventory(DataLoader(), VariableManager(), host_list=inventory_file) host = invent.get_host(hostname) if host is None: raise exceptions.IRSshException( "Host {} is not in inventory {}".format(hostname, inventory_file)) if _get_magic_var(host, "connection") == "local": raise exceptions.IRSshException("Only ssh transport acceptable.") cmd = " ".join([ "ssh {priv_key} {comm_args}", "{extra_args} -p {port} -t {user}@{host}" ]) cmd_fields = {} cmd_fields["user"] = _get_magic_var(host, "remote_user", default="root") cmd_fields["port"] = _get_magic_var(host, "port", default=22) cmd_fields["host"] = _get_magic_var(host, "remote_addr") priv_key = _get_magic_var(host, "private_key_file") cmd_fields["priv_key"] = "-i {}".format(priv_key if priv_key else "") cmd_fields["comm_args"] = _get_magic_var(host, "ssh_common_args") cmd_fields["extra_args"] = _get_magic_var(host, "ssh_extra_args") LOG.debug("Establishing ssh connection to {}".format(cmd_fields["host"])) compiled_cmd = cmd.format(**cmd_fields) if remote_command is not None: compiled_cmd = " ".join([compiled_cmd, '"{}"'.format(remote_command)]) os.system(compiled_cmd) LOG.debug("Connection to {} closed".format(cmd_fields["host"]))
def _get_inventory(self, workspace_name=None): """Returns Inventory object for the provided workspace. Use active workspace as default :param workspace_name: workspace name to list nodes from. """ workspace = self.get( workspace_name) if workspace_name else self.get_active_workspace() if workspace is None: if workspace_name is None: raise exceptions.IRNoActiveWorkspaceFound() else: raise exceptions.IRWorkspaceMissing(workspace=workspace_name) return InventoryManager(DataLoader(), sources=workspace.inventory)
def _get_inventory(self, workspace_name=None): """Returns Inventory object for the provided workspace. Use active workspace as default :param workspace_name: workspace name to list nodes from. """ workspace = self.get( workspace_name) if workspace_name else self.get_active_workspace() if workspace is None: if workspace_name is None: raise exceptions.IRNoActiveWorkspaceFound() else: raise exceptions.IRWorkspaceMissing(workspace=workspace_name) # need to have import here to avoid ansible patching from ansible.inventory.manager import InventoryManager from ansible.parsing.dataloader import DataLoader return InventoryManager(DataLoader(), sources=workspace.inventory)
def export_workspace(self, workspace_name, file_name=None): """Export content of workspace folder as gzipped tar file Replaces existing .tgz file """ if workspace_name: workspace = self.get(workspace_name) if workspace is None: raise exceptions.IRWorkspaceMissing(workspace=workspace_name) else: workspace = self.get_active_workspace() if workspace is None: raise exceptions.IRNoActiveWorkspaceFound() fname = file_name or workspace.name with tarfile.open(fname + '.tgz', "w:gz") as tar: tar.add(workspace.path, arcname="./") print("Workspace {} is exported to file {}.tgz".format( workspace.name, fname))
def export_workspace(self, workspace_name, file_name=None, copykeys=False): """Export content of workspace folder as gzipped tar file Replaces existing .tgz file """ if workspace_name: workspace = self.get(workspace_name) if workspace is None: raise exceptions.IRWorkspaceMissing(workspace=workspace_name) else: workspace = self.get_active_workspace() if workspace is None: raise exceptions.IRNoActiveWorkspaceFound() fname = file_name or workspace.name # Copy workspace to not damage original, tmpdir = tempfile.mkdtemp() tmp_workspace_path = os.path.join(tmpdir, os.path.basename(workspace.path)) try: shutil.copytree(workspace.path, tmp_workspace_path, symlinks=True) tmp_workspace = Workspace(name=workspace.name, path=tmp_workspace_path) tmp_workspace._update_paths(workspace.path, workspace.path_placeholder) if copykeys: tmp_workspace._copy_outside_keys() with tarfile.open(fname + '.tgz', "w:gz") as tar: tar.add(tmp_workspace.path, arcname="./") finally: shutil.rmtree(tmpdir) print("Workspace {} is exported to file {}.tgz".format(workspace.name, fname))
def node_list(self, workspace_name=None): """Lists nodes and connection types from workspace's inventory nodes with connection type 'local' are skipped :param workspace_name: workspace name to list nodes from. Use active workspace as default """ workspace = self.get( workspace_name) if workspace_name else self.get_active_workspace() if workspace is None: if workspace_name is None: raise exceptions.IRNoActiveWorkspaceFound() else: raise exceptions.IRWorkspaceMissing(workspace=workspace_name) invent = inventory.Inventory(DataLoader(), VariableManager(), host_list=workspace.inventory) hosts = invent.get_hosts() return [(host.name, host.address) for host in hosts if host.vars.get("ansible_connection") != "local"]