示例#1
0
    def removeentry(self, branch, find=''):
        """Removes entries from remote host based onto <find>. If <find> is
        note set, it will remove everything under that <branch>. That method
        compares the configuration before and after command execution to detect
        changes and form the bool result.

        :param branch: (str) Branch of commands.
        :param find: (str) Mikrotik CLI filter.
        :return: (bool) True when <propvals> have changed the configuration. If
            for some reason, configuration remains unchanged False will be
            returned, but the <self.errc> will be zero. It will also return
            False in case of error.
        """
        if not hasstring(branch):
            return self.err(1)

        branch = branchfix(branch)

        if not haskey(self.branch, branch, dict):
            return self.err(2, branch)

        if self.branch[branch]['class'] != 'list':
            return False

        if self.branch[branch]['readonly']:
            return False

        if not hasstring(find):
            find = ''

        # Count entries before remove command
        command = ':put [:len [{} find]]'.format(branch)
        entries_c0 = self.command(command)
        if not entries_c0:
            return self.err(3)

        # Remove command
        command = '{} remove [find {}]'.format(branch, find)
        results = self.command(command, hasstdout=False)
        if results:
            return self.err(4, results)

        # Count entries after remove command
        command = ':put [:len [{} find]]'.format(branch)
        entries_c1 = self.command(command)
        if not entries_c1:
            return self.err(5)

        # Compare Before and After remove command
        if entries_c0 != entries_c1:
            return True  # Changed
        return False  # Not changed != Failed
示例#2
0
    def getinfo_interfaces(self, interface=None):
        """Meta method. Retrieves information from Router.
        """
        branch = '/interface'
        properties = ['name', 'type', 'mac-address']
        results1 = self.getvalues(branch, properties, find='dynamic!=yes',
                                  iid=True)

        branch = '/ip address'
        properties = ['address', 'interface']
        results2 = self.getvalues(branch, properties)

        results = {}

        if results1:
            for result1 in results1:
                name = None
                if haskey(result1, 'name'):
                    name = result1['name']
                if not hasstring(name):
                    continue

                results[name] = {
                    '.id': result1['.id'],
                    'type': result1['type'],
                    'mac_address': result1['mac-address'],
                    'ip_address': []
                }

                # Bug: PPPoE intrfaces from ISP will have irregular network
                #      address
                if results2:
                    for result2 in results2:
                        if result2['interface'] == name:
                            address = result2['address'].split('/')
                            network = ipaddress.IPv4Network(result2[
                                'address'].decode('utf-8'), False)
                            ip_address = {
                                'address': address[0],
                                'nbits': address[1],
                                'netmask': str(
                                    network.netmask).encode('utf-8'),
                                'network': str(
                                    network.network_address).encode('utf-8'),
                                'broadcast': str(
                                    network.broadcast_address).encode('utf-8')
                            }

                            results[name]['ip_address'].append(ip_address)

        return results
示例#3
0
def propvals_diff_getvalues(propvals, getvalues):
    """Compares two different sets of properties and values.

    :param propvals: (dict) 1st set.
    :param getvalues: (dict) 2nd set.
    :return: (bool) True if they are same, False if not.
    """
    if not hasdict(propvals):
        return None

    if not haslist(getvalues):
        return True

    for prop in propvals:
        for getvalue in getvalues:
            if haskey(getvalue, prop):
                if propvals[prop] != getvalue[prop]:
                    return True

            else:
                return True

    return False
示例#4
0
    def test_haskey(self):
        """Test if key exists in dictionary.
        """

        none0 = None
        int0 = 0
        int1 = 1
        int2 = -1
        str0 = ''
        str1 = 'abcd'
        list0 = []
        list1 = ['ab', 'cd']
        dict0 = {}
        dict1 = {'ab': 'cd'}
        set0 = set()
        set1 = set(['a', 'b', 1, 2])
        tuple0 = ()
        tuple1 = ('a', 'b', 1, 2)

        self.assertFalse(valid.haskey(none0, none0))
        self.assertFalse(valid.haskey(dict1, none0))
        self.assertFalse(valid.haskey(dict1, int0))
        self.assertFalse(valid.haskey(dict1, int1))
        self.assertFalse(valid.haskey(dict1, int2))
        self.assertFalse(valid.haskey(dict1, str0))
        self.assertFalse(valid.haskey(dict1, str1))
        self.assertFalse(valid.haskey(dict1, list0))
        self.assertFalse(valid.haskey(dict1, list1))
        self.assertFalse(valid.haskey(dict1, dict0))
        self.assertFalse(valid.haskey(dict1, dict1))
        self.assertFalse(valid.haskey(dict1, set0))
        self.assertFalse(valid.haskey(dict1, set1))
        self.assertFalse(valid.haskey(dict1, tuple0))
        self.assertFalse(valid.haskey(dict1, tuple1))

        key0 = 'ab'
        self.assertTrue(valid.haskey(dict1, key0, str))  # assertTrue
        self.assertFalse(valid.haskey(dict1, key0, list))  # assertFalse
示例#5
0
    def addentry(self, branch, propvals=''):
        """Adds new entries to remote host. That method compares the
        configuration before and after command execution to detect changes and
        form the bool result.

        :param branch: (str) Branch of commands
        :param propvals: (str) Space seperated pairs of Variable=Value
        :return: (bool) True when <propvals> have changed the configuration. If
            for some reason, configuration remains unchanged False will be
            returned, but the <self.errc> will be zero. It will also return
            False in case of error.
        """
        if not hasstring(branch):
            return self.err(1)

        branch = branchfix(branch)

        if not haskey(self.branch, branch, dict):
            return self.err(2, branch)

        if self.branch[branch]['class'] != 'list':
            return False

        if self.branch[branch]['readonly']:
            return False

        if not hasstring(propvals):
            return self.err(3)

        # Count entries before add command
        command = ':put [:len [{} find]]'.format(branch)
        entries_c0 = self.command(command)
        if not entries_c0:
            return self.err(4)

        # Check if such an entry exists
        if self.branch[branch]['id']:
            propvals_d = propvals_to_dict(propvals)
            prop = self.branch[branch]['id'][0]

            if haskey(propvals_d, prop):
                command = ':put [:len [{} find {}={}]]'.format(branch, prop,
                                                               propvals_d[prop])
                result = self.command(command)

                if result[0] != '0':
                    return False

        # Add Command
        command = '{} add {}'.format(branch, propvals)
        results = self.command(command, hasstdout=False)
        if results:
            if self.checkline_falsepos(results[0]):
                self.err0()
                return False  # Not changed != Failed
            self.err(5, command)
            return self.err(6, results)

        # Count entries after add command
        command = ':put [:len [{} find]]'.format(branch)
        entries_c1 = self.command(command)
        if not entries_c1:
            return self.err(7)

        # Compare Before and After add command
        if entries_c0 != entries_c1:
            return True  # Changed
        return False  # Not changed != Failed
示例#6
0
    def setvalues(self, branch, propvals='', find=''):
        """Sets requested values to remote host. That method compares the
        configuration before and after command execution to detect changes and
        form the bool result.

        :param branch: (str) Branch of commands.
        :param propvals: (dict) Dictionary of Variables=Values.
        :param find: (str) Mikrotik CLI filter.
        :return: (bool) True when <propvals> have changed the configuration. If
            for some reason, configuration remains unchanged False will be
            returned, but the <self.errc> will be zero. It will also return
            False in case of error.
        """
        if not hasstring(branch):
            return self.err(1)

        branch = branchfix(branch)

        if not haskey(self.branch, branch, dict):
            return self.err(2, branch)

        if self.branch[branch]['readonly']:
            return False

        if not hasstring(propvals):
            return self.err(3)

        # Parse propvals to properties
        propvals_d = propvals_to_dict(propvals)
        if not hasdict(propvals_d):
            return self.err(4)
        properties = []
        for prop in propvals_d:
            properties.append(prop)

        # Create the find command, if find exists
        find_command = ''
        iid = True
        if self.branch[branch]['class'] == 'list':
            if hasstring(find):
                if find.find('=') > 1:
                    find_command = '[find {}] '.format(find)
                else:
                    iid = False
                    find_command = find + ' '

        # Get values before updates
        getvalues0 = self.getvalues(branch, properties, find, False, iid)
        if not getvalues0:
            return self.err(5)

        # Exit if Get is same as update
        if not propvals_diff_getvalues(propvals_d, getvalues0):
            return False   # There are no changes to apply

        # Update command
        command = '{} set {}{}'.format(branch, find_command, propvals)
        results = self.command(command, hasstdout=False)
        if results:
            self.err(6, command)
            return self.err(7, results)

        # Get values after update
        getvalues1 = self.getvalues(branch, properties, find, False, iid)
        if not getvalues1:
            return self.err(8)

        # Compare Before and After update command
        if getvalues0 != getvalues1:
            return True  # Changed
        return False  # Not changed != Failed
示例#7
0
    def getvalues(self, branch, properties, find='', csvout=False, iid=False):
        """Retrieves requested values from remote host.

        :param branch: (str) Branch of commands.
        :param properties: (str / list) List or Comma / Space separated
            properties.
        :param find: (str) Mikrotik CLI filter.
        :param csvout: (bool) Output in CSV File.
        :param iid: (bool) Adds $id to output.
        :return: (list) CSV formatted output.
            Example output if <csvout=True>:
                Return of <self.command>:

                [
                    "value1,value2,value3,...",
                    "value1,value2,value3,...",
                    ...
                ]

            Example output if <csvout=False>:
                Return of <csv_to_list_dict>:

                [
                    {
                        results"variable1": "value1",
                        ...
                    }
                    ...
                ]
        """
        results = []

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

        branch = branchfix(branch)

        if not haskey(self.branch, branch, dict):
            self.err(2, branch)
            return None

        properties = properties_to_list(properties)

        if not haslist(properties):
            self.err(3)
            return None

        command = ''
        commands = []

        if (self.branch[branch]['class'] == 'settings' or
                (self.branch[branch]['class'] == 'list' and
                 find and find.find('=') < 1)):
            for prop in properties:
                commands.append('[{} get {} {}]'.format(branch, find, prop))

            command = ':put ({})'.format('.",".'.join(commands))

        elif self.branch[branch]['class'] == 'list':
            if iid:
                commands.append('$i')

            for prop in properties:
                commands.append('[{} get $i {}]'.format(branch, prop))

            command = (':foreach i in=[' + branch + ' find ' + find + '] '
                       'do={:put (' + '.",".'.join(commands) + ')}')

        else:
            self.err(4, branch)
            return None

        lines = self.command(command)

        if not lines or self.errc():
            self.err(5, command)
            return None

        if csvout:
            results = lines
        else:
            results = csv_to_listdict(properties, lines, self.branch[branch],
                                      iid)

        return results