def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        rtp=dict(type='str', required=False, aliases=['name', 'rtp_name']),  # Not required for querying all objects
        tenant=dict(type='str', required=False, aliases=['tenant_name']),  # Not required for quering all objects
        description=dict(type='str', aliases=['descr']),
        tag=dict(type='int'),
        state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['rtp', 'tenant']],
            ['state', 'present', ['rtp', 'tenant']],
        ],
    )

    rtp = module.params['rtp']
    description = module.params['description']
    tag = module.params['tag']
    state = module.params['state']
    tenant = module.params['tenant']

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class='fvTenant',
            aci_rn='tn-{0}'.format(tenant),
            filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
            module_object=tenant,
        ),
        subclass_1=dict(
            aci_class='l3extRouteTagPol',
            aci_rn='rttag-{0}'.format(rtp),
            filter_target='eq(l3extRouteTagPol.name, "{0}")'.format(rtp),
            module_object=rtp,
        ),
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='l3extRouteTagPol',
            class_config=dict(
                name=rtp,
                descr=description, tag=tag,
            ),
        )

        aci.get_diff(aci_class='l3extRouteTagPol')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
Exemple #2
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        aep=dict(type='str', aliases=['name', 'aep_name']),  # Not required for querying all objects
        description=dict(type='str', aliases=['descr']),
        infra_vlan=dict(type='bool', aliases=['infrastructure_vlan']),
        state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['aep']],
            ['state', 'present', ['aep']],
        ],
    )

    aep = module.params['aep']
    description = module.params['description']
    infra_vlan = module.params['infra_vlan']
    state = module.params['state']

    if infra_vlan:
        child_configs = [dict(infraProvAcc=dict(attributes=dict(name='provacc')))]
    elif infra_vlan is False:
        child_configs = [dict(infraProvAcc=dict(attributes=dict(name='provacc', status='deleted')))]
    else:
        child_configs = []

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class='infraAttEntityP',
            aci_rn='infra/attentp-{0}'.format(aep),
            filter_target='eq(infraAttEntityP.name, "{0}")'.format(aep),
            module_object=aep,
        ),
    )
    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='infraAttEntityP',
            class_config=dict(
                name=aep,
                descr=description,
            ),
            child_configs=child_configs,
        )

        aci.get_diff(aci_class='infraAttEntityP')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        aaa_user=dict(type='str', required=True),  # Not required for querying all objects
        aaa_user_type=dict(type='str', default='user', choices=['appuser', 'user']),
        certificate=dict(type='str', aliases=['cert_data', 'certificate_data']),  # Not required for querying all objects
        certificate_name=dict(type='str', aliases=['cert_name']),  # Not required for querying all objects
        state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['aaa_user', 'certificate_name']],
            ['state', 'present', ['aaa_user', 'certificate', 'certificate_name']],
        ],
    )

    aaa_user = module.params['aaa_user']
    aaa_user_type = module.params['aaa_user_type']
    certificate = module.params['certificate']
    certificate_name = module.params['certificate_name']
    state = module.params['state']

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class=ACI_MAPPING[aaa_user_type]['aci_class'],
            aci_rn=ACI_MAPPING[aaa_user_type]['aci_mo'] + aaa_user,
            filter_target='eq({0}.name, "{1}")'.format(ACI_MAPPING[aaa_user_type]['aci_class'], aaa_user),
            module_object=aaa_user,
        ),
        subclass_1=dict(
            aci_class='aaaUserCert',
            aci_rn='usercert-{0}'.format(certificate_name),
            filter_target='eq(aaaUserCert.name, "{0}")'.format(certificate_name),
            module_object=certificate_name,
        ),
    )
    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='aaaUserCert',
            class_config=dict(
                data=certificate,
                name=certificate_name,
            ),
        )

        aci.get_diff(aci_class='aaaUserCert')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        lldp_policy=dict(type='str', require=False, aliases=['name']),  # Not required for querying all objects
        description=dict(type='str', aliases=['descr']),
        receive_state=dict(type='raw'),  # Turn into a boolean in v2.9
        transmit_state=dict(type='raw'),  # Turn into a boolean in v2.9
        state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['lldp_policy']],
            ['state', 'present', ['lldp_policy']],
        ],
    )

    aci = ACIModule(module)

    lldp_policy = module.params['lldp_policy']
    description = module.params['description']
    receive_state = aci.boolean(module.params['receive_state'], 'enabled', 'disabled')
    transmit_state = aci.boolean(module.params['transmit_state'], 'enabled', 'disabled')
    state = module.params['state']

    aci.construct_url(
        root_class=dict(
            aci_class='lldpIfPol',
            aci_rn='infra/lldpIfP-{0}'.format(lldp_policy),
            filter_target='eq(lldpIfPol.name, "{0}")'.format(lldp_policy),
            module_object=lldp_policy,
        ),
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='lldpIfPol',
            class_config=dict(
                name=lldp_policy,
                descr=description,
                adminRxSt=receive_state,
                adminTxSt=transmit_state,
            ),
        )

        aci.get_diff(aci_class='lldpIfPol')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        leaf_profile=dict(type='str', aliases=['leaf_profile_name']),  # Not required for querying all objects
        interface_selector=dict(type='str', aliases=['interface_profile_name', 'interface_selector_name', 'name']),  # Not required for querying all objects
        state=dict(type='str', default='present', choices=['absent', 'present', 'query'])
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['leaf_profile', 'interface_selector']],
            ['state', 'present', ['leaf_profile', 'interface_selector']]
        ],
    )

    leaf_profile = module.params['leaf_profile']
    # WARNING: interface_selector accepts non existing interface_profile names and they appear on APIC gui with a state of "missing-target"
    interface_selector = module.params['interface_selector']
    state = module.params['state']

    # Defining the interface profile tDn for clarity
    interface_selector_tDn = 'uni/infra/accportprof-{0}'.format(interface_selector)

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class='infraNodeP',
            aci_rn='infra/nprof-{0}'.format(leaf_profile),
            filter_target='eq(infraNodeP.name, "{0}")'.format(leaf_profile),
            module_object=leaf_profile
        ),
        subclass_1=dict(
            aci_class='infraRsAccPortP',
            aci_rn='rsaccPortP-[{0}]'.format(interface_selector_tDn),
            filter_target='eq(infraRsAccPortP.name, "{0}")'.format(interface_selector),
            module_object=interface_selector,
        )
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='infraRsAccPortP',
            class_config=dict(tDn=interface_selector_tDn),
        )

        aci.get_diff(aci_class='infraRsAccPortP')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        port_security=dict(type='str', required=False, aliases=['name']),  # Not required for querying all objects
        description=dict(type='str', aliases=['descr']),
        max_end_points=dict(type='int'),
        state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['port_security']],
            ['state', 'present', ['port_security']],
        ],
    )

    port_security = module.params['port_security']
    description = module.params['description']
    max_end_points = module.params['max_end_points']
    if max_end_points is not None and max_end_points not in range(12001):
        module.fail_json(msg='The "max_end_points" must be between 0 and 12000')
    state = module.params['state']

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class='l2PortSecurityPol',
            aci_rn='infra/portsecurityP-{0}'.format(port_security),
            filter_target='eq(l2PortSecurityPol.name, "{0}")'.format(port_security),
            module_object=port_security,
        ),
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='l2PortSecurityPol',
            class_config=dict(
                name=port_security,
                descr=description,
                maximum=max_end_points,
            ),
        )

        aci.get_diff(aci_class='l2PortSecurityPol')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        fc_policy=dict(type='str', required=False, aliases=['name']),  # Not required for querying all objects
        description=dict(type='str', aliases=['descr']),
        port_mode=dict(type='str', choices=['f', 'np']),  # No default provided on purpose
        state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['fc_policy']],
            ['state', 'present', ['fc_policy']],
        ],
    )

    fc_policy = module.params['fc_policy']
    port_mode = module.params['port_mode']
    description = module.params['description']
    state = module.params['state']

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class='fcIfPol',
            aci_rn='infra/fcIfPol-{0}'.format(fc_policy),
            filter_target='eq(fcIfPol.name, "{0}")'.format(fc_policy),
            module_object=fc_policy,
        ),
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='fcIfPol',
            class_config=dict(
                name=fc_policy,
                descr=description,
                portMode=port_mode,
            ),
        )

        aci.get_diff(aci_class='fcIfPol')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        leaf_profile=dict(type='str', aliases=['name', 'leaf_profile_name']),  # Not required for querying all objects
        description=dict(type='str', aliases=['descr']),
        state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['leaf_profile']],
            ['state', 'present', ['leaf_profile']],
        ],
    )

    leaf_profile = module.params['leaf_profile']
    description = module.params['description']
    state = module.params['state']

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class='infraNodeP',
            aci_rn='infra/nprof-{0}'.format(leaf_profile),
            filter_target='eq(infraNodeP.name, "{0}")'.format(leaf_profile),
            module_object=leaf_profile,
        ),
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='infraNodeP',
            class_config=dict(
                name=leaf_profile,
                descr=description,
            ),
        )

        aci.get_diff(aci_class='infraNodeP')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        admin_state=dict(type='raw'),  # Turn into a boolean in v2.9
        description=dict(type='str', aliases=['descr']),
        dst_group=dict(type='str'),
        src_group=dict(type='str', required=False, aliases=['name']),  # Not required for querying all objects
        state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
        tenant=dict(type='str', required=False, aliases=['tenant_name']),  # Not required for querying all objects
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['src_group', 'tenant']],
            ['state', 'present', ['src_group', 'tenant']],
        ],
    )

    aci = ACIModule(module)

    admin_state = aci.boolean(module.params['admin_state'], 'enabled', 'disabled')
    description = module.params['description']
    dst_group = module.params['dst_group']
    src_group = module.params['src_group']
    state = module.params['state']
    tenant = module.params['tenant']

    aci.construct_url(
        root_class=dict(
            aci_class='fvTenant',
            aci_rn='tn-{0}'.format(tenant),
            filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
            module_object=tenant,
        ),
        subclass_1=dict(
            aci_class='spanSrcGrp',
            aci_rn='srcgrp-{0}'.format(src_group),
            filter_target='eq(spanSrcGrp.name, "{0}")'.format(src_group),
            module_object=src_group,
        ),
        child_classes=['spanSpanLbl'],
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='spanSrcGrp',
            class_config=dict(
                adminSt=admin_state,
                descr=description,
                name=src_group,
            ),
            child_configs=[{'spanSpanLbl': {'attributes': {'name': dst_group}}}],
        )

        aci.get_diff(aci_class='spanSrcGrp')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
Exemple #10
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        contract=dict(type='str', required=False, aliases=['contract_name', 'name']),  # Not required for querying all objects
        tenant=dict(type='str', required=False, aliases=['tenant_name']),  # Not required for querying all objects
        description=dict(type='str', aliases=['descr']),
        scope=dict(type='str', choices=['application-profile', 'context', 'global', 'tenant']),
        priority=dict(type='str', choices=['level1', 'level2', 'level3', 'unspecified']),  # No default provided on purpose
        dscp=dict(type='str',
                  choices=['AF11', 'AF12', 'AF13', 'AF21', 'AF22', 'AF23', 'AF31', 'AF32', 'AF33', 'AF41', 'AF42', 'AF43',
                           'CS0', 'CS1', 'CS2', 'CS3', 'CS4', 'CS5', 'CS6', 'CS7', 'EF', 'VA', 'unspecified'],
                  aliases=['target']),  # No default provided on purpose
        state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['contract', 'tenant']],
            ['state', 'present', ['contract', 'tenant']],
        ],
    )

    contract = module.params['contract']
    description = module.params['description']
    scope = module.params['scope']
    priority = module.params['priority']
    dscp = module.params['dscp']
    state = module.params['state']
    tenant = module.params['tenant']

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class='fvTenant',
            aci_rn='tn-{0}'.format(tenant),
            module_object=tenant,
            target_filter={'name': tenant},
        ),
        subclass_1=dict(
            aci_class='vzBrCP',
            aci_rn='brc-{0}'.format(contract),
            module_object=contract,
            target_filter={'name': contract},
        ),
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='vzBrCP',
            class_config=dict(
                name=contract,
                descr=description,
                scope=scope,
                prio=priority,
                targetDscp=dscp,
            ),
        )

        aci.get_diff(aci_class='vzBrCP')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
Exemple #11
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        bd=dict(type='str', aliases=['bd_name']),
        description=dict(type='str', aliases=['descr']),
        enable_vip=dict(type='str', choices=['no', 'yes']),
        gateway=dict(type='str', aliases=['gateway_ip']),
        mask=dict(type='int', aliases=['subnet_mask']),
        subnet_name=dict(type='str', aliases=['name']),
        nd_prefix_policy=dict(type='str'),
        preferred=dict(type='str', choices=['no', 'yes']),
        route_profile=dict(type='str'),
        route_profile_l3_out=dict(type='str'),
        scope=dict(
            type='list',
            choices=[['private'], ['public'], ['shared'], ['private', 'shared'], ['shared', 'private'], ['public', 'shared'], ['shared', 'public']],
        ),
        subnet_control=dict(type='str', choices=['nd_ra', 'no_gw', 'querier_ip', 'unspecified']),
        state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
        tenant=dict(type='str', aliases=['tenant_name']),
        method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'),  # Deprecated starting from v2.6
        protocol=dict(type='str', removed_in_version='2.6'),  # Deprecated in v2.6
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_together=[['gateway', 'mask']],
        required_if=[
            ['state', 'present', ['bd', 'gateway', 'mask', 'tenant']],
            ['state', 'absent', ['bd', 'gateway', 'mask', 'tenant']],
        ],
    )

    description = module.params['description']
    enable_vip = module.params['enable_vip']
    tenant = module.params['tenant']
    bd = module.params['bd']
    gateway = module.params['gateway']
    mask = module.params['mask']
    if mask is not None and mask not in range(0, 129):
        # TODO: split checkes between IPv4 and IPv6 Addresses
        module.fail_json(msg='Valid Subnet Masks are 0 to 32 for IPv4 Addresses and 0 to 128 for IPv6 addresses')
    if gateway is not None:
        gateway = '{0}/{1}'.format(gateway, str(mask))
    subnet_name = module.params['subnet_name']
    nd_prefix_policy = module.params['nd_prefix_policy']
    preferred = module.params['preferred']
    route_profile = module.params['route_profile']
    route_profile_l3_out = module.params['route_profile_l3_out']
    scope = module.params['scope']
    if scope:
        if len(scope) == 1:
            scope = scope[0]
        elif 'public' in scope:
            scope = 'public,shared'
        else:
            scope = 'private,shared'
    state = module.params['state']
    subnet_control = module.params['subnet_control']
    if subnet_control:
        subnet_control = SUBNET_CONTROL_MAPPING[subnet_control]

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class='fvTenant',
            aci_rn='tn-{0}'.format(tenant),
            filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
            module_object=tenant,
        ),
        subclass_1=dict(
            aci_class='fvBD',
            aci_rn='BD-{0}'.format(bd),
            filter_target='eq(fvBD.name, "{0}")'.format(bd),
            module_object=bd,
        ),
        subclass_2=dict(
            aci_class='fvSubnet',
            aci_rn='subnet-[{0}]'.format(gateway),
            filter_target='eq(fvSubnet.ip, "{0}")'.format(gateway),
            module_object=gateway,
        ),
        child_classes=['fvRsBDSubnetToProfile', 'fvRsNdPfxPol'],
    )

    aci.get_existing()

    if state == 'present':
        # Filter out module params with null values
        aci.payload(
            aci_class='fvSubnet',
            class_config=dict(
                ctrl=subnet_control,
                descr=description,
                ip=gateway,
                name=subnet_name,
                preferred=preferred,
                scope=scope,
                virtual=enable_vip,
            ),
            child_configs=[
                {'fvRsBDSubnetToProfile': {'attributes': {'tnL3extOutName': route_profile_l3_out, 'tnRtctrlProfileName': route_profile}}},
                {'fvRsNdPfxPol': {'attributes': {'tnNdPfxPolName': nd_prefix_policy}}},
            ],
        )

        # Generate config diff which will be used as POST request body
        aci.get_diff(aci_class='fvSubnet')

        # Submit changes if module not in check_mode and the proposed is different than existing
        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    module.exit_json(**aci.result)
def main():
    argument_spec = aci_argument_spec
    argument_spec.update(
        lldp_policy=dict(type='str', require=False, aliases=['name']),
        description=dict(type='str', aliases=['descr']),
        receive_state=dict(type='str', choices=['disabled', 'enabled']),
        transmit_state=dict(type='str', choices=['disabled', 'enabled']),
        state=dict(type='str',
                   default='present',
                   choices=['absent', 'present', 'query']),
        method=dict(type='str',
                    choices=['delete', 'get', 'post'],
                    aliases=['action'],
                    removed_in_version='2.6'),  # Deprecated starting from v2.6
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['lldp_policy']],
            ['state', 'present', ['lldp_policy']],
        ],
    )

    lldp_policy = module.params['lldp_policy']
    description = module.params['description']
    receive_state = module.params['receive_state']
    transmit_state = module.params['transmit_state']
    state = module.params['state']

    aci = ACIModule(module)
    aci.construct_url(root_class=dict(
        aci_class='lldpIfPol',
        aci_rn='infra/lldpIfP-{0}'.format(lldp_policy),
        filter_target='eq(lldpIfPol.name, "{0}")'.format(lldp_policy),
        module_object=lldp_policy,
    ), )

    aci.get_existing()

    if state == 'present':
        # Filter out module parameters with null values
        aci.payload(
            aci_class='lldpIfPol',
            class_config=dict(
                name=lldp_policy,
                descr=description,
                adminRxSt=receive_state,
                adminTxSt=transmit_state,
            ),
        )

        # Generate config diff which will be used as POST request body
        aci.get_diff(aci_class='lldpIfPol')

        # Submit changes if module not in check_mode and the proposed is different than existing
        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    module.exit_json(**aci.result)
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        bd=dict(type='str', aliases=['bd_name', 'bridge_domain']),  # Not required for querying all objects
        l3out=dict(type='str'),  # Not required for querying all objects
        state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
        tenant=dict(type='str', aliases=['tenant_name']),  # Not required for querying all objects
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_together=[['gateway', 'mask']],
        required_if=[
            ['state', 'present', ['bd', 'l3out', 'tenant']],
            ['state', 'absent', ['bd', 'l3out', 'tenant']],
        ],
    )

    bd = module.params['bd']
    l3out = module.params['l3out']
    state = module.params['state']
    tenant = module.params['tenant']

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class='fvTenant',
            aci_rn='tn-{0}'.format(tenant),
            filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
            module_object=tenant,
        ),
        subclass_1=dict(
            aci_class='fvBD',
            aci_rn='BD-{0}'.format(bd),
            filter_target='eq(fvBD.name, "{0}")'.format(bd),
            module_object=bd,
        ),
        subclass_2=dict(
            aci_class='fvRsBDToOut',
            aci_rn='rsBDToOut-{0}'.format(l3out),
            filter_target='eq(fvRsBDToOut.tnL3extOutName, "{0}")'.format(l3out),
            module_object=l3out,
        ),
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='fvRsBDToOut',
            class_config=dict(tnL3extOutName=l3out),
        )

        aci.get_diff(aci_class='fvRsBDToOut')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        leaf_interface_profile=dict(
            type='str', aliases=['leaf_interface_profile_name'
                                 ]),  # Not required for querying all objects
        access_port_selector=dict(type='str',
                                  aliases=[
                                      'name', 'access_port_selector_name'
                                  ]),  # Not required for querying all objects
        leaf_port_blk=dict(type='str', aliases=[
            'leaf_port_blk_name'
        ]),  # Not required for querying all objects
        leaf_port_blk_description=dict(type='str'),
        from_port=dict(
            type='str', aliases=['from', 'fromPort', 'from_port_range']
        ),  # Not required for querying all objects and deleting port blocks
        to_port=dict(type='str', aliases=[
            'to', 'toPort', 'to_port_range'
        ]),  # Not required for querying all objects and deleting port blocks
        from_card=dict(type='str', aliases=['from_card_range']),
        to_card=dict(type='str', aliases=['to_card_range']),
        state=dict(type='str',
                   default='present',
                   choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            [
                'state', 'absent',
                [
                    'access_port_selector', 'leaf_port_blk',
                    'leaf_interface_profile'
                ]
            ],
            [
                'state', 'present',
                [
                    'access_port_selector', 'leaf_port_blk', 'from_port',
                    'to_port', 'leaf_interface_profile'
                ]
            ],
        ],
    )

    leaf_interface_profile = module.params['leaf_interface_profile']
    access_port_selector = module.params['access_port_selector']
    leaf_port_blk = module.params['leaf_port_blk']
    leaf_port_blk_description = module.params['leaf_port_blk_description']
    from_port = module.params['from_port']
    to_port = module.params['to_port']
    from_card = module.params['from_card']
    to_card = module.params['to_card']
    state = module.params['state']

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class='infraAccPortP',
            aci_rn='infra/accportprof-{0}'.format(leaf_interface_profile),
            module_object=leaf_interface_profile,
            target_filter={'name': leaf_interface_profile},
        ),
        subclass_1=dict(
            aci_class='infraHPortS',
            # NOTE: normal rn: hports-{name}-typ-{type}, hence here hardcoded to range for purposes of module
            aci_rn='hports-{0}-typ-range'.format(access_port_selector),
            module_object=access_port_selector,
            target_filter={'name': access_port_selector},
        ),
        subclass_2=dict(
            aci_class='infraPortBlk',
            aci_rn='portblk-{0}'.format(leaf_port_blk),
            module_object=leaf_port_blk,
            target_filter={'name': leaf_port_blk},
        ),
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='infraPortBlk',
            class_config=dict(
                descr=leaf_port_blk_description,
                name=leaf_port_blk,
                fromPort=from_port,
                toPort=to_port,
                fromCard=from_card,
                toCard=to_card,
                #  type='range',
            ),
        )

        aci.get_diff(aci_class='infraPortBlk')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
Exemple #15
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        tenant=dict(type='str',
                    aliases=['tenant_name'
                             ]),  # Not required for querying all objects
        ap=dict(type='str',
                aliases=['app_profile', 'app_profile_name'
                         ]),  # Not required for querying all objects
        epg=dict(type='str',
                 aliases=['epg_name'
                          ]),  # Not required for querying all objects
        description=dict(type='str', aliases=['descr']),
        encap_id=dict(type='int', aliases=['vlan', 'vlan_id']),
        primary_encap_id=dict(type='int',
                              aliases=['primary_vlan', 'primary_vlan_id']),
        deploy_immediacy=dict(type='str', choices=['immediate', 'lazy']),
        interface_mode=dict(type='str',
                            choices=[
                                '802.1p', 'access', 'native', 'regular',
                                'tagged', 'trunk', 'untagged'
                            ],
                            aliases=['interface_mode_name', 'mode']),
        interface_type=dict(
            type='str',
            default='switch_port',
            choices=['fex', 'port_channel', 'switch_port', 'vpc']),
        pod_id=dict(type='int',
                    aliases=['pod', 'pod_number'
                             ]),  # Not required for querying all objects
        leafs=dict(type='list',
                   aliases=['leaves', 'nodes', 'paths', 'switches']),
        interface=dict(type='str'),
        extpaths=dict(type='int'),
        state=dict(type='str',
                   default='present',
                   choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['interface_type', 'fex', ['extpaths']],
            [
                'state', 'absent',
                ['ap', 'epg', 'interface', 'leafs', 'pod_id', 'tenant']
            ],
            [
                'state', 'present',
                [
                    'ap', 'encap_id', 'epg', 'interface', 'leafs', 'pod_id',
                    'tenant'
                ]
            ],
        ],
    )

    tenant = module.params['tenant']
    ap = module.params['ap']
    epg = module.params['epg']
    description = module.params['description']
    encap_id = module.params['encap_id']
    primary_encap_id = module.params['primary_encap_id']
    deploy_immediacy = module.params['deploy_immediacy']
    interface_mode = module.params['interface_mode']
    interface_type = module.params['interface_type']
    pod_id = module.params['pod_id']
    leafs = module.params['leafs']
    if leafs is not None:
        # Users are likely to use integers for leaf IDs, which would raise an exception when using the join method
        leafs = [str(leaf) for leaf in module.params['leafs']]
        if len(leafs) == 1:
            if interface_type != 'vpc':
                leafs = leafs[0]
            else:
                module.fail_json(
                    msg='A interface_type of "vpc" requires 2 leafs')
        elif len(leafs) == 2:
            if interface_type == 'vpc':
                leafs = "-".join(leafs)
            else:
                module.fail_json(
                    msg=
                    'The interface_types "switch_port", "port_channel", and "fex" \
                    do not support using multiple leafs for a single binding')
        else:
            module.fail_json(
                msg='The "leafs" parameter must not have more than 2 entries')
    interface = module.params['interface']
    extpaths = module.params['extpaths']
    state = module.params['state']
    static_path = ''

    if encap_id is not None:
        if encap_id in range(1, 4097):
            encap_id = 'vlan-{0}'.format(encap_id)
        else:
            module.fail_json(msg='Valid VLAN assigments are from 1 to 4096')

    if primary_encap_id is not None:
        if primary_encap_id in range(1, 4097):
            primary_encap_id = 'vlan-{0}'.format(primary_encap_id)
        else:
            module.fail_json(msg='Valid VLAN assigments are from 1 to 4096')

    INTERFACE_MODE_MAPPING = {
        '802.1p': 'native',
        'access': 'untagged',
        'native': 'native',
        'regular': 'regular',
        'tagged': 'regular',
        'trunk': 'regular',
        'untagged': 'untagged',
    }

    INTERFACE_TYPE_MAPPING = dict(
        fex='topology/pod-{0}/paths-{1}/extpaths-{2}/pathep-[eth{3}]'.format(
            pod_id, leafs, extpaths, interface),
        port_channel='topology/pod-{0}/paths-{1}/pathep-[{2}]'.format(
            pod_id, leafs, interface),
        switch_port='topology/pod-{0}/paths-{1}/pathep-[eth{2}]'.format(
            pod_id, leafs, interface),
        vpc='topology/pod-{0}/protpaths-{1}/pathep-[{2}]'.format(
            pod_id, leafs, interface),
    )

    static_path = INTERFACE_TYPE_MAPPING[interface_type]
    if interface_mode is not None:
        interface_mode = INTERFACE_MODE_MAPPING[interface_mode]

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class='fvTenant',
            aci_rn='tn-{0}'.format(tenant),
            filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
            module_object=tenant,
        ),
        subclass_1=dict(
            aci_class='fvAp',
            aci_rn='ap-{0}'.format(ap),
            filter_target='eq(fvAp.name, "{0}")'.format(ap),
            module_object=ap,
        ),
        subclass_2=dict(
            aci_class='fvAEPg',
            aci_rn='epg-{0}'.format(epg),
            filter_target='eq(fvAEPg.name, "{0}")'.format(epg),
            module_object=epg,
        ),
        subclass_3=dict(
            aci_class='fvRsPathAtt',
            aci_rn='rspathAtt-[{0}]'.format(static_path),
            filter_target='eq(fvRsPathAtt.tDn, "{0}"'.format(static_path),
            module_object=static_path,
        ),
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='fvRsPathAtt',
            class_config=dict(
                descr=description,
                encap=encap_id,
                primaryEncap=primary_encap_id,
                instrImedcy=deploy_immediacy,
                mode=interface_mode,
                tDn=static_path,
            ),
        )

        aci.get_diff(aci_class='fvRsPathAtt')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        domain=dict(type='str', aliases=['domain_name', 'domain_profile']),
        domain_type=dict(type='str', choices=['fc', 'l2dom', 'l3dom', 'phys', 'vmm']),
        pool=dict(type='str', aliases=['pool_name']),
        pool_allocation_mode=dict(type='str', aliases=['allocation_mode', 'mode'], choices=['dynamic', 'static']),
        pool_type=dict(type='str', required=True, choices=['vlan', 'vsan', 'vxlan']),
        state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
        vm_provider=dict(type='str', choices=['cloudfoundry', 'kubernetes', 'microsoft', 'openshift', 'openstack', 'redhat', 'vmware']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['domain_type', 'vmm', ['vm_provider']],
            ['state', 'absent', ['domain', 'domain_type', 'pool', 'pool_type']],
            ['state', 'present', ['domain', 'domain_type', 'pool', 'pool_type']],
        ],
    )

    domain = module.params['domain']
    domain_type = module.params['domain_type']
    pool = module.params['pool']
    pool_allocation_mode = module.params['pool_allocation_mode']
    pool_type = module.params['pool_type']
    vm_provider = module.params['vm_provider']
    state = module.params['state']

    # Report when vm_provider is set when type is not virtual
    if domain_type != 'vmm' and vm_provider is not None:
        module.fail_json(msg="Domain type '{0}' cannot have a 'vm_provider'".format(domain_type))

    # ACI Pool URL requires the allocation mode for vlan and vsan pools (ex: uni/infra/vlanns-[poolname]-static)
    pool_name = pool
    if pool_type != 'vxlan' and pool is not None:
        if pool_allocation_mode is not None:
            pool_name = '[{0}]-{1}'.format(pool, pool_allocation_mode)
        else:
            module.fail_json(msg="ACI requires the 'pool_allocation_mode' for 'pool_type' of 'vlan' and 'vsan' when 'pool' is provided")

    # Vxlan pools do not support allocation modes
    if pool_type == 'vxlan' and pool_allocation_mode is not None:
        module.fail_json(msg='vxlan pools do not support setting the allocation_mode; please remove this parameter from the task')

    # Compile the full domain for URL building
    if domain_type == 'fc':
        domain_class = 'fcDomP'
        domain_mo = 'uni/fc-{0}'.format(domain)
        domain_rn = 'fc-{0}'.format(domain)
    elif domain_type == 'l2ext':
        domain_class = 'l2extDomP'
        domain_mo = 'uni/l2dom-{0}'.format(domain)
        domain_rn = 'l2dom-{0}'.format(domain)
    elif domain_type == 'l3ext':
        domain_class = 'l3extDomP'
        domain_mo = 'uni/l3dom-{0}'.format(domain)
        domain_rn = 'l3dom-{0}'.format(domain)
    elif domain_type == 'phys':
        domain_class = 'physDomP'
        domain_mo = 'uni/phys-{0}'.format(domain)
        domain_rn = 'phys-{0}'.format(domain)
    elif domain_type == 'vmm':
        domain_class = 'vmmDomP'
        domain_mo = 'uni/vmmp-{0}/dom-{1}'.format(VM_PROVIDER_MAPPING[vm_provider], domain)
        domain_rn = 'vmmp-{0}/dom-{1}'.format(VM_PROVIDER_MAPPING[vm_provider], domain)

    # Ensure that querying all objects works when only domain_type is provided
    if domain is None:
        domain_mo = None

    pool_mo = POOL_MAPPING[pool_type]['aci_mo'].format(pool_name)
    child_class = POOL_MAPPING[pool_type]['child_class']

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class=domain_class,
            aci_rn=domain_rn,
            filter_target='eq({0}.name, "{1}")'.format(domain_class, domain),
            module_object=domain_mo,
        ),
        child_classes=[child_class],
    )

    aci.get_existing()

    if state == 'present':
        # Filter out module params with null values
        aci.payload(
            aci_class=domain_class,
            class_config=dict(name=domain),
            child_configs=[
                {child_class: {'attributes': {'tDn': pool_mo}}},
            ]
        )

        # Generate config diff which will be used as POST request body
        aci.get_diff(aci_class=domain_class)

        # Submit changes if module not in check_mode and the proposed is different than existing
        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
Exemple #17
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        bd=dict(type='str',
                aliases=['bd_name', 'bridge_domain'
                         ]),  # Not required for querying all objects
        l3out=dict(type='str'),  # Not required for querying all objects
        state=dict(type='str',
                   default='present',
                   choices=['absent', 'present', 'query']),
        tenant=dict(type='str',
                    aliases=['tenant_name'
                             ]),  # Not required for querying all objects
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_together=[['gateway', 'mask']],
        required_if=[
            ['state', 'present', ['bd', 'l3out', 'tenant']],
            ['state', 'absent', ['bd', 'l3out', 'tenant']],
        ],
    )

    bd = module.params['bd']
    l3out = module.params['l3out']
    state = module.params['state']
    tenant = module.params['tenant']

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class='fvTenant',
            aci_rn='tn-{0}'.format(tenant),
            module_object=tenant,
            target_filter={'name': tenant},
        ),
        subclass_1=dict(
            aci_class='fvBD',
            aci_rn='BD-{0}'.format(bd),
            module_object=bd,
            target_filter={'name': bd},
        ),
        subclass_2=dict(
            aci_class='fvRsBDToOut',
            aci_rn='rsBDToOut-{0}'.format(l3out),
            module_object=l3out,
            target_filter={'tnL3extOutName': l3out},
        ),
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='fvRsBDToOut',
            class_config=dict(tnL3extOutName=l3out),
        )

        aci.get_diff(aci_class='fvRsBDToOut')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        compare_export_policy=dict(type='str'),
        compare_snapshot=dict(type='str'),
        description=dict(type='str', aliases=['descr']),
        export_policy=dict(type='str'),
        fail_on_decrypt=dict(type='bool'),
        import_mode=dict(type='str', choices=['atomic', 'best-effort']),
        import_policy=dict(type='str'),
        import_type=dict(type='str', choices=['merge', 'replace']),
        snapshot=dict(type='str', required=True),
        state=dict(type='str', default='rollback', choices=['preview', 'rollback']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=False,
        required_if=[
            ['state', 'preview', ['compare_export_policy', 'compare_snapshot']],
            ['state', 'rollback', ['import_policy']],
        ],
    )

    aci = ACIModule(module)

    description = module.params['description']
    export_policy = module.params['export_policy']
    fail_on_decrypt = aci.boolean(module.params['fail_on_decrypt'])
    import_mode = module.params['import_mode']
    import_policy = module.params['import_policy']
    import_type = module.params['import_type']
    snapshot = module.params['snapshot']
    state = module.params['state']

    if state == 'rollback':
        if snapshot.startswith('run-'):
            snapshot = snapshot.replace('run-', '', 1)

        if not snapshot.endswith('.tar.gz'):
            snapshot += '.tar.gz'

        filename = 'ce2_{0}-{1}'.format(export_policy, snapshot)

        aci.construct_url(
            root_class=dict(
                aci_class='configImportP',
                aci_rn='fabric/configimp-{0}'.format(import_policy),
                filter_target='eq(configImportP.name, "{0}")'.format(import_policy),
                module_object=import_policy,
            ),
        )

        aci.get_existing()

        aci.payload(
            aci_class='configImportP',
            class_config=dict(
                adminSt='triggered',
                descr=description,
                failOnDecryptErrors=fail_on_decrypt,
                fileName=filename,
                importMode=import_mode,
                importType=import_type,
                name=import_policy,
                snapshot='yes',
            ),
        )

        aci.get_diff(aci_class='configImportP')

        aci.post_config()

    elif state == 'preview':
        aci.url = '%(protocol)s://%(host)s/mqapi2/snapshots.diff.xml' % module.params
        aci.filter_string = (
            '?s1dn=uni/backupst/snapshots-[uni/fabric/configexp-%(export_policy)s]/snapshot-%(snapshot)s&'
            's2dn=uni/backupst/snapshots-[uni/fabric/configexp-%(compare_export_policy)s]/snapshot-%(compare_snapshot)s'
        ) % module.params

        # Generate rollback comparison
        get_preview(aci)

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        description=dict(type='str', aliases=['descr']),
        pool=dict(type='str', aliases=['name', 'pool_name']),  # Not required for querying all objects
        pool_allocation_mode=dict(type='str', aliases=['allocation_mode', 'mode'], choices=['dynamic', 'static']),
        pool_type=dict(type='str', aliases=['type'], choices=['vlan', 'vxlan', 'vsan'], required=True),
        state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['pool']],
            ['state', 'present', ['pool']],
        ],
    )

    description = module.params['description']
    pool = module.params['pool']
    pool_type = module.params['pool_type']
    pool_allocation_mode = module.params['pool_allocation_mode']
    state = module.params['state']

    aci_class = ACI_MAPPING[pool_type]["aci_class"]
    aci_mo = ACI_MAPPING[pool_type]["aci_mo"]
    pool_name = pool

    # ACI Pool URL requires the pool_allocation mode for vlan and vsan pools (ex: uni/infra/vlanns-[poolname]-static)
    if pool_type != 'vxlan' and pool is not None:
        if pool_allocation_mode is not None:
            pool_name = '[{0}]-{1}'.format(pool, pool_allocation_mode)
        else:
            module.fail_json(msg="ACI requires parameter 'pool_allocation_mode' for 'pool_type' of 'vlan' and 'vsan' when parameter 'pool' is provided")

    # Vxlan pools do not support pool allocation modes
    if pool_type == 'vxlan' and pool_allocation_mode is not None:
        module.fail_json(msg="vxlan pools do not support setting the 'pool_allocation_mode'; please remove this parameter from the task")

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class=aci_class,
            aci_rn='{0}{1}'.format(aci_mo, pool_name),
            filter_target='eq({0}.name, "{1}")'.format(aci_class, pool),
            module_object=pool,
        ),
    )

    aci.get_existing()

    if state == 'present':
        # Filter out module parameters with null values
        aci.payload(
            aci_class=aci_class,
            class_config=dict(
                allocMode=pool_allocation_mode,
                descr=description,
                name=pool,
            )
        )

        # Generate config diff which will be used as POST request body
        aci.get_diff(aci_class=aci_class)

        # Submit changes if module not in check_mode and the proposed is different than existing
        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
Exemple #20
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        contract=dict(type='str', required=False, aliases=['contract_name', 'name']),  # Not required for querying all objects
        tenant=dict(type='str', required=False, aliases=['tenant_name']),  # Not required for querying all objects
        description=dict(type='str', aliases=['descr']),
        scope=dict(type='str', choices=['application-profile', 'context', 'global', 'tenant']),
        priority=dict(type='str', choices=['level1', 'level2', 'level3', 'unspecified']),  # No default provided on purpose
        dscp=dict(type='str',
                  choices=['AF11', 'AF12', 'AF13', 'AF21', 'AF22', 'AF23', 'AF31', 'AF32', 'AF33', 'AF41', 'AF42', 'AF43',
                           'CS0', 'CS1', 'CS2', 'CS3', 'CS4', 'CS5', 'CS6', 'CS7', 'EF', 'VA', 'unspecified'],
                  aliases=['target']),  # No default provided on purpose
        state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['contract', 'tenant']],
            ['state', 'present', ['contract', 'tenant']],
        ],
    )

    contract = module.params['contract']
    description = module.params['description']
    scope = module.params['scope']
    priority = module.params['priority']
    dscp = module.params['dscp']
    state = module.params['state']
    tenant = module.params['tenant']

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class='fvTenant',
            aci_rn='tn-{0}'.format(tenant),
            filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
            module_object=tenant,
        ),
        subclass_1=dict(
            aci_class='vzBrCP',
            aci_rn='brc-{0}'.format(contract),
            filter_target='eq(vzBrCP.name, "{0}")'.format(contract),
            module_object=contract,
        ),
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='vzBrCP',
            class_config=dict(
                name=contract,
                descr=description,
                scope=scope,
                prio=priority,
                targetDscp=dscp,
            ),
        )

        aci.get_diff(aci_class='vzBrCP')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
Exemple #21
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        aaa_password=dict(type='str', no_log=True),
        aaa_password_lifetime=dict(type='int'),
        aaa_password_update_required=dict(type='bool'),
        aaa_user=dict(type='str', required=True, aliases=['name']),  # Not required for querying all objects
        clear_password_history=dict(type='bool'),
        description=dict(type='str', aliases=['descr']),
        email=dict(type='str'),
        enabled=dict(type='bool'),
        expiration=dict(type='str'),
        expires=dict(type='bool'),
        first_name=dict(type='str'),
        last_name=dict(type='str'),
        phone=dict(type='str'),
        state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['aaa_user']],
            ['state', 'present', ['aaa_user']],
            ['expires', True, ['expiration']],
        ],
    )

    aci = ACIModule(module)

    if not HAS_DATEUTIL:
        module.fail_json(msg='dateutil required for this module')

    aaa_password = module.params['aaa_password']
    aaa_password_lifetime = module.params['aaa_password_lifetime']
    aaa_password_update_required = aci.boolean(module.params['aaa_password_update_required'])
    aaa_user = module.params['aaa_user']
    clear_password_history = module.params['clear_password_history']
    description = module.params['description']
    email = module.params['email']
    enabled = aci.boolean(module.params['enabled'], 'active', 'inactive')
    expires = aci.boolean(module.params['expires'])
    first_name = module.params['first_name']
    last_name = module.params['last_name']
    phone = module.params['phone']
    state = module.params['state']

    expiration = module.params['expiration']
    if expiration is not None and expiration != 'never':
        try:
            expiration = aci.iso8601_format(dateutil.parser.parse(expiration).replace(tzinfo=tzutc()))
        except Exception as e:
            module.fail_json(msg="Failed to parse date format '%s', %s" % (module.params['expiration'], e))

    aci.construct_url(
        root_class=dict(
            aci_class='aaaUser',
            aci_rn='userext/user-{0}'.format(aaa_user),
            filter_target='eq(aaaUser.name, "{0}")'.format(aaa_user),
            module_object=aaa_user,
        ),
    )
    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='aaaUser',
            class_config=dict(
                accountStatus=enabled,
                clearPwdHistory=clear_password_history,
                email=email,
                expiration=expiration,
                expires=expires,
                firstName=first_name,
                lastName=last_name,
                name=aaa_user,
                phone=phone,
                pwd=aaa_password,
                pwdLifeTime=aaa_password_lifetime,
                pwdUpdateRequired=aaa_password_update_required,
            ),
        )

        aci.get_diff(aci_class='aaaUser')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update({
        'description': dict(type='str'),
        'leaf_profile': dict(type='str', aliases=['leaf_profile_name']),  # Not required for querying all objects
        'leaf': dict(type='str', aliases=['name', 'leaf_name', 'leaf_profile_leaf_name', 'leaf_selector_name']),  # Not required for querying all objects
        'leaf_node_blk': dict(type='str', aliases=['leaf_node_blk_name', 'node_blk_name']),
        'leaf_node_blk_description': dict(type='str'),
        # NOTE: Keyword 'from' is a reserved word in python, so we need it as a string
        'from': dict(type='int', aliases=['node_blk_range_from', 'from_range', 'range_from']),
        'to': dict(type='int', aliases=['node_blk_range_to', 'to_range', 'range_to']),
        'policy_group': dict(type='str', aliases=['policy_group_name']),
        'state': dict(type='str', default='present', choices=['absent', 'present', 'query']),
    })

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['leaf_profile', 'leaf']],
            ['state', 'present', ['leaf_profile', 'leaf', 'leaf_node_blk', 'from', 'to']]
        ]
    )

    description = module.params['description']
    leaf_profile = module.params['leaf_profile']
    leaf = module.params['leaf']
    leaf_node_blk = module.params['leaf_node_blk']
    leaf_node_blk_description = module.params['leaf_node_blk_description']
    from_ = module.params['from']
    to_ = module.params['to']
    policy_group = module.params['policy_group']
    state = module.params['state']

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class='infraNodeP',
            aci_rn='infra/nprof-{0}'.format(leaf_profile),
            filter_target='eq(infraNodeP.name, "{0}")'.format(leaf_profile),
            module_object=leaf_profile
        ),
        subclass_1=dict(
            aci_class='infraLeafS',
            # NOTE: normal rn: leaves-{name}-typ-{type}, hence here hardcoded to range for purposes of module
            aci_rn='leaves-{0}-typ-range'.format(leaf),
            filter_target='eq(infraLeafS.name, "{0}")'.format(leaf),
            module_object=leaf,
        ),
        # NOTE: infraNodeBlk is not made into a subclass because there is a 1-1 mapping between node block and leaf selector name
        child_classes=['infraNodeBlk', 'infraRsAccNodePGrp'],

    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='infraLeafS',
            class_config=dict(
                descr=description,
                name=leaf,
            ),
            child_configs=[
                dict(
                    infraNodeBlk=dict(
                        attributes=dict(
                            descr=leaf_node_blk_description,
                            name=leaf_node_blk,
                            from_=from_,
                            to_=to_,
                        ),
                    ),
                ),
                dict(
                    infraRsAccNodePGrp=dict(
                        attributes=dict(
                            tDn='uni/infra/funcprof/accnodepgrp-{0}'.format(policy_group),
                        ),
                    ),
                ),
            ],
        )

        aci.get_diff(aci_class='infraLeafS')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        description=dict(type='str', aliases=['descr']),
        export_policy=dict(type='str', aliases=['name']),  # Not required for querying all objects
        format=dict(type='str', choices=['json', 'xml']),
        include_secure=dict(type='bool'),
        max_count=dict(type='int'),
        snapshot=dict(type='str'),
        state=dict(type='str', choices=['absent', 'present', 'query'], default='present'),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=False,
        required_if=[
            ['state', 'absent', ['export_policy', 'snapshot']],
            ['state', 'present', ['export_policy']],
        ],
    )

    aci = ACIModule(module)

    description = module.params['description']
    export_policy = module.params['export_policy']
    file_format = module.params['format']
    include_secure = aci.boolean(module.params['include_secure'])
    max_count = module.params['max_count']
    if max_count is not None:
        if max_count in range(1, 11):
            max_count = str(max_count)
        else:
            module.fail_json(msg="Parameter 'max_count' must be a number between 1 and 10")
    snapshot = module.params['snapshot']
    if snapshot is not None and not snapshot.startswith('run-'):
        snapshot = 'run-' + snapshot
    state = module.params['state']

    if state == 'present':
        aci.construct_url(
            root_class=dict(
                aci_class='configExportP',
                aci_rn='fabric/configexp-{0}'.format(export_policy),
                filter_target='eq(configExportP.name, "{0}")'.format(export_policy),
                module_object=export_policy,
            ),
        )

        aci.get_existing()

        aci.payload(
            aci_class='configExportP',
            class_config=dict(
                adminSt='triggered',
                descr=description,
                format=file_format,
                includeSecureFields=include_secure,
                maxSnapshotCount=max_count,
                name=export_policy,
                snapshot='yes',
            ),
        )

        aci.get_diff('configExportP')

        # Create a new Snapshot
        aci.post_config()

    else:
        # Prefix the proper url to export_policy
        if export_policy is not None:
            export_policy = 'uni/fabric/configexp-{0}'.format(export_policy)

        aci.construct_url(
            root_class=dict(
                aci_class='configSnapshotCont',
                aci_rn='backupst/snapshots-[{0}]'.format(export_policy),
                filter_target='(configSnapshotCont.name, "{0}")'.format(export_policy),
                module_object=export_policy,
            ),
            subclass_1=dict(
                aci_class='configSnapshot',
                aci_rn='snapshot-{0}'.format(snapshot),
                filter_target='eq(configSnapshot.name, "{0}")'.format(snapshot),
                module_object=snapshot,
            ),
        )

        aci.get_existing()

        if state == 'absent':
            # Build POST request to used to remove Snapshot
            aci.payload(
                aci_class='configSnapshot',
                class_config=dict(
                    name=snapshot,
                    retire="yes",
                ),
            )

            if aci.existing:
                aci.get_diff('configSnapshot')

                # Mark Snapshot for Deletion
                aci.post_config()

    aci.exit_json()
Exemple #24
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        description=dict(type='str', aliases=['descr']),
        pool=dict(type='str', aliases=['name', 'pool_name']),  # Not required for querying all objects
        pool_allocation_mode=dict(type='str', aliases=['allocation_mode', 'mode'], choices=['dynamic', 'static']),
        state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['pool']],
            ['state', 'present', ['pool']],
        ],
    )

    description = module.params['description']
    pool = module.params['pool']
    pool_allocation_mode = module.params['pool_allocation_mode']
    state = module.params['state']

    pool_name = pool

    # ACI Pool URL requires the allocation mode for vlan and vsan pools (ex: uni/infra/vlanns-[poolname]-static)
    if pool is not None:
        if pool_allocation_mode is not None:
            pool_name = '[{0}]-{1}'.format(pool, pool_allocation_mode)
        else:
            module.fail_json(msg="ACI requires the 'pool_allocation_mode' when 'pool' is provided")

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class='fvnsVlanInstP',
            aci_rn='infra/vlanns-{0}'.format(pool_name),
            filter_target='eq(fvnsVlanInstP.name, "{0}")'.format(pool),
            module_object=pool,
        ),
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='fvnsVlanInstP',
            class_config=dict(
                allocMode=pool_allocation_mode,
                descr=description,
                name=pool,
            ),
        )

        aci.get_diff(aci_class='fvnsVlanInstP')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        protection_group=dict(type='str', aliases=['name', 'protection_group_name']),  # Not required for querying all objects
        protection_group_id=dict(type='int', aliases=['id']),
        vpc_domain_policy=dict(type='str', aliases=['vpc_domain_policy_name']),
        switch_1_id=dict(type='int'),
        switch_2_id=dict(type='int'),
        state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['protection_group']],
            ['state', 'present', ['protection_group', 'protection_group_id', 'switch_1_id', 'switch_2_id']],
        ],
    )

    protection_group = module.params['protection_group']
    protection_group_id = module.params['protection_group_id']
    vpc_domain_policy = module.params['vpc_domain_policy']
    switch_1_id = module.params['switch_1_id']
    switch_2_id = module.params['switch_2_id']
    state = module.params['state']

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class='fabricExplicitGEp',
            aci_rn='fabric/protpol/expgep-{0}'.format(protection_group),
            filter_target='eq(fabricExplicitGEp.name, "{0}")'.format(protection_group),
            module_object=protection_group,
        ),
        child_classes=['fabricNodePEp', 'fabricNodePEp', 'fabricRsVpcInstPol'],
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='fabricExplicitGEp',
            class_config=dict(
                name=protection_group,
                id=protection_group_id,
                rn='expgep-{0}'.format(protection_group),
            ),
            child_configs=[
                dict(
                    fabricNodePEp=dict(
                        attributes=dict(
                            id='{0}'.format(switch_1_id),
                            rn='nodepep-{0}'.format(switch_1_id),
                        ),
                    ),
                ),
                dict(
                    fabricNodePEp=dict(
                        attributes=dict(
                            id='{0}'.format(switch_2_id),
                            rn='nodepep-{0}'.format(switch_2_id),
                        ),
                    ),
                ),
                dict(
                    fabricRsVpcInstPol=dict(
                        attributes=dict(
                            tnVpcInstPolName=vpc_domain_policy,
                        ),
                    ),
                ),
            ],
        )

        aci.get_diff(aci_class='fabricExplicitGEp')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        tenant=dict(type='str', aliases=['tenant_name']),  # Not required for querying all objects
        ap=dict(type='str', aliases=['app_profile', 'app_profile_name']),  # Not required for querying all objects
        epg=dict(type='str', aliases=['epg_name']),  # Not required for querying all objects
        encap_id=dict(type='int', aliases=['vlan', 'vlan_id']),
        primary_encap_id=dict(type='int', aliases=['primary_vlan', 'primary_vlan_id']),
        deploy_immediacy=dict(type='str', choices=['immediate', 'lazy']),
        interface_mode=dict(type='str', choices=['802.1p', 'access', 'native', 'regular', 'tagged', 'trunk', 'untagged'],
                            aliases=['interface_mode_name', 'mode']),
        interface_type=dict(type='str', default='switch_port', choices=['fex', 'port_channel', 'switch_port', 'vpc']),
        pod_id=dict(type='int', aliases=['pod', 'pod_number']),  # Not required for querying all objects
        leafs=dict(type='list', aliases=['leaves', 'nodes', 'paths', 'switches']),
        interface=dict(type='str'),
        extpaths=dict(type='int'),
        state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['interface_type', 'fex', ['extpaths']],
            ['state', 'absent', ['ap', 'epg', 'interface', 'leafs', 'pod_id', 'tenant']],
            ['state', 'present', ['ap', 'encap_id', 'epg', 'interface', 'leafs', 'pod_id', 'tenant']],
        ],
    )

    tenant = module.params['tenant']
    ap = module.params['ap']
    epg = module.params['epg']
    encap_id = module.params['encap_id']
    primary_encap_id = module.params['primary_encap_id']
    deploy_immediacy = module.params['deploy_immediacy']
    interface_mode = module.params['interface_mode']
    interface_type = module.params['interface_type']
    pod_id = module.params['pod_id']
    # Users are likely to use integers for leaf IDs, which would raise an exception when using the join method
    leafs = [str(leaf) for leaf in module.params['leafs']]
    if leafs is not None:
        if len(leafs) == 1:
            if interface_type != 'vpc':
                leafs = leafs[0]
            else:
                module.fail_json(msg='A interface_type of "vpc" requires 2 leafs')
        elif len(leafs) == 2:
            if interface_type == 'vpc':
                leafs = "-".join(leafs)
            else:
                module.fail_json(msg='The interface_types "switch_port", "port_channel", and "fex" \
                    do not support using multiple leafs for a single binding')
        else:
            module.fail_json(msg='The "leafs" parameter must not have more than 2 entries')
    interface = module.params['interface']
    extpaths = module.params['extpaths']
    state = module.params['state']
    static_path = ''

    if encap_id is not None:
        if encap_id in range(1, 4097):
            encap_id = 'vlan-{0}'.format(encap_id)
        else:
            module.fail_json(msg='Valid VLAN assigments are from 1 to 4096')

    if primary_encap_id is not None:
        if primary_encap_id in range(1, 4097):
            primary_encap_id = 'vlan-{0}'.format(primary_encap_id)
        else:
            module.fail_json(msg='Valid VLAN assigments are from 1 to 4096')

    INTERFACE_MODE_MAPPING = {
        '802.1p': 'native',
        'access': 'untagged',
        'native': 'native',
        'regular': 'regular',
        'tagged': 'regular',
        'trunk': 'regular',
        'untagged': 'untagged',
    }

    INTERFACE_TYPE_MAPPING = dict(
        fex='topology/pod-{0}/paths-{1}/extpaths-{2}/pathep-[eth{3}]'.format(pod_id, leafs, extpaths, interface),
        port_channel='topology/pod-{0}/paths-{1}/pathep-[eth{2}]'.format(pod_id, leafs, interface),
        switch_port='topology/pod-{0}/paths-{1}/pathep-[eth{2}]'.format(pod_id, leafs, interface),
        vpc='topology/pod-{0}/protpaths-{1}/pathep-[{2}]'.format(pod_id, leafs, interface),
    )

    static_path = INTERFACE_TYPE_MAPPING[interface_type]
    if interface_mode is not None:
        interface_mode = INTERFACE_MODE_MAPPING[interface_mode]

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class='fvTenant',
            aci_rn='tn-{0}'.format(tenant),
            filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
            module_object=tenant,
        ),
        subclass_1=dict(
            aci_class='fvAp',
            aci_rn='ap-{0}'.format(ap),
            filter_target='eq(fvAp.name, "{0}")'.format(ap),
            module_object=ap,
        ),
        subclass_2=dict(
            aci_class='fvAEPg',
            aci_rn='epg-{0}'.format(epg),
            filter_target='eq(fvAEPg.name, "{0}")'.format(epg),
            module_object=epg,
        ),
        subclass_3=dict(
            aci_class='fvRsPathAtt',
            aci_rn='rspathAtt-[{0}]'.format(static_path),
            filter_target='eq(fvRsPathAtt.tDn, "{0}"'.format(static_path),
            module_object=static_path,
        ),
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='fvRsPathAtt',
            class_config=dict(
                encap=encap_id,
                primaryEncap=primary_encap_id,
                instrImedcy=deploy_immediacy,
                mode=interface_mode,
                tDn=static_path,
            ),
        )

        aci.get_diff(aci_class='fvRsPathAtt')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
Exemple #27
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        epg=dict(type='str', aliases=['epg_name', 'name']),  # Not required for querying all objects
        bd=dict(type='str', aliases=['bd_name', 'bridge_domain']),
        ap=dict(type='str', aliases=['app_profile', 'app_profile_name']),  # Not required for querying all objects
        tenant=dict(type='str', aliases=['tenant_name']),  # Not required for querying all objects
        description=dict(type='str', aliases=['descr']),
        priority=dict(type='str', choices=['level1', 'level2', 'level3', 'unspecified']),
        intra_epg_isolation=dict(choices=['enforced', 'unenforced']),
        fwd_control=dict(type='str', choices=['none', 'proxy-arp']),
        preferred_group=dict(type='bool'),
        state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['ap', 'epg', 'tenant']],
            ['state', 'present', ['ap', 'epg', 'tenant']],
        ],
    )

    aci = ACIModule(module)

    epg = module.params['epg']
    bd = module.params['bd']
    description = module.params['description']
    priority = module.params['priority']
    intra_epg_isolation = module.params['intra_epg_isolation']
    fwd_control = module.params['fwd_control']
    preferred_group = aci.boolean(module.params['preferred_group'], 'include', 'exclude')
    state = module.params['state']
    tenant = module.params['tenant']
    ap = module.params['ap']

    aci.construct_url(
        root_class=dict(
            aci_class='fvTenant',
            aci_rn='tn-{0}'.format(tenant),
            filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
            module_object=tenant,
        ),
        subclass_1=dict(
            aci_class='fvAp',
            aci_rn='ap-{0}'.format(ap),
            filter_target='eq(fvAp.name, "{0}")'.format(ap),
            module_object=ap,
        ),
        subclass_2=dict(
            aci_class='fvAEPg',
            aci_rn='epg-{0}'.format(epg),
            filter_target='eq(fvAEPg.name, "{0}")'.format(epg),
            module_object=epg,
        ),
        child_classes=['fvRsBd'],
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='fvAEPg',
            class_config=dict(
                name=epg,
                descr=description,
                prio=priority,
                pcEnfPref=intra_epg_isolation,
                fwdCtrl=fwd_control,
                prefGrMemb=preferred_group,
            ),
            child_configs=[
                dict(fvRsBd=dict(attributes=dict(tnFvBDName=bd))),
            ],
        )

        aci.get_diff(aci_class='fvAEPg')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        certificate=dict(type='str', aliases=['cert_data',
                                              'certificate_data']),
        certificate_name=dict(type='str', aliases=['cert_name']),
        state=dict(type='str',
                   default='present',
                   choices=['absent', 'present', 'query']),
        user=dict(type='str', required=True),
        user_type=dict(type='str', default='user', choices=['appuser',
                                                            'user']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['user', 'certificate_name']],
            ['state', 'present', ['user', 'certificate', 'certificate_name']],
        ],
    )

    certificate = module.params['certificate']
    certificate_name = module.params['certificate_name']
    state = module.params['state']
    user = module.params['user']
    user_type = module.params['user_type']

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class=ACI_MAPPING[user_type]['aci_class'],
            aci_rn=ACI_MAPPING[user_type]['aci_mo'] + user,
            filter_target='eq({0}.name, "{1}")'.format(
                ACI_MAPPING[user_type]['aci_class'], user),
            module_object=user,
        ),
        subclass_1=dict(
            aci_class='aaaUserCert',
            aci_rn='usercert-{0}'.format(certificate_name),
            filter_target='eq(aaaUserCert.name, "{0}")'.format(
                certificate_name),
            module_object=certificate_name,
        ),
    )
    aci.get_existing()

    if state == 'present':
        # Filter out module params with null values
        aci.payload(
            aci_class='aaaUserCert',
            class_config=dict(
                data=certificate,
                name=certificate_name,
            ),
        )

        # Generate config diff which will be used as POST request body
        aci.get_diff(aci_class='aaaUserCert')

        # Submit changes if module not in check_mode and the proposed is different than existing
        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    module.exit_json(**aci.result)
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        description=dict(type='str', aliases=['descr']),
        dst_group=dict(type='str'),  # Not required for querying all objects
        src_group=dict(type='str'),  # Not required for querying all objects
        state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
        tenant=dict(type='str', aliases=['tenant_name']),  # Not required for querying all objects
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['dst_group', 'src_group', 'tenant']],
            ['state', 'present', ['dst_group', 'src_group', 'tenant']],
        ],
    )

    description = module.params['description']
    dst_group = module.params['dst_group']
    src_group = module.params['src_group']
    state = module.params['state']
    tenant = module.params['tenant']

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class='fvTenant',
            aci_rn='tn-{0}'.format(tenant),
            filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
            module_object=tenant,
        ),
        subclass_1=dict(
            aci_class='spanSrcGrp',
            aci_rn='srcgrp-{0}'.format(src_group),
            filter_target='eq(spanSrcGrp.name, "{0}")'.format(src_group),
            module_object=src_group,
        ),
        subclass_2=dict(
            aci_class='spanSpanLbl',
            aci_rn='spanlbl-{0}'.format(dst_group),
            filter_target='eq(spanSpanLbl.name, "{0}")'.format(dst_group),
            module_object=dst_group,
        ),
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='spanSpanLbl',
            class_config=dict(
                descr=description,
                name=dst_group,
            ),
        )

        aci.get_diff(aci_class='spanSpanLbl')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
Exemple #30
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        description=dict(type='str', aliases=['descr']),
        pool=dict(type='str', aliases=['name', 'pool_name']),  # Not required for querying all objects
        pool_allocation_mode=dict(type='str', aliases=['allocation_mode', 'mode'], choices=['dynamic', 'static']),
        state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['pool']],
            ['state', 'present', ['pool']],
        ],
    )

    description = module.params['description']
    pool = module.params['pool']
    pool_allocation_mode = module.params['pool_allocation_mode']
    state = module.params['state']

    pool_name = pool

    # ACI Pool URL requires the allocation mode for vlan and vsan pools (ex: uni/infra/vlanns-[poolname]-static)
    if pool is not None:
        if pool_allocation_mode is not None:
            pool_name = '[{0}]-{1}'.format(pool, pool_allocation_mode)
        else:
            module.fail_json(msg="ACI requires the 'pool_allocation_mode' when 'pool' is provided")

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class='fvnsVlanInstP',
            aci_rn='infra/vlanns-{0}'.format(pool_name),
            module_object=pool,
            target_filter={'name': pool},
        ),
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='fvnsVlanInstP',
            class_config=dict(
                allocMode=pool_allocation_mode,
                descr=description,
                name=pool,
            ),
        )

        aci.get_diff(aci_class='fvnsVlanInstP')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        name=dict(type='str',
                  aliases=['maintenance_policy'
                           ]),  # Not required for querying all objects
        runmode=dict(type='str',
                     default='pauseOnlyOnFailures',
                     choices=['pauseOnlyOnFailures', 'pauseNever']),
        graceful=dict(type='bool'),
        scheduler=dict(type='str'),
        ignoreCompat=dict(type='bool'),
        adminst=dict(type='str',
                     default='untriggered',
                     choices=['triggered', 'untriggered']),
        state=dict(type='str',
                   default='present',
                   choices=['absent', 'present', 'query']),
        name_alias=dict(type='str'),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['name']],
            ['state', 'present', ['name', 'scheduler']],
        ],
    )

    aci = ACIModule(module)

    state = module.params.get('state')
    name = module.params.get('name')
    runmode = module.params.get('runmode')
    scheduler = module.params.get('scheduler')
    adminst = module.params.get('adminst')
    graceful = aci.boolean(module.params.get('graceful'))
    ignoreCompat = aci.boolean(module.params.get('ignoreCompat'))
    name_alias = module.params.get('name_alias')

    aci.construct_url(root_class=dict(
        aci_class='maintMaintP',
        aci_rn='fabric/maintpol-{0}'.format(name),
        target_filter={'name': name},
        module_object=name,
    ),
                      child_classes=['maintRsPolScheduler'])

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='maintMaintP',
            class_config=dict(
                name=name,
                runMode=runmode,
                graceful=graceful,
                adminSt=adminst,
                ignoreCompat=ignoreCompat,
                nameAlias=name_alias,
            ),
            child_configs=[
                dict(maintRsPolScheduler=dict(attributes=dict(
                    tnTrigSchedPName=scheduler, ), ), ),
            ],
        )

        aci.get_diff(aci_class='maintMaintP')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        protection_group=dict(type='str', aliases=['name', 'protection_group_name']),
        protection_group_id=dict(type='int', aliases=['id']),
        vpc_domain_policy=dict(type='str', aliases=['vpc_domain_policy_name']),
        switch_1_id=dict(type='int'),
        switch_2_id=dict(type='int'),
        state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['protection_group']],
            ['state', 'present', ['protection_group', 'protection_group_id', 'switch_1_id', 'switch_2_id']],
        ],
    )

    protection_group = module.params['protection_group']
    protection_group_id = module.params['protection_group_id']
    vpc_domain_policy = module.params['vpc_domain_policy']
    switch_1_id = module.params['switch_1_id']
    switch_2_id = module.params['switch_2_id']
    state = module.params['state']

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class='fabricExplicitGEp',
            aci_rn='fabric/protpol/expgep-{0}'.format(protection_group),
            filter_target='eq(fabricExplicitGEp.name, "{0}")'.format(protection_group),
            module_object=protection_group
        ),
        child_classes=['fabricNodePEp', 'fabricNodePEp', 'fabricRsVpcInstPol']
    )

    aci.get_existing()

    if state == 'present':
        # Filter out module parameters with null values
        aci.payload(
            aci_class='fabricExplicitGEp',
            class_config=dict(
                dn='uni/fabric/protpol/expgep-{0}'.format(protection_group),
                name=protection_group,
                id=protection_group_id,
                rn='expgep-{0}'.format(protection_group),
            ),
            child_configs=[
                dict(
                    fabricNodePEp=dict(
                        attributes=dict(
                            dn='uni/fabric/protpol/expgep-{0}/nodepep-{1}'.format(protection_group, switch_1_id),
                            id='{0}'.format(switch_1_id),
                            rn='nodepep-{0}'.format(switch_1_id),
                        )
                    )
                ),
                dict(
                    fabricNodePEp=dict(
                        attributes=dict(
                            dn='uni/fabric/protpol/expgep-{0}/nodepep-{1}'.format(protection_group, switch_2_id),
                            id='{0}'.format(switch_2_id),
                            rn='nodepep-{0}'.format(switch_2_id),
                        )
                    )
                ),
                dict(
                    fabricRsVpcInstPol=dict(
                        attributes=dict(
                            tnVpcInstPolName=vpc_domain_policy,
                        )
                    )
                ),
            ]
        )

        # Generate config diff which will be used as POST request body
        aci.get_diff(aci_class='fabricExplicitGEp')

        # Submit changes if module not in check_mode and the proposed is different than existing
        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
Exemple #33
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        allocation_mode=dict(type='str',
                             aliases=['mode'],
                             choices=['dynamic', 'inherit', 'static']),
        description=dict(type='str', aliases=['descr']),
        pool=dict(type='str',
                  aliases=['pool_name'
                           ]),  # Not required for querying all objects
        pool_allocation_mode=dict(type='str',
                                  aliases=['pool_mode'],
                                  choices=['dynamic', 'static']),
        block_name=dict(type='str',
                        aliases=['name'
                                 ]),  # Not required for querying all objects
        block_end=dict(type='int',
                       aliases=['end'
                                ]),  # Not required for querying all objects
        block_start=dict(type='int',
                         aliases=["start"
                                  ]),  # Not required for querying all objects
        state=dict(type='str',
                   default='present',
                   choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            [
                'state', 'absent',
                ['pool', 'block_end', 'block_name', 'block_start']
            ],
            [
                'state', 'present',
                ['pool', 'block_end', 'block_name', 'block_start']
            ],
        ],
    )

    allocation_mode = module.params['allocation_mode']
    description = module.params['description']
    pool = module.params['pool']
    pool_allocation_mode = module.params['pool_allocation_mode']
    block_end = module.params['block_end']
    block_name = module.params['block_name']
    block_start = module.params['block_start']
    state = module.params['state']

    if block_end is not None:
        encap_end = 'vlan-{0}'.format(block_end)
    else:
        encap_end = None

    if block_start is not None:
        encap_start = 'vlan-{0}'.format(block_start)
    else:
        encap_start = None

    # Collect proper mo information
    aci_block_mo = 'from-[{0}]-to-[{1}]'.format(encap_start, encap_end)
    pool_name = pool

    # Validate block_end and block_start are valid for its respective encap type
    for encap_id in block_end, block_start:
        if encap_id is not None:
            if not 1 <= encap_id <= 4094:
                module.fail_json(
                    msg=
                    "vlan pools must have 'block_start' and 'block_end' values between 1 and 4094"
                )

    # Build proper proper filter_target based on block_start, block_end, and block_name
    if block_end is not None and block_start is not None:
        # Validate block_start is less than block_end
        if block_start > block_end:
            module.fail_json(
                msg=
                "The 'block_start' must be less than or equal to the 'block_end'"
            )

        if block_name is None:
            block_filter_target = 'and(eq({0}.from, "{1}"),eq({0}.to, "{2}"))'.format(
                'fvnsEncapBlk', encap_start, encap_end)
        else:
            block_filter_target = 'and(eq({0}.from, "{1}"),eq({0}.to, "{2}"),eq({0}.name, "{3}"))'.format(
                'fvnsEncapBlk', encap_start, encap_end, block_name)
    elif block_end is None and block_start is None:
        if block_name is None:
            # Reset range managed object to None for aci util to properly handle query
            aci_block_mo = None
            block_filter_target = ''
        else:
            block_filter_target = 'eq({0}.name, "{1}")'.format(
                'fvnsEncapBlk', block_name)
    elif block_start is not None:
        if block_name is None:
            block_filter_target = 'eq({0}.from, "{1}")'.format(
                'fvnsEncapBlk', encap_start)
        else:
            block_filter_target = 'and(eq({0}.from, "{1}"),eq({0}.name, "{2}"))'.format(
                'fvnsEncapBlk', encap_start, block_name)
    else:
        if block_name is None:
            block_filter_target = 'eq({0}.to, "{1}")'.format(
                'fvnsEncapBlk', encap_end)
        else:
            block_filter_target = 'and(eq({0}.to, "{1}"),eq({0}.name, "{2}"))'.format(
                'fvnsEncapBlk', encap_end, block_name)

    # ACI Pool URL requires the allocation mode (ex: uni/infra/vlanns-[poolname]-static)
    if pool is not None:
        if pool_allocation_mode is not None:
            pool_name = '[{0}]-{1}'.format(pool, pool_allocation_mode)
        else:
            module.fail_json(
                msg=
                "ACI requires the 'pool_allocation_mode' when 'pool' is provided"
            )

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class='fvnsVlanInstP',
            aci_rn='infra/vlanns-{0}'.format(pool_name),
            filter_target='eq(fvnsVlanInstP.name, "{0}")'.format(pool),
            module_object=pool,
        ),
        subclass_1=dict(
            aci_class='fvnsEncapBlk',
            aci_rn=aci_block_mo,
            filter_target=block_filter_target,
            module_object=aci_block_mo,
        ),
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='fvnsEncapBlk',
            class_config={
                "allocMode": allocation_mode,
                "descr": description,
                "from": encap_start,
                "name": block_name,
                "to": encap_end,
            },
        )

        aci.get_diff(aci_class='fvnsEncapBlk')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
Exemple #34
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        allocation_mode=dict(type='str',
                             aliases=['mode'],
                             choices=['dynamic', 'static']),
        description=dict(type='str', aliases=['descr']),
        pool=dict(type='str', aliases=['name', 'pool_name']),
        pool_type=dict(type='str',
                       aliases=['type'],
                       choices=['vlan', 'vxlan', 'vsan'],
                       required=True),
        state=dict(type='str',
                   default='present',
                   choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['pool']],
            ['state', 'present', ['pool']],
        ],
    )

    allocation_mode = module.params['allocation_mode']
    description = module.params['description']
    pool = module.params['pool']
    pool_type = module.params['pool_type']
    state = module.params['state']

    aci_class = ACI_MAPPING[pool_type]["aci_class"]
    aci_mo = ACI_MAPPING[pool_type]["aci_mo"]
    pool_name = pool

    # ACI Pool URL requires the allocation mode for vlan and vsan pools (ex: uni/infra/vlanns-[poolname]-static)
    if pool_type != 'vxlan' and pool is not None:
        if allocation_mode is not None:
            pool_name = '[{0}]-{1}'.format(pool, allocation_mode)
        else:
            module.fail_json(
                msg=
                'ACI requires the "allocation_mode" for "pool_type" of "vlan" and "vsan" when the "pool" is provided'
            )

    # Vxlan pools do not support allocation modes
    if pool_type == 'vxlan' and allocation_mode is not None:
        module.fail_json(
            msg=
            'vxlan pools do not support setting the allocation_mode; please remove this parameter from the task'
        )

    aci = ACIModule(module)
    aci.construct_url(root_class=dict(
        aci_class=aci_class,
        aci_rn='{0}{1}'.format(aci_mo, pool_name),
        filter_target='eq({0}.name, "{1}")'.format(aci_class, pool),
        module_object=pool,
    ), )

    aci.get_existing()

    if state == 'present':
        # Filter out module parameters with null values
        aci.payload(aci_class=aci_class,
                    class_config=dict(
                        allocMode=allocation_mode,
                        descr=description,
                        name=pool,
                    ))

        # Generate config diff which will be used as POST request body
        aci.get_diff(aci_class=aci_class)

        # Submit changes if module not in check_mode and the proposed is different than existing
        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    module.exit_json(**aci.result)
Exemple #35
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        dst_group=dict(type='str', required=False,
                       aliases=['name'
                                ]),  # Not required for querying all objects
        tenant=dict(type='str', required=False,
                    aliases=['tenant_name'
                             ]),  # Not required for querying all objects
        description=dict(type='str', aliases=['descr']),
        state=dict(type='str',
                   default='present',
                   choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['dst_group', 'tenant']],
            ['state', 'present', ['dst_group', 'tenant']],
        ],
    )

    dst_group = module.params['dst_group']
    description = module.params['description']
    state = module.params['state']
    tenant = module.params['tenant']

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class='fvTenant',
            aci_rn='tn-{0}'.format(tenant),
            module_object=tenant,
            target_filter={'name': tenant},
        ),
        subclass_1=dict(
            aci_class='spanDestGrp',
            aci_rn='destgrp-{0}'.format(dst_group),
            module_object=dst_group,
            target_filter={'name': dst_group},
        ),
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='spanDestGrp',
            class_config=dict(
                name=dst_group,
                descr=description,
            ),
        )

        aci.get_diff(aci_class='spanDestGrp')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
Exemple #36
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        tenant=dict(type='str',
                    aliases=['tenant_name'
                             ]),  # not required for querying all EPRs
        epr_policy=dict(type='str', aliases=['epr_name', 'name']),
        bounce_age=dict(type='int'),
        bounce_trigger=dict(type='str', choices=['coop', 'flood']),
        hold_interval=dict(type='int'),
        local_ep_interval=dict(type='int'),
        remote_ep_interval=dict(type='int'),
        description=dict(type='str', aliases=['descr']),
        move_frequency=dict(type='int'),
        state=dict(type='str',
                   default='present',
                   choices=['absent', 'present', 'query']),
        method=dict(type='str',
                    choices=['delete', 'get', 'post'],
                    aliases=['action'],
                    removed_in_version='2.6'),  # Deprecated starting from v2.6
        protocol=dict(type='str',
                      removed_in_version='2.6'),  # Deprecated in v2.6
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['epr_policy', 'tenant']],
            ['state', 'present', ['epr_policy', 'tenant']],
        ],
    )

    epr_policy = module.params['epr_policy']
    bounce_age = module.params['bounce_age']
    if bounce_age is not None and bounce_age != 0 and bounce_age not in range(
            150, 65536):
        module.fail_json(
            msg="The bounce_age must be a value of 0 or between 150 and 65535")
    if bounce_age == 0:
        bounce_age = 'infinite'
    bounce_trigger = module.params['bounce_trigger']
    if bounce_trigger is not None:
        bounce_trigger = BOUNCE_TRIG_MAPPING[bounce_trigger]
    description = module.params['description']
    hold_interval = module.params['hold_interval']
    if hold_interval is not None and hold_interval not in range(5, 65536):
        module.fail_json(
            msg="The hold_interval must be a value between 5 and 65535")
    local_ep_interval = module.params['local_ep_interval']
    if local_ep_interval is not None and local_ep_interval != 0 and local_ep_interval not in range(
            120, 65536):
        module.fail_json(
            msg=
            "The local_ep_interval must be a value of 0 or between 120 and 65535"
        )
    if local_ep_interval == 0:
        local_ep_interval = "infinite"
    move_frequency = module.params['move_frequency']
    if move_frequency is not None and move_frequency not in range(65536):
        module.fail_json(
            msg="The move_frequency must be a value between 0 and 65535")
    if move_frequency == 0:
        move_frequency = "none"
    remote_ep_interval = module.params['remote_ep_interval']
    if remote_ep_interval is not None and remote_ep_interval not in range(
            120, 65536):
        module.fail_json(
            msg=
            "The remote_ep_interval must be a value of 0 or between 120 and 65535"
        )
    if remote_ep_interval == 0:
        remote_ep_interval = "infinite"
    state = module.params['state']
    tenant = module.params['tenant']

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class='fvTenant',
            aci_rn='tn-{0}'.format(tenant),
            filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
            module_object=tenant,
        ),
        subclass_1=dict(
            aci_class='fvEpRetPol',
            aci_rn='epRPol-{0}'.format(epr_policy),
            filter_target='eq(fvEpRetPol.name, "{0}")'.format(epr_policy),
            module_object=epr_policy,
        ),
    )

    aci.get_existing()

    if state == 'present':
        # filter out module parameters with null values
        aci.payload(
            aci_class='fvEpRetPol',
            class_config=dict(
                name=epr_policy,
                descr=description,
                bounceAgeIntvl=bounce_age,
                bounceTrig=bounce_trigger,
                holdIntvl=hold_interval,
                localEpAgeIntvl=local_ep_interval,
                remoteEpAgeIntvl=remote_ep_interval,
                moveFreq=move_frequency,
            ),
        )

        # Generate config diff which will be used as POST request body
        aci.get_diff(aci_class='fvEpRetPol')

        # Submit changes if module not in check_mode and the proposed is different than existing
        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
Exemple #37
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        source=dict(type='str',
                    aliases=['name', 'source_name'
                             ]),  # Not required for querying all objects
        polling_interval=dict(type='int'),
        url=dict(type='str'),
        url_username=dict(type='str'),
        url_password=dict(type='str', no_log=True),
        url_protocol=dict(type='str',
                          default='scp',
                          choices=['http', 'local', 'scp', 'usbkey'],
                          aliases=['url_proto']),
        state=dict(type='str',
                   default='present',
                   choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['source']],
            ['state', 'present', ['url_protocol', 'source', 'url']],
        ],
    )

    polling_interval = module.params['polling_interval']
    url_protocol = module.params['url_protocol']
    state = module.params['state']
    source = module.params['source']
    url = module.params['url']
    url_password = module.params['url_password']
    url_username = module.params['url_username']

    aci = ACIModule(module)
    aci.construct_url(root_class=dict(
        aci_class='firmwareOSource',
        aci_rn='fabric/fwrepop',
        module_object=source,
        target_filter={'name': source},
    ), )
    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='firmwareOSource',
            class_config=dict(
                name=source,
                url=url,
                password=url_password,
                pollingInterval=polling_interval,
                proto=url_protocol,
                user=url_username,
            ),
        )

        aci.get_diff(aci_class='firmwareOSource')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
Exemple #38
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update({
        'description': dict(type='str'),
        'leaf_profile': dict(type='str', aliases=['leaf_profile_name']),  # Not required for querying all objects
        'leaf': dict(type='str', aliases=['name', 'leaf_name', 'leaf_profile_leaf_name', 'leaf_selector_name']),  # Not required for querying all objects
        'leaf_node_blk': dict(type='str', aliases=['leaf_node_blk_name', 'node_blk_name']),
        'leaf_node_blk_description': dict(type='str'),
        # NOTE: Keyword 'from' is a reserved word in python, so we need it as a string
        'from': dict(type='int', aliases=['node_blk_range_from', 'from_range', 'range_from']),
        'to': dict(type='int', aliases=['node_blk_range_to', 'to_range', 'range_to']),
        'policy_group': dict(type='str', aliases=['policy_group_name']),
        'state': dict(type='str', default='present', choices=['absent', 'present', 'query']),
    })

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['leaf_profile', 'leaf']],
            ['state', 'present', ['leaf_profile', 'leaf', 'leaf_node_blk', 'from', 'to']]
        ]
    )

    description = module.params['description']
    leaf_profile = module.params['leaf_profile']
    leaf = module.params['leaf']
    leaf_node_blk = module.params['leaf_node_blk']
    leaf_node_blk_description = module.params['leaf_node_blk_description']
    from_ = module.params['from']
    to_ = module.params['to']
    policy_group = module.params['policy_group']
    state = module.params['state']

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class='infraNodeP',
            aci_rn='infra/nprof-{0}'.format(leaf_profile),
            module_object=leaf_profile,
            target_filter={'name': leaf_profile},
        ),
        subclass_1=dict(
            aci_class='infraLeafS',
            # NOTE: normal rn: leaves-{name}-typ-{type}, hence here hardcoded to range for purposes of module
            aci_rn='leaves-{0}-typ-range'.format(leaf),
            module_object=leaf,
            target_filter={'name': leaf},
        ),
        # NOTE: infraNodeBlk is not made into a subclass because there is a 1-1 mapping between node block and leaf selector name
        child_classes=['infraNodeBlk', 'infraRsAccNodePGrp'],

    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='infraLeafS',
            class_config=dict(
                descr=description,
                name=leaf,
            ),
            child_configs=[
                dict(
                    infraNodeBlk=dict(
                        attributes=dict(
                            descr=leaf_node_blk_description,
                            name=leaf_node_blk,
                            from_=from_,
                            to_=to_,
                        ),
                    ),
                ),
                dict(
                    infraRsAccNodePGrp=dict(
                        attributes=dict(
                            tDn='uni/infra/funcprof/accnodepgrp-{0}'.format(policy_group),
                        ),
                    ),
                ),
            ],
        )

        aci.get_diff(aci_class='infraLeafS')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        compare_export_policy=dict(type='str'),
        compare_snapshot=dict(type='str'),
        description=dict(type='str', aliases=['descr']),
        export_policy=dict(type='str'),
        fail_on_decrypt=dict(type='bool'),
        import_mode=dict(type='str', choices=['atomic', 'best-effort']),
        import_policy=dict(type='str'),
        import_type=dict(type='str', choices=['merge', 'replace']),
        snapshot=dict(type='str', required=True),
        state=dict(type='str',
                   default='rollback',
                   choices=['preview', 'rollback']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=False,
        required_if=[
            [
                'state', 'preview',
                ['compare_export_policy', 'compare_snapshot']
            ],
            ['state', 'rollback', ['import_policy']],
        ],
    )

    description = module.params['description']
    export_policy = module.params['export_policy']
    fail_on_decrypt = module.params['fail_on_decrypt']
    if fail_on_decrypt is True:
        fail_on_decrypt = 'yes'
    elif fail_on_decrypt is False:
        fail_on_decrypt = 'no'
    import_mode = module.params['import_mode']
    import_policy = module.params['import_policy']
    import_type = module.params['import_type']
    snapshot = module.params['snapshot']
    state = module.params['state']

    aci = ACIModule(module)

    if state == 'rollback':
        if snapshot.startswith('run-'):
            snapshot = snapshot.replace('run-', '', 1)

        if not snapshot.endswith('.tar.gz'):
            snapshot += '.tar.gz'

        filename = 'ce2_{0}-{1}'.format(export_policy, snapshot)

        aci.construct_url(root_class=dict(
            aci_class='configImportP',
            aci_rn='fabric/configimp-{0}'.format(import_policy),
            filter_target='eq(configImportP.name, "{0}")'.format(
                import_policy),
            module_object=import_policy,
        ), )

        aci.get_existing()

        # Filter out module parameters with null values
        aci.payload(
            aci_class='configImportP',
            class_config=dict(
                adminSt='triggered',
                descr=description,
                failOnDecryptErrors=fail_on_decrypt,
                fileName=filename,
                importMode=import_mode,
                importType=import_type,
                name=import_policy,
                snapshot='yes',
            ),
        )

        # Generate config diff which will be used as POST request body
        aci.get_diff(aci_class='configImportP')

        # Submit changes if module not in check_mode and the proposed is different than existing
        aci.post_config()

    elif state == 'preview':
        aci.result[
            'url'] = '%(protocol)s://%(host)s/mqapi2/snapshots.diff.xml' % module.params
        aci.result['filter_string'] = (
            '?s1dn=uni/backupst/snapshots-[uni/fabric/configexp-%(export_policy)s]/snapshot-%(snapshot)s&'
            's2dn=uni/backupst/snapshots-[uni/fabric/configexp-%(compare_export_policy)s]/snapshot-%(compare_snapshot)s'
        ) % module.params

        # Generate rollback comparison
        get_preview(aci)

    module.exit_json(**aci.result)
Exemple #40
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        domain=dict(type='str', aliases=['domain_name', 'domain_profile']),
        domain_type=dict(type='str',
                         choices=['fc', 'l2dom', 'l3dom', 'phys', 'vmm']),
        pool=dict(type='str', aliases=['pool_name']),
        pool_allocation_mode=dict(type='str',
                                  aliases=['allocation_mode', 'mode'],
                                  choices=['dynamic', 'static']),
        pool_type=dict(type='str',
                       required=True,
                       choices=['vlan', 'vsan', 'vxlan']),
        state=dict(type='str',
                   default='present',
                   choices=['absent', 'present', 'query']),
        vm_provider=dict(type='str',
                         choices=[
                             'cloudfoundry', 'kubernetes', 'microsoft',
                             'openshift', 'openstack', 'redhat', 'vmware'
                         ]),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['domain_type', 'vmm', ['vm_provider']],
            [
                'state', 'absent',
                ['domain', 'domain_type', 'pool', 'pool_type']
            ],
            [
                'state', 'present',
                ['domain', 'domain_type', 'pool', 'pool_type']
            ],
        ],
    )

    domain = module.params['domain']
    domain_type = module.params['domain_type']
    pool = module.params['pool']
    pool_allocation_mode = module.params['pool_allocation_mode']
    pool_type = module.params['pool_type']
    vm_provider = module.params['vm_provider']
    state = module.params['state']

    # Report when vm_provider is set when type is not virtual
    if domain_type != 'vmm' and vm_provider is not None:
        module.fail_json(msg="Domain type '{0}' cannot have a 'vm_provider'".
                         format(domain_type))

    # ACI Pool URL requires the allocation mode for vlan and vsan pools (ex: uni/infra/vlanns-[poolname]-static)
    pool_name = pool
    if pool_type != 'vxlan' and pool is not None:
        if pool_allocation_mode is not None:
            pool_name = '[{0}]-{1}'.format(pool, pool_allocation_mode)
        else:
            module.fail_json(
                msg=
                "ACI requires the 'pool_allocation_mode' for 'pool_type' of 'vlan' and 'vsan' when 'pool' is provided"
            )

    # Vxlan pools do not support allocation modes
    if pool_type == 'vxlan' and pool_allocation_mode is not None:
        module.fail_json(
            msg=
            'vxlan pools do not support setting the allocation_mode; please remove this parameter from the task'
        )

    # Compile the full domain for URL building
    if domain_type == 'fc':
        domain_class = 'fcDomP'
        domain_mo = 'uni/fc-{0}'.format(domain)
        domain_rn = 'fc-{0}'.format(domain)
    elif domain_type == 'l2ext':
        domain_class = 'l2extDomP'
        domain_mo = 'uni/l2dom-{0}'.format(domain)
        domain_rn = 'l2dom-{0}'.format(domain)
    elif domain_type == 'l3ext':
        domain_class = 'l3extDomP'
        domain_mo = 'uni/l3dom-{0}'.format(domain)
        domain_rn = 'l3dom-{0}'.format(domain)
    elif domain_type == 'phys':
        domain_class = 'physDomP'
        domain_mo = 'uni/phys-{0}'.format(domain)
        domain_rn = 'phys-{0}'.format(domain)
    elif domain_type == 'vmm':
        domain_class = 'vmmDomP'
        domain_mo = 'uni/vmmp-{0}/dom-{1}'.format(
            VM_PROVIDER_MAPPING[vm_provider], domain)
        domain_rn = 'vmmp-{0}/dom-{1}'.format(VM_PROVIDER_MAPPING[vm_provider],
                                              domain)

    # Ensure that querying all objects works when only domain_type is provided
    if domain is None:
        domain_mo = None

    pool_mo = POOL_MAPPING[pool_type]['aci_mo'].format(pool_name)
    child_class = POOL_MAPPING[pool_type]['child_class']

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class=domain_class,
            aci_rn=domain_rn,
            module_object=domain_mo,
            target_filter={'name': domain},
        ),
        child_classes=[child_class],
    )

    aci.get_existing()

    if state == 'present':
        # Filter out module params with null values
        aci.payload(aci_class=domain_class,
                    class_config=dict(name=domain),
                    child_configs=[
                        {
                            child_class: {
                                'attributes': {
                                    'tDn': pool_mo
                                }
                            }
                        },
                    ])

        # Generate config diff which will be used as POST request body
        aci.get_diff(aci_class=domain_class)

        # Submit changes if module not in check_mode and the proposed is different than existing
        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
Exemple #41
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        bd=dict(type='str',
                aliases=['bd_name']),  # Not required for querying all objects
        description=dict(type='str', aliases=['descr']),
        enable_vip=dict(type='bool'),
        gateway=dict(type='str',
                     aliases=['gateway_ip'
                              ]),  # Not required for querying all objects
        mask=dict(type='int',
                  aliases=['subnet_mask'
                           ]),  # Not required for querying all objects
        subnet_name=dict(type='str', aliases=['name']),
        nd_prefix_policy=dict(type='str'),
        preferred=dict(type='bool'),
        route_profile=dict(type='str'),
        route_profile_l3_out=dict(type='str'),
        scope=dict(type='list', choices=['private', 'public', 'shared']),
        subnet_control=dict(
            type='str',
            choices=['nd_ra', 'no_gw', 'querier_ip', 'unspecified']),
        state=dict(type='str',
                   default='present',
                   choices=['absent', 'present', 'query']),
        tenant=dict(type='str',
                    aliases=['tenant_name'
                             ]),  # Not required for querying all objects
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_together=[['gateway', 'mask']],
        required_if=[
            ['state', 'present', ['bd', 'gateway', 'mask', 'tenant']],
            ['state', 'absent', ['bd', 'gateway', 'mask', 'tenant']],
        ],
    )

    aci = ACIModule(module)

    description = module.params['description']
    enable_vip = aci.boolean(module.params['enable_vip'])
    tenant = module.params['tenant']
    bd = module.params['bd']
    gateway = module.params['gateway']
    mask = module.params['mask']
    if mask is not None and mask not in range(0, 129):
        # TODO: split checkes between IPv4 and IPv6 Addresses
        module.fail_json(
            msg=
            'Valid Subnet Masks are 0 to 32 for IPv4 Addresses and 0 to 128 for IPv6 addresses'
        )
    if gateway is not None:
        gateway = '{0}/{1}'.format(gateway, str(mask))
    subnet_name = module.params['subnet_name']
    nd_prefix_policy = module.params['nd_prefix_policy']
    preferred = aci.boolean(module.params['preferred'])
    route_profile = module.params['route_profile']
    route_profile_l3_out = module.params['route_profile_l3_out']
    scope = module.params['scope']
    if scope is not None:
        if 'private' in scope and 'public' in scope:
            module.fail_json(
                msg=
                "Parameter 'scope' cannot be both 'private' and 'public', got: %s"
                % scope)
        else:
            scope = ','.join(sorted(scope))
    state = module.params['state']
    subnet_control = module.params['subnet_control']
    if subnet_control:
        subnet_control = SUBNET_CONTROL_MAPPING[subnet_control]

    aci.construct_url(
        root_class=dict(
            aci_class='fvTenant',
            aci_rn='tn-{0}'.format(tenant),
            filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
            module_object=tenant,
        ),
        subclass_1=dict(
            aci_class='fvBD',
            aci_rn='BD-{0}'.format(bd),
            filter_target='eq(fvBD.name, "{0}")'.format(bd),
            module_object=bd,
        ),
        subclass_2=dict(
            aci_class='fvSubnet',
            aci_rn='subnet-[{0}]'.format(gateway),
            filter_target='eq(fvSubnet.ip, "{0}")'.format(gateway),
            module_object=gateway,
        ),
        child_classes=['fvRsBDSubnetToProfile', 'fvRsNdPfxPol'],
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='fvSubnet',
            class_config=dict(
                ctrl=subnet_control,
                descr=description,
                ip=gateway,
                name=subnet_name,
                preferred=preferred,
                scope=scope,
                virtual=enable_vip,
            ),
            child_configs=[
                {
                    'fvRsBDSubnetToProfile': {
                        'attributes': {
                            'tnL3extOutName': route_profile_l3_out,
                            'tnRtctrlProfileName': route_profile
                        }
                    }
                },
                {
                    'fvRsNdPfxPol': {
                        'attributes': {
                            'tnNdPfxPolName': nd_prefix_policy
                        }
                    }
                },
            ],
        )

        aci.get_diff(aci_class='fvSubnet')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
Exemple #42
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        description=dict(type='str', aliases=['descr']),
        node_id=dict(type='int'),  # Not required for querying all objects
        pod_id=dict(type='int'),
        role=dict(type='str',
                  choices=['leaf', 'spine', 'unspecified'],
                  aliases=['role_name']),
        serial=dict(type='str',
                    aliases=['serial_number'
                             ]),  # Not required for querying all objects
        switch=dict(type='str', aliases=['name', 'switch_name']),
        state=dict(type='str',
                   default='present',
                   choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['node_id', 'serial']],
            ['state', 'present', ['node_id', 'serial']],
        ],
    )

    pod_id = module.params.get('pod_id')
    serial = module.params.get('serial')
    node_id = module.params.get('node_id')
    switch = module.params.get('switch')
    description = module.params.get('description')
    role = module.params.get('role')
    state = module.params.get('state')

    aci = ACIModule(module)
    aci.construct_url(root_class=dict(
        aci_class='fabricNodeIdentP',
        aci_rn='controller/nodeidentpol/nodep-{0}'.format(serial),
        module_object=serial,
        target_filter={'serial': serial},
    ))

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='fabricNodeIdentP',
            class_config=dict(
                descr=description,
                name=switch,
                nodeId=node_id,
                podId=pod_id,
                # NOTE: Originally we were sending 'rn', but now we need 'dn' for idempotency
                # FIXME: Did this change with ACI version ?
                dn='uni/controller/nodeidentpol/nodep-{0}'.format(serial),
                # rn='nodep-{0}'.format(serial),
                role=role,
                serial=serial,
            ))

        aci.get_diff(aci_class='fabricNodeIdentP')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json(**aci.result)
Exemple #43
0
def main():
    argument_spec = aci_argument_spec
    argument_spec.update(
        dst_group=dict(type='str', required=False,
                       aliases=['name'
                                ]),  # Not required for querying all objects
        tenant=dict(type='str', required=False,
                    aliases=['tenant_name'
                             ]),  # Not required for querying all objects
        description=dict(type='str', aliases=['descr']),
        state=dict(type='str',
                   default='present',
                   choices=['absent', 'present', 'query']),
        method=dict(type='str',
                    choices=['delete', 'get', 'post'],
                    aliases=['action'],
                    removed_in_version='2.6'),  # Deprecated starting from v2.6
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['dst_group', 'tenant']],
            ['state', 'present', ['dst_group', 'tenant']],
        ],
    )

    dst_group = module.params['dst_group']
    description = module.params['description']
    state = module.params['state']
    tenant = module.params['tenant']

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class='fvTenant',
            aci_rn='tn-{}'.format(tenant),
            filter_target='(fvTenant.name, "{}")'.format(tenant),
            module_object=tenant,
        ),
        subclass_1=dict(
            aci_class='spanDestGrp',
            aci_rn='destgrp-{}'.format(dst_group),
            filter_target='(spanDestGrp.name, "{}")'.format(dst_group),
            module_object=dst_group,
        ),
    )

    aci.get_existing()

    if state == 'present':
        # Filter out module parameters with null values
        aci.payload(
            aci_class='spanDestGrp',
            class_config=dict(
                name=dst_group,
                descr=description,
            ),
        )

        # Generate config diff which will be used as POST request body
        aci.get_diff(aci_class='spanDestGrp')

        # Submit changes if module not in check_mode and the proposed is different than existing
        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    module.exit_json(**aci.result)
Exemple #44
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        epg=dict(type='str',
                 aliases=['epg_name',
                          'name']),  # Not required for querying all objects
        bd=dict(type='str', aliases=['bd_name', 'bridge_domain']),
        ap=dict(type='str',
                aliases=['app_profile', 'app_profile_name'
                         ]),  # Not required for querying all objects
        tenant=dict(type='str',
                    aliases=['tenant_name'
                             ]),  # Not required for querying all objects
        description=dict(type='str', aliases=['descr']),
        priority=dict(type='str',
                      choices=['level1', 'level2', 'level3', 'unspecified']),
        intra_epg_isolation=dict(choices=['enforced', 'unenforced']),
        fwd_control=dict(type='str', choices=['none', 'proxy-arp']),
        preferred_group=dict(type='bool'),
        state=dict(type='str',
                   default='present',
                   choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['ap', 'epg', 'tenant']],
            ['state', 'present', ['ap', 'epg', 'tenant']],
        ],
    )

    aci = ACIModule(module)

    epg = module.params['epg']
    bd = module.params['bd']
    description = module.params['description']
    priority = module.params['priority']
    intra_epg_isolation = module.params['intra_epg_isolation']
    fwd_control = module.params['fwd_control']
    preferred_group = aci.boolean(module.params['preferred_group'], 'include',
                                  'exclude')
    state = module.params['state']
    tenant = module.params['tenant']
    ap = module.params['ap']

    aci.construct_url(
        root_class=dict(
            aci_class='fvTenant',
            aci_rn='tn-{0}'.format(tenant),
            module_object=tenant,
            target_filter={'name': tenant},
        ),
        subclass_1=dict(
            aci_class='fvAp',
            aci_rn='ap-{0}'.format(ap),
            module_object=ap,
            target_filter={'name': ap},
        ),
        subclass_2=dict(
            aci_class='fvAEPg',
            aci_rn='epg-{0}'.format(epg),
            module_object=epg,
            target_filter={'name': epg},
        ),
        child_classes=['fvRsBd'],
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='fvAEPg',
            class_config=dict(
                name=epg,
                descr=description,
                prio=priority,
                pcEnfPref=intra_epg_isolation,
                fwdCtrl=fwd_control,
                prefGrMemb=preferred_group,
            ),
            child_configs=[
                dict(fvRsBd=dict(attributes=dict(tnFvBDName=bd, ), ), )
            ],
        )

        aci.get_diff(aci_class='fvAEPg')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        allocation_mode=dict(type='str', aliases=['mode'], choices=['dynamic', 'inherit', 'static']),
        description=dict(type='str', aliases=['descr']),
        pool=dict(type='str', aliases=['pool_name']),  # Not required for querying all objects
        pool_allocation_mode=dict(type='str', aliases=['pool_mode'], choices=['dynamic', 'static']),
        block_name=dict(type='str', aliases=['name']),  # Not required for querying all objects
        block_end=dict(type='int', aliases=['end']),  # Not required for querying all objects
        block_start=dict(type='int', aliases=["start"]),  # Not required for querying all objects
        state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['pool', 'block_end', 'block_name', 'block_start']],
            ['state', 'present', ['pool', 'block_end', 'block_name', 'block_start']],
        ],
    )

    allocation_mode = module.params['allocation_mode']
    description = module.params['description']
    pool = module.params['pool']
    pool_allocation_mode = module.params['pool_allocation_mode']
    block_end = module.params['block_end']
    block_name = module.params['block_name']
    block_start = module.params['block_start']
    state = module.params['state']

    if block_end is not None:
        encap_end = 'vlan-{0}'.format(block_end)
    else:
        encap_end = None

    if block_start is not None:
        encap_start = 'vlan-{0}'.format(block_start)
    else:
        encap_start = None

    # Collect proper mo information
    aci_block_mo = 'from-[{0}]-to-[{1}]'.format(encap_start, encap_end)
    pool_name = pool

    # Validate block_end and block_start are valid for its respective encap type
    for encap_id in block_end, block_start:
        if encap_id is not None:
            if not 1 <= encap_id <= 4094:
                module.fail_json(msg="vlan pools must have 'block_start' and 'block_end' values between 1 and 4094")

    # Build proper proper filter_target based on block_start, block_end, and block_name
    if block_end is not None and block_start is not None:
        # Validate block_start is less than block_end
        if block_start > block_end:
            module.fail_json(msg="The 'block_start' must be less than or equal to the 'block_end'")

        if block_name is None:
            block_filter_target = 'and(eq({0}.from, "{1}"),eq({0}.to, "{2}"))'.format('fvnsEncapBlk', encap_start, encap_end)
        else:
            block_filter_target = 'and(eq({0}.from, "{1}"),eq({0}.to, "{2}"),eq({0}.name, "{3}"))'.format('fvnsEncapBlk', encap_start, encap_end, block_name)
    elif block_end is None and block_start is None:
        if block_name is None:
            # Reset range managed object to None for aci util to properly handle query
            aci_block_mo = None
            block_filter_target = ''
        else:
            block_filter_target = 'eq({0}.name, "{1}")'.format('fvnsEncapBlk', block_name)
    elif block_start is not None:
        if block_name is None:
            block_filter_target = 'eq({0}.from, "{1}")'.format('fvnsEncapBlk', encap_start)
        else:
            block_filter_target = 'and(eq({0}.from, "{1}"),eq({0}.name, "{2}"))'.format('fvnsEncapBlk', encap_start, block_name)
    else:
        if block_name is None:
            block_filter_target = 'eq({0}.to, "{1}")'.format('fvnsEncapBlk', encap_end)
        else:
            block_filter_target = 'and(eq({0}.to, "{1}"),eq({0}.name, "{2}"))'.format('fvnsEncapBlk', encap_end, block_name)

    # ACI Pool URL requires the allocation mode (ex: uni/infra/vlanns-[poolname]-static)
    if pool is not None:
        if pool_allocation_mode is not None:
            pool_name = '[{0}]-{1}'.format(pool, pool_allocation_mode)
        else:
            module.fail_json(msg="ACI requires the 'pool_allocation_mode' when 'pool' is provided")

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class='fvnsVlanInstP',
            aci_rn='infra/vlanns-{0}'.format(pool_name),
            filter_target='eq(fvnsVlanInstP.name, "{0}")'.format(pool),
            module_object=pool,
        ),
        subclass_1=dict(
            aci_class='fvnsEncapBlk',
            aci_rn=aci_block_mo,
            filter_target=block_filter_target,
            module_object=aci_block_mo,
        ),
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='fvnsEncapBlk',
            class_config={
                "allocMode": allocation_mode,
                "descr": description,
                "from": encap_start,
                "name": block_name,
                "to": encap_end,
            },
        )

        aci.get_diff(aci_class='fvnsEncapBlk')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
Exemple #46
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        aaa_password=dict(type='str', no_log=True),
        aaa_password_lifetime=dict(type='int'),
        aaa_password_update_required=dict(type='bool'),
        aaa_user=dict(type='str', required=True,
                      aliases=['name'
                               ]),  # Not required for querying all objects
        clear_password_history=dict(type='bool'),
        description=dict(type='str', aliases=['descr']),
        email=dict(type='str'),
        enabled=dict(type='bool'),
        expiration=dict(type='str'),
        expires=dict(type='bool'),
        first_name=dict(type='str'),
        last_name=dict(type='str'),
        phone=dict(type='str'),
        state=dict(type='str',
                   default='present',
                   choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['aaa_user']],
            ['state', 'present', ['aaa_user']],
            ['expires', True, ['expiration']],
        ],
    )

    aci = ACIModule(module)

    if not HAS_DATEUTIL:
        module.fail_json(msg='dateutil required for this module')

    aaa_password = module.params['aaa_password']
    aaa_password_lifetime = module.params['aaa_password_lifetime']
    aaa_password_update_required = aci.boolean(
        module.params['aaa_password_update_required'])
    aaa_user = module.params['aaa_user']
    clear_password_history = module.params['clear_password_history']
    description = module.params['description']
    email = module.params['email']
    enabled = aci.boolean(module.params['enabled'], 'active', 'inactive')
    expires = aci.boolean(module.params['expires'])
    first_name = module.params['first_name']
    last_name = module.params['last_name']
    phone = module.params['phone']
    state = module.params['state']

    expiration = module.params['expiration']
    if expiration is not None and expiration != 'never':
        try:
            expiration = aci.iso8601_format(
                dateutil.parser.parse(expiration).replace(tzinfo=tzutc()))
        except Exception as e:
            module.fail_json(msg="Failed to parse date format '%s', %s" %
                             (module.params['expiration'], e))

    aci.construct_url(root_class=dict(
        aci_class='aaaUser',
        aci_rn='userext/user-{0}'.format(aaa_user),
        module_object=aaa_user,
        target_filter={'name': aaa_user},
    ), )
    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='aaaUser',
            class_config=dict(
                accountStatus=enabled,
                clearPwdHistory=clear_password_history,
                email=email,
                expiration=expiration,
                expires=expires,
                firstName=first_name,
                lastName=last_name,
                name=aaa_user,
                phone=phone,
                pwd=aaa_password,
                pwdLifeTime=aaa_password_lifetime,
                pwdUpdateRequired=aaa_password_update_required,
            ),
        )

        aci.get_diff(aci_class='aaaUser')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
Exemple #47
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        l3out=dict(type='str', aliases=['l3out_name', 'name']),
        domain=dict(type='str', aliases=['ext_routed_domain_name', 'routed_domain']),
        vrf=dict(type='str', aliases=['vrf_name']),
        tenant=dict(type='str', aliases=['tenant_name']),
        description=dict(type='str', aliases=['descr']),
        route_control=dict(type='list', choices=['export', 'import'], aliases=['route_control_enforcement']),
        dscp=dict(type='str',
                  choices=['AF11', 'AF12', 'AF13', 'AF21', 'AF22', 'AF23', 'AF31', 'AF32', 'AF33', 'AF41', 'AF42',
                           'AF43', 'CS0', 'CS1', 'CS2', 'CS3', 'CS4', 'CS5', 'CS6', 'CS7', 'EF', 'VA', 'unspecified'],
                  aliases=['target']),
        l3protocol=dict(type='list', choices=['static', 'bgp', 'ospf', 'pim']),
        state=dict(type='str', default='present', choices=['absent', 'present', 'query'])
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['name', 'tenant']],
            ['state', 'present', ['name', 'tenant', 'domain', 'vrf']],
        ],
    )

    aci = ACIModule(module)

    l3out = module.params['l3out']
    domain = module.params['domain']
    dscp = module.params['dscp']
    description = module.params['description']
    enforceRtctrl = module.params['route_control']
    vrf = module.params['vrf']
    l3protocol = module.params['l3protocol']
    state = module.params['state']
    tenant = module.params['tenant']

    enforce_ctrl = ''
    if enforceRtctrl is not None:
        if len(enforceRtctrl) == 1 and enforceRtctrl[0] == 'import':
            aci.fail_json(
                "The route_control parameter is invalid: allowed options are export or import,export only")
        elif len(enforceRtctrl) == 1 and enforceRtctrl[0] == 'export':
            enforce_ctrl = 'export'
        else:
            enforce_ctrl = 'export,import'
    child_classes = ['l3extRsL3DomAtt', 'l3extRsEctx', 'bgpExtP', 'ospfExtP', 'eigrpExtP', 'pimExtP']

    aci.construct_url(
        root_class=dict(
            aci_class='fvTenant',
            aci_rn='tn-{0}'.format(tenant),
            filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
            module_object=tenant,
        ),
        subclass_1=dict(
            aci_class='l3extOut',
            aci_rn='out-{0}'.format(l3out),
            filter_target='eq(l3extOut.name, "{0}")'.format(l3out),
            module_object=l3out,
        ),
        child_classes=child_classes,
    )

    aci.get_existing()

    child_configs = [
        dict(l3extRsL3DomAtt=dict(attributes=dict(
            tDn='uni/l3dom-{0}'.format(domain)))),
        dict(l3extRsEctx=dict(attributes=dict(tnFvCtxName=vrf))),
    ]
    if l3protocol is not None:
        for protocol in l3protocol:
            if protocol == 'bgp':
                child_configs.append(
                    dict(bgpExtP=dict(attributes=dict(descr='', nameAlias=''))))
            elif protocol == 'ospf':
                child_configs.append(
                    dict(ospfExtP=dict(attributes=dict(descr='', nameAlias=''))))
            elif protocol == 'pim':
                child_configs.append(
                    dict(pimExtP=dict(attributes=dict(descr='', nameAlias=''))))

    if state == 'present':
        aci.payload(
            aci_class='l3extOut',
            class_config=dict(
                name=l3out,
                descr=description,
                dn='uni/tn-{0}/out-{1}'.format(tenant, l3out),
                enforceRtctrl=enforce_ctrl,
                targetDscp=dscp
            ),
            child_configs=child_configs,
        )

        aci.get_diff(aci_class='l3extOut')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        policy_group=dict(type='str',
                          aliases=['name', 'policy_group_name'
                                   ]),  # Not required for querying all objects
        description=dict(type='str', aliases=['descr']),
        # NOTE: Since this module needs to include both infra:AccBndlGrp (for PC and VPC) and infra:AccPortGrp (for leaf access port policy group):
        # NOTE: I'll allow the user to make the choice here (link(PC), node(VPC), leaf(leaf-access port policy group))
        lag_type=dict(type='str',
                      required=True,
                      aliases=['lag_type_name'],
                      choices=['leaf', 'link', 'node']),
        link_level_policy=dict(type='str', aliases=['link_level_policy_name']),
        cdp_policy=dict(type='str', aliases=['cdp_policy_name']),
        mcp_policy=dict(type='str', aliases=['mcp_policy_name']),
        lldp_policy=dict(type='str', aliases=['lldp_policy_name']),
        stp_interface_policy=dict(type='str',
                                  aliases=['stp_interface_policy_name']),
        egress_data_plane_policing_policy=dict(
            type='str', aliases=['egress_data_plane_policing_policy_name']),
        ingress_data_plane_policing_policy=dict(
            type='str', aliases=['ingress_data_plane_policing_policy_name']),
        priority_flow_control_policy=dict(
            type='str', aliases=['priority_flow_control_policy_name']),
        fibre_channel_interface_policy=dict(
            type='str', aliases=['fibre_channel_interface_policy_name']),
        slow_drain_policy=dict(type='str', aliases=['slow_drain_policy_name']),
        port_channel_policy=dict(type='str',
                                 aliases=['port_channel_policy_name']),
        monitoring_policy=dict(type='str', aliases=['monitoring_policy_name']),
        storm_control_interface_policy=dict(
            type='str', aliases=['storm_control_interface_policy_name']),
        l2_interface_policy=dict(type='str',
                                 aliases=['l2_interface_policy_name']),
        port_security_policy=dict(type='str',
                                  aliases=['port_security_policy_name']),
        aep=dict(type='str', aliases=['aep_name']),
        state=dict(type='str',
                   default='present',
                   choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['policy_group']],
            ['state', 'present', ['policy_group']],
        ],
    )

    policy_group = module.params['policy_group']
    description = module.params['description']
    lag_type = module.params['lag_type']
    link_level_policy = module.params['link_level_policy']
    cdp_policy = module.params['cdp_policy']
    mcp_policy = module.params['mcp_policy']
    lldp_policy = module.params['lldp_policy']
    stp_interface_policy = module.params['stp_interface_policy']
    egress_data_plane_policing_policy = module.params[
        'egress_data_plane_policing_policy']
    ingress_data_plane_policing_policy = module.params[
        'ingress_data_plane_policing_policy']
    priority_flow_control_policy = module.params[
        'priority_flow_control_policy']
    fibre_channel_interface_policy = module.params[
        'fibre_channel_interface_policy']
    slow_drain_policy = module.params['slow_drain_policy']
    port_channel_policy = module.params['port_channel_policy']
    monitoring_policy = module.params['monitoring_policy']
    storm_control_interface_policy = module.params[
        'storm_control_interface_policy']
    l2_interface_policy = module.params['l2_interface_policy']
    port_security_policy = module.params['port_security_policy']
    aep = module.params['aep']
    state = module.params['state']

    if lag_type == 'leaf':
        aci_class_name = 'infraAccPortGrp'
        dn_name = 'accportgrp'
        class_config_dict = dict(
            name=policy_group,
            descr=description,
        )
    elif lag_type in ('link', 'node'):
        aci_class_name = 'infraAccBndlGrp'
        dn_name = 'accbundle'
        class_config_dict = dict(
            name=policy_group,
            descr=description,
            lagT=lag_type,
        )

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class=aci_class_name,
            aci_rn='infra/funcprof/{0}-{1}'.format(dn_name, policy_group),
            filter_target='eq({0}.name, "{1}")'.format(aci_class_name,
                                                       policy_group),
            module_object=policy_group,
        ),
        child_classes=[
            'infraRsAttEntP',
            'infraRsCdpIfPol',
            'infraRsFcIfPol',
            'infraRsHIfPol',
            'infraRsL2IfPol',
            'infraRsL2PortSecurityPol',
            'infraRsLacpPol',
            'infraRsLldpIfPol',
            'infraRsMcpIfPol',
            'infraRsMonIfInfraPol',
            'infraRsQosEgressDppIfPol',
            'infraRsQosIngressDppIfPol',
            'infraRsQosPfcIfPol',
            'infraRsQosSdIfPol',
            'infraRsStormctrlIfPol',
            'infraRsStpIfPol',
        ],
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class=aci_class_name,
            class_config=class_config_dict,
            child_configs=[
                dict(infraRsAttEntP=dict(attributes=dict(
                    tDn='uni/infra/attentp-{0}'.format(aep), ), ), ),
                dict(infraRsCdpIfPol=dict(attributes=dict(
                    tnCdpIfPolName=cdp_policy, ), ), ),
                dict(infraRsFcIfPol=dict(attributes=dict(
                    tnFcIfPolName=fibre_channel_interface_policy, ), ), ),
                dict(infraRsHIfPol=dict(attributes=dict(
                    tnFabricHIfPolName=link_level_policy, ), ), ),
                dict(infraRsL2IfPol=dict(attributes=dict(
                    tnL2IfPolName=l2_interface_policy, ), ), ),
                dict(infraRsL2PortSecurityPol=dict(attributes=dict(
                    tnL2PortSecurityPolName=port_security_policy, ), ), ),
                dict(infraRsLacpPol=dict(attributes=dict(
                    tnLacpLagPolName=port_channel_policy, ), ), ),
                dict(infraRsLldpIfPol=dict(attributes=dict(
                    tnLldpIfPolName=lldp_policy, ), ), ),
                dict(infraRsMcpIfPol=dict(attributes=dict(
                    tnMcpIfPolName=mcp_policy, ), ), ),
                dict(infraRsMonIfInfraPol=dict(attributes=dict(
                    tnMonInfraPolName=monitoring_policy, ), ), ),
                dict(infraRsQosEgressDppIfPol=dict(attributes=dict(
                    tnQosDppPolName=egress_data_plane_policing_policy, ), ), ),
                dict(infraRsQosIngressDppIfPol=dict(attributes=dict(
                    tnQosDppPolName=ingress_data_plane_policing_policy, ), ),
                     ),
                dict(infraRsQosPfcIfPol=dict(attributes=dict(
                    tnQosPfcIfPolName=priority_flow_control_policy, ), ), ),
                dict(infraRsQosSdIfPol=dict(attributes=dict(
                    tnQosSdIfPolName=slow_drain_policy, ), ), ),
                dict(infraRsStormctrlIfPol=dict(attributes=dict(
                    tnStormctrlIfPolName=storm_control_interface_policy, ), ),
                     ),
                dict(infraRsStpIfPol=dict(attributes=dict(
                    tnStpIfPolName=stp_interface_policy, ), ), ),
            ],
        )

        aci.get_diff(aci_class=aci_class_name)

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        port_channel=dict(type='str', required=False, aliases=['name']),  # Not required for querying all objects
        description=dict(type='str', aliases=['descr']),
        min_links=dict(type='int'),
        max_links=dict(type='int'),
        mode=dict(type='str', choices=['off', 'mac-pin', 'active', 'passive', 'mac-pin-nicload']),
        fast_select=dict(type='bool'),
        graceful_convergence=dict(type='bool'),
        load_defer=dict(type='bool'),
        suspend_individual=dict(type='bool'),
        symmetric_hash=dict(type='bool'),
        state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['port_channel']],
            ['state', 'present', ['port_channel']],
        ],
    )

    port_channel = module.params['port_channel']
    description = module.params['description']
    min_links = module.params['min_links']
    if min_links is not None and min_links not in range(1, 17):
        module.fail_json(msg='The "min_links" must be a value between 1 and 16')
    max_links = module.params['max_links']
    if max_links is not None and max_links not in range(1, 17):
        module.fail_json(msg='The "max_links" must be a value between 1 and 16')
    mode = module.params['mode']
    state = module.params['state']

    # Build ctrl value for request
    ctrl = []
    if module.params['fast_select'] is True:
        ctrl.append('fast-sel-hot-stdby')
    if module.params['graceful_convergence'] is True:
        ctrl.append('graceful-conv')
    if module.params['load_defer'] is True:
        ctrl.append('load-defer')
    if module.params['suspend_individual'] is True:
        ctrl.append('susp-individual')
    if module.params['symmetric_hash'] is True:
        ctrl.append('symmetric-hash')
    if not ctrl:
        ctrl = None
    else:
        ctrl = ",".join(ctrl)

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class='lacpLagPol',
            aci_rn='infra/lacplagp-{0}'.format(port_channel),
            filter_target='eq(lacpLagPol.name, "{0}")'.format(port_channel),
            module_object=port_channel,
        ),
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='lacpLagPol',
            class_config=dict(
                name=port_channel,
                ctrl=ctrl,
                descr=description,
                minLinks=min_links,
                maxLinks=max_links,
                mode=mode,
            ),
        )

        aci.get_diff(aci_class='lacpLagPol')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
Exemple #50
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        description=dict(type='str', aliases=['descr']),
        export_policy=dict(
            type='str',
            aliases=['name']),  # Not required for querying all objects
        format=dict(type='str', choices=['json', 'xml']),
        include_secure=dict(type='bool'),
        max_count=dict(type='int'),
        snapshot=dict(type='str'),
        state=dict(type='str',
                   choices=['absent', 'present', 'query'],
                   default='present'),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=False,
        required_if=[
            ['state', 'absent', ['export_policy', 'snapshot']],
            ['state', 'present', ['export_policy']],
        ],
    )

    aci = ACIModule(module)

    description = module.params.get('description')
    export_policy = module.params.get('export_policy')
    file_format = module.params.get('format')
    include_secure = aci.boolean(module.params.get('include_secure'))
    max_count = module.params.get('max_count')
    if max_count is not None:
        if max_count in range(1, 11):
            max_count = str(max_count)
        else:
            module.fail_json(
                msg="Parameter 'max_count' must be a number between 1 and 10")
    snapshot = module.params.get('snapshot')
    if snapshot is not None and not snapshot.startswith('run-'):
        snapshot = 'run-' + snapshot
    state = module.params.get('state')

    if state == 'present':
        aci.construct_url(root_class=dict(
            aci_class='configExportP',
            aci_rn='fabric/configexp-{0}'.format(export_policy),
            module_object=export_policy,
            target_filter={'name': export_policy},
        ), )

        aci.get_existing()

        aci.payload(
            aci_class='configExportP',
            class_config=dict(
                adminSt='triggered',
                descr=description,
                format=file_format,
                includeSecureFields=include_secure,
                maxSnapshotCount=max_count,
                name=export_policy,
                snapshot='yes',
            ),
        )

        aci.get_diff('configExportP')

        # Create a new Snapshot
        aci.post_config()

    else:
        # Prefix the proper url to export_policy
        if export_policy is not None:
            export_policy = 'uni/fabric/configexp-{0}'.format(export_policy)

        aci.construct_url(
            root_class=dict(
                aci_class='configSnapshotCont',
                aci_rn='backupst/snapshots-[{0}]'.format(export_policy),
                module_object=export_policy,
                target_filter={'name': export_policy},
            ),
            subclass_1=dict(
                aci_class='configSnapshot',
                aci_rn='snapshot-{0}'.format(snapshot),
                module_object=snapshot,
                target_filter={'name': snapshot},
            ),
        )

        aci.get_existing()

        if state == 'absent':
            # Build POST request to used to remove Snapshot
            aci.payload(
                aci_class='configSnapshot',
                class_config=dict(
                    name=snapshot,
                    retire="yes",
                ),
            )

            if aci.existing:
                aci.get_diff('configSnapshot')

                # Mark Snapshot for Deletion
                aci.post_config()

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update({
        'leaf_interface_profile': dict(type='str', aliases=['leaf_interface_profile_name']),  # Not required for querying all objects
        'access_port_selector': dict(type='str', aliases=['name', 'access_port_selector_name']),  # Not required for querying all objects
        'description': dict(typ='str'),
        'leaf_port_blk': dict(type='str', aliases=['leaf_port_blk_name']),
        'leaf_port_blk_description': dict(type='str'),
        # NOTE: Keyword 'from' is a reserved word in python, so we need it as a string
        'from': dict(type='str', aliases=['fromPort', 'from_port_range']),
        'to': dict(type='str', aliases=['toPort', 'to_port_range']),
        'policy_group': dict(type='str', aliases=['policy_group_name']),
        'state': dict(type='str', default='present', choices=['absent', 'present', 'query']),
    })

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['leaf_interface_profile', 'access_port_selector']],
            ['state', 'present', ['leaf_interface_profile', 'access_port_selector']],
        ],
    )

    leaf_interface_profile = module.params['leaf_interface_profile']
    access_port_selector = module.params['access_port_selector']
    description = module.params['description']
    leaf_port_blk = module.params['leaf_port_blk']
    leaf_port_blk_description = module.params['leaf_port_blk_description']
    from_ = module.params['from']
    to_ = module.params['to']
    policy_group = module.params['policy_group']
    state = module.params['state']

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class='infraAccPortP',
            aci_rn='infra/accportprof-{0}'.format(leaf_interface_profile),
            filter_target='eq(infraAccPortP.name, "{0}")'.format(leaf_interface_profile),
            module_object=leaf_interface_profile
        ),
        subclass_1=dict(
            aci_class='infraHPortS',
            # NOTE: normal rn: hports-{name}-typ-{type}, hence here hardcoded to range for purposes of module
            aci_rn='hports-{0}-typ-range'.format(access_port_selector),
            filter_target='eq(infraHPortS.name, "{0}")'.format(access_port_selector),
            module_object=access_port_selector,
        ),
        child_classes=['infraPortBlk', 'infraRsAccBaseGrp']
    )
    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='infraHPortS',
            class_config=dict(
                descr=description,
                name=access_port_selector,
            ),
            child_configs=[
                dict(
                    infraPortBlk=dict(
                        attributes=dict(
                            descr=leaf_port_blk_description,
                            name=leaf_port_blk,
                            fromPort=from_,
                            toPort=to_,
                        ),
                    ),
                ),
                dict(
                    infraRsAccBaseGrp=dict(
                        attributes=dict(
                            tDn='uni/infra/funcprof/accportgrp-{0}'.format(policy_group),
                        ),
                    ),
                ),
            ],
        )

        aci.get_diff(aci_class='infraHPortS')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        l2_policy=dict(type='str',
                       aliases=['name'
                                ]),  # Not required for querying all policies
        description=dict(type='str', aliases=['descr']),
        vlan_scope=dict(type='str',
                        choices=['global', 'portlocal'
                                 ]),  # No default provided on purpose
        qinq=dict(type='str', choices=['core', 'disabled', 'edge']),
        vepa=dict(type='bool'),
        state=dict(type='str',
                   default='present',
                   choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['l2_policy']],
            ['state', 'present', ['l2_policy']],
        ],
    )

    aci = ACIModule(module)

    l2_policy = module.params.get('l2_policy')
    vlan_scope = module.params.get('vlan_scope')
    qinq = module.params.get('qinq')
    if qinq is not None:
        qinq = QINQ_MAPPING.get(qinq)
    vepa = aci.boolean(module.params.get('vepa'), 'enabled', 'disabled')
    description = module.params.get('description')
    state = module.params.get('state')

    aci.construct_url(root_class=dict(
        aci_class='l2IfPol',
        aci_rn='infra/l2IfP-{0}'.format(l2_policy),
        module_object=l2_policy,
        target_filter={'name': l2_policy},
    ), )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='l2IfPol',
            class_config=dict(
                name=l2_policy,
                descr=description,
                vlanScope=vlan_scope,
                qinq=qinq,
                vepa=vepa,
            ),
        )

        aci.get_diff(aci_class='l2IfPol')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        description=dict(type='str', aliases=['descr']),
        node_id=dict(type='int'),  # Not required for querying all objects
        pod_id=dict(type='int'),
        role=dict(type='str', choices=['leaf', 'spine', 'unspecified'], aliases=['role_name']),
        serial=dict(type='str', aliases=['serial_number']),  # Not required for querying all objects
        switch=dict(type='str', aliases=['name', 'switch_name']),
        state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['node_id', 'serial']],
            ['state', 'present', ['node_id', 'serial']],
        ],
    )

    pod_id = module.params['pod_id']
    serial = module.params['serial']
    node_id = module.params['node_id']
    switch = module.params['switch']
    description = module.params['description']
    role = module.params['role']
    state = module.params['state']

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class='fabricNodeIdentP',
            aci_rn='controller/nodeidentpol/nodep-{0}'.format(serial),
            filter_target='eq(fabricNodeIdentP.serial, "{0}")'.format(serial),
            module_object=serial,
        )
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='fabricNodeIdentP',
            class_config=dict(
                descr=description,
                name=switch,
                nodeId=node_id,
                podId=pod_id,
                rn='nodep-{0}'.format(serial),
                role=role,
                serial=serial,
            )
        )

        aci.get_diff(aci_class='fabricNodeIdentP')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json(**aci.result)
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        allow_useg=dict(type='str', choices=['encap', 'useg']),
        ap=dict(type='str',
                aliases=['app_profile', 'app_profile_name'
                         ]),  # Not required for querying all objects
        deploy_immediacy=dict(type='str', choices=['immediate', 'lazy']),
        domain=dict(type='str',
                    aliases=['domain_name', 'domain_profile'
                             ]),  # Not required for querying all objects
        domain_type=dict(type='str', choices=['phys', 'vmm'],
                         aliases=['type'
                                  ]),  # Not required for querying all objects
        encap=dict(type='int'),
        encap_mode=dict(type='str', choices=['auto', 'vlan', 'vxlan']),
        epg=dict(type='str',
                 aliases=['name', 'epg_name'
                          ]),  # Not required for querying all objects
        netflow=dict(type='raw'),  # Turn into a boolean in v2.9
        primary_encap=dict(type='int'),
        resolution_immediacy=dict(
            type='str', choices=['immediate', 'lazy', 'pre-provision']),
        state=dict(type='str',
                   default='present',
                   choices=['absent', 'present', 'query']),
        tenant=dict(type='str',
                    aliases=['tenant_name'
                             ]),  # Not required for querying all objects
        vm_provider=dict(type='str',
                         choices=[
                             'cloudfoundry', 'kubernetes', 'microsoft',
                             'openshift', 'openstack', 'redhat', 'vmware'
                         ]),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['domain_type', 'vmm', ['vm_provider']],
            [
                'state', 'absent',
                ['ap', 'domain', 'domain_type', 'epg', 'tenant']
            ],
            [
                'state', 'present',
                ['ap', 'domain', 'domain_type', 'epg', 'tenant']
            ],
        ],
    )

    aci = ACIModule(module)

    allow_useg = module.params['allow_useg']
    ap = module.params['ap']
    deploy_immediacy = module.params['deploy_immediacy']
    domain = module.params['domain']
    domain_type = module.params['domain_type']
    vm_provider = module.params['vm_provider']
    encap = module.params['encap']
    if encap is not None:
        if encap in range(1, 4097):
            encap = 'vlan-{0}'.format(encap)
        else:
            module.fail_json(msg='Valid VLAN assigments are from 1 to 4096')
    encap_mode = module.params['encap_mode']
    epg = module.params['epg']
    netflow = aci.boolean(module.params['netflow'], 'enabled', 'disabled')
    primary_encap = module.params['primary_encap']
    if primary_encap is not None:
        if primary_encap in range(1, 4097):
            primary_encap = 'vlan-{0}'.format(primary_encap)
        else:
            module.fail_json(msg='Valid VLAN assigments are from 1 to 4096')
    resolution_immediacy = module.params['resolution_immediacy']
    state = module.params['state']
    tenant = module.params['tenant']

    if domain_type == 'phys' and vm_provider is not None:
        module.fail_json(msg="Domain type 'phys' cannot have a 'vm_provider'")

    # Compile the full domain for URL building
    if domain_type == 'vmm':
        epg_domain = 'uni/vmmp-{0}/dom-{1}'.format(
            VM_PROVIDER_MAPPING[vm_provider], domain)
    elif domain_type is not None:
        epg_domain = 'uni/phys-{0}'.format(domain)
    else:
        epg_domain = None

    aci.construct_url(
        root_class=dict(
            aci_class='fvTenant',
            aci_rn='tn-{0}'.format(tenant),
            module_object=tenant,
            target_filter={'name': tenant},
        ),
        subclass_1=dict(
            aci_class='fvAp',
            aci_rn='ap-{0}'.format(ap),
            module_object=ap,
            target_filter={'name': ap},
        ),
        subclass_2=dict(
            aci_class='fvAEPg',
            aci_rn='epg-{0}'.format(epg),
            module_object=epg,
            target_filter={'name': epg},
        ),
        subclass_3=dict(
            aci_class='fvRsDomAtt',
            aci_rn='rsdomAtt-[{0}]'.format(epg_domain),
            module_object=epg_domain,
            target_filter={'tDn': epg_domain},
        ),
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='fvRsDomAtt',
            class_config=dict(
                classPref=allow_useg,
                encap=encap,
                encapMode=encap_mode,
                instrImedcy=deploy_immediacy,
                netflowPref=netflow,
                primaryEncap=primary_encap,
                resImedcy=resolution_immediacy,
            ),
        )

        aci.get_diff(aci_class='fvRsDomAtt')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        contract=dict(type='str', aliases=['contract_name']),  # Not required for querying all objects
        filter=dict(type='str', aliases=['filter_name']),  # Not required for querying all objects
        log=dict(tyep='str', choices=['log', 'none'], aliases=['directive']),
        subject=dict(type='str', aliases=['contract_subject', 'subject_name']),  # Not required for querying all objects
        tenant=dict(type='str', aliases=['tenant_name']),  # Not required for querying all objects
        state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['contract', 'filter', 'subject', 'tenant']],
            ['state', 'present', ['contract', 'filter', 'subject', 'tenant']],
        ],
    )

    contract = module.params['contract']
    filter_name = module.params['filter']
    log = module.params['log']
    subject = module.params['subject']
    tenant = module.params['tenant']
    state = module.params['state']

    # Add subject_filter key to modul.params for building the URL
    module.params['subject_filter'] = filter_name

    # Convert log to empty string if none, as that is what API expects. An empty string is not a good option to present the user.
    if log == 'none':
        log = ''

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class='fvTenant',
            aci_rn='tn-{0}'.format(tenant),
            filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
            module_object=tenant,
        ),
        subclass_1=dict(
            aci_class='vzBrCP',
            aci_rn='brc-{0}'.format(contract),
            filter_target='eq(vzBrCP.name, "{0}")'.format(contract),
            module_object=contract,
        ),
        subclass_2=dict(
            aci_class='vzSubj',
            aci_rn='subj-{0}'.format(subject),
            filter_target='eq(vzSubj.name, "{0}")'.format(subject),
            module_object=subject,
        ),
        subclass_3=dict(
            aci_class='vzRsSubjFiltAtt',
            aci_rn='rssubjFiltAtt-{0}'.format(filter_name),
            filter_target='eq(vzRsSubjFiltAtt.tnVzFilterName, "{0}")'.format(filter_name),
            module_object=filter_name,
        ),
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='vzRsSubjFiltAtt',
            class_config=dict(
                tnVzFilterName=filter_name,
                directives=log,
            ),
        )

        aci.get_diff(aci_class='vzRsSubjFiltAtt')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    # Remove subject_filter used to build URL from module.params
    module.params.pop('subject_filter')

    aci.exit_json()
Exemple #56
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        filter=dict(type='str',
                    aliases=['name', 'filter_name'
                             ]),  # Not required for querying all objects
        tenant=dict(type='str',
                    aliases=['tenant_name'
                             ]),  # Not required for querying all objects
        description=dict(type='str', aliases=['descr']),
        state=dict(type='str',
                   default='present',
                   choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['filter', 'tenant']],
            ['state', 'present', ['filter', 'tenant']],
        ],
    )

    filter_name = module.params.get('filter')
    description = module.params.get('description')
    state = module.params.get('state')
    tenant = module.params.get('tenant')

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class='fvTenant',
            aci_rn='tn-{0}'.format(tenant),
            module_object=tenant,
            target_filter={'name': tenant},
        ),
        subclass_1=dict(
            aci_class='vzFilter',
            aci_rn='flt-{0}'.format(filter_name),
            module_object=filter_name,
            target_filter={'name': filter_name},
        ),
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='vzFilter',
            class_config=dict(
                name=filter_name,
                descr=description,
            ),
        )

        aci.get_diff(aci_class='vzFilter')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        aep=dict(type='str', aliases=['aep_name']),  # Not required for querying all objects
        domain=dict(type='str', aliases=['domain_name', 'domain_profile']),  # Not required for querying all objects
        domain_type=dict(type='str', choices=['fc', 'l2dom', 'l3dom', 'phys', 'vmm'], aliases=['type']),  # Not required for querying all objects
        state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
        vm_provider=dict(type='str', choices=['cloudfoundry', 'kubernetes', 'microsoft', 'openshift', 'openstack', 'redhat', 'vmware']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['domain_type', 'vmm', ['vm_provider']],
            ['state', 'absent', ['aep', 'domain', 'domain_type']],
            ['state', 'present', ['aep', 'domain', 'domain_type']],
        ],
        required_together=[
            ['domain', 'domain_type'],
        ],
    )

    aep = module.params['aep']
    domain = module.params['domain']
    domain_type = module.params['domain_type']
    vm_provider = module.params['vm_provider']
    state = module.params['state']

    # Report when vm_provider is set when type is not virtual
    if domain_type != 'vmm' and vm_provider is not None:
        module.fail_json(msg="Domain type '{0}' cannot have a 'vm_provider'".format(domain_type))

    # Compile the full domain for URL building
    if domain_type == 'fc':
        domain_mo = 'uni/fc-{0}'.format(domain)
    elif domain_type == 'l2dom':
        domain_mo = 'uni/l2dom-{0}'.format(domain)
    elif domain_type == 'l3dom':
        domain_mo = 'uni/l3dom-{0}'.format(domain)
    elif domain_type == 'phys':
        domain_mo = 'uni/phys-{0}'.format(domain)
    elif domain_type == 'vmm':
        domain_mo = 'uni/vmmp-{0}/dom-{1}'.format(VM_PROVIDER_MAPPING[vm_provider], domain)
    else:
        domain_mo = None

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class='infraAttEntityP',
            aci_rn='infra/attentp-{0}'.format(aep),
            filter_target='eq(infraAttEntityP.name, "{0}")'.format(aep),
            module_object=aep,
        ),
        subclass_1=dict(
            aci_class='infraRsDomP',
            aci_rn='rsdomP-[{0}]'.format(domain_mo),
            filter_target='eq(infraRsDomP.tDn, "{0}")'.format(domain_mo),
            module_object=domain_mo,
        ),
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='infraRsDomP',
            class_config=dict(tDn=domain_mo),
        )

        aci.get_diff(aci_class='infraRsDomP')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
Exemple #58
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        domain_type=dict(type='str',
                         required=True,
                         choices=['fc', 'l2dom', 'l3dom', 'phys', 'vmm'],
                         aliases=['type']),
        domain=dict(type='str',
                    aliases=['domain_name', 'domain_profile',
                             'name']),  # Not required for querying all objects
        dscp=dict(type='str',
                  choices=[
                      'AF11', 'AF12', 'AF13', 'AF21', 'AF22', 'AF23', 'AF31',
                      'AF32', 'AF33', 'AF41', 'AF42', 'AF43', 'CS0', 'CS1',
                      'CS2', 'CS3', 'CS4', 'CS5', 'CS6', 'CS7', 'EF', 'VA',
                      'unspecified'
                  ],
                  aliases=['target']),
        encap_mode=dict(type='str', choices=['unknown', 'vlan', 'vxlan']),
        multicast_address=dict(type='str'),
        state=dict(type='str',
                   default='present',
                   choices=['absent', 'present', 'query']),
        vm_provider=dict(type='str',
                         choices=[
                             'cloudfoundry', 'kubernetes', 'microsoft',
                             'openshift', 'openstack', 'redhat', 'vmware'
                         ]),
        vswitch=dict(type='str', choices=['avs', 'default', 'dvs', 'unknown']),
        name_alias=dict(type='str'),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['domain_type', 'vmm', ['vm_provider']],
            ['state', 'absent', ['domain', 'domain_type']],
            ['state', 'present', ['domain', 'domain_type']],
        ],
    )

    dscp = module.params.get('dscp')
    domain = module.params.get('domain')
    domain_type = module.params.get('domain_type')
    encap_mode = module.params.get('encap_mode')
    multicast_address = module.params.get('multicast_address')
    vm_provider = module.params.get('vm_provider')
    vswitch = module.params.get('vswitch')
    if vswitch is not None:
        vswitch = VSWITCH_MAPPING.get(vswitch)
    state = module.params.get('state')
    name_alias = module.params.get('name_alias')

    if domain_type != 'vmm':
        if vm_provider is not None:
            module.fail_json(
                msg="Domain type '{0}' cannot have parameter 'vm_provider'".
                format(domain_type))
        if encap_mode is not None:
            module.fail_json(
                msg="Domain type '{0}' cannot have parameter 'encap_mode'".
                format(domain_type))
        if multicast_address is not None:
            module.fail_json(
                msg="Domain type '{0}' cannot have parameter 'multicast_address'"
                .format(domain_type))
        if vswitch is not None:
            module.fail_json(
                msg="Domain type '{0}' cannot have parameter 'vswitch'".format(
                    domain_type))

    if dscp is not None and domain_type not in ['l2dom', 'l3dom']:
        module.fail_json(
            msg="DSCP values can only be assigned to 'l2ext and 'l3ext' domains"
        )

    # Compile the full domain for URL building
    if domain_type == 'fc':
        domain_class = 'fcDomP'
        domain_mo = 'uni/fc-{0}'.format(domain)
        domain_rn = 'fc-{0}'.format(domain)
    elif domain_type == 'l2dom':
        domain_class = 'l2extDomP'
        domain_mo = 'uni/l2dom-{0}'.format(domain)
        domain_rn = 'l2dom-{0}'.format(domain)
    elif domain_type == 'l3dom':
        domain_class = 'l3extDomP'
        domain_mo = 'uni/l3dom-{0}'.format(domain)
        domain_rn = 'l3dom-{0}'.format(domain)
    elif domain_type == 'phys':
        domain_class = 'physDomP'
        domain_mo = 'uni/phys-{0}'.format(domain)
        domain_rn = 'phys-{0}'.format(domain)
    elif domain_type == 'vmm':
        domain_class = 'vmmDomP'
        domain_mo = 'uni/vmmp-{0}/dom-{1}'.format(
            VM_PROVIDER_MAPPING.get(vm_provider), domain)
        domain_rn = 'vmmp-{0}/dom-{1}'.format(
            VM_PROVIDER_MAPPING.get(vm_provider), domain)

    # Ensure that querying all objects works when only domain_type is provided
    if domain is None:
        domain_mo = None

    aci = ACIModule(module)
    aci.construct_url(root_class=dict(
        aci_class=domain_class,
        aci_rn=domain_rn,
        module_object=domain_mo,
        target_filter={'name': domain},
    ), )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class=domain_class,
            class_config=dict(
                encapMode=encap_mode,
                mcastAddr=multicast_address,
                mode=vswitch,
                name=domain,
                targetDscp=dscp,
                nameAlias=name_alias,
            ),
        )

        aci.get_diff(aci_class=domain_class)

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        arp_flag=dict(type='str', choices=VALID_ARP_FLAGS),
        description=dict(type='str', aliases=['descr']),
        dst_port=dict(type='str'),
        dst_port_end=dict(type='str'),
        dst_port_start=dict(type='str'),
        entry=dict(type='str', aliases=['entry_name', 'filter_entry', 'name']),  # Not required for querying all objects
        ether_type=dict(choices=VALID_ETHER_TYPES, type='str'),
        filter=dict(type='str', aliases=['filter_name']),  # Not required for querying all objects
        icmp_msg_type=dict(type='str', choices=VALID_ICMP_TYPES),
        icmp6_msg_type=dict(type='str', choices=VALID_ICMP6_TYPES),
        ip_protocol=dict(choices=VALID_IP_PROTOCOLS, type='str'),
        state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
        stateful=dict(type='bool'),
        tenant=dict(type="str", aliases=['tenant_name']),  # Not required for querying all objects
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['entry', 'filter', 'tenant']],
            ['state', 'present', ['entry', 'filter', 'tenant']],
        ],
    )

    aci = ACIModule(module)

    arp_flag = module.params['arp_flag']
    if arp_flag is not None:
        arp_flag = ARP_FLAG_MAPPING[arp_flag]
    description = module.params['description']
    dst_port = module.params['dst_port']
    if dst_port in FILTER_PORT_MAPPING.keys():
        dst_port = FILTER_PORT_MAPPING[dst_port]
    dst_end = module.params['dst_port_end']
    if dst_end in FILTER_PORT_MAPPING.keys():
        dst_end = FILTER_PORT_MAPPING[dst_end]
    dst_start = module.params['dst_port_start']
    if dst_start in FILTER_PORT_MAPPING.keys():
        dst_start = FILTER_PORT_MAPPING[dst_start]
    entry = module.params['entry']
    ether_type = module.params['ether_type']
    filter_name = module.params['filter']
    icmp_msg_type = module.params['icmp_msg_type']
    if icmp_msg_type is not None:
        icmp_msg_type = ICMP_MAPPING[icmp_msg_type]
    icmp6_msg_type = module.params['icmp6_msg_type']
    if icmp6_msg_type is not None:
        icmp6_msg_type = ICMP6_MAPPING[icmp6_msg_type]
    ip_protocol = module.params['ip_protocol']
    state = module.params['state']
    stateful = aci.boolean(module.params['stateful'])
    tenant = module.params['tenant']

    # validate that dst_port is not passed with dst_start or dst_end
    if dst_port is not None and (dst_end is not None or dst_start is not None):
        module.fail_json(msg="Parameter 'dst_port' cannot be used with 'dst_end' and 'dst_start'")
    elif dst_port is not None:
        dst_end = dst_port
        dst_start = dst_port

    aci.construct_url(
        root_class=dict(
            aci_class='fvTenant',
            aci_rn='tn-{0}'.format(tenant),
            filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
            module_object=tenant,
        ),
        subclass_1=dict(
            aci_class='vzFilter',
            aci_rn='flt-{0}'.format(filter_name),
            filter_target='eq(vzFilter.name, "{0}")'.format(filter_name),
            module_object=filter_name,
        ),
        subclass_2=dict(
            aci_class='vzEntry',
            aci_rn='e-{0}'.format(entry),
            filter_target='eq(vzEntry.name, "{0}")'.format(entry),
            module_object=entry
        ),
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='vzEntry',
            class_config=dict(
                arpOpc=arp_flag,
                descr=description,
                dFromPort=dst_start,
                dToPort=dst_end,
                etherT=ether_type,
                icmpv4T=icmp_msg_type,
                icmpv6T=icmp6_msg_type,
                name=entry,
                prot=ip_protocol,
                stateful=stateful,
            ),
        )

        aci.get_diff(aci_class='vzEntry')

        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    aci.exit_json()
Exemple #60
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        allocation_mode=dict(type='str',
                             aliases=['mode'],
                             choices=['dynamic', 'static']),
        description=dict(type='str', aliases=['descr']),
        pool=dict(type='str', aliases=['name', 'pool_name']),
        state=dict(type='str',
                   default='present',
                   choices=['absent', 'present', 'query']),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['pool']],
            ['state', 'present', ['pool']],
        ],
    )

    allocation_mode = module.params['allocation_mode']
    description = module.params['description']
    pool = module.params['pool']
    state = module.params['state']

    pool_name = pool

    # ACI Pool URL requires the allocation mode for vlan and vsan pools (ex: uni/infra/vlanns-[poolname]-static)
    if pool is not None:
        if allocation_mode is not None:
            pool_name = '[{0}]-{1}'.format(pool, allocation_mode)
        else:
            module.fail_json(
                msg="ACI requires the 'allocation_mode' when 'pool' is provided"
            )

    aci = ACIModule(module)
    aci.construct_url(root_class=dict(
        aci_class='fvnsVlanInstP',
        aci_rn='infra/vlanns-{0}'.format(pool_name),
        filter_target='eq(fvnsVlanInstP.name, "{0}")'.format(pool),
        module_object=pool,
    ), )

    aci.get_existing()

    if state == 'present':
        # Filter out module parameters with null values
        aci.payload(aci_class='fvnsVlanInstP',
                    class_config=dict(
                        allocMode=allocation_mode,
                        descr=description,
                        name=pool,
                    ))

        # Generate config diff which will be used as POST request body
        aci.get_diff(aci_class='fvnsVlanInstP')

        # Submit changes if module not in check_mode and the proposed is different than existing
        aci.post_config()

    elif state == 'absent':
        aci.delete_config()

    module.exit_json(**aci.result)