예제 #1
0
    def download_file(self, remote, local):
        """Downloads remote files to local path.

        :param remote: (str) Remote path.
        :param local: (str) Local path.
        :return: (bool) True on success, False on failure.
        """
        if not self.isfile_remote(remote):
            return self.err(1, remote)

        if not hasstring(local):
            return self.err(2, local)

        if isdir(local) and local[-1] != '/':
            local += '/'

        if local[-1] == '/':
            local += remote.split('/')[:-1]

        if not isdir('/'.join(local.split('/')[:-1]), True):
            return self.err(3, local)

        try:
            self.connection.get(remote, local)
            return True

        except Exception:
            _, message = getexcept()
            return self.err(4, message)
예제 #2
0
    def mkdir_remote(self, data):
        """Creates remote directories.

        :param data: (str) Path.
        :return: (bool) True on success, False on failure.
        """
        if not hasstring(data):
            return False

        if data[-1] == '/':
            data = data[:-1]

        path = data.split('/')
        path_c = len(path)
        index = 1

        for index in range(0, path_c):
            try:
                if stat.S_ISREG(
                        self.connection.stat(
                            '/'.join(path[0:index + 1])).st_mode):
                    return False
            except IOError:
                index -= 1
                break

        if index < path_c - 1:
            try:
                for index in range(index + 1, path_c):
                    self.connection.mkdir('/'.join(path[0:index + 1]))
            except IOError:
                _, message = getexcept()
                return self.err(1, message)

        return True
예제 #3
0
    def upload_file(self, local, remote):
        """Uploads local files to remote host.

        :param local: (str) Local path.
        :param remote: (str) Remote path.
        :return: (bool) True on success, False on failure.
        """
        if not isfile(local):
            return self.err(1, local)

        if not hasstring(remote):
            return self.err(2, remote)

        if self.isdir_remote(remote) and remote[-1] != '/':
            remote += '/'

        if remote[-1] == '/':
            remote += local.split('/')[-1]

        if not self.isdir_remote('/'.join(remote.split('/')[:-1]), True):
            return self.err(3, remote)

        try:
            self.connection.put(local, remote)
            return True

        except Exception:
            _, message = getexcept()
            return self.err(4, message)
예제 #4
0
def csv_parse(lines):
    """Converts the CSV-expected input to array.

    :param lines: (str / [str]) CSV input - it can either linefeeded string or
        list.
    :return: ([str]) String Array or None on error.
    """
    if not lines:
        return None
    if not haslist(lines):
        if hasstring(lines):
            lines = lines.split('\n')
        else:
            return None
    try:
        return list(csv.reader(lines, delimiter=',', quotechar='"'))
    except Exception:
        getexcept()
    return None
예제 #5
0
def isport(data):
    """TCP/UDP Port validation.

    :param data: (int / long) Port.
    :return: (bool) True or False.
    """
    if not isinstance(data, (int, long)):
        try:
            data = int(data)
        except Exception:
            return getexcept()
    if data < 1 or data > 65536:
        return False
    return True
예제 #6
0
def isdir(data, makedirs=False):
    """Directory validation and auto-creation.

    :param data: (str) Directory.
    :return: (bool) True or False.
    """
    if not hasstring(data):
        return False
    if makedirs:
        if not os.path.isdir(data):
            try:
                os.makedirs(data)
            except Exception:
                return getexcept()
    return os.path.isdir(data)
예제 #7
0
    def upload_dir(self, local, remote):
        """Uploads local directories to remote host.

        Source: https://www.tutorialspoint.com/python/os_walk.htm

        :param local: (str) Local path.
        :param remote: (str) Remote path.
        :return: (bool) True on success, False on failure.
        """
        if not isdir(local):
            return self.err(1, local)

        if self.isfile_remote(remote):
            return self.err(2, remote)

        if not self.isdir_remote(remote, True):
            return self.err(3, remote)

        if local[-1] == '/':
            local = local[:-1]

        if remote[-1] == '/':
            remote = remote[:-1]

        local_c = len(local)

        for root, dirs, files in os.walk(local, topdown=False):
            remote_root = remote + root[local_c:]

            if not self.mkdir_remote(remote_root):
                return self.err(4, remote_root)

            for name in dirs:
                remote_dir = remote_root + '/' + name

                if not self.mkdir_remote(remote_dir):
                    return self.err(5, remote_dir)

            try:
                for name in files:
                    remote_file = remote_root + '/' + name
                    self.connection.put(root + '/' + name, remote_file)
            except Exception:
                _, message = getexcept()
                self.err(6, remote_file)
                return self.err(7, message)

        return True
예제 #8
0
    def disconnect(self):
        """Disconnects from current host, unless it is already disconnected.

        :return: (bool) True on success, False on failure.
        """
        if not self.checkconnection():
            return True

        try:
            self.connection.close()
            self.status = 0
            return True

        except Exception:
            _, message = getexcept()
            return self.err(1, message)
예제 #9
0
    def download_dir(self, remote, local):
        """Downloads remote directories to local path.

        :param remote: (str) Remote path.
        :param local: (str) Local path.
        :return: (bool) True on success, False on failure.
        """
        if not self.isdir_remote(remote):
            return self.err(1, remote)

        if isfile(local):
            return self.err(2, local)

        if not isdir(local, True):
            return self.err(3, local)

        if remote[-1] == '/':
            remote = remote[:-1]

        if local[-1] == '/':
            local = local[:-1]

        remote_c = len(remote)

        for root, dirs, files in self.walk_remote(remote):
            local_root = local + root[remote_c:]

            if not isdir(local_root, True):
                return self.err(4, local_root)

            for name in dirs:
                local_dir = local_root + '/' + name

                if not isdir(local_dir, True):
                    return self.err(5, local_dir)

            try:
                for name in files:
                    local_file = local_root + '/' + name
                    self.connection.get(root + '/' + name, local_file)
            except Exception:
                _, message = getexcept()
                self.err(6, local_file)
                return self.err(7, message)

        return True
예제 #10
0
    def checkconnection(self):
        """Sends a single null command to check the connectivity.

        :return: (bool) True on success, False on failure.
        """
        try:
            transport = self.connection.get_transport()
            transport.send_ignore()
            self.status = 1
            return True

        except (EOFError, AttributeError):
            self.status = 0
            return False

        except Exception:
            _, message = getexcept()
            return self.err(1, message)
예제 #11
0
def writejson(filename, data):
    """Saves the (dict) data to JSON file.

    :param filename: (str) Filename to write JSON to.
    :param data: (dict) Dict to save to JSON file.
    :return: (bool) True on success, False on failure.
    """
    if not hasstring(filename):
        return False
    if not isdir('/'.join(filename.split('/')[:-1]), True):
        return False
    if not isinstance(data, dict):
        return False
    try:
        with open(filename, 'w') as handler:
            json.dump(data, handler)
    except IOError:
        return getexcept()
    return True
예제 #12
0
def writefile(filename, lines):
    """Saves lines to file.

    :param filename: (str) File to write.
    :param lines: (list) List of lines to write.
    :return: (bool) True on success, False on failure.
    """
    if not isdir('/'.join(filename.split('/')[:-1]), True):
        return False
    if not haslist(lines):
        return False
    try:
        handler = open(filename, 'w')
        for line in lines:
            handler.write(line + '\n')
        handler.close()
        return True
    except Exception:
        return getexcept()
    return False
예제 #13
0
    def connect(self, timeout=30):
        """Connects to remote host via SFTP.

        :param timeout: (int) Connection timeout.
        :return: (bool) Connection status.
        """
        if not isinstance(timeout, int) or timeout < 0:
            timeout = 30

        if self.status < 0:
            return self.err(1, self.status)

        if self.status == 1:
            if self.checkconnection():
                return True

        # Check this approach (timeout is not being used):
        # https://stackoverflow.com/questions/9758432/timeout-in-paramiko-python
        _ = timeout
        # After changing it, in the password connect, add:
        # allow_agent=False, look_for_keys=False

        try:
            if self.pkey_string:
                handler = StringIO.StringIO(self.pkey_string)
                self.pkey = paramiko.RSAKey.from_private_key(handler)
                handler.close()
            elif self.pkey_file:
                self.pkey = paramiko.RSAKey.from_private_key_file(
                    self.pkey_file)

            self.transport = paramiko.Transport((self.host, self.port))

            if self.pkey:
                self.ssh_auth = 2
                self.transport.connect(username=self.username,
                                       pkey=self.pkey)
            else:
                self.ssh_auth = 1
                self.transport.connect(username=self.username,
                                       password=self.password)

            self.connection = paramiko.SFTPClient.from_transport(
                self.transport)
            self.status = 1
            return True

        except socket.error:
            _, message = getexcept()
            err_code = 2

        except paramiko.AuthenticationException:
            _, message = getexcept()
            err_code = 3

        except paramiko.BadHostKeyException:
            _, message = getexcept()
            err_code = 4

        except paramiko.SSHException:
            _, message = getexcept()
            err_code = 5

        except Exception:
            _, message = getexcept()
            err_code = 6

        return self.err(err_code, message)
예제 #14
0
    def connect(self, timeout=30):
        """Connects to remote host via SSH.

        :param timeout: (int) Connection timeout.
        :return: (bool) Connection status.
        """
        if not isinstance(timeout, int) or timeout < 0:
            timeout = 30

        if self.status < 0:
            return self.err(1, self.status)

        if self.status == 1:
            if self.checkconnection():
                return True

        try:
            if self.pkey_string:
                handler = StringIO.StringIO(self.pkey_string)
                self.pkey = paramiko.RSAKey.from_private_key(handler)
                handler.close()
            elif self.pkey_file:
                self.pkey = paramiko.RSAKey.from_private_key_file(
                    self.pkey_file)

            self.connection = paramiko.SSHClient()
            self.connection.set_missing_host_key_policy(
                paramiko.AutoAddPolicy())

            if self.pkey:
                self.ssh_auth = 2
                self.connection.connect(hostname=self.host,
                                        port=self.port,
                                        username=self.username,
                                        pkey=self.pkey,
                                        timeout=timeout)
            else:
                self.ssh_auth = 1
                self.connection.connect(hostname=self.host,
                                        port=self.port,
                                        username=self.username,
                                        password=self.password,
                                        timeout=timeout,
                                        allow_agent=False,
                                        look_for_keys=False)

            self.status = 1
            return True

        except socket.error:
            _, message = getexcept()
            err_code = 2

        except paramiko.AuthenticationException:
            _, message = getexcept()
            err_code = 3

        except paramiko.BadHostKeyException:
            _, message = getexcept()
            err_code = 4

        except paramiko.SSHException:
            _, message = getexcept()
            err_code = 5

        except Exception:
            _, message = getexcept()
            err_code = 6

        return self.err(err_code, message)
예제 #15
0
    def command(self, command, raw=False, connect=True, hasstdout=True):
        """Executes the <command> on the remote host and returns the results.

        :param command: (str) The command that has to be executed.
        :param raw: (bool) Returns all results without filtering lines that
            start with #.
        :param connect: (bool) Connects to host, if it is not connected already.
        :param hasstdout: (bool) Is it expected the command to give output?
        :return: (list) The execution result.
        """
        status = 0

        self.history.append(command)

        if not hasstring(command):
            self.err(1)
            return None

        if self.status < 1 and connect:
            if self.connect():
                status = 1

        if self.status < 1:
            self.err(2, self.status)
            return None

        if self.reseterrors:
            self.err0()

        lines = []

        try:
            # stdin, stdout, stderr = ...
            _, stdout, stderr = self.connection.exec_command(command)
            lines = stdout.read().replace('\r', '').split('\n')

            # Mikrotik CLI is not producing stderr. Linux does.
            if not (hasstring(lines) or haslist(lines)):
                lines = stderr.read().replace('\r', '').split('\n')

        except Exception:
            _, message = getexcept()
            self.err(3, message)

        finally:
            if status == 1:
                self.disconnect()
        ##### fix the logic ^^^ \/\/\/\ of get/except/disconnect

        results = []

        if raw:
            for line in lines:
                results.append(line)

        elif lines:
            for line in lines:
                if line:
                    if line[0] != '#':
                        results.append(line.strip())

        if not haslist(results) and hasstdout:
            self.err(4, command)

        return results