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()
Example #2
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(aci_annotation_spec())
    argument_spec.update(
        tenant=dict(type="str",
                    aliases=["tenant_name"
                             ]),  # Not required for querying all objects
        l3out=dict(type="str",
                   aliases=["l3out_name"
                            ]),  # Not required for querying all objects
        extepg=dict(type="str",
                    aliases=["extepg_name",
                             "name"]),  # Not required for querying all objects
        description=dict(type="str", aliases=["descr"]),
        preferred_group=dict(type="bool"),
        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"],
        ),
        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", ["extepg", "l3out", "tenant"]],
            ["state", "absent", ["extepg", "l3out", "tenant"]],
        ],
    )

    aci = ACIModule(module)

    tenant = module.params.get("tenant")
    l3out = module.params.get("l3out")
    extepg = module.params.get("extepg")
    description = module.params.get("description")
    preferred_group = aci.boolean(module.params.get("preferred_group"),
                                  "include", "exclude")
    dscp = module.params.get("dscp")
    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},
        ),
    )

    aci.get_existing()

    if state == "present":
        aci.payload(
            aci_class="l3extInstP",
            class_config=dict(
                name=extepg,
                descr=description,
                prefGrMemb=preferred_group,
                targetDscp=dscp,
                nameAlias=name_alias,
            ),
        )

        aci.get_diff(aci_class="l3extInstP")

        aci.post_config()

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

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

    port_security = module.params.get('port_security')
    description = module.params.get('description')
    max_end_points = module.params.get('max_end_points')
    port_security_timeout = module.params.get('port_security_timeout')
    name_alias = module.params.get('name_alias')
    if max_end_points is not None and max_end_points not in range(12001):
        module.fail_json(
            msg='The "max_end_points" must be between 0 and 12000')
    if port_security_timeout is not None and port_security_timeout not in range(
            60, 3601):
        module.fail_json(
            msg='The "port_security_timeout" must be between 60 and 3600')
    state = module.params.get('state')

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

    aci.get_existing()

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

        aci.get_diff(aci_class='l2PortSecurityPol')

        aci.post_config()

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

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

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

    aci = ACIModule(module)

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

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

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

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

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

        aci.get_existing()

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

        aci.get_diff(aci_class='configImportP')

        aci.post_config()

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

        # Generate rollback comparison
        get_preview(aci)

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        tenant=dict(type='str', aliases=['tenant_name']),  # Not required for querying all objects
        l3out=dict(type='str', aliases=['l3out_name']),  # Not required for querying all objects
        logical_node=dict(type='str', aliases=['node_profile', 'node_profile_name']),  # Not required for querying all objects
        pod_id=dict(type='int'),
        node_id=dict(type='int'),
        prefix=dict(type='str', aliases=['route']),
        track_policy=dict(type='str'),
        preference=dict(type='int'),
        bfd=dict(type='str', choices=['bfd', None]),
        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', 'present', ['prefix', 'node_id', 'pod_id', 'logical_node', 'l3out', 'tenant']],
            ['state', 'absent', ['prefix', 'node_id', 'pod_id', 'logical_node', 'l3out', 'tenant']],
        ],
    )

    aci = ACIModule(module)

    tenant = module.params.get('tenant')
    l3out = module.params.get('l3out')
    logical_node = module.params.get('logical_node')
    node_id = module.params.get('node_id')
    pod_id = module.params.get('pod_id')
    prefix = module.params.get('prefix')
    track_policy = module.params.get('track_policy')
    preference = module.params.get('preference')
    bfd = module.params.get('bfd')
    description = module.params.get('description')
    state = module.params.get('state')
    name_alias = module.params.get('name_alias')

    fabric_node = 'topology/pod-{0}/node-{1}'.format(pod_id, node_id)
    child_classes = ['ipNexthopP']
    if track_policy is not None:
        child_classes.append('ipRsRouteTrack')

    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(logical_node),
            module_object=logical_node,
            target_filter={'name': logical_node},
        ),
        subclass_3=dict(
            aci_class='l3extRsNodeL3OutAtt',
            aci_rn='rsnodeL3OutAtt-[{0}]'.format(fabric_node),
            module_object=fabric_node,
            target_filter={'name': fabric_node},
        ),
        subclass_4=dict(
            aci_class='ipRouteP',
            aci_rn='rt-[{0}]'.format(prefix),
            module_object=prefix,
            target_filter={'name': prefix},
        ),
        child_classes=child_classes
    )

    aci.get_existing()

    if state == 'present':
        child_configs = []
        class_config = dict(
            descr=description,
            ip=prefix,
            pref=preference,
            nameAlias=name_alias,
        )
        if bfd is not None:
            class_config['rtCtrl'] = bfd

        if track_policy is not None:
            tDn = 'uni/tn-{0}/tracklist-{1}'.format(tenant, track_policy)
            child_configs.append({'ipRsRouteTrack': {'attributes': {'tDn': tDn}}})

        aci.payload(
            aci_class='ipRouteP',
            class_config=class_config,
            child_configs=child_configs
        ),

        aci.get_diff(aci_class='ipRouteP')

        aci.post_config()

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

    aci.exit_json()
Example #6
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=["leaf_profile", "leaf_switch_profile"]),
        name=dict(type="str",
                  aliases=["association_name", "switch_association"]),
        policy_group=dict(type="str"),
        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", ["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")
    description = module.params.get("description")
    state = module.params.get("state")
    child_classes = ["fabricRsLeNodePGrp", "fabricNodeBlk"]

    aci.construct_url(
        root_class=dict(
            aci_class="fabricLeafP",
            aci_rn="fabric/leprof-{0}".format(profile),
            module_object=profile,
            target_filter={"name": profile},
        ),
        subclass_1=dict(
            aci_class="fabricLeafS",
            aci_rn="leaves-{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/lenodepgrp-{0}".format(policy_group)
            child_configs.append(
                dict(fabricRsLeNodePGrp=dict(attributes=dict(tDn=tDn))))
        aci.payload(
            aci_class="fabricLeafS",
            class_config=dict(name=name, descr=description),
            child_configs=child_configs,
        )

        aci.get_diff(aci_class="fabricLeafS")

        aci.post_config()

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

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

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

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

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

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

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

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

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

    aci.get_existing()

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

        aci.get_diff(aci_class=domain_class)

        aci.post_config()

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

    aci.exit_json()
Example #8
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        name=dict(type='str', aliases=['credential_name', 'credential_profile']),
        credential_password=dict(type='str', no_log=True),
        credential_username=dict(type='str'),
        description=dict(type='str', aliases=['descr']),
        domain=dict(type='str', aliases=['domain_name', 'domain_profile']),
        state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
        vm_provider=dict(type='str', choices=VM_PROVIDER_MAPPING.keys()),
        name_alias=dict(type='str'),
    )

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

    name = module.params.get('name')
    credential_password = module.params.get('credential_password')
    credential_username = module.params.get('credential_username')
    description = module.params.get('description')
    domain = module.params.get('domain')
    state = module.params.get('state')
    vm_provider = module.params.get('vm_provider')
    name_alias = module.params.get('name_alias')

    credential_class = 'vmmUsrAccP'
    usracc_mo = 'uni/vmmp-{0}/dom-{1}/usracc-{2}'.format(VM_PROVIDER_MAPPING.get(vm_provider), domain, name)
    usracc_rn = 'vmmp-{0}/dom-{1}/usracc-{2}'.format(VM_PROVIDER_MAPPING.get(vm_provider), domain, name)

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

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class=credential_class,
            aci_rn=usracc_rn,
            module_object=usracc_mo,
            target_filter={'name': domain, 'usracc': name},
        ),
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class=credential_class,
            class_config=dict(
                descr=description,
                name=name,
                pwd=credential_password,
                usr=credential_username,
                nameAlias=name_alias,
            ),
        )

        aci.get_diff(aci_class=credential_class)

        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(
        compare_export_policy=dict(type="str"),
        compare_snapshot=dict(type="str"),
        description=dict(type="str", aliases=["descr"]),
        export_policy=dict(type="str"),
        fail_on_decrypt=dict(type="bool"),
        import_mode=dict(type="str", choices=["atomic", "best-effort"]),
        import_policy=dict(type="str"),
        import_type=dict(type="str", choices=["merge", "replace"]),
        snapshot=dict(type="str", required=True),
        state=dict(type="str",
                   default="rollback",
                   choices=["preview", "rollback"]),
    )

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

    aci = ACIModule(module)

    description = module.params.get("description")
    export_policy = module.params.get("export_policy")
    fail_on_decrypt = aci.boolean(module.params.get("fail_on_decrypt"))
    import_mode = module.params.get("import_mode")
    import_policy = module.params.get("import_policy")
    import_type = module.params.get("import_type")
    snapshot = module.params.get("snapshot")
    state = module.params.get("state")

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

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

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

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

        aci.get_existing()

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

        aci.get_diff(aci_class="configImportP")

        aci.post_config()

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

        # Generate rollback comparison
        get_preview(aci)

    aci.exit_json()
Example #10
0
def main():
    argument_spec = aci_argument_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()
Example #11
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(aci_annotation_spec())
    argument_spec.update(
        name=dict(type="str", aliases=["syslog_src", "syslog_source"]),
        include=dict(type="list",
                     elements="str",
                     choices=["audit", "events", "faults", "session"]),
        min_severity=dict(type="str",
                          choices=[
                              "alerts", "critical", "debugging", "emergencies",
                              "errors", "information", "notifications",
                              "warnings"
                          ]),
        destination_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", ["name"]],
            ["state", "present", ["name"]],
        ],
    )

    name = module.params.get("name")
    include = module.params.get("include")
    min_severity = module.params.get("min_severity")
    destination_group = module.params.get("destination_group")
    state = module.params.get("state")

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class="syslogSrc",
            aci_rn="fabric/moncommon/slsrc-{0}".format(name),
            module_object=name,
            target_filter={"name": name},
        ),
        child_classes=["syslogRsDestGroup"],
    )

    aci.get_existing()

    if state == "present":
        class_config = dict(name=name, minSev=min_severity)
        if include:
            class_config["incl"] = ",".join(include)

        aci.payload(
            aci_class="syslogSrc",
            class_config=class_config,
            child_configs=[
                dict(syslogRsDestGroup=dict(attributes=dict(tDn=(
                    "uni/fabric/slgroup-{0}".format(destination_group))), ), ),
            ],
        )

        aci.get_diff(aci_class="syslogSrc")

        aci.post_config()

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

    aci.exit_json()
Example #12
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(aci_annotation_spec())
    argument_spec.update(aci_owner_spec())
    argument_spec.update(
        aaa_user=dict(type="str", required=True),
        aaa_user_type=dict(type="str",
                           default="user",
                           choices=["appuser", "user"]),
        certificate=dict(type="str", aliases=["cert_data",
                                              "certificate_data"]),
        name=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", ["aaa_user", "name"]],
            ["state", "present", ["aaa_user", "certificate", "name"]],
        ],
    )

    aaa_user = module.params.get("aaa_user")
    aaa_user_type = module.params.get("aaa_user_type")
    certificate = module.params.get("certificate")
    name = module.params.get("name")
    state = module.params.get("state")
    name_alias = module.params.get("name_alias")

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class=ACI_MAPPING.get(aaa_user_type).get("aci_class"),
            aci_rn=ACI_MAPPING.get(aaa_user_type).get("aci_mo") + aaa_user,
            module_object=aaa_user,
            target_filter={"name": aaa_user},
        ),
        subclass_1=dict(
            aci_class="aaaUserCert",
            aci_rn="usercert-{0}".format(name),
            module_object=name,
            target_filter={"name": name},
        ),
    )
    aci.get_existing()

    if state == "present":
        aci.payload(
            aci_class="aaaUserCert",
            class_config=dict(
                data=certificate,
                name=name,
                nameAlias=name_alias,
            ),
        )

        aci.get_diff(aci_class="aaaUserCert")

        aci.post_config()

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

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

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

    tenant = module.params.get("tenant")
    ap = module.params.get("ap")
    epg = module.params.get("epg")
    description = module.params.get("description")
    encap_id = module.params.get("encap_id")
    primary_encap_id = module.params.get("primary_encap_id")
    deploy_immediacy = module.params.get("deploy_immediacy")
    interface_mode = module.params.get("interface_mode")
    interface_type = module.params.get("interface_type")
    pod_id = module.params.get("pod_id")
    leafs = module.params.get("leafs")
    interface = module.params.get("interface")
    extpaths = module.params.get("extpaths")
    state = module.params.get("state")

    aci = ACIModule(module)

    if leafs is not None:
        # Process leafs, and support dash-delimited leafs
        leafs = []
        for leaf in module.params.get("leafs"):
            # Users are likely to use integers for leaf IDs, which would raise an exception when using the join method
            leafs.extend(str(leaf).split("-"))
        if len(leafs) == 1:
            if interface_type in ["vpc", "fex_vpc"]:
                aci.fail_json(msg='A interface_type of "vpc" requires 2 leafs')
            leafs = leafs[0]
        elif len(leafs) == 2:
            if interface_type not in ["vpc", "fex_vpc"]:
                aci.fail_json(
                    msg=
                    'The interface_types "switch_port", "port_channel", and "fex" \
                    do not support using multiple leafs for a single binding')
            leafs = "-".join(leafs)
        else:
            aci.fail_json(
                msg='The "leafs" parameter must not have more than 2 entries')

    if extpaths is not None:
        # Process extpaths, and support dash-delimited extpaths
        extpaths = []
        for extpath in module.params.get("extpaths"):
            # Users are likely to use integers for extpaths IDs, which would raise an exception when using the join method
            extpaths.extend(str(extpath).split("-"))
        if len(extpaths) == 1:
            if interface_type == "fex_vpc":
                aci.fail_json(
                    msg='A interface_type of "fex_vpc" requires 2 extpaths')
            extpaths = extpaths[0]
        elif len(extpaths) == 2:
            if interface_type != "fex_vpc":
                aci.fail_json(msg='The interface_types "fex" \
                    and "fex_port_channel" do not support using multiple extpaths for a single binding'
                              )
            extpaths = "-".join(extpaths)
        else:
            aci.fail_json(
                msg='The "extpaths" parameter must not have more than 2 entries'
            )

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

    if primary_encap_id is not None:
        try:
            primary_encap_id = int(primary_encap_id)
            if isinstance(primary_encap_id, int) and primary_encap_id in range(
                    1, 4097):
                primary_encap_id = "vlan-{0}".format(primary_encap_id)
            else:
                aci.fail_json(
                    msg="Valid VLAN assignments are from 1 to 4096 or unknown."
                )
        except Exception as e:
            if isinstance(primary_encap_id,
                          str) and primary_encap_id != "unknown":
                aci.fail_json(
                    msg=
                    "Valid VLAN assignments are from 1 to 4096 or unknown. %s"
                    % e)

    static_path = INTERFACE_TYPE_MAPPING[interface_type].format(
        pod_id=pod_id, leafs=leafs, extpaths=extpaths, interface=interface)

    path_target_filter = {}
    if pod_id is not None and leafs is not None and interface is not None and (
            interface_type != "fex" or extpaths is not None):
        path_target_filter = {"tDn": static_path}

    if interface_mode is not None:
        interface_mode = INTERFACE_MODE_MAPPING[interface_mode]

    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="fvRsPathAtt",
            aci_rn="rspathAtt-[{0}]".format(static_path),
            module_object=static_path,
            target_filter=path_target_filter,
        ),
    )

    aci.get_existing()

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

        aci.get_diff(aci_class="fvRsPathAtt")

        aci.post_config()

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

    aci.exit_json()
Example #14
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        domain_type=dict(type='str',
                         required=True,
                         choices=['fc', 'l2dom', 'l3dom', 'phys', 'vmm']),
        domain=dict(type='str',
                    aliases=['domain_name', 'domain_profile'
                             ]),  # Not required for querying all objects
        pool=dict(type='str',
                  aliases=['pool_name', 'vlan_pool'
                           ]),  # Not required for querying all objects
        pool_allocation_mode=dict(type='str',
                                  required=True,
                                  aliases=['allocation_mode', 'mode'],
                                  choices=['dynamic', 'static']),
        state=dict(type='str',
                   default='present',
                   choices=['absent', 'present', 'query']),
        vm_provider=dict(type='str',
                         choices=[
                             'cloudfoundry', 'kubernetes', 'microsoft',
                             'openshift', 'openstack', 'redhat', 'vmware'
                         ]),
    )

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

    domain = module.params.get('domain')
    domain_type = module.params.get('domain_type')
    pool = module.params.get('pool')
    pool_allocation_mode = module.params.get('pool_allocation_mode')
    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))

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

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

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

    aci_mo = 'uni/infra/vlanns-{0}'.format(pool_name)

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

    aci.get_existing()

    if state == 'present':
        aci.payload(aci_class=domain_class,
                    class_config=dict(name=domain),
                    child_configs=[
                        {
                            'infraRsVlanNs': {
                                'attributes': {
                                    'tDn': aci_mo
                                }
                            }
                        },
                    ])

        aci.get_diff(aci_class=domain_class)

        aci.post_config()

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

    aci.exit_json()
Example #15
0
def main():
    argument_spec = aci_argument_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()
Example #16
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        leaf_interface_profile=dict(
            type='str', aliases=['leaf_interface_profile_name'
                                 ]),  # Not required for querying all objects
        access_port_selector=dict(type='str',
                                  aliases=[
                                      'name', 'access_port_selector_name'
                                  ]),  # Not required for querying all objects
        leaf_port_blk=dict(type='str', aliases=[
            'leaf_port_blk_name'
        ]),  # Not required for querying all objects
        leaf_port_blk_description=dict(type='str'),
        from_port=dict(type='str',
                       aliases=['from', 'fromPort', 'from_port_range']),
        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']),
        state=dict(type='str',
                   default='present',
                   choices=['absent', 'present', 'query']),
    )

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

    leaf_interface_profile = module.params.get('leaf_interface_profile')
    access_port_selector = module.params.get('access_port_selector')
    leaf_port_blk = module.params.get('leaf_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')
    state = module.params.get('state')

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

    aci.get_existing()

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

        aci.get_diff(aci_class='infraPortBlk')

        aci.post_config()

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

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        tenant=dict(type='str', aliases=['tenant_name'], required=True),
        ap=dict(type='str', aliases=['app_profile', 'app_profile_name'], required=True),
        epg=dict(type='str', aliases=['epg_name', 'name'], required=True),
        contract_master_ap=dict(type='str'),
        contract_master_epg=dict(type='str'),
        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_master_ap', 'contract_master_epg']],
            ['state', 'present', ['contract_master_ap', 'contract_master_epg']],
        ],
    )

    aci = ACIModule(module)

    tenant = module.params.get('tenant')
    ap = module.params.get('ap')
    epg = module.params.get('epg')
    contract_master_ap = module.params.get('contract_master_ap')
    contract_master_epg = module.params.get('contract_master_epg')
    state = module.params.get('state')
    name_alias = module.params.get('name_alias')

    contract_master = 'uni/tn-{0}/ap-{1}/epg-{2}'.format(tenant, contract_master_ap, contract_master_epg)

    child_configs = []

    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='fvRsSecInherited',
            aci_rn='rssecInherited-[{0}]'.format(contract_master),
            module_object=contract_master,
            target_filter={'tDn': contract_master},
        ),
        child_classes=[],
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='fvRsSecInherited',
            class_config=dict(
                tDn=contract_master
            ),
            child_configs=child_configs
        )

        aci.get_diff(aci_class='fvRsSecInherited')

        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(
        l2_policy=dict(type="str", aliases=["name"]),  # Not required for querying all policies
        description=dict(type="str", aliases=["descr"]),
        vlan_scope=dict(type="str", choices=["global", "portlocal"]),  # No default provided on purpose
        qinq=dict(type="str", choices=["core", "disabled", "edge"]),
        vepa=dict(type="bool"),
        state=dict(type="str", default="present", choices=["absent", "present", "query"]),
        name_alias=dict(type="str"),
    )

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

    aci = ACIModule(module)

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

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

    aci.get_existing()

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

        aci.get_diff(aci_class="l2IfPol")

        aci.post_config()

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

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

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

    description = module.params.get('description')
    leaf_profile = module.params.get('leaf_profile')
    leaf = module.params.get('leaf')
    leaf_node_blk = module.params.get('leaf_node_blk')
    leaf_node_blk_description = module.params.get('leaf_node_blk_description')
    from_ = module.params.get('from')
    to_ = module.params.get('to')
    policy_group = module.params.get('policy_group')
    state = module.params.get('state')
    name_alias = module.params.get('name_alias')

    # Build child_configs dynamically
    child_configs = [
        dict(
            infraNodeBlk=dict(
                attributes=dict(
                    descr=leaf_node_blk_description,
                    name=leaf_node_blk,
                    from_=from_,
                    to_=to_,
                ),
            ),
        ),
    ]

    # Add infraRsAccNodePGrp only when policy_group was defined
    if policy_group is not None:
        child_configs.append(dict(
            infraRsAccNodePGrp=dict(
                attributes=dict(
                    tDn='uni/infra/funcprof/accnodepgrp-{0}'.format(policy_group),
                ),
            ),
        ))

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

    )

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='infraLeafS',
            class_config=dict(
                descr=description,
                name=leaf,
                nameAlias=name_alias,
            ),
            child_configs=child_configs,
        )

        aci.get_diff(aci_class='infraLeafS')

        aci.post_config()

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

    aci.exit_json()
Example #20
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(aci_annotation_spec())
    argument_spec.update(
        domain_type=dict(type="str",
                         required=True,
                         choices=["fc", "l2dom", "l3dom", "phys", "vmm"]),
        domain=dict(type="str",
                    aliases=["domain_name", "domain_profile"
                             ]),  # Not required for querying all objects
        pool=dict(type="str",
                  aliases=["pool_name", "vlan_pool"
                           ]),  # Not required for querying all objects
        pool_allocation_mode=dict(type="str",
                                  required=True,
                                  aliases=["allocation_mode", "mode"],
                                  choices=["dynamic", "static"]),
        state=dict(type="str",
                   default="present",
                   choices=["absent", "present", "query"]),
        vm_provider=dict(type="str",
                         choices=[
                             "cloudfoundry", "kubernetes", "microsoft",
                             "openshift", "openstack", "redhat", "vmware"
                         ]),
    )

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

    domain = module.params.get("domain")
    domain_type = module.params.get("domain_type")
    pool = module.params.get("pool")
    pool_allocation_mode = module.params.get("pool_allocation_mode")
    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))

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

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

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

    aci_mo = "uni/infra/vlanns-{0}".format(pool_name)

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

    aci.get_existing()

    if state == "present":
        aci.payload(
            aci_class=domain_class,
            class_config=dict(name=domain),
            child_configs=[
                {
                    "infraRsVlanNs": {
                        "attributes": {
                            "tDn": aci_mo
                        }
                    }
                },
            ],
        )

        aci.get_diff(aci_class=domain_class)

        aci.post_config()

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

    aci.exit_json()
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(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
        dst_group=dict(type="str"),  # Not required for querying all objects
        src_group=dict(type="str"),  # 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", ["dst_group", "src_group", "tenant"]],
            ["state", "present", ["dst_group", "src_group", "tenant"]],
        ],
    )

    description = module.params.get("description")
    dst_group = module.params.get("dst_group")
    src_group = module.params.get("src_group")
    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="spanSrcGrp",
            aci_rn="srcgrp-{0}".format(src_group),
            module_object=src_group,
            target_filter={"name": src_group},
        ),
        subclass_2=dict(
            aci_class="spanSpanLbl",
            aci_rn="spanlbl-{0}".format(dst_group),
            module_object=dst_group,
            target_filter={"name": dst_group},
        ),
    )

    aci.get_existing()

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

        aci.get_diff(aci_class="spanSpanLbl")

        aci.post_config()

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

    aci.exit_json()
Example #22
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        policy=dict(type='str', aliases=['snmp_policy', 'snmp_policy_name']),
        name=dict(type='str', aliases=['snmp_user_policy']),
        auth_type=dict(type='str', choices=['hmac-md5-96', 'hmac-sha1-96']),
        auth_key=dict(type='str'),
        privacy_type=dict(type='str', choices=['aes-128', 'des', 'none']),
        privacy_key=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', 'name']],
                               ['state', 'present', ['policy', 'name']],
                           ])

    aci = ACIModule(module)

    policy = module.params.get('policy')
    name = module.params.get('name')
    auth_type = module.params.get('auth_type')
    auth_key = module.params.get('auth_key')
    privacy_type = module.params.get('privacy_type')
    privacy_key = module.params.get('privacy_key')
    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='snmpUserP',
                          aci_rn='user-{0}'.format(name),
                          module_object=name,
                          target_filter={'name': name},
                      ))

    aci.get_existing()

    if state == 'present':
        aci.payload(
            aci_class='snmpUserP',
            class_config=dict(privType=privacy_type,
                              privKey=privacy_key,
                              authType=auth_type,
                              authKey=auth_key,
                              name=name),
        )

        aci.get_diff(aci_class='snmpUserP')

        aci.post_config()

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

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

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

    aci = ACIModule(module)

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

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

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

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

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

        aci.get_diff(aci_class='aaaUser')

        aci.post_config()

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

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

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

    description = module.params.get("description")
    leaf_profile = module.params.get("leaf_profile")
    leaf = module.params.get("leaf")
    leaf_node_blk = module.params.get("leaf_node_blk")
    leaf_node_blk_description = module.params.get("leaf_node_blk_description")
    from_ = module.params.get("from")
    to_ = module.params.get("to")
    policy_group = module.params.get("policy_group")
    state = module.params.get("state")
    name_alias = module.params.get("name_alias")

    # Build child_configs dynamically
    child_configs = [
        dict(infraNodeBlk=dict(attributes=dict(
            descr=leaf_node_blk_description,
            name=leaf_node_blk,
            from_=from_,
            to_=to_,
        ), ), ),
    ]

    # Add infraRsAccNodePGrp only when policy_group was defined
    if policy_group is not None:
        child_configs.append(
            dict(infraRsAccNodePGrp=dict(attributes=dict(
                tDn="uni/infra/funcprof/accnodepgrp-{0}".format(
                    policy_group), ), ), ))

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

    aci.get_existing()

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

        aci.get_diff(aci_class="infraLeafS")

        aci.post_config()

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

    aci.exit_json()
Example #25
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        bd=dict(type='str'),
        l2out=dict(type='str', aliases=['name']),
        domain=dict(type='str'),
        vlan=dict(type='int'),
        description=dict(type='str'),
        state=dict(type='str',
                   default='present',
                   choices=['absent', 'present', 'query']),
        tenant=dict(type='str'),
        name_alias=dict(type='str'),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ['state', 'absent', ['l2out', 'tenant']],
            ['state', 'present', ['bd', 'l2out', 'tenant', 'domain', 'vlan']],
        ],
    )

    bd = module.params.get('bd')
    l2out = module.params.get('l2out')
    description = module.params.get('description')
    domain = module.params.get('domain')
    vlan = module.params.get('vlan')
    state = module.params.get('state')
    tenant = module.params.get('tenant')
    name_alias = module.params.get('name_alias')
    child_classes = ['l2extRsEBd', 'l2extRsL2DomAtt', 'l2extLNodeP']

    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},
        ),
        child_classes=child_classes,
    )

    aci.get_existing()

    if state == 'present':
        child_configs = [
            dict(l2extRsL2DomAtt=dict(attributes=dict(
                tDn='uni/l2dom-{0}'.format(domain)))),
            dict(l2extRsEBd=dict(
                attributes=dict(tnFvBDName=bd, encap='vlan-{0}'.format(vlan))))
        ]

        aci.payload(
            aci_class='l2extOut',
            class_config=dict(name=l2out,
                              descr=description,
                              dn='uni/tn-{0}/l2out-{1}'.format(tenant, l2out),
                              nameAlias=name_alias),
            child_configs=child_configs,
        )

        aci.get_diff(aci_class='l2extOut')

        aci.post_config()

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

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

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

    aci = ACIModule(module)

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

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

    aci.get_existing()

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

        aci.get_diff(aci_class='l2IfPol')

        aci.post_config()

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

    aci.exit_json()
Example #27
0
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(tenant=dict(type='str'),
                         contract=dict(type='str'),
                         subject=dict(type='str'),
                         service_graph=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',
                ['contract', 'service_graph', 'subject', 'tenant']
            ],
            [
                'state', 'present',
                ['contract', 'service_graph', 'subject', 'tenant']
            ],
        ])

    aci = ACIModule(module)

    tenant = module.params.get('tenant')
    contract = module.params.get('contract')
    subject = module.params.get('subject')
    service_graph = module.params.get('service_graph')
    state = module.params.get('state')

    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='vzRsSubjGraphAtt',
                        aci_rn='rsSubjGraphAtt',
                        module_object=service_graph,
                        target_filter={'name': service_graph}),
    )

    aci.get_existing()

    if state == 'present':
        aci.payload(aci_class='vzRsSubjGraphAtt',
                    class_config=dict(tnVnsAbsGraphName=service_graph))

        aci.get_diff(aci_class='vzRsSubjGraphAtt')

        aci.post_config()

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

    aci.exit_json()