def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(aci_annotation_spec())
    argument_spec.update(aci_owner_spec())
    argument_spec.update(
        group=dict(type="str"),  # Not required for querying all objects
        policy=dict(type="str"),  # Not required for querying all objects
        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", ["group"]],
            ["state", "present", ["group"]],
        ],
    )

    state = module.params.get("state")
    group = module.params.get("group")
    policy = module.params.get("policy")
    name_alias = module.params.get("name_alias")
    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class="maintMaintGrp",
            aci_rn="fabric/maintgrp-{0}".format(group),
            target_filter={"name": group},
            module_object=group,
        ),
        child_classes=["maintRsMgrpp"],
    )

    aci.get_existing()

    if state == "present":
        aci.payload(
            aci_class="maintMaintGrp",
            class_config=dict(
                name=group,
                nameAlias=name_alias,
            ),
            child_configs=[
                dict(maintRsMgrpp=dict(attributes=dict(
                    tnMaintMaintPName=policy, ), ), ),
            ],
        )

        aci.get_diff(aci_class="maintMaintGrp")

        aci.post_config()

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

    aci.exit_json()
示例#2
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(aci_annotation_spec())
    argument_spec.update(
        region=dict(type="str", aliases=["name"]),
        cloud=dict(type="str", choices=["aws", "azure"], required=True),
        state=dict(type="str", default="query", choices=["query"]),
    )

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

    region = module.params.get("region")
    cloud = module.params.get("cloud")

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class="cloudProvP",
            aci_rn="clouddomp/provp-{0}".format(cloud),
            target_filter='eq(cloudProvP.vendor, "{0}")'.format(cloud),
            module_object=cloud),
        subclass_1=dict(
            aci_class="cloudRegion",
            aci_rn="region-{0}".format(region),
            target_filter='eq(cloudRegion.name, "{0}")'.format(region),
            module_object=region),
        child_classes=[],
    )

    aci.get_existing()

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(aci_annotation_spec())
    argument_spec.update(
        community=dict(type="str"),
        policy=dict(type="str", aliases=["snmp_policy", "snmp_policy_name"]),
        description=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", ["policy", "community"]],
            ["state", "present", ["policy", "community"]],
        ],
    )

    aci = ACIModule(module)

    community = module.params.get("community")
    policy = module.params.get("policy")
    description = module.params.get("description")
    state = module.params.get("state")

    aci.construct_url(
        root_class=dict(
            aci_class="snmpPol",
            aci_rn="fabric/snmppol-{0}".format(policy),
            module_object=policy,
            target_filter={"name": policy},
        ),
        subclass_1=dict(
            aci_class="snmpCommunityP",
            aci_rn="community-{0}".format(community),
            module_object=community,
            target_filter={"name": community},
        ),
    )

    aci.get_existing()

    if state == "present":
        aci.payload(
            aci_class="snmpCommunityP",
            class_config=dict(name=community, descr=description),
        )

        aci.get_diff(aci_class="snmpCommunityP")

        aci.post_config()

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

    aci.exit_json()
示例#4
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(aci_annotation_spec())
    argument_spec.update(aci_owner_spec())
    argument_spec.update(
        cdp_policy=dict(type="str", required=False, aliases=["cdp_interface", "name"]),  # Not required for querying all objects
        description=dict(type="str", aliases=["descr"]),
        admin_state=dict(type="bool"),
        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", ["cdp_policy"]],
            ["state", "present", ["cdp_policy"]],
        ],
    )

    aci = ACIModule(module)

    cdp_policy = module.params.get("cdp_policy")
    description = module.params.get("description")
    admin_state = aci.boolean(module.params.get("admin_state"), "enabled", "disabled")
    state = module.params.get("state")
    name_alias = module.params.get("name_alias")

    aci.construct_url(
        root_class=dict(
            aci_class="cdpIfPol",
            aci_rn="infra/cdpIfP-{0}".format(cdp_policy),
            module_object=cdp_policy,
            target_filter={"name": cdp_policy},
        ),
    )

    aci.get_existing()

    if state == "present":
        aci.payload(
            aci_class="cdpIfPol",
            class_config=dict(
                name=cdp_policy,
                descr=description,
                adminSt=admin_state,
                nameAlias=name_alias,
            ),
        )

        aci.get_diff(aci_class="cdpIfPol")

        aci.post_config()

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

    aci.exit_json()
示例#5
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(aci_annotation_spec())
    argument_spec.update(aci_owner_spec())
    argument_spec.update(
        name=dict(type="str", aliases=["snmp_policy", "snmp_policy_name"]),
        admin_state=dict(type="str", choices=["enabled", "disabled"]),
        contact=dict(type="str"),
        description=dict(type="str"),
        location=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", ["name"]],
            ["state", "present", ["name"]],
        ],
    )

    aci = ACIModule(module)

    name = module.params.get("name")
    admin_state = module.params.get("admin_state")
    contact = module.params.get("contact")
    description = module.params.get("description")
    location = module.params.get("location")
    state = module.params.get("state")

    aci.construct_url(
        root_class=dict(
            aci_class="snmpPol",
            aci_rn="fabric/snmppol-{0}".format(name),
            module_object=name,
            target_filter={"name": name},
        ),
        child_classes=["snmpCommunityP", "snmpClientGrpP"],
    )

    aci.get_existing()

    if state == "present":
        aci.payload(
            aci_class="snmpPol",
            class_config=dict(name=name, adminSt=admin_state, contact=contact, descr=description, loc=location),
        )

        aci.get_diff(aci_class="snmpPol")

        aci.post_config()

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

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(aci_annotation_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.get("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.get("interface_selector")
    state = module.params.get("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),
            module_object=leaf_profile,
            target_filter={"name": leaf_profile},
        ),
        subclass_1=dict(
            aci_class="infraRsAccPortP",
            aci_rn="rsaccPortP-[{0}]".format(interface_selector_tDn),
            module_object=interface_selector,
            target_filter={"name": 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()
示例#7
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(aci_annotation_spec())
    argument_spec.update(aci_owner_spec())
    argument_spec.update(
        tenant=dict(type="str", aliases=["name", "tenant_name"]),  # Not required for querying all objects
        description=dict(type="str", aliases=["descr"]),
        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", ["tenant"]],
            ["state", "present", ["tenant"]],
        ],
    )

    description = module.params.get("description")
    state = module.params.get("state")
    tenant = module.params.get("tenant")
    name_alias = module.params.get("name_alias")

    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},
        ),
    )
    aci.get_existing()

    if state == "present":
        aci.payload(
            aci_class="fvTenant",
            class_config=dict(
                name=tenant,
                descr=description,
                nameAlias=name_alias,
            ),
        )

        aci.get_diff(aci_class="fvTenant")

        aci.post_config()

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

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(aci_annotation_spec())
    argument_spec.update(aci_owner_spec())
    argument_spec.update(
        name=dict(type="str", aliases=["leaf_switch_profile", "leaf_profile"]),
        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", ["name"]],
            ["state", "present", ["name"]],
        ],
    )

    aci = ACIModule(module)

    name = module.params.get("name")
    description = module.params.get("description")
    state = module.params.get("state")
    child_classes = ["fabricLeafS"]

    aci.construct_url(
        root_class=dict(
            aci_class="fabricLeafP",
            aci_rn="fabric/leprof-{0}".format(name),
            module_object=name,
            target_filter={"name": name},
        ),
        child_classes=child_classes,
    )

    aci.get_existing()

    if state == "present":
        aci.payload(
            aci_class="fabricLeafP",
            class_config=dict(name=name, descr=description),
        )

        aci.get_diff(aci_class="fabricLeafP")

        aci.post_config()

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

    aci.exit_json()
示例#9
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(aci_annotation_spec())
    argument_spec.update(
        tenant=dict(type="str", aliases=["tenant_name"]),
        vrf=dict(type="str", aliases=["context", "vrf_name"]),
        contract=dict(type="str", aliases=["contract_name"]),
        type=dict(type="str", required=True, choices=["provider", "consumer", "interface"], aliases=["contract_type"]),
        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", "vrf", "tenant"]], ["state", "present", ["contract", "vrf", "tenant"]]],
    )

    tenant = module.params.get("tenant")
    vrf = module.params.get("vrf")
    contract = module.params.get("contract")
    type = module.params.get("type")
    state = module.params.get("state")

    aci_class = ACI_CLASS_MAPPING[type]["class"]
    aci_rn = ACI_CLASS_MAPPING[type]["rn"]
    aci_target_attribute = ACI_CLASS_MAPPING[type]["target_attribute"]

    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="fvCtx", aci_rn="ctx-{0}".format(vrf), module_object=vrf, target_filter={"name": vrf}),
        subclass_2=dict(aci_class="vzAny", aci_rn="any", module_object="any", target_filter={"name": "any"}),
        subclass_3=dict(aci_class=aci_class, aci_rn="{0}{1}".format(aci_rn, contract), module_object=contract, target_filter={aci_target_attribute: contract}),
    )

    aci.get_existing()

    if state == "present":
        aci.payload(aci_class=aci_class, class_config={aci_target_attribute: contract})

        aci.get_diff(aci_class=aci_class)

        aci.post_config()

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

    aci.exit_json()
示例#10
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(aci_annotation_spec())
    argument_spec.update(state=dict(type="str",
                                    default="query",
                                    choices=["query"]), )

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

    aci = ACIModule(module)
    aci.construct_url(root_class=dict(aci_class="cloudProvP"))

    aci.get_existing()

    aci.exit_json()
示例#11
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(aci_annotation_spec())
    argument_spec.update({
        "asn":
        dict(type="str"),
        "description":
        dict(type="str", aliases=["descr"]),
        "name":
        dict(type="str",
             aliases=[
                 "autonomous_system_profile", "autonomous_system_profile_name"
             ]),
        "name_alias":
        dict(type="str"),
        "state":
        dict(type="str",
             default="present",
             choices=["absent", "present", "query"]),
    })

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

    annotation = module.params["annotation"]
    asn = module.params["asn"]
    description = module.params["description"]
    name = module.params["name"]
    name_alias = module.params["name_alias"]
    state = module.params["state"]
    child_configs = []

    aci = ACIModule(module)
    aci.construct_url(root_class={
        "aci_class": "cloudBgpAsP",
        "aci_rn": "clouddomp/as".format(),
        "target_filter": {
            "name": name
        },
        "module_object": None
    },
                      child_classes=[])

    aci.get_existing()

    if state == "present":
        aci.payload(
            aci_class="cloudBgpAsP",
            class_config={
                "annotation": annotation,
                "asn": asn,
                "descr": description,
                "name": name,
                "nameAlias": name_alias,
            },
            child_configs=child_configs,
        )

        aci.get_diff(aci_class="cloudBgpAsP")

        aci.post_config()

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

    aci.exit_json()
示例#12
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(aci_annotation_spec())
    argument_spec.update(aci_owner_spec())
    argument_spec.update(
        profile=dict(type="str",
                     aliases=["spine_profile", "spine_switch_profile"]),
        name=dict(type="str",
                  aliases=["association_name", "switch_association"]),
        policy_group=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", ["profile", "name"]],
            ["state", "present", ["profile", "name"]],
        ],
    )

    aci = ACIModule(module)

    profile = module.params.get("profile")
    name = module.params.get("name")
    policy_group = module.params.get("policy_group")
    state = module.params.get("state")
    child_classes = ["fabricRsSpNodePGrp", "fabricNodeBlk"]

    aci.construct_url(
        root_class=dict(
            aci_class="fabricSpineP",
            aci_rn="fabric/spprof-{0}".format(profile),
            module_object=profile,
            target_filter={"name": profile},
        ),
        subclass_1=dict(
            aci_class="fabricSpineS",
            aci_rn="spines-{0}-typ-range".format(name),
            module_object=name,
            target_filter={"name": name},
        ),
        child_classes=child_classes,
    )

    aci.get_existing()

    if state == "present":
        child_configs = []
        if policy_group:
            tDn = "uni/fabric/funcprof/spnodepgrp-{0}".format(policy_group)
            child_configs.append(
                dict(fabricRsSpNodePGrp=dict(attributes=dict(tDn=tDn))))
        aci.payload(
            aci_class="fabricSpineS",
            class_config=dict(name=name),
            child_configs=child_configs,
        )

        aci.get_diff(aci_class="fabricSpineS")

        aci.post_config()

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

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(aci_annotation_spec())
    argument_spec.update(
        pod_id=dict(type="int", aliases=["pod", "pod_number"]),
        node_id=dict(type="int", aliases=["leaf", "spine", "node"]),
        fex_id=dict(type="int"),
        interface=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", ["pod_id", "node_id", "interface"]],
            ["state", "present", ["pod_id", "node_id", "interface"]],
        ],
    )

    aci = ACIModule(module)

    pod_id = module.params.get("pod_id")
    node_id = module.params.get("node_id")
    interface = module.params.get("interface")
    fex_id = module.params.get("fex_id")
    state = module.params.get("state")

    if fex_id:
        rn = "rsoosPath-[topology/pod-{0}/paths-{1}/extpaths-{2}/pathep-[eth{3}]]".format(
            pod_id, node_id, fex_id, interface)
    else:
        rn = "rsoosPath-[topology/pod-{0}/paths-{1}/pathep-[eth{2}]]".format(
            pod_id, node_id, interface)

    aci.construct_url(
        root_class=dict(
            aci_class="fabricInst",
            aci_rn="fabric",
            module_object="fabric",
            target_filter={"name": "fabric"},
        ),
        subclass_1=dict(
            aci_class="fabricOOServicePol",
            aci_rn="outofsvc",
            module_object="outofsvc",
            target_filter={"name": "default"},
        ),
        subclass_2=dict(
            aci_class="fabricRsOosPath",
            aci_rn=rn,
        ),
    )

    aci.get_existing()

    if state == "present":
        aci.payload(
            aci_class="fabricRsOosPath",
            class_config=dict(lc="blacklist", ),
        )

        aci.get_diff(aci_class="fabricRsOosPath")

        aci.post_config()

    elif state == "absent":

        aci.delete_config()

    aci.exit_json()
示例#14
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(aci_annotation_spec())
    argument_spec.update(
        tenant=dict(type="str", required=True, aliases=["tenant_name"]),
        l3out=dict(type="str", required=True, aliases=["l3out_name"]),
        extepg=dict(type="str", required=True, aliases=["extepg_name",
                                                        "name"]),
        network=dict(type="str", aliases=["address", "ip"]),
        description=dict(type="str", aliases=["descr"]),
        subnet_name=dict(type="str", aliases=["name"]),
        scope=dict(type="list",
                   elements="str",
                   default=["import-security"],
                   choices=[
                       "export-rtctrl", "import-security", "shared-rtctrl",
                       "shared-security"
                   ]),
        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", "present", ["network"]],
            ["state", "absent", ["network"]],
        ],
    )

    aci = ACIModule(module)

    tenant = module.params.get("tenant")
    l3out = module.params.get("l3out")
    extepg = module.params.get("extepg")
    network = module.params.get("network")
    description = module.params.get("description")
    subnet_name = module.params.get("subnet_name")
    scope = ",".join(sorted(module.params.get("scope")))
    state = module.params.get("state")
    name_alias = module.params.get("name_alias")

    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="l3extOut",
            aci_rn="out-{0}".format(l3out),
            module_object=l3out,
            target_filter={"name": l3out},
        ),
        subclass_2=dict(
            aci_class="l3extInstP",
            aci_rn="instP-{0}".format(extepg),
            module_object=extepg,
            target_filter={"name": extepg},
        ),
        subclass_3=dict(
            aci_class="l3extSubnet",
            aci_rn="extsubnet-[{0}]".format(network),
            module_object=network,
            target_filter={"name": network},
        ),
    )

    aci.get_existing()

    if state == "present":
        aci.payload(
            aci_class="l3extSubnet",
            class_config=dict(
                ip=network,
                descr=description,
                name=subnet_name,
                scope=scope,
                nameAlias=name_alias,
            ),
        )

        aci.get_diff(aci_class="l3extSubnet")

        aci.post_config()

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

    aci.exit_json()
示例#15
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(aci_annotation_spec())
    argument_spec.update(aci_owner_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"]),
        name_alias=dict(type="str"),
    )

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

    aep = module.params.get("aep")
    description = module.params.get("description")
    infra_vlan = module.params.get("infra_vlan")
    state = module.params.get("state")
    name_alias = module.params.get("name_alias")
    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),
            module_object=aep,
            target_filter={"name": aep},
        ),
        child_classes=["infraProvAcc"],
    )

    aci.get_existing()

    try:
        if len(aci.existing[0]
               ["infraAttEntityP"]) == 1 and infra_vlan is False:
            child_configs = []
    except Exception:
        pass

    if state == "present":

        aci.payload(
            aci_class="infraAttEntityP",
            class_config=dict(
                name=aep,
                descr=description,
                nameAlias=name_alias,
            ),
            child_configs=child_configs,
        )

        aci.get_diff(aci_class="infraAttEntityP")

        aci.post_config()

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

    aci.exit_json()
示例#16
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(aci_annotation_spec())
    argument_spec.update(aci_owner_spec())
    argument_spec.update(
        path=dict(type="str", required=True, aliases=["uri"]),
        method=dict(type="str",
                    default="get",
                    choices=["delete", "get", "post"],
                    aliases=["action"]),
        src=dict(type="path", aliases=["config_file"]),
        content=dict(type="raw"),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        mutually_exclusive=[["content", "src"]],
    )

    content = module.params.get("content")
    path = module.params.get("path")
    src = module.params.get("src")

    # Report missing file
    file_exists = False
    if src:
        if os.path.isfile(src):
            file_exists = True
        else:
            module.fail_json(msg="Cannot find/access src '%s'" % src)

    # Find request type
    if path.find(".xml") != -1:
        rest_type = "xml"
        if not HAS_LXML_ETREE:
            module.fail_json(
                msg=
                "The lxml python library is missing, or lacks etree support.")
        if not HAS_XMLJSON_COBRA:
            module.fail_json(
                msg=
                "The xmljson python library is missing, or lacks cobra support."
            )
    elif path.find(".json") != -1:
        rest_type = "json"
    else:
        module.fail_json(
            msg="Failed to find REST API payload type (neither .xml nor .json)."
        )

    aci = ACIRESTModule(module)
    aci.result["status"] = -1  # Ensure we always return a status

    # We include the payload as it may be templated
    payload = content
    if file_exists:
        with open(src, "r") as config_object:
            # TODO: Would be nice to template this, requires action-plugin
            payload = config_object.read()
            payload_output_file = json.loads(payload)

    # Validate payload
    if rest_type == "json":
        if content and isinstance(content, dict):
            # Validate inline YAML/JSON
            payload = json.dumps(payload)
            payload_output_file = json.loads(payload)
        elif payload and isinstance(payload, str) and HAS_YAML:
            try:
                # Validate YAML/JSON string
                payload = json.dumps(yaml.safe_load(payload))
                payload_output_file = json.loads(payload)
            except Exception as e:
                module.fail_json(
                    msg="Failed to parse provided JSON/YAML payload: %s" %
                    to_text(e),
                    exception=to_text(e),
                    payload=payload)
    elif rest_type == "xml" and HAS_LXML_ETREE:
        if content and isinstance(content, dict) and HAS_XMLJSON_COBRA:
            # Validate inline YAML/JSON
            payload = etree.tostring(cobra.etree(payload)[0])
        elif payload and isinstance(payload, str):
            try:
                # Validate XML string
                payload = etree.tostring(etree.fromstring(payload))
            except Exception as e:
                module.fail_json(
                    msg="Failed to parse provided XML payload: %s" %
                    to_text(e),
                    payload=payload)

    # Perform actual request using auth cookie (Same as aci.request(), but also supports XML)
    if "port" in aci.params and aci.params.get("port") is not None:
        aci.url = "%(protocol)s://%(host)s:%(port)s/" % aci.params + path.lstrip(
            "/")
    else:
        aci.url = "%(protocol)s://%(host)s/" % aci.params + path.lstrip("/")
    if aci.params.get("method") != "get":
        path += "?rsp-subtree=modified"
        aci.url = update_qsl(aci.url, {"rsp-subtree": "modified"})

    # Sign and encode request as to APIC's wishes
    if aci.params.get("private_key") is not None:
        aci.cert_auth(path=path, payload=payload)

    aci.method = aci.params.get("method").upper()

    # Perform request
    resp, info = fetch_url(module,
                           aci.url,
                           data=payload,
                           headers=aci.headers,
                           method=aci.method,
                           timeout=aci.params.get("timeout"),
                           use_proxy=aci.params.get("use_proxy"))

    aci.response = info.get("msg")
    aci.status = info.get("status")

    # Report failure
    if info.get("status") != 200:
        try:
            # APIC error
            aci.response_type(info.get("body"), rest_type)
            aci.fail_json(msg="APIC Error %(code)s: %(text)s" % aci.error)
        except KeyError:
            # Connection error
            aci.fail_json(msg="Connection failed for %(url)s. %(msg)s" % info)

    aci.response_type(resp.read(), rest_type)

    aci.result["imdata"] = aci.imdata
    aci.result["totalCount"] = aci.totalCount

    if aci.params.get("method") != "get":
        output_path = aci.params.get("output_path")
        if output_path is not None:
            with open(output_path, "a") as output_file:
                json.dump([payload_output_file], output_file)

    # Report success
    aci.exit_json(**aci.result)
示例#17
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(aci_annotation_spec())
    argument_spec.update(aci_owner_spec())
    argument_spec.update(
        link_level_policy=dict(type="str", aliases=["name"]),
        description=dict(type="str", aliases=["descr"]),
        auto_negotiation=dict(type="bool", default="true"),
        speed=dict(type="str",
                   default="inherit",
                   choices=[
                       "100M", "1G", "10G", "25G", "40G", "50G", "100G",
                       "200G", "400G", "inherit"
                   ]),
        link_debounce_interval=dict(type="int", default="100"),
        forwarding_error_correction=dict(type="str",
                                         default="inherit",
                                         choices=[
                                             "inherit", "kp-fec",
                                             "cl91-rs-fec", "cl74-fc-fec",
                                             "disable-fec", "ieee-rs-fec",
                                             "cons16-rs-fec"
                                         ]),
        state=dict(type="str",
                   default="present",
                   choices=["absent", "present", "query"]),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ["state", "absent", ["link_level_policy"]],
            ["state", "present", ["link_level_policy"]],
        ],
    )

    aci = ACIModule(module)

    link_level_policy = module.params["link_level_policy"]
    description = module.params["description"]
    auto_negotiation = aci.boolean(module.params["auto_negotiation"], "on",
                                   "off")
    speed = module.params["speed"]
    link_debounce_interval = module.params["link_debounce_interval"]
    if link_debounce_interval is not None and link_debounce_interval not in range(
            0, 5001):
        module.fail_json(
            msg=
            'The "link_debounce_interval" must be a value between 0 and 5000')
    forwarding_error_correction = module.params["forwarding_error_correction"]
    state = module.params["state"]

    aci.construct_url(root_class=dict(
        aci_class="fabricHIfPol",
        aci_rn="infra/hintfpol-{0}".format(link_level_policy),
        module_object=link_level_policy,
        target_filter={"name": link_level_policy},
    ), )

    aci.get_existing()

    if state == "present":
        aci.payload(
            aci_class="fabricHIfPol",
            class_config=dict(
                name=link_level_policy,
                descr=description,
                autoNeg=auto_negotiation,
                speed=speed,
                linkDebounce=link_debounce_interval,
                fecMode=forwarding_error_correction,
            ),
        )

        aci.get_diff(aci_class="fabricHIfPol")

        aci.post_config()

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

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(aci_annotation_spec())
    argument_spec.update(
        contract_type=dict(type="str",
                           required=True,
                           choices=["consumer", "provider"]),
        l2out=dict(type="str", aliases=["l2out_name"]),
        contract=dict(type="str"),
        priority=dict(type="str",
                      choices=["level1", "level2", "level3", "unspecified"]),
        provider_match=dict(
            type="str", choices=["all", "at_least_one", "at_most_one",
                                 "none"]),
        state=dict(type="str",
                   default="present",
                   choices=["absent", "present", "query"]),
        tenant=dict(type="str"),
        extepg=dict(type="str", aliases=["extepg_name", "external_epg"]),
    )
    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ["state", "absent", ["extepg", "contract", "l2out", "tenant"]],
            ["state", "present", ["extepg", "contract", "l2out", "tenant"]],
        ],
    )

    l2out = module.params.get("l2out")
    contract = module.params.get("contract")
    contract_type = module.params.get("contract_type")
    extepg = module.params.get("extepg")
    priority = module.params.get("priority")
    provider_match = module.params.get("provider_match")
    if provider_match is not None:
        provider_match = PROVIDER_MATCH_MAPPING.get(provider_match)
    state = module.params.get("state")
    tenant = module.params.get("tenant")

    aci_class = ACI_CLASS_MAPPING.get(contract_type)["class"]
    aci_rn = ACI_CLASS_MAPPING.get(contract_type)["rn"]

    if contract_type == "consumer" and provider_match is not None:
        module.fail_json(
            msg=
            "the 'provider_match' is only configurable for Provided Contracts")

    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="l2extOut",
            aci_rn="l2out-{0}".format(l2out),
            module_object=l2out,
            target_filter={"name": l2out},
        ),
        subclass_2=dict(
            aci_class="l2extInstP",
            aci_rn="instP-{0}".format(extepg),
            module_object=extepg,
            target_filter={"name": extepg},
        ),
        subclass_3=dict(
            aci_class=aci_class,
            aci_rn="{0}{1}".format(aci_rn, contract),
            module_object=contract,
            target_filter={"tnVzBrCPName": contract},
        ),
    )

    aci.get_existing()

    if state == "present":
        aci.payload(
            aci_class=aci_class,
            class_config=dict(
                matchT=provider_match,
                prio=priority,
                tnVzBrCPName=contract,
            ),
        )

        aci.get_diff(aci_class=aci_class)

        aci.post_config()

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

    aci.exit_json()
示例#19
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(aci_annotation_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.get("aep")
    domain = module.params.get("domain")
    domain_type = module.params.get("domain_type")
    vm_provider = module.params.get("vm_provider")
    state = module.params.get("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),
            module_object=aep,
            target_filter={"name": aep},
        ),
        subclass_1=dict(
            aci_class="infraRsDomP",
            aci_rn="rsdomP-[{0}]".format(domain_mo),
            module_object=domain_mo,
            target_filter={"tDn": 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()
示例#20
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(aci_annotation_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=["l2dom", "phys", "vmm"],
                         aliases=["type"
                                  ]),  # Not required for querying all objects
        encap=dict(type="int"),
        encap_mode=dict(type="str", choices=["auto", "vlan", "vxlan"]),
        switching_mode=dict(type="str",
                            default="native",
                            choices=["AVE", "native"]),
        epg=dict(type="str",
                 aliases=["name", "epg_name"
                          ]),  # Not required for querying all objects
        enhanced_lag_policy=dict(type="str", aliases=["lag_policy"]),
        netflow=dict(type="bool"),
        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"
                         ]),
        promiscuous=dict(type="str",
                         default="reject",
                         choices=["accept", "reject"]),
        custom_epg_name=dict(type="str"),
    )

    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.get("allow_useg")
    ap = module.params.get("ap")
    deploy_immediacy = module.params.get("deploy_immediacy")
    domain = module.params.get("domain")
    domain_type = module.params.get("domain_type")
    vm_provider = module.params.get("vm_provider")
    promiscuous = module.params.get("promiscuous")
    custom_epg_name = module.params.get("custom_epg_name")
    encap = module.params.get("encap")
    if encap is not None:
        if encap in range(1, 4097):
            encap = "vlan-{0}".format(encap)
        else:
            module.fail_json(msg="Valid VLAN assignments are from 1 to 4096")
    encap_mode = module.params.get("encap_mode")
    switching_mode = module.params.get("switching_mode")
    epg = module.params.get("epg")
    enhanced_lag_policy = module.params.get("enhanced_lag_policy")
    netflow = aci.boolean(module.params.get("netflow"), "enabled", "disabled")
    primary_encap = module.params.get("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 assignments are from 1 to 4096")
    resolution_immediacy = module.params.get("resolution_immediacy")
    state = module.params.get("state")
    tenant = module.params.get("tenant")

    if domain_type in ["l2dom", "phys"] and vm_provider is not None:
        module.fail_json(msg="Domain type '%s' cannot have a 'vm_provider'" %
                         domain_type)

    child_classes = None
    child_configs = None

    # 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)
        child_configs = [
            dict(vmmSecP=dict(attributes=dict(allowPromiscuous=promiscuous)))
        ]
        child_classes = ["vmmSecP"]

        if enhanced_lag_policy is not None:
            lag_policy = epg_domain + "/vswitchpolcont/enlacplagp-{0}".format(
                enhanced_lag_policy)
            child_configs.append(
                dict(fvAEPgLagPolAtt=dict(
                    attributes=dict(annotation=""),
                    children=[
                        dict(fvRsVmmVSwitchEnhancedLagPol=dict(
                            attributes=dict(annotation="", tDn=lag_policy)))
                    ])))
            child_classes.append("fvAEPgLagPolAtt")

    elif domain_type == "l2dom":
        epg_domain = "uni/l2dom-{0}".format(domain)
    elif domain_type == "phys":
        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},
        ),
        child_classes=child_classes,
    )

    aci.get_existing()

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

        aci.get_diff(aci_class="fvRsDomAtt")

        aci.post_config()

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

    aci.exit_json()
示例#21
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(aci_annotation_spec())
    argument_spec.update(aci_owner_spec())
    argument_spec.update(
        {
            "name": dict(type="str", aliases=["selector", "cloud_external_epg_selector", "external_epg_selector", "extepg_selector", "selector_name"]),
            "subnet": dict(type="str", aliases=["ip"]),
            "tenant": dict(type="str"),
            "cloud_external_epg": dict(type="str"),
            "ap": dict(type="str", aliases=["app_profile", "app_profile_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", ["subnet", "tenant", "ap", "cloud_external_epg"]],
            ["state", "present", ["subnet", "tenant", "ap", "cloud_external_epg"]],
        ],
    )

    name = module.params.get("name")
    subnet = module.params.get("subnet")
    tenant = module.params.get("tenant")
    ap = module.params.get("ap")
    cloud_external_epg = module.params.get("cloud_external_epg")
    state = module.params.get("state")
    child_configs = []

    aci = ACIModule(module)
    aci.construct_url(
        root_class={
            "aci_class": "fvTenant",
            "aci_rn": "tn-{0}".format(tenant),
            "target_filter": 'eq(fvTenant.name, "{0}")'.format(tenant),
            "module_object": tenant,
        },
        subclass_1={"aci_class": "cloudApp", "aci_rn": "cloudapp-{0}".format(ap), "target_filter": 'eq(cloudApp.name, "{0}")'.format(ap), "module_object": ap},
        subclass_2={
            "aci_class": "cloudExtEPg",
            "aci_rn": "cloudextepg-{0}".format(cloud_external_epg),
            "target_filter": 'eq(cloudExtEPg.name, "{0}")'.format(cloud_external_epg),
            "module_object": cloud_external_epg,
        },
        subclass_3={
            "aci_class": "cloudExtEPSelector",
            "aci_rn": "extepselector-[{0}]".format(subnet),
            "target_filter": 'eq(cloudExtEPSelector.name, "{0}")'.format(subnet),
            "module_object": subnet,
        },
        child_classes=[],
    )

    aci.get_existing()

    if state == "present":
        aci.payload(
            aci_class="cloudExtEPSelector",
            class_config={
                "name": name,
                "subnet": subnet,
            },
            child_configs=child_configs,
        )

        aci.get_diff(aci_class="cloudExtEPSelector")

        aci.post_config()

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

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(aci_annotation_spec())
    argument_spec.update(aci_owner_spec())
    argument_spec.update(
        tenant=dict(type="str",
                    aliases=["tenant_name"
                             ]),  # Not required for querying all objects
        destination_epg=dict(type="dict", options=destination_epg_spec()),
        destination_group=dict(type="str", aliases=[
            "name", "dst_group"
        ]),  # Not required for querying all objects
        description=dict(type="str", aliases=["descr"]),
        name_alias=dict(type="str"),
        source_ip=dict(type="str"),
        destination_ip=dict(type="str"),
        mtu=dict(type="int"),
        ttl=dict(type="int"),
        flow_id=dict(type="int"),
        version_enforced=dict(type="bool"),
        span_version=dict(type="str", choices=["version_1", "version_2"]),
        dscp=dict(type="str",
                  choices=[
                      "CS0", "CS1", "CS2", "CS3", "CS4", "CS5", "CS6", "CS7",
                      "EF", "VA", "AF11", "AF12", "AF13", "AF21", "AF22",
                      "AF23", "AF31", "AF32", "AF33", "AF41", "AF42", "AF43",
                      "unspecified"
                  ]),
        state=dict(type="str",
                   default="present",
                   choices=["absent", "present", "query"]),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ["state", "absent", ["destination_group", "tenant"]],
            [
                "state", "present",
                [
                    "destination_group", "destination_ip", "source_ip",
                    "destination_epg", "tenant"
                ]
            ],
        ],
    )

    aci = ACIModule(module)

    destination_epg = module.params.get("destination_epg")
    destination_group = module.params.get("destination_group")
    description = module.params.get("description")
    state = module.params.get("state")
    tenant = module.params.get("tenant")
    destination_ip = module.params.get("destination_ip")
    source_ip = module.params.get("source_ip")
    span_version = module.params.get("span_version")
    name_alias = module.params.get("name_alias")
    dscp = module.params.get("dscp")
    mtu = str(module.params.get("mtu"))
    ttl = str(module.params.get("ttl"))
    flow_id = str(module.params.get("flow_id"))
    version_enforced = module.params.get("version_enforced")

    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(destination_group),
            module_object=destination_group,
            target_filter={"name": destination_group},
        ),
        child_classes=["spanDest", "spanRsDestEpg"],
    )

    aci.get_existing()

    if state == "present":
        dest_tdn = "uni/tn-{0}/ap-{1}/epg-{2}".format(
            destination_epg["tenant"], destination_epg["ap"],
            destination_epg["epg"])

        if version_enforced is True:
            version_enforced = "yes"
        else:
            version_enforced = "no"

        if span_version == "version_1":
            span_version = "ver1"
        else:
            span_version = "ver2"

        child_configs = [
            dict(spanDest=dict(attributes=dict(name=destination_group),
                               children=[
                                   dict(spanRsDestEpg=dict(attributes=dict(
                                       ip=destination_ip,
                                       srcIpPrefix=source_ip,
                                       ver=span_version,
                                       verEnforced=version_enforced,
                                       ttl=ttl,
                                       mtu=mtu,
                                       flowId=flow_id,
                                       dscp=dscp,
                                       tDn=dest_tdn)))
                               ])),
        ]

        aci.payload(
            aci_class="spanDestGrp",
            class_config=dict(
                name=destination_group,
                descr=description,
                nameAlias=name_alias,
            ),
            child_configs=child_configs,
        )

        aci.get_diff(aci_class="spanDestGrp")

        aci.post_config()

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

    aci.exit_json()
示例#23
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(aci_annotation_spec())
    argument_spec.update(aci_owner_spec())
    argument_spec.update(
        contract=dict(type="str",
                      aliases=["contract_name", "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"]),
        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"]),
        name_alias=dict(type="str"),
    )

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

    contract = module.params.get("contract")
    description = module.params.get("description")
    scope = module.params.get("scope")
    priority = module.params.get("priority")
    dscp = module.params.get("dscp")
    state = module.params.get("state")
    tenant = module.params.get("tenant")
    name_alias = module.params.get("name_alias")

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

        aci.get_diff(aci_class="vzBrCP")

        aci.post_config()

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

    aci.exit_json()
示例#24
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(aci_annotation_spec())
    argument_spec.update(aci_owner_spec())
    argument_spec.update(
        arp_flooding=dict(type="bool"),
        bd=dict(type="str",
                aliases=["bd_name",
                         "name"]),  # Not required for querying all objects
        bd_type=dict(type="str", choices=["ethernet", "fc"]),
        description=dict(type="str"),
        enable_multicast=dict(type="bool"),
        enable_routing=dict(type="bool"),
        endpoint_clear=dict(type="bool"),
        endpoint_move_detect=dict(type="str", choices=["default", "garp"]),
        endpoint_retention_action=dict(type="str",
                                       choices=["inherit", "resolve"]),
        endpoint_retention_policy=dict(type="str"),
        igmp_snoop_policy=dict(type="str"),
        ip_learning=dict(type="bool"),
        ipv6_nd_policy=dict(type="str"),
        l2_unknown_unicast=dict(type="str", choices=["proxy", "flood"]),
        l3_unknown_multicast=dict(type="str", choices=["flood", "opt-flood"]),
        ipv6_l3_unknown_multicast=dict(type="str",
                                       choices=["flood", "opt-flood"]),
        limit_ip_learn=dict(type="bool"),
        mac_address=dict(type="str", aliases=["mac"]),
        multi_dest=dict(type="str",
                        choices=["bd-flood", "drop", "encap-flood"]),
        state=dict(type="str",
                   default="present",
                   choices=["absent", "present", "query"]),
        tenant=dict(type="str",
                    aliases=["tenant_name"
                             ]),  # Not required for querying all objects
        vrf=dict(type="str", aliases=["vrf_name"]),
        route_profile=dict(type="str"),
        route_profile_l3out=dict(type="str"),
        name_alias=dict(type="str"),
    )

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

    aci = ACIModule(module)

    arp_flooding = aci.boolean(module.params.get("arp_flooding"))
    bd = module.params.get("bd")
    bd_type = module.params.get("bd_type")
    if bd_type == "ethernet":
        # ethernet type is represented as regular, but that is not clear to the users
        bd_type = "regular"
    description = module.params.get("description")
    enable_multicast = aci.boolean(module.params.get("enable_multicast"))
    enable_routing = aci.boolean(module.params.get("enable_routing"))
    endpoint_clear = aci.boolean(module.params.get("endpoint_clear"))
    endpoint_move_detect = module.params.get("endpoint_move_detect")
    if endpoint_move_detect == "default":
        # the ACI default setting is an empty string, but that is not a good input value
        endpoint_move_detect = ""
    endpoint_retention_action = module.params.get("endpoint_retention_action")
    endpoint_retention_policy = module.params.get("endpoint_retention_policy")
    igmp_snoop_policy = module.params.get("igmp_snoop_policy")
    ip_learning = aci.boolean(module.params.get("ip_learning"))
    ipv6_nd_policy = module.params.get("ipv6_nd_policy")
    l2_unknown_unicast = module.params.get("l2_unknown_unicast")
    l3_unknown_multicast = module.params.get("l3_unknown_multicast")
    ipv6_l3_unknown_multicast = module.params.get("ipv6_l3_unknown_multicast")
    limit_ip_learn = aci.boolean(module.params.get("limit_ip_learn"))
    mac_address = module.params.get("mac_address")
    multi_dest = module.params.get("multi_dest")
    state = module.params.get("state")
    tenant = module.params.get("tenant")
    vrf = module.params.get("vrf")
    route_profile = module.params.get("route_profile")
    route_profile_l3out = module.params.get("route_profile_l3out")
    name_alias = module.params.get("name_alias")

    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},
        ),
        child_classes=[
            "fvRsCtx", "fvRsIgmpsn", "fvRsBDToNdP", "fvRsBdToEpRet",
            "fvRsBDToProfile"
        ],
    )

    aci.get_existing()

    if state == "present":
        class_config = dict(
            arpFlood=arp_flooding,
            descr=description,
            epClear=endpoint_clear,
            epMoveDetectMode=endpoint_move_detect,
            ipLearning=ip_learning,
            limitIpLearnToSubnets=limit_ip_learn,
            mac=mac_address,
            mcastAllow=enable_multicast,
            multiDstPktAct=multi_dest,
            name=bd,
            type=bd_type,
            unicastRoute=enable_routing,
            unkMacUcastAct=l2_unknown_unicast,
            unkMcastAct=l3_unknown_multicast,
            nameAlias=name_alias,
        )

        if ipv6_l3_unknown_multicast is not None:
            class_config["v6unkMcastAct"] = ipv6_l3_unknown_multicast

        aci.payload(
            aci_class="fvBD",
            class_config=class_config,
            child_configs=[
                {
                    "fvRsCtx": {
                        "attributes": {
                            "tnFvCtxName": vrf
                        }
                    }
                },
                {
                    "fvRsIgmpsn": {
                        "attributes": {
                            "tnIgmpSnoopPolName": igmp_snoop_policy
                        }
                    }
                },
                {
                    "fvRsBDToNdP": {
                        "attributes": {
                            "tnNdIfPolName": ipv6_nd_policy
                        }
                    }
                },
                {
                    "fvRsBdToEpRet": {
                        "attributes": {
                            "resolveAct": endpoint_retention_action,
                            "tnFvEpRetPolName": endpoint_retention_policy
                        }
                    }
                },
                {
                    "fvRsBDToProfile": {
                        "attributes": {
                            "tnL3extOutName": route_profile_l3out,
                            "tnRtctrlProfileName": route_profile
                        }
                    }
                },
            ],
        )

        aci.get_diff(aci_class="fvBD")

        aci.post_config()

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

    aci.exit_json()
示例#25
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(aci_annotation_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
        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
        log=dict(type="str", choices=["log", "none"], aliases=["directive"]),
        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.get("contract")
    filter_name = module.params.get("filter")
    log = module.params.get("log")
    subject = module.params.get("subject")
    tenant = module.params.get("tenant")
    state = module.params.get("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),
            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},
        ),
        subclass_2=dict(
            aci_class="vzSubj",
            aci_rn="subj-{0}".format(subject),
            module_object=subject,
            target_filter={"name": subject},
        ),
        subclass_3=dict(
            aci_class="vzRsSubjFiltAtt",
            aci_rn="rssubjFiltAtt-{0}".format(filter_name),
            module_object=filter_name,
            target_filter={"tnVzFilterName": 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()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(aci_annotation_spec())
    argument_spec.update(aci_owner_spec())
    argument_spec.update(
        node_profile=dict(
            type="str", aliases=["name", "node_profile_name", "logical_node"]),
        tenant=dict(type="str", aliases=["tenant_name"]),
        l3out=dict(type="str", aliases=["l3out_name"]),
        description=dict(type="str", aliases=["descr"]),
        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_dscp"],
        ),
        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", ["tenant", "l3out", "node_profile"]],
            ["state", "present", ["tenant", "l3out", "node_profile"]],
        ],
    )

    node_profile = module.params.get("node_profile")
    tenant = module.params.get("tenant")
    l3out = module.params.get("l3out")
    description = module.params.get("description")
    dscp = module.params.get("dscp")
    state = module.params.get("state")
    name_alias = module.params.get("name_alias")

    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="l3extOut",
            aci_rn="out-{0}".format(l3out),
            module_object=l3out,
            target_filter={"name": l3out},
        ),
        subclass_2=dict(
            aci_class="l3extLNodeP",
            aci_rn="lnodep-{0}".format(node_profile),
            module_object=node_profile,
            target_filter={"name": node_profile},
        ),
    )

    aci.get_existing()

    if state == "present":
        aci.payload(
            aci_class="l3extLNodeP",
            class_config=dict(
                descr=description,
                name=node_profile,
                targetDscp=dscp,
                nameAlias=name_alias,
            ),
        )

        aci.get_diff(aci_class="l3extLNodeP")

        aci.post_config()

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

    aci.exit_json()
示例#27
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(aci_annotation_spec())
    argument_spec.update(aci_owner_spec())
    argument_spec.update(
        interface_profile=dict(type="str",
                               aliases=[
                                   "leaf_interface_profile_name",
                                   "leaf_interface_profile",
                                   "interface_profile_name"
                               ]),
        access_port_selector=dict(type="str",
                                  aliases=[
                                      "name", "access_port_selector_name"
                                  ]),  # Not required for querying all objects
        description=dict(type="str"),
        port_blk=dict(
            type="str",
            aliases=["leaf_port_blk_name", "leaf_port_blk", "port_blk_name"]),
        leaf_port_blk_description=dict(type="str"),
        from_port=dict(type="str",
                       aliases=["from", "fromPort", "from_port_range"]),
        to_port=dict(type="str", aliases=["to", "toPort", "to_port_range"]),
        from_card=dict(type="str", aliases=["from_card_range"]),
        to_card=dict(type="str", aliases=["to_card_range"]),
        policy_group=dict(type="str", aliases=["policy_group_name"]),
        interface_type=dict(type="str",
                            default="switch_port",
                            choices=[
                                "breakout", "fex", "port_channel",
                                "switch_port", "vpc", "fex_port_channel",
                                "fex_vpc"
                            ]),
        type=dict(type="str", default="leaf", choices=["fex", "leaf"]),
        state=dict(type="str",
                   default="present",
                   choices=["absent", "present", "query"]),
    )

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

    interface_profile = module.params.get("interface_profile")
    access_port_selector = module.params.get("access_port_selector")
    description = module.params.get("description")
    port_blk = module.params.get("port_blk")
    leaf_port_blk_description = module.params.get("leaf_port_blk_description")
    from_port = module.params.get("from_port")
    to_port = module.params.get("to_port")
    from_card = module.params.get("from_card")
    to_card = module.params.get("to_card")
    policy_group = module.params.get("policy_group")
    interface_type = module.params.get("interface_type")
    state = module.params.get("state")
    type_profile = module.params.get("type")

    # Build child_configs dynamically
    child_configs = [
        dict(infraPortBlk=dict(attributes=dict(
            descr=leaf_port_blk_description,
            name=port_blk,
            fromPort=from_port,
            toPort=to_port,
            fromCard=from_card,
            toCard=to_card,
        ), ), )
    ]

    # Add infraRsAccBaseGrp only when policy_group was defined
    if policy_group is not None:
        child_configs.append(
            dict(infraRsAccBaseGrp=dict(attributes=dict(
                tDn=INTERFACE_TYPE_MAPPING[interface_type].format(
                    policy_group), ), ), ))

    aci = ACIModule(module)
    aci_class = "infraAccPortP"
    aci_rn = "accportprof"
    if type_profile == "fex":
        aci_class = "infraFexP"
        aci_rn = "fexprof"
    aci.construct_url(
        root_class=dict(
            aci_class=aci_class,
            aci_rn="infra/" + aci_rn + "-{0}".format(interface_profile),
            module_object=interface_profile,
            target_filter={"name": 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},
        ),
        child_classes=["infraPortBlk", "infraRsAccBaseGrp"],
    )

    aci.get_existing()

    if state == "present":
        aci.payload(
            aci_class="infraHPortS",
            class_config=dict(
                descr=description,
                name=access_port_selector,
                #  type='range',
            ),
            child_configs=child_configs,
        )

        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(aci_annotation_spec())
    argument_spec.update(aci_owner_spec())
    argument_spec.update({
        "description":
        dict(type="str"),
        "expressions":
        dict(type="list", elements="dict", options=expression_spec()),
        "name":
        dict(type="str", aliases=["selector", "selector_name"]),
        "tenant":
        dict(type="str", required=True),
        "ap":
        dict(type="str", required=True),
        "epg":
        dict(type="str", 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", ["name"]],
            ["state", "present", ["name"]],
        ],
    )

    description = module.params.get("description")
    expressions = module.params.get("expressions")
    name = module.params.get("name")
    tenant = module.params.get("tenant")
    ap = module.params.get("ap")
    epg = module.params.get("epg")
    state = module.params.get("state")
    child_configs = []

    aci = ACIModule(module)
    aci.construct_url(
        root_class={
            "aci_class": "fvTenant",
            "aci_rn": "tn-{0}".format(tenant),
            "target_filter": 'eq(fvTenant.name, "{0}")'.format(tenant),
            "module_object": tenant,
        },
        subclass_1={
            "aci_class": "cloudApp",
            "aci_rn": "cloudapp-{0}".format(ap),
            "target_filter": 'eq(cloudApp.name, "{0}")'.format(ap),
            "module_object": ap
        },
        subclass_2={
            "aci_class": "cloudEPg",
            "aci_rn": "cloudepg-{0}".format(epg),
            "target_filter": 'eq(cloudEPg.name, "{0}")'.format(epg),
            "module_object": epg,
        },
        subclass_3={
            "aci_class": "cloudEPSelector",
            "aci_rn": "epselector-{0}".format(name),
            "target_filter": 'eq(cloudEPSelector.name, "{0}")'.format(name),
            "module_object": name,
        },
        child_classes=[],
    )

    aci.get_existing()

    if state == "present":
        expressions_list = []
        for expression in expressions:
            key = expression.get("key")
            operator = expression.get("operator")
            if expression.get("value"):
                value = "'" + "','".join(
                    expression.get("value").split(",")) + "'"
            else:
                value = None
            if operator in ["has_key", "does_not_have_key"]:
                if value:
                    module.fail_json(
                        msg=
                        "Attribute 'value' is not supported for operator '{0}' in expression '{1}'"
                        .format(operator, key))
                if key in ["ip", "region"]:
                    module.fail_json(
                        msg=
                        "Operator '{0}' is not supported when expression key is '{1}'"
                        .format(operator, key))
            if operator in ["not_in", "in", "equals", "not_equals"
                            ] and not value:
                module.fail_json(
                    msg=
                    "Attribute 'value' needed for operator '{0}' in expression '{1}'"
                    .format(operator, key))
            if key in ["ip", "region", "zone"]:
                key = EXPRESSION_KEYS.get(key)
            else:
                key = "custom:" + key
            if operator in ["not_in", "in"]:
                expressions_list.append("{0} {1}({2})".format(
                    key, EXPRESSION_OPERATORS.get(operator), value))
            elif operator in ["equals", "not_equals"]:
                expressions_list.append("{0}{1}{2}".format(
                    key, EXPRESSION_OPERATORS.get(operator), value))
            elif operator == "does_not_have_key":
                expressions_list.append("!{0}".format(key))
            else:
                expressions_list.append(key)
        matchExpression = ",".join(expressions_list)
        aci.payload(
            aci_class="cloudEPSelector",
            class_config={
                "descr": description,
                "matchExpression": matchExpression,
                "name": name,
            },
            child_configs=child_configs,
        )

        aci.get_diff(aci_class="cloudEPSelector")

        aci.post_config()

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

    aci.exit_json()
示例#29
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(aci_annotation_spec())
    argument_spec.update(aci_owner_spec())
    argument_spec.update(
        pool=dict(type="str",
                  aliases=["name", "pool_name"
                           ]),  # Not required for querying all objects
        description=dict(type="str", aliases=["descr"]),
        pool_allocation_mode=dict(type="str",
                                  aliases=["allocation_mode", "mode"],
                                  choices=["dynamic", "static"]),
        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", ["pool"]],
            ["state", "present", ["pool"]],
        ],
    )

    description = module.params.get("description")
    pool = module.params.get("pool")
    pool_allocation_mode = module.params.get("pool_allocation_mode")
    state = module.params.get("state")
    name_alias = module.params.get("name_alias")

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

        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(aci_annotation_spec())
    argument_spec.update(
        name=dict(type="str", aliases=["block_name"]),
        switch_type=dict(type="str", choices=["leaf", "spine"], required=True),
        profile=dict(type="str", aliases=["profile_name", "switch_profile"]),
        association=dict(type="str",
                         aliases=["association_name", "switch_association"]),
        description=dict(type="str", aliases=["descr"]),
        from_node=dict(type="int", aliases=["from", "from_"]),
        to_node=dict(type="int", aliases=["to", "to_"]),
        state=dict(type="str",
                   default="present",
                   choices=["absent", "present", "query"]),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ["state", "absent", ["profile", "association", "name"]],
            ["state", "present", ["profile", "association", "name"]],
        ],
    )

    aci = ACIModule(module)

    name = module.params.get("name")
    profile = module.params.get("profile")
    switch_type = module.params.get("switch_type")
    association = module.params.get("association")
    descr = module.params.get("descr")
    from_node = module.params.get("from_node")
    to_node = module.params.get("to_node")
    state = module.params.get("state")

    if switch_type == "spine":
        aci_root_class = "fabricSpineP"
        aci_root_rn = "fabric/spprof-{0}".format(profile)
        aci_subclass1_class = "fabricSpineS"
        aci_subclass1_rn = "spines-{0}-typ-range".format(association)
    elif switch_type == "leaf":
        aci_root_class = "fabricLeafP"
        aci_root_rn = "fabric/leprof-{0}".format(profile)
        aci_subclass1_class = "fabricLeafS"
        aci_subclass1_rn = "leaves-{0}-typ-range".format(association)

    aci.construct_url(
        root_class=dict(
            aci_class=aci_root_class,
            aci_rn=aci_root_rn,
            module_object=profile,
            target_filter={"name": profile},
        ),
        subclass_1=dict(
            aci_class=aci_subclass1_class,
            aci_rn=aci_subclass1_rn,
            module_object=association,
            target_filter={"name": association},
        ),
        subclass_2=dict(
            aci_class="fabricNodeBlk",
            aci_rn="nodeblk-{0}".format(name),
            module_object=name,
            target_filter={"name": name},
        ),
    )

    aci.get_existing()

    if state == "present":
        aci.payload(
            aci_class="fabricNodeBlk",
            class_config=dict(name=name,
                              descr=descr,
                              from_=from_node,
                              to_=to_node),
        )

        aci.get_diff(aci_class="fabricNodeBlk")

        aci.post_config()

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

    aci.exit_json()