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']),
        name_alias=dict(type='str'),
    )

    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.get('polling_interval')
    url_protocol = module.params.get('url_protocol')
    state = module.params.get('state')
    source = module.params.get('source')
    url = module.params.get('url')
    url_password = module.params.get('url_password')
    url_username = module.params.get('url_username')
    name_alias = module.params.get('name_alias')

    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,
                nameAlias=name_alias,
            ),
        )

        aci.get_diff(aci_class='firmwareOSource')

        aci.post_config()

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

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        # 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']),
        policy_group=dict(type='str',
                          aliases=['name', 'policy_group_name'
                                   ]),  # Not required for querying all objects
        description=dict(type='str', aliases=['descr']),
        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']),
        name_alias=dict(type='str'),
    )

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

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

    if lag_type == 'leaf':
        aci_class_name = 'infraAccPortGrp'
        dn_name = 'accportgrp'
        class_config_dict = dict(
            name=policy_group,
            descr=description,
            nameAlias=name_alias,
        )
        # Reset for target_filter
        lag_type = None
    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,
            nameAlias=name_alias,
        )

    child_configs = [
        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, ), ), ),
    ]

    # Add infraRsattEntP binding only when aep was defined
    if aep is not None:
        child_configs.append(
            dict(infraRsAttEntP=dict(attributes=dict(
                tDn='uni/infra/attentp-{0}'.format(aep), ), ), ))

    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),
            module_object=policy_group,
            target_filter={
                'name': policy_group,
                'lagT': lag_type
            },
        ),
        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=child_configs,
        )

        aci.get_diff(aci_class=aci_class_name)

        aci.post_config()

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

    aci.exit_json()