Ejemplo n.º 1
0
def check_declarative_intent_params(module, want, result):
    failed_conditions = []
    for w in want:
        want_state = w.get('state')
        want_tx_rate = w.get('tx_rate')
        want_rx_rate = w.get('rx_rate')
        if want_state not in (
                'up', 'down') and not want_tx_rate and not want_rx_rate:
            continue

        if result['changed']:
            sleep(w['delay'])

        command = 'show interfaces %s' % w['name']
        rc, out, err = exec_command(module, command)
        if rc != 0:
            module.fail_json(msg=to_text(err, errors='surrogate_then_replace'),
                             command=command,
                             rc=rc)

        if want_state in ('up', 'down'):
            match = re.search(r'%s (\w+)' % 'line protocol is', out, re.M)
            have_state = None
            if match:
                have_state = match.group(1)
                if have_state.strip() == 'administratively':
                    match = re.search(r'%s (\w+)' % 'administratively', out,
                                      re.M)
                    if match:
                        have_state = match.group(1)

            if have_state is None or not conditional(want_state,
                                                     have_state.strip()):
                failed_conditions.append('state ' + 'eq(%s)' % want_state)

        if want_tx_rate:
            match = re.search(r'%s (\d+)' % 'output rate', out, re.M)
            have_tx_rate = None
            if match:
                have_tx_rate = match.group(1)

            if have_tx_rate is None or not conditional(
                    want_tx_rate, have_tx_rate.strip(), cast=int):
                failed_conditions.append('tx_rate ' + want_tx_rate)

        if want_rx_rate:
            match = re.search(r'%s (\d+)' % 'input rate', out, re.M)
            have_rx_rate = None
            if match:
                have_rx_rate = match.group(1)

            if have_rx_rate is None or not conditional(
                    want_rx_rate, have_rx_rate.strip(), cast=int):
                failed_conditions.append('rx_rate ' + want_rx_rate)

    return failed_conditions
Ejemplo n.º 2
0
def check_declarative_intent_params(module, want, result):
    failed_conditions = []
    for w in want:
        want_state = w.get('state')
        want_tx_rate = w.get('tx_rate')
        want_rx_rate = w.get('rx_rate')
        if want_state not in ('up', 'down') and not want_tx_rate and not want_rx_rate:
            continue

        if result['changed']:
            sleep(w['delay'])

        command = 'show interfaces %s' % w['name']
        rc, out, err = exec_command(module, command)
        if rc != 0:
            module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), command=command, rc=rc)

        if want_state in ('up', 'down'):
            match = re.search(r'%s (\w+)' % 'line protocol is', out, re.M)
            have_state = None
            if match:
                have_state = match.group(1)
                if have_state.strip() == 'administratively':
                    match = re.search(r'%s (\w+)' % 'administratively', out, re.M)
                    if match:
                        have_state = match.group(1)

            if have_state is None or not conditional(want_state, have_state.strip()):
                failed_conditions.append('state ' + 'eq(%s)' % want_state)

        if want_tx_rate:
            match = re.search(r'%s (\d+)' % 'output rate', out, re.M)
            have_tx_rate = None
            if match:
                have_tx_rate = match.group(1)

            if have_tx_rate is None or not conditional(want_tx_rate, have_tx_rate.strip(), cast=int):
                failed_conditions.append('tx_rate ' + want_tx_rate)

        if want_rx_rate:
            match = re.search(r'%s (\d+)' % 'input rate', out, re.M)
            have_rx_rate = None
            if match:
                have_rx_rate = match.group(1)

            if have_rx_rate is None or not conditional(want_rx_rate, have_rx_rate.strip(), cast=int):
                failed_conditions.append('rx_rate ' + want_rx_rate)

    return failed_conditions
Ejemplo n.º 3
0
def check_declarative_intent_params(module, want, result):
    failed_conditions = []
    have_neighbors = None
    for w in want:
        want_state = w.get('state')
        want_tx_rate = w.get('tx_rate')
        want_rx_rate = w.get('rx_rate')
        want_neighbors = w.get('neighbors')

        if want_state not in ('up', 'down') and not want_tx_rate and not want_rx_rate and not want_neighbors:
            continue

        if result['changed']:
            sleep(w['delay'])

        command = 'show interfaces ethernet %s' % w['name']
        rc, out, err = exec_command(module, command)
        if rc != 0:
            module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), command=command, rc=rc)

        if want_state in ('up', 'down'):
            match = re.search(r'%s (\w+)' % 'state', out, re.M)
            have_state = None
            if match:
                have_state = match.group(1)
            if have_state is None or not conditional(want_state, have_state.strip().lower()):
                failed_conditions.append('state ' + 'eq(%s)' % want_state)

        if want_neighbors:
            have_host = []
            have_port = []
            if have_neighbors is None:
                rc, have_neighbors, err = exec_command(module, 'show lldp neighbors detail')
                if rc != 0:
                    module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), command=command, rc=rc)

            if have_neighbors:
                lines = have_neighbors.strip().split('Interface: ')
                for line in lines:
                    field = line.split('\n')
                    if field[0].split(',')[0].strip() == w['name']:
                        for item in field:
                            if item.strip().startswith('SysName:'):
                                have_host.append(item.split(':')[1].strip())
                            if item.strip().startswith('PortDescr:'):
                                have_port.append(item.split(':')[1].strip())
            for item in want_neighbors:
                host = item.get('host')
                port = item.get('port')
                if host and host not in have_host:
                    failed_conditions.append('host ' + host)
                if port and port not in have_port:
                    failed_conditions.append('port ' + port)

    return failed_conditions
Ejemplo n.º 4
0
    def check_declarative_intent_params(self, result):
        failed_conditions = []
        for req_if in self._required_config:
            want_state = req_if.get('state')
            name = req_if['name']
            if want_state not in ('up', 'down'):
                continue

            if result['changed']:
                sleep(req_if['delay'])
            curr_if = self._current_config.get(name)
            curr_state = curr_if['state']
            if curr_state is None or not \
                    conditional(want_state, curr_state.strip()):
                failed_conditions.append('state ' + 'eq(%s)' % want_state)
        return failed_conditions
Ejemplo n.º 5
0
def main():
    """ main entry point for module execution
    """
    neighbors_spec = dict(host=dict(), port=dict())

    element_spec = dict(name=dict(),
                        description=dict(),
                        enabled=dict(default=True, type='bool'),
                        speed=dict(),
                        mtu=dict(type='int'),
                        duplex=dict(choices=['full', 'half', 'auto']),
                        tx_rate=dict(),
                        rx_rate=dict(),
                        neighbors=dict(type='list',
                                       elements='dict',
                                       options=neighbors_spec),
                        delay=dict(default=10, type='int'),
                        state=dict(default='present',
                                   choices=['present', 'absent', 'up',
                                            'down']),
                        active=dict(default=True, type='bool'))

    aggregate_spec = deepcopy(element_spec)
    aggregate_spec['name'] = dict(required=True)

    # remove default in aggregate spec, to handle common arguments
    remove_default_spec(aggregate_spec)

    argument_spec = dict(aggregate=dict(type='list',
                                        elements='dict',
                                        options=aggregate_spec), )

    argument_spec.update(element_spec)
    argument_spec.update(junos_argument_spec)

    required_one_of = [['name', 'aggregate']]
    mutually_exclusive = [['name', 'aggregate']]

    module = AnsibleModule(argument_spec=argument_spec,
                           required_one_of=required_one_of,
                           mutually_exclusive=mutually_exclusive,
                           supports_check_mode=True)

    warnings = list()
    result = {'changed': False}

    if warnings:
        result['warnings'] = warnings

    top = 'interfaces/interface'

    param_to_xpath_map = collections.OrderedDict()
    param_to_xpath_map.update([('name', {
        'xpath': 'name',
        'is_key': True
    }), ('description', 'description'), ('speed', 'speed'), ('mtu', 'mtu'),
                               ('duplex', 'link-mode'),
                               ('disable', {
                                   'xpath': 'disable',
                                   'tag_only': True
                               })])

    choice_to_value_map = {
        'link-mode': {
            'full': 'full-duplex',
            'half': 'half-duplex',
            'auto': 'automatic'
        }
    }

    params = to_param_list(module)

    requests = list()
    for param in params:
        # if key doesn't exist in the item, get it from module.params
        for key in param:
            if param.get(key) is None:
                param[key] = module.params[key]

        item = param.copy()
        state = item.get('state')
        item['disable'] = True if not item.get('enabled') else False

        if state in ('present', 'up', 'down'):
            item['state'] = 'present'

        validate_param_values(module, param_to_xpath_map, param=item)
        want = map_params_to_obj(module, param_to_xpath_map, param=item)
        requests.append(
            map_obj_to_ele(module,
                           want,
                           top,
                           value_map=choice_to_value_map,
                           param=item))

    diff = None
    with locked_config(module):
        for req in requests:
            diff = load_config(module, tostring(req), warnings, action='merge')

        # issue commit after last configuration change is done
        commit = not module.check_mode
        if diff:
            if commit:
                commit_configuration(module)
            else:
                discard_changes(module)
            result['changed'] = True

            if module._diff:
                result['diff'] = {'prepared': diff}

    failed_conditions = []
    neighbors = None
    for item in params:
        state = item.get('state')
        tx_rate = item.get('tx_rate')
        rx_rate = item.get('rx_rate')
        want_neighbors = item.get('neighbors')

        if state not in (
                'up', 'down'
        ) and tx_rate is None and rx_rate is None and want_neighbors is None:
            continue

        element = Element('get-interface-information')
        intf_name = SubElement(element, 'interface-name')
        intf_name.text = item.get('name')

        if result['changed']:
            sleep(item.get('delay'))

        reply = exec_rpc(module, tostring(element), ignore_warning=False)
        if state in ('up', 'down'):
            admin_status = reply.xpath(
                'interface-information/physical-interface/admin-status')
            if not admin_status or not conditional(
                    state, admin_status[0].text.strip()):
                failed_conditions.append('state ' + 'eq(%s)' % state)

        if tx_rate:
            output_bps = reply.xpath(
                'interface-information/physical-interface/traffic-statistics/output-bps'
            )
            if not output_bps or not conditional(
                    tx_rate, output_bps[0].text.strip(), cast=int):
                failed_conditions.append('tx_rate ' + tx_rate)

        if rx_rate:
            input_bps = reply.xpath(
                'interface-information/physical-interface/traffic-statistics/input-bps'
            )
            if not input_bps or not conditional(
                    rx_rate, input_bps[0].text.strip(), cast=int):
                failed_conditions.append('rx_rate ' + rx_rate)

        if want_neighbors:
            if neighbors is None:
                element = Element('get-lldp-interface-neighbors')
                intf_name = SubElement(element, 'interface-device')
                intf_name.text = item.get('name')

                reply = exec_rpc(module,
                                 tostring(element),
                                 ignore_warning=False)
                have_host = [
                    item.text for item in reply.xpath(
                        'lldp-neighbors-information/lldp-neighbor-information/lldp-remote-system-name'
                    )
                ]
                have_port = [
                    item.text for item in reply.xpath(
                        'lldp-neighbors-information/lldp-neighbor-information/lldp-remote-port-id'
                    )
                ]

            for neighbor in want_neighbors:
                host = neighbor.get('host')
                port = neighbor.get('port')
                if host and host not in have_host:
                    failed_conditions.append('host ' + host)
                if port and port not in have_port:
                    failed_conditions.append('port ' + port)
    if failed_conditions:
        msg = 'One or more conditional statements have not be satisfied'
        module.fail_json(msg=msg, failed_conditions=failed_conditions)

    module.exit_json(**result)
 def test_conditional(self):
     self.assertTrue(conditional(10, 10))
     self.assertTrue(conditional('10', '10'))
     self.assertTrue(conditional('foo', 'foo'))
     self.assertTrue(conditional(True, True))
     self.assertTrue(conditional(False, False))
     self.assertTrue(conditional(None, None))
     self.assertTrue(conditional("ge(1)", 1))
     self.assertTrue(conditional("gt(1)", 2))
     self.assertTrue(conditional("le(2)", 2))
     self.assertTrue(conditional("lt(3)", 2))
     self.assertTrue(conditional("eq(1)", 1))
     self.assertTrue(conditional("neq(0)", 1))
     self.assertTrue(conditional("min(1)", 1))
     self.assertTrue(conditional("max(1)", 1))
     self.assertTrue(conditional("exactly(1)", 1))
Ejemplo n.º 7
0
def main():
    """ main entry point for module execution
    """
    neighbors_spec = dict(
        host=dict(),
        port=dict()
    )

    element_spec = dict(
        name=dict(),
        description=dict(),
        enabled=dict(default=True, type='bool'),
        speed=dict(),
        mtu=dict(type='int'),
        duplex=dict(choices=['full', 'half', 'auto']),
        tx_rate=dict(),
        rx_rate=dict(),
        neighbors=dict(type='list', elements='dict', options=neighbors_spec),
        delay=dict(default=10, type='int'),
        state=dict(default='present', choices=['present', 'absent', 'up', 'down']),
        active=dict(default=True, type='bool')
    )

    aggregate_spec = deepcopy(element_spec)
    aggregate_spec['name'] = dict(required=True)

    # remove default in aggregate spec, to handle common arguments
    remove_default_spec(aggregate_spec)

    argument_spec = dict(
        aggregate=dict(type='list', elements='dict', options=aggregate_spec),
    )

    argument_spec.update(element_spec)
    argument_spec.update(junos_argument_spec)

    required_one_of = [['name', 'aggregate']]
    mutually_exclusive = [['name', 'aggregate']]

    module = AnsibleModule(argument_spec=argument_spec,
                           required_one_of=required_one_of,
                           mutually_exclusive=mutually_exclusive,
                           supports_check_mode=True)

    warnings = list()
    check_args(module, warnings)

    result = {'changed': False}

    if warnings:
        result['warnings'] = warnings

    top = 'interfaces/interface'

    param_to_xpath_map = collections.OrderedDict()
    param_to_xpath_map.update([
        ('name', {'xpath': 'name', 'is_key': True}),
        ('description', 'description'),
        ('speed', 'speed'),
        ('mtu', 'mtu'),
        ('duplex', 'link-mode'),
        ('disable', {'xpath': 'disable', 'tag_only': True})
    ])

    choice_to_value_map = {
        'link-mode': {'full': 'full-duplex', 'half': 'half-duplex', 'auto': 'automatic'}
    }

    params = to_param_list(module)

    requests = list()
    for param in params:
        # if key doesn't exist in the item, get it from module.params
        for key in param:
            if param.get(key) is None:
                param[key] = module.params[key]

        item = param.copy()
        state = item.get('state')
        item['disable'] = True if not item.get('enabled') else False

        if state in ('present', 'up', 'down'):
            item['state'] = 'present'

        validate_param_values(module, param_to_xpath_map, param=item)
        want = map_params_to_obj(module, param_to_xpath_map, param=item)
        requests.append(map_obj_to_ele(module, want, top, value_map=choice_to_value_map, param=item))

    diff = None
    with locked_config(module):
        for req in requests:
            diff = load_config(module, tostring(req), warnings, action='merge')

        # issue commit after last configuration change is done
        commit = not module.check_mode
        if diff:
            if commit:
                commit_configuration(module)
            else:
                discard_changes(module)
            result['changed'] = True

            if module._diff:
                result['diff'] = {'prepared': diff}

    failed_conditions = []
    neighbors = None
    for item in params:
        state = item.get('state')
        tx_rate = item.get('tx_rate')
        rx_rate = item.get('rx_rate')
        want_neighbors = item.get('neighbors')

        if state not in ('up', 'down') and tx_rate is None and rx_rate is None and want_neighbors is None:
            continue

        element = Element('get-interface-information')
        intf_name = SubElement(element, 'interface-name')
        intf_name.text = item.get('name')

        if result['changed']:
            sleep(item.get('delay'))

        reply = send_request(module, element, ignore_warning=False)

        if state in ('up', 'down'):
            admin_status = reply.xpath('interface-information/physical-interface/admin-status')
            if not admin_status or not conditional(state, admin_status[0].text.strip()):
                failed_conditions.append('state ' + 'eq(%s)' % state)

        if tx_rate:
            output_bps = reply.xpath('interface-information/physical-interface/traffic-statistics/output-bps')
            if not output_bps or not conditional(tx_rate, output_bps[0].text.strip(), cast=int):
                failed_conditions.append('tx_rate ' + tx_rate)

        if rx_rate:
            input_bps = reply.xpath('interface-information/physical-interface/traffic-statistics/input-bps')
            if not input_bps or not conditional(rx_rate, input_bps[0].text.strip(), cast=int):
                failed_conditions.append('rx_rate ' + rx_rate)

        if want_neighbors:
            if neighbors is None:
                element = Element('get-lldp-interface-neighbors')
                intf_name = SubElement(element, 'interface-device')
                intf_name.text = item.get('name')

                reply = send_request(module, element, ignore_warning=False)
                have_host = [item.text for item in reply.xpath('lldp-neighbors-information/lldp-neighbor-information/lldp-remote-system-name')]
                have_port = [item.text for item in reply.xpath('lldp-neighbors-information/lldp-neighbor-information/lldp-remote-port-id')]

            for neighbor in want_neighbors:
                host = neighbor.get('host')
                port = neighbor.get('port')
                if host and host not in have_host:
                    failed_conditions.append('host ' + host)
                if port and port not in have_port:
                    failed_conditions.append('port ' + port)
    if failed_conditions:
        msg = 'One or more conditional statements have not be satisfied'
        module.fail_json(msg=msg, failed_conditions=failed_conditions)

    module.exit_json(**result)
Ejemplo n.º 8
0
def check_declarative_intent_params(module, want, result):
    failed_conditions = []
    have_neighbors = None
    for w in want:
        want_state = w.get('state')
        want_tx_rate = w.get('tx_rate')
        want_rx_rate = w.get('rx_rate')
        want_neighbors = w.get('neighbors')

        if want_state not in ('up', 'down') and not want_tx_rate and not want_rx_rate and not want_neighbors:
            continue

        if result['changed']:
            sleep(w['delay'])

        command = 'show interfaces %s' % w['name']
        rc, out, err = exec_command(module, command)
        if rc != 0:
            module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), command=command, rc=rc)

        if want_state in ('up', 'down'):
            match = re.search(r'%s (\w+)' % 'line protocol is', out, re.M)
            have_state = None
            if match:
                have_state = match.group(1)
            if have_state is None or not conditional(want_state, have_state.strip()):
                failed_conditions.append('state ' + 'eq(%s)' % want_state)

        if want_tx_rate:
            match = re.search(r'%s (\d+)' % 'output rate', out, re.M)
            have_tx_rate = None
            if match:
                have_tx_rate = match.group(1)

            if have_tx_rate is None or not conditional(want_tx_rate, have_tx_rate.strip(), cast=int):
                failed_conditions.append('tx_rate ' + want_tx_rate)

        if want_rx_rate:
            match = re.search(r'%s (\d+)' % 'input rate', out, re.M)
            have_rx_rate = None
            if match:
                have_rx_rate = match.group(1)

            if have_rx_rate is None or not conditional(want_rx_rate, have_rx_rate.strip(), cast=int):
                failed_conditions.append('rx_rate ' + want_rx_rate)

        if want_neighbors:
            have_host = []
            have_port = []
            if have_neighbors is None:
                rc, have_neighbors, err = exec_command(module, 'show lldp neighbors detail')
                if rc != 0:
                    module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), command=command, rc=rc)

            if have_neighbors:
                lines = have_neighbors.strip().split('Local Intf: ')
                for line in lines:
                    field = line.split('\n')
                    if field[0].strip() == w['name']:
                        for item in field:
                            if item.startswith('System Name:'):
                                have_host.append(item.split(':')[1].strip())
                            if item.startswith('Port Description:'):
                                have_port.append(item.split(':')[1].strip())
            for item in want_neighbors:
                host = item.get('host')
                port = item.get('port')
                if host and host not in have_host:
                    failed_conditions.append('host ' + host)
                if port and port not in have_port:
                    failed_conditions.append('port ' + port)
    return failed_conditions