コード例 #1
0
ファイル: sshjail.py プロジェクト: chiahsuy/koadstation
class Connection(object):
    ''' jail-over-ssh based connections '''

    def match_jail(self):
        if self.jid == None:
            code, _, stdout, stderr = self._exec_command("jls -q jid name host.hostname path")
            if code != 0:
                vvv("JLS stdout: %s" % stdout)
                raise errors.AnsibleError("jls returned non-zero!")

            lines = stdout.strip().split('\n')
            found = False
            for line in lines:
                jid, name, hostname, path = line.strip().split()
                if name == self.jailspec or hostname == self.jailspec:
                    self.jid = jid
                    self.jname = name
                    self.jhost = hostname
                    self.jpath = path
                    found = True
                    break

            if not found:
                raise errors.AnsibleError("failed to find a jail with name or hostname of '%s'" % self.jailspec)

    def get_jail_path(self):
        self.match_jail()
        return self.jpath

    def get_jail_id(self):
        self.match_jail()
        return self.jid

    def get_tmp_file(self):
        code, _, stdout, stderr = self._exec_command('mktemp', '', None)
        return stdout.strip().split('\n')[-1]


    def __init__(self, runner, host, port, user, password, private_key_file, *args, **kwargs):
        # [email protected] => my-jail is jail name/hostname, my.jailhost is jailhost hostname
        self.host = host
        self.jailspec, self.jailhost = host.split('@',1)

        # piggyback off of the standard SSH connection
        self.runner = runner
        self.has_pipelining = False
        self.ssh = SSHConn(runner, self.jailhost, port, user, password, private_key_file, *args)

        # jail information loaded on first use by match_jail
        self.jid = None
        self.jname = None
        self.jhost = None
        self.jpath = None

        # loaded after first exec_command
        self.juser = None

    def connect(self, port=None):
        self.ssh.connect();
        return self

    # runs a command on the jailhost, rather than inside the jail
    def _exec_command(self, cmd, tmp_path='', become_user=None, sudoable=False, executable='/bin/sh', in_data=None):
        # oh lordy I hate this approach, but we need to note what user we use to access the jail so put/fetch works
        if become_user != None:
            self.juser = become_user

        return self.ssh.exec_command(cmd, tmp_path, become_user, sudoable, executable, in_data)


    def exec_command(self, cmd, tmp_path, become_user=None, sudoable=False, executable='/bin/sh', in_data=None):
        ''' run a command in the jail '''

        if SSHJAIL_USE_JAILME:
            jcmd = ['jailme', self.get_jail_id()]
        else:
            jcmd = ['jexec', self.get_jail_id()]

        if executable:
            local_cmd = ' '.join([jcmd[0], jcmd[1], executable, '-c', '"%s"' % cmd])
        else:
            local_cmd = '%s "%s" "%s"' % (jcmd[0], jcmd[1], cmd)

        vvv("JAIL (%s) %s" % (become_user, local_cmd), host=self.host)
        return self._exec_command(local_cmd, tmp_path, become_user, True, executable, in_data)

    def _normalize_path(self, path, prefix):
        if not path.startswith(os.path.sep):
            path = os.path.join(os.path.sep, path)
        normpath = os.path.normpath(path)
        return os.path.join(prefix, normpath[1:])

    def put_file(self, in_path, out_path):
        ''' transfer a file from local to remote jail '''
        tmp = self.get_tmp_file()
        self.ssh.put_file(in_path, tmp)
        out_path = self._normalize_path(out_path, self.get_jail_path())

        code, _, stdout, stderr = self._exec_command(' '.join(['chmod 0777',tmp]))
        if code != 0:
            raise errors.AnsibleError("failed to make temp file %s world writable:\n%s\n%s" % (tmp, stdout, stderr))

        code, _, stdout, stderr = self._exec_command(' '.join(['cp',tmp,out_path]), '', self.juser, True)
        if code != 0:
            raise errors.AnsibleError("failed to move file from %s to %s:\n%s\n%s" % (tmp, out_path, stdout, stderr))

    def fetch_file(self, in_path, out_path):
        ''' fetch a file from remote jail to local '''
        tmp = self.get_tmp_file()
        in_path = self._normalize_path(in_path, self.get_jail_path())
        self._exec_command(' '.join(['mv',in_path,tmp]), '', self.juser, True)
        self.ssh.fetch_file(tmp, out_path)

    def close(self):
        ''' terminate the connection; nothing to do here '''
        pass
コード例 #2
0
ファイル: sshjail.py プロジェクト: egwynn/ansible-sshjail
class Connection(object):
    ''' jail-over-ssh based connections '''

    def get_jail_path(self):
        return self.path

    def get_jail_id(self):
        return self.jid

    def match_jail(self):
        code, _, stdout, stderr = self._exec_command(' '.join(['jls', 'name', 'jid', 'path']))
        lines = stdout.strip().split('\n')

        lines = [ line.split() for line in lines ]

        names = dict(
            (re.sub(r'\W', '_', name), {
                'name': name.strip(),
                'jid': jid.strip(),
                'path': path.strip(),
            }) for name, jid, path in lines
        )

        if len(names) != len(lines):
            vvv("WARNING: This host's jail names are not unique after underscore-substitution!")

        # remove \n
        jail = names.get(self.jname)
        if jail:
            self.jid = jail['jid']
            self.path = jail['path']
            self.jname = jail['name']
            vvv('Matched jail: %s' % self.jname)
        else:
            vvv('No jail found with name: %s' % self.jname)

    def get_tmp_file(self):
        code, _, stdout, stderr = self._exec_command('mktemp', '', None)
        return stdout.strip().split('\n')[-1]


    def __init__(self, runner, host, port, user, password, private_key_file, *args, **kwargs):
        self.host = host
        jaildef, self.jailhost = host.split('@',1)
        self.jname = re.sub(r'\W','_',jaildef)
        self.runner = runner
        self.has_pipelining = False
        self.ssh = SSHConn(runner, self.jailhost, port, user, password, private_key_file, *args)
        self.jid = None
        self.path = None
        self.juser = None
        self.matched = False

    def connect(self, port=None):
        self.ssh.connect()
        if not self.matched:
            self.match_jail()
            self.matched = True
        return self

    def _exec_command(self, cmd, tmp_path='', become_user=None, sudoable=False, executable='/bin/sh', in_data=None):
        # oh lordy I hate this approach, but we need to note what user we use to access the jail so put/fetch works
        if become_user != None:
            self.juser = become_user

        return self.ssh.exec_command(cmd, tmp_path, become_user, sudoable, executable, in_data)


    def exec_command(self, cmd, tmp_path, become_user=None, sudoable=False, executable='/bin/sh', in_data=None):
        ''' run a command in the jail '''

        if SSHJAIL_USE_JAILME:
            jcmd = ['jailme', self.jid]
        else:
            jcmd = ['jexec', self.jname]

        if executable:
            local_cmd = ' '.join([jcmd[0], jcmd[1], executable, '-c', '"%s"' % cmd])
        else:
            local_cmd = '%s "%s" "%s"' % (jcmd[0], jcmd[1], cmd)

        vvv("JAIL (%s) %s" % (become_user, local_cmd), host=self.host)
        return self._exec_command(local_cmd, tmp_path, become_user, True, executable, in_data)

    def _normalize_path(self, path, prefix):
        if not path.startswith(os.path.sep):
            path = os.path.join(os.path.sep, path)
        normpath = os.path.normpath(path)
        return os.path.join(prefix, normpath[1:])

    def put_file(self, in_path, out_path):
        ''' transfer a file from local to remote jail '''
        tmp = self.get_tmp_file()
        self.ssh.put_file(in_path, tmp)
        out_path = self._normalize_path(out_path, self.get_jail_path())

        code, _, stdout, stderr = self._exec_command(' '.join(['chmod 0777',tmp]))
        if code != 0:
            raise errors.AnsibleError("failed to make temp file %s world writable:\n%s\n%s" % (tmp, stdout, stderr))

        code, _, stdout, stderr = self._exec_command(' '.join(['cp',tmp,out_path]), '', self.juser, True)
        if code != 0:
            raise errors.AnsibleError("failed to move file from %s to %s:\n%s\n%s" % (tmp, out_path, stdout, stderr))

    def fetch_file(self, in_path, out_path):
        ''' fetch a file from remote jail to local '''
        tmp = self.get_tmp_file()
        in_path = self._normalize_path(in_path, self.get_jail_path())
        self._exec_command(' '.join(['mv',in_path,tmp]), '', self.juser, True)
        self.ssh.fetch_file(tmp, out_path)

    def close(self):
        ''' terminate the connection; nothing to do here '''
        pass
コード例 #3
0
class Connection(object):
    ''' jail-over-ssh based connections '''
    def get_jail_path(self):
        return self.path

    def get_jail_id(self):
        return self.jid

    def match_jail(self):
        code, _, stdout, stderr = self._exec_command(' '.join(
            ['jls', 'name', 'jid', 'path']))
        lines = stdout.strip().split('\n')

        lines = [line.split() for line in lines]

        names = dict((re.sub(r'\W', '_', name), {
            'name': name.strip(),
            'jid': jid.strip(),
            'path': path.strip(),
        }) for name, jid, path in lines)

        if len(names) != len(lines):
            vvv("WARNING: This host's jail names are not unique after underscore-substitution!"
                )

        # remove \n
        jail = names.get(self.jname)
        if jail:
            self.jid = jail['jid']
            self.path = jail['path']
            self.jname = jail['name']
            vvv('Matched jail: %s' % self.jname)
        else:
            vvv('No jail found with name: %s' % self.jname)

    def get_tmp_file(self):
        code, _, stdout, stderr = self._exec_command('mktemp', '', None)
        return stdout.strip().split('\n')[-1]

    def __init__(self, runner, host, port, user, password, private_key_file,
                 *args, **kwargs):
        self.host = host
        jaildef, self.jailhost = host.split('@', 1)
        self.jname = re.sub(r'\W', '_', jaildef)
        self.runner = runner
        self.has_pipelining = False
        self.ssh = SSHConn(runner, self.jailhost, port, user, password,
                           private_key_file, *args)
        self.jid = None
        self.path = None
        self.juser = None
        self.matched = False

    def connect(self, port=None):
        self.ssh.connect()
        if not self.matched:
            self.match_jail()
            self.matched = True
        return self

    def _exec_command(self,
                      cmd,
                      tmp_path='',
                      become_user=None,
                      sudoable=False,
                      executable='/bin/sh',
                      in_data=None):
        # oh lordy I hate this approach, but we need to note what user we use to access the jail so put/fetch works
        if become_user != None:
            self.juser = become_user

        return self.ssh.exec_command(cmd, tmp_path, become_user, sudoable,
                                     executable, in_data)

    def exec_command(self,
                     cmd,
                     tmp_path,
                     become_user=None,
                     sudoable=False,
                     executable='/bin/sh',
                     in_data=None):
        ''' run a command in the jail '''

        if SSHJAIL_USE_JAILME:
            jcmd = ['jailme', self.jid]
        else:
            jcmd = ['jexec', self.jname]

        if executable:
            local_cmd = ' '.join(
                [jcmd[0], jcmd[1], executable, '-c',
                 '"%s"' % cmd])
        else:
            local_cmd = '%s "%s" "%s"' % (jcmd[0], jcmd[1], cmd)

        vvv("JAIL (%s) %s" % (become_user, local_cmd), host=self.host)
        return self._exec_command(local_cmd, tmp_path, become_user, True,
                                  executable, in_data)

    def _normalize_path(self, path, prefix):
        if not path.startswith(os.path.sep):
            path = os.path.join(os.path.sep, path)
        normpath = os.path.normpath(path)
        return os.path.join(prefix, normpath[1:])

    def put_file(self, in_path, out_path):
        ''' transfer a file from local to remote jail '''
        tmp = self.get_tmp_file()
        self.ssh.put_file(in_path, tmp)
        out_path = self._normalize_path(out_path, self.get_jail_path())

        code, _, stdout, stderr = self._exec_command(' '.join(
            ['chmod 0777', tmp]))
        if code != 0:
            raise errors.AnsibleError(
                "failed to make temp file %s world writable:\n%s\n%s" %
                (tmp, stdout, stderr))

        code, _, stdout, stderr = self._exec_command(
            ' '.join(['cp', tmp, out_path]), '', self.juser, True)
        if code != 0:
            raise errors.AnsibleError(
                "failed to move file from %s to %s:\n%s\n%s" %
                (tmp, out_path, stdout, stderr))

    def fetch_file(self, in_path, out_path):
        ''' fetch a file from remote jail to local '''
        tmp = self.get_tmp_file()
        in_path = self._normalize_path(in_path, self.get_jail_path())
        self._exec_command(' '.join(['mv', in_path, tmp]), '', self.juser,
                           True)
        self.ssh.fetch_file(tmp, out_path)

    def close(self):
        ''' terminate the connection; nothing to do here '''
        pass
コード例 #4
0
class Connection(object):
    ''' jail-over-ssh based connections '''
    def match_jail(self):
        if self.jid == None:
            code, _, stdout, stderr = self._exec_command(
                "jls -q jid name host.hostname path")
            if code != 0:
                vvv("JLS stdout: %s" % stdout)
                raise errors.AnsibleError("jls returned non-zero!")

            lines = stdout.strip().split('\n')
            found = False
            for line in lines:
                if line.strip() == '':
                    break

                jid, name, hostname, path = line.strip().split()
                if name == self.jailspec or hostname == self.jailspec:
                    self.jid = jid
                    self.jname = name
                    self.jhost = hostname
                    self.jpath = path
                    found = True
                    break

            if not found:
                raise errors.AnsibleError(
                    "failed to find a jail with name or hostname of '%s'" %
                    self.jailspec)

    def get_jail_path(self):
        self.match_jail()
        return self.jpath

    def get_jail_id(self):
        self.match_jail()
        return self.jid

    def get_tmp_file(self):
        code, _, stdout, stderr = self._exec_command('mktemp', '', None)
        return stdout.strip().split('\n')[-1]

    def __init__(self, runner, host, port, user, password, private_key_file,
                 *args, **kwargs):
        # [email protected] => my-jail is jail name/hostname, my.jailhost is jailhost hostname
        self.host = host
        self.jailspec, self.jailhost = host.split('@', 1)

        # piggyback off of the standard SSH connection
        self.runner = runner
        self.has_pipelining = False
        self.ssh = SSHConn(runner, self.jailhost, port, user, password,
                           private_key_file, *args)

        # jail information loaded on first use by match_jail
        self.jid = None
        self.jname = None
        self.jhost = None
        self.jpath = None

    def connect(self, port=None):
        self.ssh.connect()
        return self

    # runs a command on the jailhost, rather than inside the jail
    def _exec_command(self,
                      cmd,
                      tmp_path='',
                      become_user=None,
                      sudoable=False,
                      executable='/bin/sh',
                      in_data=None):
        return self.ssh.exec_command(cmd, tmp_path, become_user, sudoable,
                                     executable, in_data)

    def exec_command(self,
                     cmd,
                     tmp_path,
                     become_user=None,
                     sudoable=False,
                     executable='/bin/sh',
                     in_data=None):
        ''' run a command in the jail '''

        if executable:
            cmd = ' '.join([executable, '-c', '"%s"' % cmd])

        local_cmd = 'which -s jailme && jailme %s %s || jexec %s %s' % (
            self.get_jail_id(), cmd, self.get_jail_id(), cmd)

        vvv("JAIL (%s) %s" % (become_user, local_cmd), host=self.host)
        return self._exec_command(local_cmd, tmp_path, become_user, True,
                                  executable, in_data)

    def _normalize_path(self, path, prefix):
        if not path.startswith(os.path.sep):
            path = os.path.join(os.path.sep, path)
        normpath = os.path.normpath(path)
        return os.path.join(prefix, normpath[1:])

    def put_file(self, in_path, out_path):
        ''' transfer a file from local to remote jail '''
        tmp = self.get_tmp_file()
        self.ssh.put_file(in_path, tmp)
        out_path = self._normalize_path(out_path, self.get_jail_path())

        code, _, stdout, stderr = self._exec_command(' '.join(
            ['chmod 0644', tmp]))
        if code != 0:
            raise errors.AnsibleError(
                "failed to make temp file %s world readable:\n%s\n%s" %
                (tmp, stdout, stderr))

        code, _, stdout, stderr = self._exec_command(
            ' '.join(['cp', tmp, out_path]), '', self.runner.become_user, True)
        if code != 0:
            raise errors.AnsibleError(
                "failed to move file from %s to %s:\n%s\n%s" %
                (tmp, out_path, stdout, stderr))

        code, _, stdout, stderr = self._exec_command(' '.join(['rm', tmp]))
        if code != 0:
            raise errors.AnsibleError(
                "failed to remove temp file %s:\n%s\n%s" %
                (tmp, stdout, stderr))

    def fetch_file(self, in_path, out_path):
        ''' fetch a file from remote jail to local '''
        tmp = self.get_tmp_file()
        in_path = self._normalize_path(in_path, self.get_jail_path())
        self._exec_command(' '.join(['mv', in_path, tmp]), '', self.juser,
                           True)
        self.ssh.fetch_file(tmp, out_path)

    def close(self):
        ''' terminate the connection; nothing to do here '''
        pass