def main():
    argument_spec = dict(
        group=dict(required=True, type='str'),
        interface=dict(required=True),
        version=dict(choices=['1', '2'], default='1', required=False),
        priority=dict(type='str', required=False),
        preempt=dict(type='str', choices=['disabled', 'enabled'], required=False),
        vip=dict(type='str', required=False),
        auth_type=dict(choices=['text', 'md5'], required=False),
        auth_string=dict(type='str', required=False),
        state=dict(choices=['absent', 'present'], required=False, default='present')
    )

    argument_spec.update(nxos_argument_spec)

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

    warnings = list()
    results = dict(changed=False, warnings=warnings)

    interface = module.params['interface'].lower()
    group = module.params['group']
    version = module.params['version']
    state = module.params['state']
    priority = module.params['priority']
    preempt = module.params['preempt']
    vip = module.params['vip']
    auth_type = module.params['auth_type']
    auth_full_string = module.params['auth_string']
    auth_enc = '0'
    auth_string = None
    if auth_full_string:
        kstr = auth_full_string.split()
        if len(kstr) == 2:
            auth_enc = kstr[0]
            auth_string = kstr[1]
        elif len(kstr) == 1:
            auth_string = kstr[0]
        else:
            module.fail_json(msg='Invalid auth_string')
        if auth_enc != '0' and auth_enc != '7':
            module.fail_json(msg='Invalid auth_string, only 0 or 7 allowed')

    device_info = get_capabilities(module)
    network_api = device_info.get('network_api', 'nxapi')

    intf_type = get_interface_type(interface)
    if (intf_type != 'ethernet' and network_api == 'cliconf'):
        if is_default(interface, module) == 'DNE':
            module.fail_json(msg='That interface does not exist yet. Create '
                                 'it first.', interface=interface)
        if intf_type == 'loopback':
            module.fail_json(msg="Loopback interfaces don't support HSRP.",
                             interface=interface)

    mode = get_interface_mode(interface, intf_type, module)
    if mode == 'layer2':
        module.fail_json(msg='That interface is a layer2 port.\nMake it '
                             'a layer 3 port first.', interface=interface)

    if auth_type or auth_string:
        if not (auth_type and auth_string):
            module.fail_json(msg='When using auth parameters, you need BOTH '
                                 'auth_type AND auth_string.')

    args = dict(group=group, version=version, priority=priority,
                preempt=preempt, vip=vip, auth_type=auth_type,
                auth_string=auth_string, auth_enc=auth_enc)

    proposed = dict((k, v) for k, v in args.items() if v is not None)

    existing = get_hsrp_group(group, interface, module)

    # This will enforce better practice with md5 and hsrp version.
    if proposed.get('auth_type', None) == 'md5':
        if proposed['version'] == '1':
            module.fail_json(msg="It's recommended to use HSRP v2 "
                                 "when auth_type=md5")

    elif not proposed.get('auth_type', None) and existing:
        if (proposed['version'] == '1' and
                existing['auth_type'] == 'md5') and state == 'present':
            module.fail_json(msg="Existing auth_type is md5. It's recommended "
                                 "to use HSRP v2 when using md5")

    commands = []
    if state == 'present':
        delta = dict(
            set(proposed.items()).difference(existing.items()))
        if delta:
            command = get_commands_config_hsrp(delta, interface, args, existing)
            commands.extend(command)

    elif state == 'absent':
        if existing:
            command = get_commands_remove_hsrp(group, interface)
            commands.extend(command)

    if commands:
        if module.check_mode:
            module.exit_json(**results)
        else:
            load_config(module, commands)

            # validate IP
            if network_api == 'cliconf' and state == 'present':
                commands.insert(0, 'config t')
                body = run_commands(module, commands)
                validate_config(body, vip, module)

            results['changed'] = True

            if 'configure' in commands:
                commands.pop(0)

    results['commands'] = commands
    module.exit_json(**results)
Exemple #2
0
def map_config_to_obj(want, module):
    objs = list()

    for w in want:
        obj = dict(name=None,
                   description=None,
                   admin_state=None,
                   speed=None,
                   mtu=None,
                   mode=None,
                   duplex=None,
                   interface_type=None,
                   ip_forward=None,
                   fabric_forwarding_anycast_gateway=None)

        if not w['name']:
            return obj

        command = 'show interface {0}'.format(w['name'])
        try:
            body = execute_show_command(command, module)[0]
        except IndexError:
            return list()
        if body:
            try:
                interface_table = body['TABLE_interface']['ROW_interface']
            except (KeyError, TypeError):
                return list()

            if interface_table:
                if interface_table.get('eth_mode') == 'fex-fabric':
                    module.fail_json(
                        msg=
                        'nxos_interface does not support interfaces with mode "fex-fabric"'
                    )

                intf_type = get_interface_type(w['name'])

                if intf_type in ['portchannel', 'ethernet']:
                    if not interface_table.get('eth_mode'):
                        obj['mode'] = 'layer3'

                if intf_type == 'ethernet':
                    obj['name'] = normalize_interface(
                        interface_table.get('interface'))
                    obj['admin_state'] = interface_table.get('admin_state')
                    obj['description'] = interface_table.get('desc')
                    obj['mtu'] = interface_table.get('eth_mtu')
                    obj['duplex'] = interface_table.get('eth_duplex')
                    speed = interface_table.get('eth_speed')
                    mode = interface_table.get('eth_mode')
                    if mode in ('access', 'trunk'):
                        obj['mode'] = 'layer2'
                    elif mode in ('routed', 'layer3'):
                        obj['mode'] = 'layer3'

                    command = 'show run interface {0}'.format(obj['name'])
                    body = execute_show_command(command, module)[0]

                    speed_match = re.search(r'speed (\d+)', body)
                    if speed_match is None:
                        obj['speed'] = 'auto'
                    else:
                        obj['speed'] = speed_match.group(1)

                    duplex_match = re.search(r'duplex (\S+)', body)
                    if duplex_match is None:
                        obj['duplex'] = 'auto'
                    else:
                        obj['duplex'] = duplex_match.group(1)

                    if 'ip forward' in body:
                        obj['ip_forward'] = 'enable'
                    else:
                        obj['ip_forward'] = 'disable'

                elif intf_type == 'svi':
                    obj['name'] = normalize_interface(
                        interface_table.get('interface'))
                    attributes = get_vlan_interface_attributes(
                        obj['name'], intf_type, module)
                    obj['admin_state'] = str(
                        attributes.get('admin_state', 'nxapibug'))
                    obj['description'] = str(
                        attributes.get('description', 'nxapi_bug'))

                    command = 'show run interface {0}'.format(obj['name'])
                    body = execute_show_command(command, module)[0]
                    if 'ip forward' in body:
                        obj['ip_forward'] = 'enable'
                    else:
                        obj['ip_forward'] = 'disable'
                    if 'fabric forwarding mode anycast-gateway' in body:
                        obj['fabric_forwarding_anycast_gateway'] = True
                    else:
                        obj['fabric_forwarding_anycast_gateway'] = False

                elif intf_type in ('loopback', 'management', 'nve'):
                    obj['name'] = normalize_interface(
                        interface_table.get('interface'))
                    obj['admin_state'] = interface_table.get('admin_state')
                    obj['description'] = interface_table.get('desc')

                elif intf_type == 'portchannel':
                    obj['name'] = normalize_interface(
                        interface_table.get('interface'))
                    obj['admin_state'] = interface_table.get('admin_state')
                    obj['description'] = interface_table.get('desc')
                    obj['mode'] = interface_table.get('eth_mode')

        objs.append(obj)

    return objs
Exemple #3
0
def main():
    argument_spec = dict(group=dict(required=True, type='str'),
                         interface=dict(required=True),
                         interval=dict(required=False, type='str'),
                         priority=dict(required=False, type='str'),
                         preempt=dict(required=False, type='bool'),
                         vip=dict(required=False, type='str'),
                         admin_state=dict(
                             required=False,
                             type='str',
                             choices=['shutdown', 'no shutdown', 'default'],
                             default='shutdown'),
                         authentication=dict(required=False, type='str'),
                         state=dict(choices=['absent', 'present'],
                                    required=False,
                                    default='present'))
    argument_spec.update(nxos_argument_spec)

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

    warnings = list()
    results = {'changed': False, 'commands': [], 'warnings': warnings}

    state = module.params['state']
    interface = module.params['interface'].lower()
    group = module.params['group']
    priority = module.params['priority']
    interval = module.params['interval']
    preempt = module.params['preempt']
    vip = module.params['vip']
    authentication = module.params['authentication']
    admin_state = module.params['admin_state']

    device_info = get_capabilities(module)
    network_api = device_info.get('network_api', 'nxapi')

    if state == 'present' and not vip:
        module.fail_json(msg='the "vip" param is required when state=present')

    intf_type = get_interface_type(interface)
    if (intf_type != 'ethernet' and network_api == 'cliconf'):
        if is_default(interface, module) == 'DNE':
            module.fail_json(msg='That interface does not exist yet. Create '
                             'it first.',
                             interface=interface)
        if intf_type == 'loopback':
            module.fail_json(msg="Loopback interfaces don't support VRRP.",
                             interface=interface)

    mode, name = get_interface_mode(interface, intf_type, module)
    if mode == 'layer2':
        module.fail_json(msg='That interface is a layer2 port.\nMake it '
                         'a layer 3 port first.',
                         interface=interface)

    args = dict(group=group,
                priority=priority,
                preempt=preempt,
                vip=vip,
                authentication=authentication,
                interval=interval,
                admin_state=admin_state)

    proposed = dict((k, v) for k, v in args.items() if v is not None)
    existing = get_existing_vrrp(interface, group, module, name)

    commands = []

    if state == 'present':
        delta = dict(set(proposed.items()).difference(existing.items()))
        if delta:
            command = get_commands_config_vrrp(delta, existing, group)
            if command:
                commands.append(command)
    elif state == 'absent':
        if existing:
            commands.append(['no vrrp {0}'.format(group)])

    if commands:
        commands.insert(0, ['interface {0}'.format(interface)])
        commands = flatten_list(commands)
        results['commands'] = commands
        results['changed'] = True
        if not module.check_mode:
            load_config(module, commands)
            if 'configure' in commands:
                commands.pop(0)

    module.exit_json(**results)
Exemple #4
0
def main():
    argument_spec = dict(interface=dict(required=True, type='str'),
                         version=dict(required=False, type='str'),
                         startup_query_interval=dict(required=False,
                                                     type='str'),
                         startup_query_count=dict(required=False, type='str'),
                         robustness=dict(required=False, type='str'),
                         querier_timeout=dict(required=False, type='str'),
                         query_mrt=dict(required=False, type='str'),
                         query_interval=dict(required=False, type='str'),
                         last_member_qrt=dict(required=False, type='str'),
                         last_member_query_count=dict(required=False,
                                                      type='str'),
                         group_timeout=dict(required=False, type='str'),
                         report_llg=dict(type='bool'),
                         immediate_leave=dict(type='bool'),
                         oif_routemap=dict(required=False, type='str'),
                         oif_prefix=dict(required=False,
                                         type='str',
                                         removed_in_version='2.10'),
                         oif_source=dict(required=False,
                                         type='str',
                                         removed_in_version='2.10'),
                         oif_ps=dict(required=False,
                                     type='list',
                                     elements='dict'),
                         restart=dict(type='bool', default=False),
                         state=dict(choices=['present', 'absent', 'default'],
                                    default='present'))

    argument_spec.update(nxos_argument_spec)
    mutually_exclusive = [('oif_ps', 'oif_prefix'), ('oif_ps', 'oif_source'),
                          ('oif_ps', 'oif_routemap'),
                          ('oif_prefix', 'oif_routemap')]

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

    warnings = list()
    check_args(module, warnings)

    state = module.params['state']
    interface = module.params['interface']
    oif_prefix = module.params['oif_prefix']
    oif_source = module.params['oif_source']
    oif_routemap = module.params['oif_routemap']
    oif_ps = module.params['oif_ps']

    if oif_source and not oif_prefix:
        module.fail_json(msg='oif_prefix required when setting oif_source')
    elif oif_source and oif_prefix:
        oif_ps = [{'source': oif_source, 'prefix': oif_prefix}]
    elif not oif_source and oif_prefix:
        oif_ps = [{'prefix': oif_prefix}]

    intf_type = get_interface_type(interface)
    if get_interface_mode(interface, intf_type, module) == 'layer2':
        module.fail_json(msg='this module only works on Layer 3 interfaces')

    existing = get_igmp_interface(module, interface)
    existing_copy = existing.copy()
    end_state = existing_copy

    if not existing.get('version'):
        module.fail_json(msg='pim needs to be enabled on the interface')

    existing_oif_prefix_source = existing.get('oif_prefix_source')
    # not json serializable
    existing.pop('oif_prefix_source')

    if oif_routemap and existing_oif_prefix_source:
        module.fail_json(msg='Delete static-oif configurations on this '
                         'interface if you want to use a routemap')

    if oif_ps and existing.get('oif_routemap'):
        module.fail_json(msg='Delete static-oif route-map configuration '
                         'on this interface if you want to config '
                         'static entries')

    args = [
        'version',
        'startup_query_interval',
        'startup_query_count',
        'robustness',
        'querier_timeout',
        'query_mrt',
        'query_interval',
        'last_member_qrt',
        'last_member_query_count',
        'group_timeout',
        'report_llg',
        'immediate_leave',
        'oif_routemap',
    ]

    changed = False
    commands = []
    proposed = dict((k, v) for k, v in module.params.items()
                    if v is not None and k in args)

    CANNOT_ABSENT = [
        'version', 'startup_query_interval', 'startup_query_count',
        'robustness', 'querier_timeout', 'query_mrt', 'query_interval',
        'last_member_qrt', 'last_member_query_count', 'group_timeout',
        'report_llg', 'immediate_leave'
    ]

    if state == 'absent':
        for each in CANNOT_ABSENT:
            if each in proposed:
                module.fail_json(msg='only params: oif_prefix, oif_source, '
                                 'oif_ps, oif_routemap can be used when '
                                 'state=absent')

    # delta check for all params except oif_ps
    delta = dict(set(proposed.items()).difference(existing.items()))

    if oif_ps:
        if oif_ps == ['default']:
            delta['oif_ps'] = []
        else:
            delta['oif_ps'] = oif_ps

    if state == 'present':
        if delta:
            command = config_igmp_interface(delta, existing,
                                            existing_oif_prefix_source)
            if command:
                commands.append(command)

    elif state == 'default':
        command = config_default_igmp_interface(existing, delta)
        if command:
            commands.append(command)
    elif state == 'absent':
        command = None
        if existing.get('oif_routemap') or existing_oif_prefix_source:
            command = config_remove_oif(existing, existing_oif_prefix_source)

        if command:
            commands.append(command)

        command = config_default_igmp_interface(existing, delta)
        if command:
            commands.append(command)

    cmds = []
    results = {}
    if commands:
        commands.insert(0, ['interface {0}'.format(interface)])
        cmds = flatten_list(commands)

        if module.check_mode:
            module.exit_json(changed=True, commands=cmds)
        else:
            load_config(module, cmds)
            changed = True
            end_state = get_igmp_interface(module, interface)
            if 'configure' in cmds:
                cmds.pop(0)

    if module.params['restart']:
        cmd = {'command': 'restart igmp', 'output': 'text'}
        run_commands(module, cmd)

    results['proposed'] = proposed
    results['existing'] = existing_copy
    results['updates'] = cmds
    results['changed'] = changed
    results['warnings'] = warnings
    results['end_state'] = end_state

    module.exit_json(**results)
Exemple #5
0
def map_obj_to_commands(updates, module):
    commands = list()
    commands2 = list()
    want, have = updates

    args = ('speed', 'description', 'duplex', 'mtu')
    for w in want:
        name = w['name']
        mode = w['mode']
        ip_forward = w['ip_forward']
        fabric_forwarding_anycast_gateway = w[
            'fabric_forwarding_anycast_gateway']
        admin_state = w['admin_state']
        state = w['state']
        interface_type = w['interface_type']
        del w['state']
        if name:
            w['interface_type'] = None

        if interface_type:
            obj_in_have = {}
            if state in ('present', 'default'):
                module.fail_json(
                    msg=
                    'The interface_type param can be used only with state absent.'
                )
        else:
            obj_in_have = search_obj_in_list(name, have)
            is_default = is_default_interface(name, module)

        if name:
            interface = 'interface ' + name

        if state == 'absent':
            if obj_in_have:
                commands.append('no interface {0}'.format(name))
            elif interface_type and not obj_in_have:
                intfs = get_interfaces_dict(module)[interface_type]
                cmds = get_interface_type_removed_cmds(intfs)
                commands.extend(cmds)

        elif state == 'present':
            if obj_in_have:
                # Don't run switchport command for loopback and svi interfaces
                if get_interface_type(name) in ('ethernet', 'portchannel'):
                    if mode == 'layer2' and mode != obj_in_have.get('mode'):
                        add_command_to_interface(interface, 'switchport',
                                                 commands)
                    elif mode == 'layer3' and mode != obj_in_have.get('mode'):
                        add_command_to_interface(interface, 'no switchport',
                                                 commands)

                if admin_state == 'up' and admin_state != obj_in_have.get(
                        'admin_state'):
                    add_command_to_interface(interface, 'no shutdown',
                                             commands)
                elif admin_state == 'down' and admin_state != obj_in_have.get(
                        'admin_state'):
                    add_command_to_interface(interface, 'shutdown', commands)

                if ip_forward == 'enable' and ip_forward != obj_in_have.get(
                        'ip_forward'):
                    add_command_to_interface(interface, 'ip forward', commands)
                elif ip_forward == 'disable' and ip_forward != obj_in_have.get(
                        'ip forward'):
                    add_command_to_interface(interface, 'no ip forward',
                                             commands)

                if (fabric_forwarding_anycast_gateway is True and
                        obj_in_have.get('fabric_forwarding_anycast_gateway') is
                        False):
                    add_command_to_interface(
                        interface, 'fabric forwarding mode anycast-gateway',
                        commands)

                elif (fabric_forwarding_anycast_gateway is False
                      and obj_in_have.get('fabric_forwarding_anycast_gateway')
                      is True):
                    add_command_to_interface(
                        interface, 'no fabric forwarding mode anycast-gateway',
                        commands)

                for item in args:
                    candidate = w.get(item)
                    if candidate and candidate != obj_in_have.get(item):
                        cmd = item + ' ' + str(candidate)
                        add_command_to_interface(interface, cmd, commands)

                if name and get_interface_type(name) == 'ethernet':
                    if mode != obj_in_have.get('mode'):
                        admin_state = w.get('admin_state') or obj_in_have.get(
                            'admin_state')
                        if admin_state:
                            c1 = 'interface {0}'.format(
                                normalize_interface(w['name']))
                            c2 = get_admin_state(admin_state)
                            commands2.append(c1)
                            commands2.append(c2)

            else:
                commands.append(interface)
                # Don't run switchport command for loopback and svi interfaces
                if get_interface_type(name) in ('ethernet', 'portchannel'):
                    if mode == 'layer2':
                        commands.append('switchport')
                    elif mode == 'layer3':
                        commands.append('no switchport')

                if admin_state == 'up':
                    commands.append('no shutdown')
                elif admin_state == 'down':
                    commands.append('shutdown')

                if ip_forward == 'enable':
                    commands.append('ip forward')
                elif ip_forward == 'disable':
                    commands.append('no ip forward')

                if fabric_forwarding_anycast_gateway is True:
                    commands.append('fabric forwarding mode anycast-gateway')

                elif fabric_forwarding_anycast_gateway is False:
                    commands.append(
                        'no fabric forwarding mode anycast-gateway')

                for item in args:
                    candidate = w.get(item)
                    if candidate:
                        commands.append(item + ' ' + str(candidate))

        elif state == 'default':
            if is_default is False:
                commands.append('default interface {0}'.format(name))
            elif is_default == 'DNE':
                module.exit_json(
                    msg='interface you are trying to default does not exist')

    return commands, commands2
def main():
    argument_spec = dict(
        interface=dict(required=True),
        sparse=dict(type='bool', default=False),
        dr_prio=dict(type='str'),
        hello_auth_key=dict(type='str'),
        hello_interval=dict(type='int'),
        jp_policy_out=dict(type='str'),
        jp_policy_in=dict(type='str'),
        jp_type_out=dict(choices=['prefix', 'routemap']),
        jp_type_in=dict(choices=['prefix', 'routemap']),
        border=dict(type='bool', default=False),
        neighbor_policy=dict(type='str'),
        neighbor_type=dict(choices=['prefix', 'routemap']),
        state=dict(choices=['present', 'absent', 'default'],
                   default='present'),
    )
    argument_spec.update(nxos_argument_spec)

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

    warnings = list()
    check_args(module, warnings)
    results = {'changed': False, 'commands': [], 'warnings': warnings}

    state = module.params['state']
    interface = module.params['interface']
    jp_type_in = module.params['jp_type_in']
    jp_type_out = module.params['jp_type_out']
    jp_policy_in = module.params['jp_policy_in']
    jp_policy_out = module.params['jp_policy_out']
    neighbor_policy = module.params['neighbor_policy']
    neighbor_type = module.params['neighbor_type']
    hello_interval = module.params['hello_interval']

    intf_type = get_interface_type(interface)
    if get_interface_mode(interface, intf_type, module) == 'layer2':
        module.fail_json(msg='this module only works on Layer 3 interfaces.')

    if jp_policy_in:
        if not jp_type_in:
            module.fail_json(
                msg='jp_type_in required when using jp_policy_in.')
    if jp_policy_out:
        if not jp_type_out:
            module.fail_json(
                msg='jp_type_out required when using jp_policy_out.')
    if neighbor_policy:
        if not neighbor_type:
            module.fail_json(
                msg='neighbor_type required when using neighbor_policy.')

    get_existing = get_pim_interface(module, interface)
    existing, jp_bidir, isauth = local_existing(get_existing)

    args = PARAM_TO_COMMAND_KEYMAP.keys()
    proposed = dict((k, v) for k, v in module.params.items()
                    if v is not None and k in args)

    if hello_interval:
        proposed['hello_interval'] = str(proposed['hello_interval'] * 1000)

    delta = dict(set(proposed.items()).difference(existing.items()))

    commands = []
    if state == 'present':
        if delta:
            command = config_pim_interface(delta, existing, jp_bidir, isauth)
            if command:
                commands.append(command)
    elif state == 'default' or state == 'absent':
        defaults = config_pim_interface_defaults(existing, jp_bidir, isauth)
        if defaults:
            commands.append(defaults)

    if commands:
        commands.insert(0, ['interface {0}'.format(interface)])

    cmds = flatten_list(commands)
    if cmds:
        results['changed'] = True
        if not module.check_mode:
            load_config(module, cmds)
        if 'configure' in cmds:
            cmds.pop(0)

    results['commands'] = cmds

    module.exit_json(**results)
Exemple #7
0
def map_obj_to_commands(updates, module):
    commands = list()
    want, have = updates
    state = module.params['state']
    purge = module.params['purge']

    args = ('rd', 'description', 'vni')

    for w in want:
        name = w['name']
        admin_state = w['admin_state']
        vni = w['vni']
        interfaces = w.get('interfaces') or []
        state = w['state']
        del w['state']

        obj_in_have = search_obj_in_list(name, have)

        if state == 'absent' and obj_in_have:
            commands.append('no vrf context {0}'.format(name))

        elif state == 'present':
            if not obj_in_have:
                commands.append('vrf context {0}'.format(name))
                for item in args:
                    candidate = w.get(item)
                    if candidate and candidate != 'default':
                        cmd = item + ' ' + str(candidate)
                        commands.append(cmd)
                if admin_state == 'up':
                    commands.append('no shutdown')
                elif admin_state == 'down':
                    commands.append('shutdown')
                commands.append('exit')

                if interfaces and interfaces[0] != 'default':
                    for i in interfaces:
                        commands.append('interface {0}'.format(i))
                        if get_interface_type(i) in ('ethernet',
                                                     'portchannel'):
                            commands.append('no switchport')
                        commands.append('vrf member {0}'.format(name))

            else:
                # If vni is already configured on vrf, unconfigure it first.
                if vni:
                    if obj_in_have.get(
                            'vni') and vni != obj_in_have.get('vni'):
                        commands.append('no vni {0}'.format(
                            obj_in_have.get('vni')))

                for item in args:
                    candidate = w.get(item)
                    if candidate == 'default':
                        if obj_in_have.get(item):
                            cmd = 'no ' + item + ' ' + obj_in_have.get(item)
                            commands.append(cmd)
                    elif candidate and candidate != obj_in_have.get(item):
                        cmd = item + ' ' + str(candidate)
                        commands.append(cmd)
                if admin_state and admin_state != obj_in_have.get(
                        'admin_state'):
                    if admin_state == 'up':
                        commands.append('no shutdown')
                    elif admin_state == 'down':
                        commands.append('shutdown')

                if commands:
                    commands.insert(0, 'vrf context {0}'.format(name))
                    commands.append('exit')

                if interfaces and interfaces[0] != 'default':
                    if not obj_in_have['interfaces']:
                        for i in interfaces:
                            commands.append('vrf context {0}'.format(name))
                            commands.append('exit')
                            commands.append('interface {0}'.format(i))
                            if get_interface_type(i) in ('ethernet',
                                                         'portchannel'):
                                commands.append('no switchport')
                            commands.append('vrf member {0}'.format(name))

                    elif set(interfaces) != set(obj_in_have['interfaces']):
                        missing_interfaces = list(
                            set(interfaces) - set(obj_in_have['interfaces']))
                        for i in missing_interfaces:
                            commands.append('vrf context {0}'.format(name))
                            commands.append('exit')
                            commands.append('interface {0}'.format(i))
                            if get_interface_type(i) in ('ethernet',
                                                         'portchannel'):
                                commands.append('no switchport')
                            commands.append('vrf member {0}'.format(name))

                        superfluous_interfaces = list(
                            set(obj_in_have['interfaces']) - set(interfaces))
                        for i in superfluous_interfaces:
                            commands.append('vrf context {0}'.format(name))
                            commands.append('exit')
                            commands.append('interface {0}'.format(i))
                            if get_interface_type(i) in ('ethernet',
                                                         'portchannel'):
                                commands.append('no switchport')
                            commands.append('no vrf member {0}'.format(name))
                elif interfaces and interfaces[0] == 'default':
                    if obj_in_have['interfaces']:
                        for i in obj_in_have['interfaces']:
                            commands.append('vrf context {0}'.format(name))
                            commands.append('exit')
                            commands.append('interface {0}'.format(i))
                            if get_interface_type(i) in ('ethernet',
                                                         'portchannel'):
                                commands.append('no switchport')
                            commands.append('no vrf member {0}'.format(name))

    if purge:
        existing = get_existing_vrfs(module)
        if existing:
            for h in existing:
                if h['name'] in ('default', 'management'):
                    pass
                else:
                    obj_in_want = search_obj_in_list(h['name'], want)
                    if not obj_in_want:
                        commands.append('no vrf context {0}'.format(h['name']))

    return commands
Exemple #8
0
def main():
    argument_spec = dict(
        vrf=dict(required=True),
        interface=dict(type='str', required=True),
        state=dict(default='present',
                   choices=['present', 'absent'],
                   required=False),
    )

    argument_spec.update(nxos_argument_spec)

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

    warnings = list()
    results = {'changed': False, 'commands': [], 'warnings': warnings}

    vrf = module.params['vrf']
    interface = module.params['interface'].lower()
    state = module.params['state']

    device_info = get_capabilities(module)
    network_api = device_info.get('network_api', 'nxapi')

    current_vrfs = get_vrf_list(module)
    if vrf not in current_vrfs:
        warnings.append("The VRF is not present/active on the device. "
                        "Use nxos_vrf to fix this.")

    intf_type = get_interface_type(interface)
    if (intf_type != 'ethernet' and network_api == 'cliconf'):
        if is_default(interface, module) == 'DNE':
            module.fail_json(msg="interface does not exist on switch. Verify "
                             "switch platform or create it first with "
                             "nxos_interface if it's a logical interface")

    mode = get_interface_mode(interface, intf_type, module)
    if mode == 'layer2':
        module.fail_json(msg='Ensure interface is a Layer 3 port before '
                         'configuring a VRF on an interface. You can '
                         'use nxos_interface')

    current_vrf = get_interface_info(interface, module)
    existing = dict(interface=interface, vrf=current_vrf)
    changed = False

    if not existing['vrf']:
        pass
    elif vrf != existing['vrf'] and state == 'absent':
        module.fail_json(msg='The VRF you are trying to remove '
                         'from the interface does not exist '
                         'on that interface.',
                         interface=interface,
                         proposed_vrf=vrf,
                         existing_vrf=existing['vrf'])

    commands = []
    if existing:
        if state == 'absent':
            if existing and vrf == existing['vrf']:
                command = 'no vrf member {0}'.format(vrf)
                commands.append(command)

        elif state == 'present':
            if existing['vrf'] != vrf:
                command = 'vrf member {0}'.format(vrf)
                commands.append(command)

    if commands:
        commands.insert(0, 'interface {0}'.format(interface))

    if commands:
        if module.check_mode:
            module.exit_json(changed=True, commands=commands)
        else:
            load_config(module, commands)
            changed = True
            if 'configure' in commands:
                commands.pop(0)

    results['commands'] = commands
    results['changed'] = changed

    module.exit_json(**results)
def main():
    argument_spec = dict(
        interface=dict(required=True),
        addr=dict(required=False),
        version=dict(required=False, choices=['v4', 'v6'],
                     default='v4'),
        mask=dict(type='str', required=False),
        dot1q=dict(required=False, default=0, type='int'),
        tag=dict(required=False, default=0, type='int'),
        state=dict(required=False, default='present',
                   choices=['present', 'absent']),
        allow_secondary=dict(required=False, default=False,
                             type='bool')
    )

    argument_spec.update(nxos_argument_spec)

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

    if not HAS_IPADDRESS:
        module.fail_json(msg="ipaddress is required for this module. Run 'pip install ipaddress' for install.")

    warnings = list()

    addr = module.params['addr']
    version = module.params['version']
    mask = module.params['mask']
    dot1q = module.params['dot1q']
    tag = module.params['tag']
    allow_secondary = module.params['allow_secondary']
    interface = module.params['interface'].lower()
    state = module.params['state']

    intf_type = get_interface_type(interface)
    validate_params(addr, interface, mask, dot1q, tag, allow_secondary, version, state, intf_type, module)

    mode = get_interface_mode(interface, intf_type, module)
    if mode == 'layer2':
        module.fail_json(msg='That interface is a layer2 port.\nMake it '
                             'a layer 3 port first.', interface=interface)

    existing = get_ip_interface(interface, version, module)

    dot1q_tag = get_dot1q_id(interface, module)
    if dot1q_tag > 1:
        existing['dot1q'] = dot1q_tag

    args = dict(addr=addr, mask=mask, dot1q=dot1q, tag=tag, interface=interface, allow_secondary=allow_secondary)
    proposed = dict((k, v) for k, v in args.items() if v is not None)
    commands = []
    changed = False
    end_state = existing

    commands = ['interface {0}'.format(interface)]
    if state == 'absent':
        if existing['addresses']:
            if find_same_addr(existing, addr, mask):
                command = get_remove_ip_config_commands(interface, addr,
                                                        mask, existing, version)
                commands.append(command)
        if 'dot1q' in existing and existing['dot1q'] > 1:
            command = 'no encapsulation dot1Q {0}'.format(existing['dot1q'])
            commands.append(command)
    elif state == 'present':
        if not find_same_addr(existing, addr, mask, full=True, tag=tag, version=version):
            command = get_config_ip_commands(proposed, interface, existing, version)
            commands.append(command)
        if 'dot1q' not in existing and (intf_type in ['ethernet', 'portchannel'] and "." in interface):
            command = 'encapsulation dot1Q {0}'.format(proposed['dot1q'])
            commands.append(command)
    if len(commands) < 2:
        del commands[0]
    cmds = flatten_list(commands)
    if cmds:
        if module.check_mode:
            module.exit_json(changed=True, commands=cmds)
        else:
            load_config(module, cmds)
            changed = True
            end_state = get_ip_interface(interface, version, module)
            if 'configure' in cmds:
                cmds.pop(0)

    results = {}
    results['proposed'] = proposed
    results['existing'] = existing
    results['end_state'] = end_state
    results['commands'] = cmds
    results['changed'] = changed
    results['warnings'] = warnings

    module.exit_json(**results)
def parse_unstructured_data(body, interface_name, version, module):
    interface = {}
    interface['addresses'] = []
    interface['prefixes'] = []
    vrf = None

    body = body[0]
    splitted_body = body.split('\n')

    if version == "v6":
        if "ipv6 is disabled" not in body.lower():
            address_list = []
            # We can have multiple IPv6 on the same interface.
            # We need to parse them manually from raw output.
            for index in range(0, len(splitted_body) - 1):
                if "IPv6 address:" in splitted_body[index]:
                    first_reference_point = index + 1
                elif "IPv6 subnet:" in splitted_body[index]:
                    last_reference_point = index
                    break

            interface_list_table = splitted_body[first_reference_point:last_reference_point]

            for each_line in interface_list_table:
                address = each_line.strip().split(' ')[0]
                if address not in address_list:
                    address_list.append(address)
                    interface['prefixes'].append(str(ipaddress.ip_interface(u"%s" % address).network))

            if address_list:
                for ipv6 in address_list:
                    address = {}
                    splitted_address = ipv6.split('/')
                    address['addr'] = splitted_address[0]
                    address['mask'] = splitted_address[1]
                    interface['addresses'].append(address)

    else:
        for index in range(0, len(splitted_body) - 1):
            if "IP address" in splitted_body[index]:
                regex = r'.*IP\saddress:\s(?P<addr>\d{1,3}(?:\.\d{1,3}){3}),\sIP\ssubnet:' + \
                        r'\s\d{1,3}(?:\.\d{1,3}){3}\/(?P<mask>\d+)(?:\s(?P<secondary>secondary)\s)?' + \
                        r'(.+?tag:\s(?P<tag>\d+).*)?'
                match = re.match(regex, splitted_body[index])
                if match:
                    match_dict = match.groupdict()
                    if match_dict['secondary'] is None:
                        match_dict['secondary'] = False
                    else:
                        match_dict['secondary'] = True
                    if match_dict['tag'] is None:
                        match_dict['tag'] = 0
                    else:
                        match_dict['tag'] = int(match_dict['tag'])
                    interface['addresses'].append(match_dict)
                    prefix = str(ipaddress.ip_interface(u"%(addr)s/%(mask)s" % match_dict).network)
                    interface['prefixes'].append(prefix)

    try:
        vrf_regex = r'.+?VRF\s+(?P<vrf>\S+?)\s'
        match_vrf = re.match(vrf_regex, body, re.DOTALL)
        vrf = match_vrf.groupdict()['vrf']
    except AttributeError:
        vrf = None

    interface['interface'] = interface_name
    interface['type'] = get_interface_type(interface_name)
    interface['vrf'] = vrf

    return interface