ACI: Various changes to module documentation and guide (#36516)

* ACI: Various changes to module documentation and guide

This PR includes:
- We moved the object class information to the notes
- Add version information to guide chapters
- Add generic note to modules with reference to ACI guide
- Reference known issues in aci_rest documentation
- Remove module_utils function docs from modules
- Indicate which parameters are not required for querying all objects
- Added missing RETURN information

* Fix copyright strings

* Remove aci_domain_to_encap_pool.py for v2.5

* More updates

* PEP8 fix

* Improve listings of parameters/return values
pull/36535/head
Dag Wieers 7 years ago committed by GitHub
parent 7ce1d49c55
commit 7435e115e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -61,39 +61,90 @@ For instance ensuring that a specific tenant exists, is done using the following
A complete list of existing ACI modules is available for `the latest stable release <http://docs.ansible.com/ansible/latest/modules/list_of_network_modules.html#aci>`_ as well as `the current development version <http://docs.ansible.com/ansible/devel/modules/list_of_network_modules.html#aci>`_.
Standard module parameters
..........................
Common parameters
.................
Every Ansible ACI module accepts the following parameters that influence the module's communication with the APIC REST API:
- ``host`` -- Hostname or IP address of the APIC
- ``port`` -- Port to use for communication (defaults to ``443`` for HTTPS, and ``80`` for HTTP)
- ``username`` -- User name used to log on to the APIC (defaults to ``admin``)
- ``password`` -- Password for ``username`` to log on to the APIC (using password-based authentication)
- ``private_key`` -- Private key for ``username`` to log on to APIC (using signature-based authentication)
- ``certificate_name`` -- Name of the certificate in the ACI Web GUI (defaults to ``private_key`` file base name)
- ``timeout`` -- Timeout value for socket-level communication
- ``use_proxy`` -- Use system proxy settings (defaults to ``yes``)
- ``use_ssl`` -- Use HTTPS or HTTP for APIC REST communication (defaults to ``yes``)
- ``validate_certs`` -- Validate certificate when using HTTPS communication (defaults to ``yes``)
- ``output_level`` -- Influence the level of detail ACI modules return to the user (one of ``normal``, ``info`` or ``debug``)
host
Hostname or IP address of the APIC.
port
Port to use for communication. (Defaults to ``443`` for HTTPS, and ``80`` for HTTP)
username
User name used to log on to the APIC. (Defaults to ``admin``)
password
Password for ``username`` to log on to the APIC, using password-based authentication.
private_key
Private key for ``username`` to log on to APIC, using signature-based authentication. *New in version 2.5*
certificate_name
Name of the certificate in the ACI Web GUI. (Defaults to ``private_key`` file base name) *New in version 2.5*
timeout
Timeout value for socket-level communication.
use_proxy
Use system proxy settings. (Defaults to ``yes``)
use_ssl
Use HTTPS or HTTP for APIC REST communication. (Defaults to ``yes``)
validate_certs
Validate certificate when using HTTPS communication. (Defaults to ``yes``)
output_level
Influence the level of detail ACI modules return to the user. (One of ``normal``, ``info`` or ``debug``) *New in version 2.5*
Proxy support
.............
By default, if an environment variable ``<protocol>_proxy`` is set on the target host, requests will be sent through that proxy. This behaviour can be overridden by setting a variable for this task (see setting the environment), or by using the ``use_proxy`` module parameter.
By default, if an environment variable ``<protocol>_proxy`` is set on the target host, requests will be sent through that proxy. This behaviour can be overridden by setting a variable for this task (see :ref:`setting the environment <playbooks_environment>`), or by using the ``use_proxy`` module parameter.
HTTP redirects can redirect from HTTP to HTTPS so you should be sure that your proxy environment for both protocols is correct.
If you don't need proxy support, but the system may have it configured nevertheless, you can add this parameter setting: ``use_proxy: no`` to avoid accidental proxy usage.
.. note:: Selective proxy support using the ``no_proxy`` environment variable is also supported.
.. hint:: Selective proxy support using the ``no_proxy`` environment variable is also supported.
Return values
.............
.. versionadded:: 2.5
The following values are always returned:
current
The resulting state of the managed object.
The following values are returned when ``output_level: info``:
previous
The original state of the managed object (before any change was made).
proposed
The proposed config payload, based on user-supplied values.
Module return values
....................
By default the ACI modules (excluding :ref:`the aci_rest module <aci_rest>`) return the resulting state of the managed object in a key ``current``.
sent
The sent config payload, based on user-supplied values and the existing configuration.
By increasing the ``output_level`` to ``info``, the modules give access to the ``previous`` state of the object, but also the ``proposed`` and ``sent`` configuration payload.
The following values are returned when ``output_level: debug`` or ``ANSIBLE_DEBUG=1``:
For troubleshooting purposes setting ``output_level: debug`` or defining environment variable ``ANSIBLE_DEBUG=1`` enables more detailed information on the actual APIC REST communication, incl. ``filter_string``, ``method``, ``response``, ``status`` and ``url``.
filter_string
The filter used for specific APIC queries.
method
The HTTP method used for the sent payload. (Either ``GET`` for queries, ``DELETE`` or ``POST`` for changes)
response
The HTTP response from the APIC.
status
The HTTP status code for the request.
url
The url used for the request.
.. note:: The module return values are documented in detail as part of each module's documentation.
@ -128,9 +179,11 @@ Password-based authentication is very simple to work with, but it is not the mos
The "Vault" feature of Ansible allows you to keep sensitive data such as passwords or keys in encrypted files, rather than as plain text in your playbooks or roles. These vault files can then be distributed or placed in source control. See :doc:`playbooks_vault` for more information.
Signature-based authentication using certificates
.................................................
.. versionadded:: 2.5
Using signature-based authentication is more efficient and more reliable than password-based authentication.
Generate certificate and private key
@ -183,7 +236,7 @@ You need the following parameters with your ACI module(s) for it to work:
private_key: pki/admin.key
certificate_name: admin # This could be left out !
.. note:: If you use a certificate name in ACI that matches the private key's basename, you can leave out the ``certificate_name`` parameter like the example above.
.. hint:: If you use a certificate name in ACI that matches the private key's basename, you can leave out the ``certificate_name`` parameter like the example above.
More information
,,,,,,,,,,,,,,,,
@ -271,8 +324,9 @@ More information
................
Plenty of resources exist to learn about ACI's APIC REST interface, we recommend the links below:
- :ref:`The apic_rest Ansible module <aci_rest>`
- `APIC REST API Configuration Guide <https://www.cisco.com/c/en/us/td/docs/switches/datacenter/aci/apic/sw/2-x/rest_cfg/2_1_x/b_Cisco_APIC_REST_API_Configuration_Guide.html>`_
- :ref:`The apic_rest Ansible module documentation <aci_rest>`
- `APIC REST API Configuration Guide <https://www.cisco.com/c/en/us/td/docs/switches/datacenter/aci/apic/sw/2-x/rest_cfg/2_1_x/b_Cisco_APIC_REST_API_Configuration_Guide.html>`_-- Detailed guide on how the APIC REST API is designed and used, incl. many examples
- `APIC Management Information Model reference <https://developer.cisco.com/docs/apic-mim-ref/>`_-- Complete reference of the APIC object model
- `Cisco DevNet Learning Labs about ACI and REST <https://learninglabs.cisco.com/labs/tags/ACI,REST>`_
@ -334,22 +388,18 @@ APIC error messages
-------------------
The following error messages may occur and this section can help you understand what exactly is going on.
- **APIC Error 122: unknown managed object class 'polUni'**
APIC Error 122: unknown managed object class 'polUni'
In case you receive this error while you are certain your :ref:`aci_rest <aci_rest>` payload and object classes are seemingly correct, the issue might be that your payload is not in fact correct JSON (e.g. the sent payload is using single quotes, rather than double quotes), and as a result the APIC is not correctly parsing your object classes from the payload. One way to avoid this is by using a YAML or an XML formatted payload.
- **APIC Error 400: invalid data at line '1'. Attributes are missing, tag 'attributes' must be specified first, before any other tag**
APIC Error 400: invalid data at line '1'. Attributes are missing, tag 'attributes' must be specified first, before any other tag
Although the JSON specification allows unordered elements, the APIC REST API requires that the JSON ``attributes`` element precede the ``children`` array or other elements. So you need to ensure that your payload conforms to this requirement. Sorting your dictionary keys will do the trick just fine. If you don't have any attributes, it may be necessary to add: ``attributes: {}`` as the APIC does expect the entry to proceed any ``children``.
- **APIC Error 801: property descr of uni/tn-TENANT/ap-AP failed validation for value 'A "legacy" network'**
APIC Error 801: property descr of uni/tn-TENANT/ap-AP failed validation for value 'A "legacy" network'
Some values in the APIC have strict format-rules to comply to, and the internal APIC validation check for the provided value failed. In the above case, the ``description`` parameter (internally known as ``descr``) only accepts values conforming to `Regex: [a-zA-Z0-9\\!#$%()*,-./:;@ _{|}~?&+]+ <https://pubhub-prod.s3.amazonaws.com/media/apic-mim-ref/docs/MO-fvAp.html#descr>`_, in general it must not include quotes or square brackets.
.. _aci_guide_issues:
.. _aci_guide_known_issues:
Known issues
------------
@ -357,37 +407,27 @@ Known issues
All below issues either have been reported to the vendor, or can simply be avoided.
- **Too many consecutive API calls may result in connection throttling**
Too many consecutive API calls may result in connection throttling
Starting with ACI v3.1 the APIC will actively throttle password-based authenticated connection rates over a specific treshold. This is as part of an anti-DDOS measure but can act up when using Ansible with ACI using password-based authentication. Currently, one solution is to increase this treshold within the nginx configuration, but using signature-based authentication is recommended.
**NOTE:** It is advisable to use signature-based authentication with ACI as it not only prevents connection-throttling, but also improves general performance when using the ACI modules.
- **Specific requests may not reflect changes correctly**
Specific requests may not reflect changes correctly (`#35401 <https://github.com/ansible/ansible/issues/35041>`_)
There is a known issue where specific requests to the APIC do not properly reflect changed in the resulting output, even when we request those changes explicitly from the APIC. In one instance using the path ``api/node/mo/uni/infra.xml`` fails, where ``api/node/mo/uni/infra/.xml`` does work correctly.
More information from: `#35401 aci_rest: change not detected <https://github.com/ansible/ansible/issues/35041>`_
**NOTE:** A workaround is to register the task return values (e.g. ``register: this``) and influence when the task should report a change by adding: ``changed_when: this.imdata != []``.
- **Specific requests are known to not be idempotent**
Specific requests are known to not be idempotent (`#35050 <https://github.com/ansible/ansible/issues/35050>`_)
The behaviour of the APIC is inconsistent to the use of ``status="created"`` and ``status="deleted"``. The result is that when you use ``status="created"`` in your payload the resulting tasks are not idempotent and creation will fail when the object was already created. However this is not the case with ``status="deleted"`` where such call to an non-existing object does not cause any failure whatsoever.
More information from: `#35050 aci_rest: Using status="created" behaves differently than status="deleted" <https://github.com/ansible/ansible/issues/35050>`_
**NOTE:** A workaround is to avoid using ``status="created"`` and instead use ``status="modified"`` when idempotency is essential to your workflow..
- **Setting user password is not idempotent**
Setting user password is not idempotent (`#35544 <https://github.com/ansible/ansible/issues/35544>`_)
Due to an inconsistency in the APIC REST API, a task that sets the password of a locally-authenticated user is not idempotent. The APIC will complain with message ``Password history check: user dag should not use previous 5 passwords``.
More information from: `#35544 aci_aaa_user: Setting user password is not idempotent <https://github.com/ansible/ansible/issues/35544>`_
**NOTE:** There is no workaround for this issue.

@ -17,15 +17,16 @@ module: aci_aaa_user
short_description: Manage AAA users (aaa:User)
description:
- Manage AAA users.
- More information from the internal APIC class I(aaa:User) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Dag Wieers (@dagwieers)
notes:
- This module is not idempotent when C(aaa_password) is being used
(even if that password was already set identically). This
appears to be an inconsistency wrt. the idempotent nature
of the APIC REST API.
of the APIC REST API. The vendor has been informed.
More information in :ref:`the ACI documentation <aci_guide_known_issues>`.
- More information from the internal APIC class I(aaa:User) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Dag Wieers (@dagwieers)
requirements:
- python-dateutil
version_added: '2.5'
@ -246,7 +247,7 @@ def main():
aaa_password=dict(type='str', no_log=True),
aaa_password_lifetime=dict(type='int'),
aaa_password_update_required=dict(type='bool'),
aaa_user=dict(type='str', required=True, aliases=['name']),
aaa_user=dict(type='str', required=True, aliases=['name']), # Not required for querying all objects
clear_password_history=dict(type='bool'),
description=dict(type='str', aliases=['descr']),
email=dict(type='str'),
@ -306,7 +307,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module params with null values
aci.payload(
aci_class='aaaUser',
class_config=dict(
@ -325,10 +325,8 @@ def main():
),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='aaaUser')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -16,15 +16,15 @@ DOCUMENTATION = r'''
module: aci_aaa_user_certificate
short_description: Manage AAA user certificates (aaa:UserCert)
description:
- Manage AAA user and appuser certificates.
- Manage AAA user certificates.
notes:
- The C(aaa_user) must exist before using this module in your playbook.
The M(aci_aaa_user) module can be used for this.
- More information from the internal APIC class I(aaa:UserCert) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Dag Wieers (@dagwieers)
version_added: '2.5'
notes:
- The C(aaa_user) must exist before using this module in your playbook.
The M(aci_aaa_user) module can be used for this.
options:
aaa_user:
description:
@ -212,10 +212,10 @@ ACI_MAPPING = dict(
def main():
argument_spec = aci_argument_spec()
argument_spec.update(
aaa_user=dict(type='str', required=True),
aaa_user=dict(type='str', required=True), # Not required for querying all objects
aaa_user_type=dict(type='str', default='user', choices=['appuser', 'user']),
certificate=dict(type='str', aliases=['cert_data', 'certificate_data']),
certificate_name=dict(type='str', aliases=['cert_name']),
certificate=dict(type='str', aliases=['cert_data', 'certificate_data']), # Not required for querying all objects
certificate_name=dict(type='str', aliases=['cert_name']), # Not required for querying all objects
state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
)
@ -252,7 +252,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module params with null values
aci.payload(
aci_class='aaaUserCert',
class_config=dict(
@ -261,10 +260,8 @@ def main():
),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='aaaUserCert')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -17,6 +17,7 @@ module: aci_access_port_to_interface_policy_leaf_profile
short_description: Manage Fabric interface policy leaf profile interface selectors on Cisco ACI fabrics (infra:HPortS, infra:RsAccBaseGrp, infra:PortBlk)
description:
- Manage Fabric interface policy leaf profile interface selectors on Cisco ACI fabrics.
notes:
- More information from the internal APIC class I(infra:HPortS, infra:RsAccBaseGrp, infra:PortBlk) at
U(https://developer.cisco.com/media/mim-ref).
author:
@ -36,7 +37,6 @@ options:
description:
description:
- The description to assign to the C(access_port_selector)
required: no
leaf_port_blk:
description:
- The name of the Fabric access policy leaf interface profile access port block.
@ -59,7 +59,6 @@ options:
policy_group:
description:
- The name of the fabric access policy group to be associated with the leaf interface profile interface selector.
required: no
aliases: [ policy_group_name ]
state:
description:
@ -227,8 +226,8 @@ from ansible.module_utils.basic import AnsibleModule
def main():
argument_spec = aci_argument_spec()
argument_spec.update({
'leaf_interface_profile': dict(type='str', aliases=['leaf_interface_profile_name']),
'access_port_selector': dict(type='str', aliases=['name', 'access_port_selector_name']),
'leaf_interface_profile': dict(type='str', aliases=['leaf_interface_profile_name']), # Not required for querying all objects
'access_port_selector': dict(type='str', aliases=['name', 'access_port_selector_name']), # Not required for querying all objects
'description': dict(typ='str'),
'leaf_port_blk': dict(type='str', aliases=['leaf_port_blk_name']),
'leaf_port_blk_description': dict(type='str'),
@ -277,7 +276,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class='infraHPortS',
class_config=dict(
@ -292,23 +290,21 @@ def main():
name=leaf_port_blk,
fromPort=from_,
toPort=to_,
)
)
),
),
),
dict(
infraRsAccBaseGrp=dict(
attributes=dict(
tDn='uni/infra/funcprof/accportgrp-{0}'.format(policy_group),
)
)
),
),
),
],
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='infraHPortS')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -17,13 +17,12 @@ short_description: Manage attachable Access Entity Profile (AEP) on Cisco ACI fa
description:
- Connect to external virtual and physical domains by using
attachable Access Entity Profiles (AEP) on Cisco ACI fabrics.
notes:
- More information from the internal APIC classes I(infra:AttEntityP) and I(infra:ProvAcc) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Swetha Chunduri (@schunduri)
version_added: '2.4'
requirements:
- ACI Fabric 1.0(3f)+
options:
aep:
description:
@ -198,7 +197,7 @@ from ansible.module_utils.basic import AnsibleModule
def main():
argument_spec = aci_argument_spec()
argument_spec.update(
aep=dict(type='str', aliases=['name', 'aep_name']), # not required for querying all AEPs
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']),
@ -237,7 +236,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class='infraAttEntityP',
class_config=dict(
@ -247,10 +245,8 @@ def main():
child_configs=child_configs,
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='infraAttEntityP')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -17,14 +17,14 @@ module: aci_aep_to_domain
short_description: Bind AEPs to Physical or Virtual Domains on Cisco ACI fabrics (infra:RsDomP)
description:
- Bind AEPs to Physical or Virtual Domains on Cisco ACI fabrics.
notes:
- The C(aep) and C(domain) parameters should exist before using this module.
The M(aci_aep) and M(aci_domain) can be used for these.
- More information from the internal APIC class I(infra:RsDomP) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Dag Wieers (@dagwieers)
version_added: '2.5'
notes:
- The C(aep) and C(domain) parameters should exist before using this module.
The M(aci_aep) and M(aci_domain) can be used for these.
options:
aep:
description:
@ -215,9 +215,9 @@ VM_PROVIDER_MAPPING = dict(
def main():
argument_spec = aci_argument_spec()
argument_spec.update(
aep=dict(type='str', aliases=['aep_name']),
domain=dict(type='str', aliases=['domain_name', 'domain_profile']),
domain_type=dict(type='str', choices=['fc', 'l2dom', 'l3dom', 'phys', 'vmm'], aliases=['type']),
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']),
)
@ -278,16 +278,13 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module params with null values
aci.payload(
aci_class='infraRsDomP',
class_config=dict(tDn=domain_mo),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='infraRsDomP')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -16,15 +16,15 @@ module: aci_ap
short_description: Manage top level Application Profile (AP) objects on Cisco ACI fabrics (fv:Ap)
description:
- Manage top level Application Profile (AP) objects on Cisco ACI fabrics
notes:
- This module does not manage EPGs, see M(aci_epg) to do this.
- The C(tenant) used must exist before using this module in your playbook.
The M(aci_tenant) module can be used for this.
- More information from the internal APIC class I(fv:Ap) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Swetha Chunduri (@schunduri)
version_added: '2.4'
notes:
- This module does not manage EPGs, see M(aci_epg) to do this.
- The C(tenant) used must exist before using this module in your playbook.
The M(aci_tenant) module can be used for this.
options:
tenant:
description:
@ -198,8 +198,8 @@ from ansible.module_utils.basic import AnsibleModule
def main():
argument_spec = aci_argument_spec()
argument_spec.update(
tenant=dict(type='str', aliases=['tenant_name']), # tenant not required for querying all APs
ap=dict(type='str', aliases=['app_profile', 'app_profile_name', 'name']),
tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects
ap=dict(type='str', aliases=['app_profile', 'app_profile_name', 'name']), # Not required for querying all objects
description=dict(type='str', aliases=['descr'], required=False),
state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6
@ -215,7 +215,6 @@ def main():
],
)
# tenant = module.params['tenant']
ap = module.params['ap']
description = module.params['description']
state = module.params['state']
@ -240,7 +239,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class='fvAp',
class_config=dict(
@ -249,10 +247,8 @@ def main():
),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='fvAp')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -16,14 +16,14 @@ module: aci_bd
short_description: Manage Bridge Domains (BD) on Cisco ACI Fabrics (fv:BD)
description:
- Manages Bridge Domains (BD) on Cisco ACI Fabrics.
notes:
- The C(tenant) used must exist before using this module in your playbook.
The M(aci_tenant) module can be used for this.
- More information from the internal APIC class I(fv:BD) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Jacob McGill (@jmcgill298)
version_added: '2.4'
notes:
- The C(tenant) used must exist before using this module in your playbook.
The M(aci_tenant) module can be used for this.
options:
arp_flooding:
description:
@ -319,7 +319,7 @@ def main():
argument_spec = aci_argument_spec()
argument_spec.update(
arp_flooding=dict(type='bool'),
bd=dict(type='str', aliases=['bd_name', 'name']),
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'),
@ -337,7 +337,7 @@ def main():
mac_address=dict(type='str', aliases=['mac']),
multi_dest=dict(choices=['bd-flood', 'drop', 'encap-flood']),
state=dict(choices=['absent', 'present', 'query'], type='str', default='present'),
tenant=dict(type='str', aliases=['tenant_name']),
tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects
vrf=dict(type='str', aliases=['vrf_name']),
gateway_ip=dict(type='str', removed_in_version='2.4'), # Deprecated starting from v2.4
scope=dict(type='str', removed_in_version='2.4'), # Deprecated starting from v2.4
@ -409,7 +409,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module params with null values
aci.payload(
aci_class='fvBD',
class_config=dict(
@ -436,10 +435,8 @@ def main():
],
)
# generate config diff which will be used as POST request body
aci.get_diff(aci_class='fvBD')
# submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -16,16 +16,16 @@ module: aci_bd_subnet
short_description: Manage Subnets on Cisco ACI fabrics (fv:Subnet)
description:
- Manage Subnets on Cisco ACI fabrics.
- More information from the internal APIC class I(fv:Subnet) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Jacob McGill (@jmcgill298)
version_added: '2.4'
notes:
- The C(gateway) parameter is the root key used to access the Subnet (not name), so the C(gateway)
is required when the state is C(absent) or C(present).
- The C(tenant) and C(bd) used must exist before using this module in your playbook.
The M(aci_tenant) module and M(aci_bd) can be used for these.
- More information from the internal APIC class I(fv:Subnet) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Jacob McGill (@jmcgill298)
version_added: '2.4'
options:
bd:
description:
@ -316,11 +316,11 @@ from ansible.module_utils.basic import AnsibleModule, SEQUENCETYPE
def main():
argument_spec = aci_argument_spec()
argument_spec.update(
bd=dict(type='str', aliases=['bd_name']),
bd=dict(type='str', aliases=['bd_name']), # Not required for querying all objects
description=dict(type='str', aliases=['descr']),
enable_vip=dict(type='bool'),
gateway=dict(type='str', aliases=['gateway_ip']),
mask=dict(type='int', aliases=['subnet_mask']),
gateway=dict(type='str', aliases=['gateway_ip']), # Not required for querying all objects
mask=dict(type='int', aliases=['subnet_mask']), # Not required for querying all objects
subnet_name=dict(type='str', aliases=['name']),
nd_prefix_policy=dict(type='str'),
preferred=dict(type='bool'),
@ -329,7 +329,7 @@ def main():
scope=dict(type='list', choices=['private', 'public', 'shared']),
subnet_control=dict(type='str', choices=['nd_ra', 'no_gw', 'querier_ip', 'unspecified']),
state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
tenant=dict(type='str', aliases=['tenant_name']),
tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects
method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6
protocol=dict(type='str', removed_in_version='2.6'), # Deprecated in v2.6
)
@ -398,7 +398,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module params with null values
aci.payload(
aci_class='fvSubnet',
class_config=dict(
@ -416,10 +415,8 @@ def main():
],
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='fvSubnet')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -16,14 +16,14 @@ module: aci_bd_to_l3out
short_description: Bind Bridge Domain to L3 Out on Cisco ACI fabrics (fv:RsBDToOut)
description:
- Bind Bridge Domain to L3 Out on Cisco ACI fabrics.
notes:
- The C(bd) and C(l3out) parameters should exist before using this module.
The M(aci_bd) and M(aci_l3out) can be used for these.
- More information from the internal APIC class I(fv:RsBDToOut) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Jacob McGill (@jmcgill298)
version_added: '2.4'
notes:
- The C(bd) and C(l3out) parameters should exist before using this module.
The M(aci_bd) and M(aci_l3out) can be used for these.
options:
bd:
description:
@ -162,10 +162,10 @@ from ansible.module_utils.basic import AnsibleModule
def main():
argument_spec = aci_argument_spec()
argument_spec.update(
bd=dict(type='str', aliases=['bd_name', 'bridge_domain']),
l3out=dict(type='str'),
bd=dict(type='str', aliases=['bd_name', 'bridge_domain']), # Not required for querying all objects
l3out=dict(type='str'), # Not required for querying all objects
state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
tenant=dict(type='str', aliases=['tenant_name']),
tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects
method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6
protocol=dict(type='str', removed_in_version='2.6'), # Deprecated in v2.6
)
@ -210,16 +210,13 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module params with null values
aci.payload(
aci_class='fvRsBDToOut',
class_config=dict(tnL3extOutName=l3out),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='fvRsBDToOut')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -17,6 +17,7 @@ short_description: Provides rollback and rollback preview functionality for Cisc
description:
- Provides rollback and rollback preview functionality for Cisco ACI fabric.
- Config Rollbacks are done using snapshots C(aci_snapshot) with the configImportP class.
notes:
- More information from the internal APIC class I(config:ImportP) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
@ -241,7 +242,6 @@ def main():
aci.get_existing()
# Filter out module parameters with null values
aci.payload(
aci_class='configImportP',
class_config=dict(
@ -256,10 +256,8 @@ def main():
),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='configImportP')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'preview':

@ -18,15 +18,15 @@ description:
- Manage Config Snapshots on Cisco ACI fabrics.
- Creating new Snapshots is done using the configExportP class.
- Removing Snapshots is done using the configSnapshot class.
notes:
- The APIC does not provide a mechanism for naming the snapshots.
- 'Snapshot files use the following naming structure: ce_<config export policy name>-<yyyy>-<mm>-<dd>T<hh>:<mm>:<ss>.<mss>+<hh>:<mm>.'
- 'Snapshot objects use the following naming structure: run-<yyyy>-<mm>-<dd>T<hh>-<mm>-<ss>.'
- More information from the internal APIC classes I(config:Snapshot) and I(config:ExportP) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Jacob McGill (@jmcgill298)
version_added: '2.4'
notes:
- The APIC does not provide a mechanism for naming the snapshots.
- 'Snapshot files use the following naming structure: ce_<config export policy name>-<yyyy>-<mm>-<dd>T<hh>:<mm>:<ss>.<mss>+<hh>:<mm>.'
- 'Snapshot objects use the following naming structure: run-<yyyy>-<mm>-<dd>T<hh>-<mm>-<ss>.'
options:
description:
description:
@ -215,7 +215,7 @@ def main():
argument_spec = aci_argument_spec()
argument_spec.update(
description=dict(type='str', aliases=['descr']),
export_policy=dict(type='str', aliases=['name']),
export_policy=dict(type='str', aliases=['name']), # Not required for querying all objects
format=dict(type='str', choices=['json', 'xml']),
include_secure=dict(type='bool'),
max_count=dict(type='int'),
@ -261,7 +261,6 @@ def main():
aci.get_existing()
# Filter out module params with null values
aci.payload(
aci_class='configExportP',
class_config=dict(

@ -16,16 +16,16 @@ module: aci_contract
short_description: Manage contract resources on Cisco ACI fabrics (vz:BrCP)
description:
- Manage Contract resources on Cisco ACI fabrics.
- More information from the internal APIC class I(vz:BrCP) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Dag Wieers (@dagwieers)
version_added: '2.4'
notes:
- This module does not manage Contract Subjects, see M(aci_contract_subject) to do this.
Contract Subjects can still be removed using this module.
- The C(tenant) used must exist before using this module in your playbook.
The M(aci_tenant) module can be used for this.
- More information from the internal APIC class I(vz:BrCP) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Dag Wieers (@dagwieers)
version_added: '2.4'
options:
contract:
description:
@ -234,8 +234,8 @@ def main():
argument_spec=argument_spec,
supports_check_mode=True,
required_if=[
['state', 'absent', ['tenant', 'contract']],
['state', 'present', ['tenant', 'contract']],
['state', 'absent', ['contract', 'tenant']],
['state', 'present', ['contract', 'tenant']],
],
)
@ -266,7 +266,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class='vzBrCP',
class_config=dict(
@ -278,10 +277,8 @@ def main():
),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='vzBrCP')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -16,14 +16,14 @@ module: aci_contract_subject
short_description: Manage initial Contract Subjects on Cisco ACI fabrics (vz:Subj)
description:
- Manage initial Contract Subjects on Cisco ACI fabrics.
notes:
- The C(tenant) and C(contract) used must exist before using this module in your playbook.
- The M(aci_tenant) and M(aci_contract) modules can be used for this.
- More information from the internal APIC class I(vz:Subj) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Swetha Chunduri (@schunduri)
version_added: '2.4'
notes:
- The C(tenant) and C(contract) used must exist before using this module in your playbook.
- The M(aci_tenant) and M(aci_contract) modules can be used for this.
options:
tenant:
description:
@ -240,9 +240,9 @@ MATCH_MAPPING = dict(all='All', at_least_one='AtleastOne', at_most_one='AtmostOn
def main():
argument_spec = aci_argument_spec()
argument_spec.update(
contract=dict(type='str', aliases=['contract_name']),
subject=dict(type='str', aliases=['contract_subject', 'name', 'subject_name']),
tenant=dict(type='str', aliases=['tenant_name']),
contract=dict(type='str', aliases=['contract_name']), # Not required for querying all objects
subject=dict(type='str', aliases=['contract_subject', 'name', 'subject_name']), # Not required for querying all objects
tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects
priority=dict(type='str', choices=['unspecified', 'level1', 'level2', 'level3']),
reverse_filter=dict(type='bool'),
dscp=dict(type='str', aliases=['target']),
@ -311,7 +311,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class='vzSubj',
class_config=dict(
@ -325,10 +324,8 @@ def main():
),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='vzSubj')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -16,16 +16,14 @@ module: aci_contract_subject_to_filter
short_description: Bind Contract Subjects to Filters on Cisco ACI fabrics (vz:RsSubjFiltAtt)
description:
- Bind Contract Subjects to Filters on Cisco ACI fabrics.
notes:
- The C(tenant), C(contract), C(subject), and C(filter_name) must exist before using this module in your playbook.
- The M(aci_tenant), M(aci_contract), M(aci_contract_subject), and M(aci_filter) modules can be used for these.
- More information from the internal APIC class I(vz:RsSubjFiltAtt) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Jacob McGill (@jmcgill298)
version_added: '2.4'
requirements:
- ACI Fabric 1.0(3f)+
notes:
- The C(tenant), C(contract), C(subject), and C(filter_name) must exist before using this module in your playbook.
- The M(aci_tenant), M(aci_contract), M(aci_contract_subject), and M(aci_filter) modules can be used for these.
options:
contract:
description:
@ -60,7 +58,6 @@ options:
extends_documentation_fragment: aci
'''
# FIXME: Add more, better examples
EXAMPLES = r'''
- name: Add a new contract subject to filer binding
aci_subject_filter_binding:
@ -220,11 +217,11 @@ from ansible.module_utils.basic import AnsibleModule
def main():
argument_spec = aci_argument_spec()
argument_spec.update(
contract=dict(type='str', aliases=['contract_name']),
filter=dict(type='str', aliases=['filter_name']),
contract=dict(type='str', aliases=['contract_name']), # Not required for querying all objects
filter=dict(type='str', aliases=['filter_name']), # Not required for querying all objects
log=dict(tyep='str', choices=['log', 'none'], aliases=['directive']),
subject=dict(type='str', aliases=['contract_subject', 'subject_name']),
tenant=dict(type='str', aliases=['tenant_name']),
subject=dict(type='str', aliases=['contract_subject', 'subject_name']), # Not required for querying all objects
tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects
state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6
protocol=dict(type='str', removed_in_version='2.6'), # Deprecated in v2.6
@ -284,7 +281,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class='vzRsSubjFiltAtt',
class_config=dict(
@ -293,10 +289,8 @@ def main():
),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='vzRsSubjFiltAtt')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -16,6 +16,7 @@ module: aci_domain
short_description: Manage physical, virtual, bridged, routed or FC domain profiles (*:DomP)
description:
- Manage physical, virtual, bridged, routed or FC domain profiles.
notes:
- More information from the internal APIC classes I(phys:DomP),
I(vmm:DomP), I(l2ext:DomP), I(l3ext:DomP), I(fc:DomP) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
@ -259,8 +260,8 @@ def main():
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']),
domain=dict(type='str', aliases=['domain_name', 'domain_profile', 'name']),
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
domain_type=dict(type='str', required=True, choices=['fc', 'l2dom', 'l3dom', 'phys', 'vmm'], aliases=['type']), # Not required for querying all objects
encap_mode=dict(type='str', choices=['unknown', 'vlan', 'vxlan']),
multicast_address=dict(type='str'),
state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
@ -341,7 +342,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class=domain_class,
class_config=dict(
@ -353,10 +353,8 @@ def main():
),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class=domain_class)
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -17,14 +17,14 @@ module: aci_domain_to_encap_pool
short_description: Bind Domain to Encap Pools on Cisco ACI fabrics (infra:RsVlanNs)
description:
- Bind Domain to Encap Pools on Cisco ACI fabrics.
notes:
- The C(domain) and C(encap_pool) parameters should exist before using this module.
The M(aci_domain) and M(aci_encap_pool) can be used for these.
- More information from the internal APIC class I(infra:RsVlanNs) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Dag Wieers (@dagwieers)
version_added: '2.5'
notes:
- The C(domain) and C(encap_pool) parameters should exist before using this module.
The M(aci_domain) and M(aci_encap_pool) can be used for these.
options:
domain:
description:

@ -17,14 +17,14 @@ module: aci_domain_to_vlan_pool
short_description: Bind Domain to VLAN Pools on Cisco ACI fabrics (infra:RsVlanNs)
description:
- Bind Domain to VLAN Pools on Cisco ACI fabrics.
notes:
- The C(domain) and C(vlan_pool) parameters should exist before using this module.
The M(aci_domain) and M(aci_vlan_pool) can be used for these.
- More information from the internal APIC class I(infra:RsVlanNs) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Dag Wieers (@dagwieers)
version_added: '2.5'
notes:
- The C(domain) and C(vlan_pool) parameters should exist before using this module.
The M(aci_domain) and M(aci_vlan_pool) can be used for these.
options:
domain:
description:
@ -248,9 +248,9 @@ VM_PROVIDER_MAPPING = dict(
def main():
argument_spec = aci_argument_spec()
argument_spec.update(
domain=dict(type='str', aliases=['domain_name', 'domain_profile']),
domain_type=dict(type='str', required=True, choices=['fc', 'l2dom', 'l3dom', 'phys', 'vmm']),
pool=dict(type='str', aliases=['pool_name', 'vlan_pool']),
domain=dict(type='str', aliases=['domain_name', 'domain_profile']), # Not required for querying all objects
domain_type=dict(type='str', required=True, choices=['fc', 'l2dom', 'l3dom', 'phys', 'vmm']), # 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']),
@ -324,7 +324,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module params with null values
aci.payload(
aci_class=domain_class,
class_config=dict(name=domain),
@ -333,10 +332,8 @@ def main():
]
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class=domain_class)
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -16,6 +16,7 @@ module: aci_encap_pool
short_description: Manage encap pools on Cisco ACI fabrics (fvns:VlanInstP, fvns:VxlanInstP, fvns:VsanInstP)
description:
- Manage vlan, vxlan, and vsan pools on Cisco ACI fabrics.
notes:
- More information from the internal APIC class
I(fvns:VlanInstP), I(fvns:VxlanInstP), and I(fvns:VsanInstP) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
@ -218,7 +219,7 @@ def main():
argument_spec = aci_argument_spec()
argument_spec.update(
description=dict(type='str', aliases=['descr']),
pool=dict(type='str', aliases=['name', 'pool_name']),
pool=dict(type='str', aliases=['name', 'pool_name']), # Not required for querying all objects
pool_allocation_mode=dict(type='str', aliases=['allocation_mode', 'mode'], choices=['dynamic', 'static']),
pool_type=dict(type='str', aliases=['type'], choices=['vlan', 'vxlan', 'vsan'], required=True),
state=dict(type='str', default='present', choices=['absent', 'present', 'query']),

@ -16,13 +16,13 @@ module: aci_encap_pool_range
short_description: Manage encap ranges assigned to pools on Cisco ACI fabrics (fvns:EncapBlk, fvns:VsanEncapBlk)
description:
- Manage vlan, vxlan, and vsan ranges that are assigned to pools on Cisco ACI fabrics.
notes:
- The C(pool) must exist in order to add or delete a range.
- More information from the internal APIC class I(fvns:EncapBlk) and I(fvns:VsanEncapBlk) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Jacob McGill (@jmcgill298)
version_added: '2.5'
requirements:
- The C(pool) must exist in order to add or delete a range.
options:
allocation_mode:
description:
@ -252,12 +252,12 @@ def main():
argument_spec.update(
allocation_mode=dict(type='str', aliases=['mode'], choices=['dynamic', 'inherit', 'static']),
description=dict(type='str', aliases=['descr']),
pool=dict(type='str', aliases=['pool_name']),
pool=dict(type='str', aliases=['pool_name']), # Not required for querying all objects
pool_allocation_mode=dict(type='str', aliases=['pool_mode'], choices=['dynamic', 'static']),
pool_type=dict(type='str', aliases=['type'], choices=['vlan', 'vxlan', 'vsan'], required=True),
range_end=dict(type='int', aliases=['end']),
range_name=dict(type='str', aliases=["name", "range"]),
range_start=dict(type='int', aliases=["start"]),
range_end=dict(type='int', aliases=['end']), # Not required for querying all objects
range_name=dict(type='str', aliases=["name", "range"]), # Not required for querying all objects
range_start=dict(type='int', aliases=["start"]), # Not required for querying all objects
state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
)
@ -383,7 +383,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class=aci_range_class,
class_config={
@ -392,13 +391,11 @@ def main():
"from": encap_start,
"name": range_name,
"to": encap_end,
}
},
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class=aci_range_class)
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -16,14 +16,14 @@ module: aci_epg
short_description: Manage End Point Groups (EPG) on Cisco ACI fabrics (fv:AEPg)
description:
- Manage End Point Groups (EPG) on Cisco ACI fabrics.
notes:
- The C(tenant) and C(app_profile) used must exist before using this module in your playbook.
The M(aci_tenant) and M(aci_ap) modules can be used for this.
- More information from the internal APIC class I(fv:AEPg) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Swetha Chunduri (@schunduri)
version_added: '2.4'
notes:
- The C(tenant) and C(app_profile) used must exist before using this module in your playbook.
The M(aci_tenant) and M(aci_ap) modules can be used for this.
options:
tenant:
description:
@ -270,10 +270,10 @@ from ansible.module_utils.basic import AnsibleModule
def main():
argument_spec = aci_argument_spec()
argument_spec.update(
epg=dict(type='str', aliases=['name', 'epg_name']),
epg=dict(type='str', aliases=['name', 'epg_name']), # Not required for querying all objects
bd=dict(type='str', aliases=['bd_name', 'bridge_domain']),
ap=dict(type='str', aliases=['app_profile', 'app_profile_name']),
tenant=dict(type='str', aliases=['tenant_name']),
ap=dict(type='str', aliases=['app_profile', 'app_profile_name']), # Not required for querying all objects
tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects
description=dict(type='str', aliases=['descr']),
priority=dict(type='str', choices=['level1', 'level2', 'level3', 'unspecified']),
intra_epg_isolation=dict(choices=['enforced', 'unenforced']),
@ -331,7 +331,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class='fvAEPg',
class_config=dict(
@ -347,10 +346,8 @@ def main():
],
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='fvAEPg')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -16,16 +16,14 @@ module: aci_epg_monitoring_policy
short_description: Manage monitoring policies on Cisco ACI fabrics (mon:EPGPol)
description:
- Manage monitoring policies on Cisco ACI fabrics.
notes:
- The C(tenant) used must exist before using this module in your playbook.
The M(aci_tenant) module can be used for this.
- More information from the internal APIC class I(mon:EPGPol) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Dag Wieers (@dagwieers)
version_added: '2.4'
requirements:
- ACI Fabric 1.0(3f)+
notes:
- The C(tenant) used must exist before using this module in your playbook.
The M(aci_tenant) module can be used for this.
options:
monitoring_policy:
description:
@ -214,7 +212,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class='monEPGPol',
class_config=dict(
@ -223,10 +220,8 @@ def main():
),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='monEPGPol')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -16,14 +16,14 @@ module: aci_epg_to_contract
short_description: Bind EPGs to Contracts on Cisco ACI fabrics (fv:RsCons and fv:RsProv)
description:
- Bind EPGs to Contracts on Cisco ACI fabrics.
notes:
- The C(tenant), C(app_profile), C(EPG), and C(Contract) used must exist before using this module in your playbook.
The M(aci_tenant), M(aci_ap), M(aci_epg), and M(aci_contract) modules can be used for this.
- More information from the internal APIC classes I(fv:RsCons) and I(fv:RsProv) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Jacob McGill (@jmcgill298)
version_added: '2.4'
notes:
- The C(tenant), C(app_profile), C(EPG), and C(Contract) used must exist before using this module in your playbook.
The M(aci_tenant), M(aci_ap), M(aci_epg), and M(aci_contract) modules can be used for this.
options:
ap:
description:
@ -228,14 +228,14 @@ PROVIDER_MATCH_MAPPING = {"all": "All", "at_least_one": "AtleastOne", "at_most_o
def main():
argument_spec = aci_argument_spec()
argument_spec.update(
ap=dict(type='str', aliases=['app_profile', 'app_profile_name']),
epg=dict(type='str', aliases=['epg_name']),
contract=dict(type='str', aliases=['contract_name']),
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
contract=dict(type='str', aliases=['contract_name']), # Not required for querying all objects
contract_type=dict(type='str', required=True, choices=['consumer', 'provider']),
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', aliases=['tenant_name']),
tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects
method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6
protocol=dict(type='str', removed_in_version='2.6'), # Deprecated in v2.6
)
@ -297,7 +297,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class=aci_class,
class_config=dict(
@ -307,10 +306,8 @@ def main():
),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class=aci_class)
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -16,17 +16,17 @@ module: aci_epg_to_domain
short_description: Bind EPGs to Domains on Cisco ACI fabrics (fv:RsDomAtt)
description:
- Bind EPGs to Physical and Virtual Domains on Cisco ACI fabrics.
- More information from the internal APIC class I(fv:RsDomAtt) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Jacob McGill (@jmcgill298)
version_added: '2.4'
notes:
- The C(tenant), C(ap), C(epg), and C(domain) used must exist before using this module in your playbook.
The M(aci_tenant) M(aci_ap), M(aci_epg) M(aci_domain) modules can be used for this.
- OpenStack VMM domains must not be created using this module. The OpenStack VMM domain is created directly
by the Cisco APIC Neutron plugin as part of the installation and configuration.
This module can be used to query status of an OpenStack VMM domain.
- More information from the internal APIC class I(fv:RsDomAtt) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Jacob McGill (@jmcgill298)
version_added: '2.4'
options:
allow_useg:
description:
@ -271,18 +271,18 @@ def main():
argument_spec = aci_argument_spec()
argument_spec.update(
allow_useg=dict(type='str', choices=['encap', 'useg']),
ap=dict(type='str', aliases=['app_profile', 'app_profile_name']),
ap=dict(type='str', aliases=['app_profile', 'app_profile_name']), # Not required for querying all objects
deploy_immediacy=dict(type='str', choices=['immediate', 'on-demand']),
domain=dict(type='str', aliases=['domain_name', 'domain_profile']),
domain_type=dict(type='str', choices=['phys', 'vmm'], aliases=['type']),
domain=dict(type='str', aliases=['domain_name', 'domain_profile']), # Not required for querying all objects
domain_type=dict(type='str', choices=['phys', 'vmm'], aliases=['type']), # Not required for querying all objects
encap=dict(type='int'),
encap_mode=dict(type='str', choices=['auto', 'vlan', 'vxlan']),
epg=dict(type='str', aliases=['name', 'epg_name']),
epg=dict(type='str', aliases=['name', 'epg_name']), # Not required for querying all objects
netflow=dict(type='raw'), # Turn into a boolean in v2.9
primary_encap=dict(type='int'),
resolution_immediacy=dict(type='str', choices=['immediate', 'lazy', 'pre-provision']),
state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
tenant=dict(type='str', aliases=['tenant_name']),
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']),
method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6
protocol=dict(type='str', removed_in_version='2.6'), # Deprecated in v2.6
@ -366,7 +366,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class='fvRsDomAtt',
class_config=dict(
@ -380,10 +379,8 @@ def main():
),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='fvRsDomAtt')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -17,6 +17,7 @@ module: aci_fabric_node
short_description: Add a new Fabric Node Member on Cisco ACI fabrics (fabric:NodeIdentP)
description:
- Add a new Fabric Node Member on Cisco ACI fabrics.
notes:
- More information from the internal APIC class
I(fabric:NodeIdentP) at U(https://developer.cisco.com/site/aci/docs/apis/apic-mim-ref/).
author:
@ -36,7 +37,7 @@ options:
switch:
description:
- Switch Name for the new Fabric Node Member.
aliases: [ switch_name ]
aliases: [ name, switch_name ]
description:
description:
- Description for the new Fabric Node Member.
@ -71,7 +72,108 @@ EXAMPLES = r'''
'''
RETURN = r'''
#
current:
description: The existing configuration from the APIC after the module has finished
returned: success
type: list
sample:
[
{
"fvTenant": {
"attributes": {
"descr": "Production environment",
"dn": "uni/tn-production",
"name": "production",
"nameAlias": "",
"ownerKey": "",
"ownerTag": ""
}
}
}
]
error:
description: The error information as returned from the APIC
returned: failure
type: dict
sample:
{
"code": "122",
"text": "unknown managed object class foo"
}
raw:
description: The raw output returned by the APIC REST API (xml or json)
returned: parse error
type: string
sample: '<?xml version="1.0" encoding="UTF-8"?><imdata totalCount="1"><error code="122" text="unknown managed object class foo"/></imdata>'
sent:
description: The actual/minimal configuration pushed to the APIC
returned: info
type: list
sample:
{
"fvTenant": {
"attributes": {
"descr": "Production environment"
}
}
}
previous:
description: The original configuration from the APIC before the module has started
returned: info
type: list
sample:
[
{
"fvTenant": {
"attributes": {
"descr": "Production",
"dn": "uni/tn-production",
"name": "production",
"nameAlias": "",
"ownerKey": "",
"ownerTag": ""
}
}
}
]
proposed:
description: The assembled configuration from the user-provided parameters
returned: info
type: dict
sample:
{
"fvTenant": {
"attributes": {
"descr": "Production environment",
"name": "production"
}
}
}
filter_string:
description: The filter string used for the request
returned: failure or debug
type: string
sample: '?rsp-prop-include=config-only'
method:
description: The HTTP method used for the request to the APIC
returned: failure or debug
type: string
sample: POST
response:
description: The HTTP response from the APIC
returned: failure or debug
type: string
sample: OK (30 bytes)
status:
description: The HTTP status from the APIC
returned: failure or debug
type: int
sample: 200
url:
description: The HTTP url used for the request to the APIC
returned: failure or debug
type: string
sample: https://10.11.12.13/api/mo/uni/tn-production.json
'''
from ansible.module_utils.network.aci.aci import ACIModule, aci_argument_spec
@ -84,12 +186,12 @@ from ansible.module_utils.basic import AnsibleModule
def main():
argument_spec = aci_argument_spec()
argument_spec.update(
pod_id=dict(type='int'),
serial=dict(type='str', aliases=['serial_number']),
node_id=dict(type='int'),
switch=dict(type='str', aliases=['switch_name']),
description=dict(type='str', aliases=['descr']),
node_id=dict(type='int'), # Not required for querying all objects
pod_id=dict(type='int'),
role=dict(type='str', choices=['leaf', 'spine', 'unspecified'], aliases=['role_name']),
serial=dict(type='str', aliases=['serial_number']), # Not required for querying all objects
switch=dict(type='str', aliases=['name', 'switch_name']),
state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
)
@ -97,8 +199,8 @@ def main():
argument_spec=argument_spec,
supports_check_mode=True,
required_if=[
['state', 'absent', ['serial', 'node_id']],
['state', 'present', ['serial', 'node_id']],
['state', 'absent', ['node_id', 'serial']],
['state', 'present', ['node_id', 'serial']],
],
)
@ -123,31 +225,27 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class='fabricNodeIdentP',
class_config=dict(
dn='uni/controller/nodeidentpol/nodep-{0}'.format(serial),
podId=pod_id,
serial=serial,
nodeId=node_id,
descr=description,
name=switch,
role=role,
nodeId=node_id,
podId=pod_id,
rn='nodep-{0}'.format(serial),
descr=description,
role=role,
serial=serial,
)
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='fabricNodeIdentP')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':
aci.delete_config()
module.exit_json(**aci.result)
aci.exit_json(**aci.result)
if __name__ == "__main__":

@ -16,15 +16,15 @@ module: aci_filter
short_description: Manages top level filter objects on Cisco ACI fabrics (vz:Filter)
description:
- Manages top level filter objects on Cisco ACI fabrics.
- This modules does not manage filter entries, see M(aci_filter_entry) for this functionality.
notes:
- The C(tenant) used must exist before using this module in your playbook.
The M(aci_tenant) module can be used for this.
- More information from the internal APIC class I(vz:Filter) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
- This modules does not manage filter entries, see M(aci_filter_entry) for this functionality.
author:
- Dag Wieers (@dagwieers)
version_added: '2.4'
notes:
- The C(tenant) used must exist before using this module in your playbook.
The M(aci_tenant) module can be used for this.
options:
filter:
description:
@ -240,7 +240,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class='vzFilter',
class_config=dict(
@ -249,10 +248,8 @@ def main():
),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='vzFilter')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -16,14 +16,14 @@ module: aci_filter_entry
short_description: Manage filter entries on Cisco ACI fabrics (vz:Entry)
description:
- Manage filter entries for a filter on Cisco ACI fabrics.
notes:
- The C(tenant) and C(filter) used must exist before using this module in your playbook.
The M(aci_tenant) and M(aci_filter) modules can be used for this.
- More information from the internal APIC class I(vz:Entry) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Jacob McGill (@jmcgill298)
version_added: '2.4'
notes:
- The C(tenant) and C(filter) used must exist before using this module in your playbook.
The M(aci_tenant) and M(aci_filter) modules can be used for this.
options:
arp_flag:
description:
@ -247,15 +247,15 @@ def main():
dst_port=dict(type='str'),
dst_port_end=dict(type='str'),
dst_port_start=dict(type='str'),
entry=dict(type='str', aliases=['entry_name', 'filter_entry', 'name']),
entry=dict(type='str', aliases=['entry_name', 'filter_entry', 'name']), # Not required for querying all objects
ether_type=dict(choices=VALID_ETHER_TYPES, type='str'),
filter=dict(type='str', aliases=['filter_name']),
filter=dict(type='str', aliases=['filter_name']), # Not required for querying all objects
icmp_msg_type=dict(type='str', choices=VALID_ICMP_TYPES),
icmp6_msg_type=dict(type='str', choices=VALID_ICMP6_TYPES),
ip_protocol=dict(choices=VALID_IP_PROTOCOLS, type='str'),
state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
stateful=dict(type='bool'),
tenant=dict(type="str", aliases=['tenant_name']),
tenant=dict(type="str", aliases=['tenant_name']), # Not required for querying all objects
)
module = AnsibleModule(
@ -327,7 +327,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module params with null values
aci.payload(
aci_class='vzEntry',
class_config=dict(
@ -344,10 +343,8 @@ def main():
),
)
# generate config diff which will be used as POST request body
aci.get_diff(aci_class='vzEntry')
# submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -17,11 +17,12 @@ module: aci_firmware_source
short_description: Manage firmware image sources on Cisco ACI fabrics (firmware:OSource)
description:
- Manage firmware image sources on Cisco ACI fabrics.
- More information from the internal APIC class I(firmware:OSource) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Dag Wieers (@dagwieers)
version_added: '2.5'
notes:
- More information from the internal APIC class I(firmware:OSource) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
options:
source:
description:
@ -241,7 +242,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class='firmwareOSource',
class_config=dict(
@ -254,10 +254,8 @@ def main():
),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='firmwareOSource')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -16,11 +16,12 @@ module: aci_interface_policy_fc
short_description: Manage Fibre Channel interface policies on Cisco ACI fabrics (fc:IfPol)
description:
- Manage ACI Fiber Channel interface policies on Cisco ACI fabrics.
- More information from the internal APIC class I(fc:IfPol) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Dag Wieers (@dagwieers)
version_added: '2.4'
notes:
- More information from the internal APIC class I(fc:IfPol) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
options:
fc_policy:
description:
@ -203,7 +204,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class='fcIfPol',
class_config=dict(
@ -213,10 +213,8 @@ def main():
),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='fcIfPol')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -16,11 +16,12 @@ module: aci_interface_policy_l2
short_description: Manage Layer 2 interface policies on Cisco ACI fabrics (l2:IfPol)
description:
- Manage Layer 2 interface policies on Cisco ACI fabrics.
- More information from the internal APIC class I(l2:IfPol) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Dag Wieers (@dagwieers)
version_added: '2.4'
notes:
- More information from the internal APIC class I(l2:IfPol) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
options:
l2_policy:
description:
@ -222,7 +223,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class='l2IfPol',
class_config=dict(
@ -233,10 +233,8 @@ def main():
),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='l2IfPol')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -17,6 +17,9 @@ module: aci_interface_policy_leaf_policy_group
short_description: Add Fabric Interface Policy Leaf Policy Groups on Cisco ACI fabrics.
description:
- Add Fabric Interface Policy Leaf Policy Groups on Cisco ACI fabrics.
notes:
- When using the module please select the appropriate link_aggregation_type (lag_type).
C(link) for Port Channel(PC), C(node) for Virtual Port Channel(VPC) and C(leaf) for Leaf Access Port Policy Group.
- More information from the internal APIC class I(infra:AccBndlGrp), I(infra:AccPortGrp) at
U(https://developer.cisco.com/site/aci/docs/apis/apic-mim-ref/).
author:
@ -112,7 +115,7 @@ options:
extends_documentation_fragment: aci
'''
# TODO: Add query examples
# FIXME: Add query examples
EXAMPLES = r'''
- name: Create a Port Channel (PC) Interface Policy Group
aci_interface_policy_leaf_policy_group:
@ -158,7 +161,7 @@ EXAMPLES = r'''
state: absent
'''
RETURN = '''
RETURN = r'''
current:
description: The existing configuration from the APIC after the module has finished
returned: success
@ -270,11 +273,11 @@ from ansible.module_utils.basic import AnsibleModule
def main():
argument_spec = aci_argument_spec()
argument_spec.update({
'policy_group': dict(type='str', aliases=['name', 'policy_group_name']),
'policy_group': dict(type='str', aliases=['name', 'policy_group_name']), # Not required for querying all objects
'description': dict(type='str', aliases=['descr']),
# NOTE: Since this module needs to include both infra:AccBndlGrp (for PC and VPC) and infra:AccPortGrp (for leaf access port policy group):
# NOTE: I'll allow the user to make the choice here (link(PC), node(VPC), leaf(leaf-access port policy group))
'lag_type': dict(type='str', aliases=['lag_type_name'], choices=['leaf', 'link', 'node']),
'lag_type': dict(type='str', aliases=['lag_type_name'], choices=['leaf', 'link', 'node']), # Not required for querying all objects
'link_level_policy': dict(type='str', aliases=['link_level_policy_name']),
'cdp_policy': dict(type='str', aliases=['cdp_policy_name']),
'mcp_policy': dict(type='str', aliases=['mcp_policy_name']),
@ -371,7 +374,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module params with null values
aci.payload(
aci_class=aci_class_name,
class_config=class_config_dict,
@ -491,10 +493,8 @@ def main():
],
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class=aci_class_name)
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -17,6 +17,7 @@ module: aci_interface_policy_leaf_profile
short_description: Manage Fabric interface policy leaf profiles on Cisco ACI fabrics (infra:AccPortP)
description:
- Manage Fabric interface policy leaf profiles on Cisco ACI fabrics.
notes:
- More information from the internal APIC class I(infra:AccPortP) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
@ -217,7 +218,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class='infraAccPortP',
class_config=dict(
@ -226,10 +226,8 @@ def main():
),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='infraAccPortP')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -16,6 +16,7 @@ module: aci_interface_policy_lldp
short_description: Manage LLDP interface policies on Cisco ACI fabrics (lldp:IfPol)
description:
- Manage LLDP interface policies on Cisco ACI fabrics.
notes:
- More information from the internal APIC class I(lldp:IfPol) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
@ -33,13 +34,13 @@ options:
aliases: [ descr ]
receive_state:
description:
- Enable or disable Receive state (FIXME!)
- Enable or disable Receive state.
required: yes
choices: [ disabled, enabled ]
default: enabled
transmit_state:
description:
- Enable or Disable Transmit state (FIXME!)
- Enable or Disable Transmit state.
required: false
choices: [ disabled, enabled ]
default: enabled
@ -176,7 +177,7 @@ from ansible.module_utils.basic import AnsibleModule
def main():
argument_spec = aci_argument_spec()
argument_spec.update(
lldp_policy=dict(type='str', require=False, aliases=['name']),
lldp_policy=dict(type='str', require=False, aliases=['name']), # Not required for querying all objects
description=dict(type='str', aliases=['descr']),
receive_state=dict(type='raw'), # Turn into a boolean in v2.9
transmit_state=dict(type='raw'), # Turn into a boolean in v2.9
@ -214,7 +215,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class='lldpIfPol',
class_config=dict(
@ -225,10 +225,8 @@ def main():
),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='lldpIfPol')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -16,6 +16,7 @@ module: aci_interface_policy_mcp
short_description: Manage MCP interface policies on Cisco ACI fabrics (mcp:IfPol)
description:
- Manage MCP interface policies on Cisco ACI fabrics.
notes:
- More information from the internal APIC class I(mcp:IfPol) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
@ -204,7 +205,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class='mcpIfPol',
class_config=dict(
@ -214,10 +214,8 @@ def main():
),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='mcpIfPol')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -16,6 +16,7 @@ module: aci_interface_policy_port_channel
short_description: Manage port channel interface policies on Cisco ACI fabrics (lacp:LagPol)
description:
- Manage port channel interface policies on Cisco ACI fabrics.
notes:
- More information from the internal APIC class I(lacp:LagPol) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
@ -288,7 +289,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class='lacpLagPol',
class_config=dict(
@ -301,10 +301,8 @@ def main():
),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='lacpLagPol')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -16,6 +16,7 @@ module: aci_interface_policy_port_security
short_description: Manage port security on Cisco ACI fabrics (l2:PortSecurityPol)
description:
- Manage port security on Cisco ACI fabrics.
notes:
- More information from the internal APIC class I(l2:PortSecurityPol) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
@ -204,7 +205,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class='l2PortSecurityPol',
class_config=dict(
@ -214,10 +214,8 @@ def main():
),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='l2PortSecurityPol')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -17,15 +17,13 @@ module: aci_interface_selector_to_switch_policy_leaf_profile
short_description: Associates an Interface Selector Profile to a Switch Policy Leaf Profile (infra:RsAccPortP)
description:
- Associates an Interface Profile (Selector) to a Switch Policy Leaf Profile on Cisco ACI fabrics.
notes:
- This module requires an existing leaf profile, the module M(aci_switch_policy_leaf_profile) can be used for this.
- More information from the internal APIC class I(infra:RsAccPortP) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Bruno Calogero (@brunocalogero)
version_added: '2.5'
notes:
- This module can be used with M(aci_switch_policy_leaf_profile).
One first creates a leaf profile (infra:NodeP),
Finally, associates an interface profile using the provided interface selector profile (infra:RsAccPortP)
options:
leaf_profile:
description:
@ -185,8 +183,8 @@ from ansible.module_utils.basic import AnsibleModule
def main():
argument_spec = aci_argument_spec()
argument_spec.update(
leaf_profile=dict(type='str', aliases=['leaf_profile_name']),
interface_selector=dict(type='str', aliases=['name', 'interface_selector_name', 'interface_profile_name']),
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'])
)
@ -226,16 +224,13 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module params with null values
aci.payload(
aci_class='infraRsAccPortP',
class_config=dict(tDn=interface_selector_tDn)
class_config=dict(tDn=interface_selector_tDn),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='infraRsAccPortP')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -16,14 +16,14 @@ module: aci_l3out_route_tag_policy
short_description: Manage route tag policies on Cisco ACI fabrics (l3ext:RouteTagPol)
description:
- Manage route tag policies on Cisco ACI fabrics.
notes:
- The C(tenant) used must exist before using this module in your playbook.
The M(aci_tenant) module can be used for this.
- More information from the internal APIC class I(l3ext:RouteTagPol) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Dag Wieers (@dagwieers)
version_added: '2.4'
notes:
- The C(tenant) used must exist before using this module in your playbook.
The M(aci_tenant) module can be used for this.
options:
rtp:
description:
@ -219,7 +219,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class='l3extRouteTagPol',
class_config=dict(
@ -228,10 +227,8 @@ def main():
),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='l3extRouteTagPol')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -1,6 +1,7 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright: (c) 2017, Dag Wieers (@dagwieers) <dag@wieers.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
@ -16,6 +17,15 @@ module: aci_rest
short_description: Direct access to the Cisco APIC REST API
description:
- Enables the management of the Cisco ACI fabric through direct access to the Cisco APIC REST API.
- Thanks to the idempotent nature of the APIC, this module is idempotent and reports changes.
notes:
- Certain payloads are known not to be idempotent, so be careful when constructing payloads,
e.g. using C(status="created") will cause idempotency issues, use C(status="modified") instead.
More information in :ref:`the ACI documentation <aci_guide_known_issues>`.
- Certain payloads (and used paths) are known to report no changes happened when changes did happen.
This is a known APIC problem and has been reported to the vendor. A workaround for this issue exists.
More information in :ref:`the ACI documentation <aci_guide_known_issues>`.
- XML payloads require the C(lxml) and C(xmljson) python libraries. For JSON payloads nothing special is needed.
- More information regarding the Cisco APIC REST API is available from
U(http://www.cisco.com/c/en/us/td/docs/switches/datacenter/aci/apic/sw/2-x/rest_cfg/2_1_x/b_Cisco_APIC_REST_API_Configuration_Guide.html).
author:
@ -25,7 +35,6 @@ requirements:
- lxml (when using XML payload)
- xmljson >= 0.1.8 (when using XML payload)
- python 2.7+ (when using xmljson)
extends_documentation_fragment: aci
options:
method:
description:
@ -52,14 +61,7 @@ options:
- Name of the absolute path of the filname that includes the body
of the http request being sent to the ACI fabric.
aliases: [ config_file ]
notes:
- Certain payloads are known not to be idempotent, so be careful when constructing payloads,
e.g. using C(status="created") will cause idempotency issues, use C(status="modified") instead.
More information at U(https://github.com/ansible/community/wiki/Network:-ACI-Documentation#known-issues)
- Certain payloads (or used paths) are known to report no changes happened when changes did happen.
This is a known APIC problem and has been reported to the vendor.
More information at U(https://github.com/ansible/community/wiki/Network:-ACI-Documentation#known-issues)
- XML payloads require the C(lxml) and C(xmljson) python libraries. For JSON payloads nothing special is needed.
extends_documentation_fragment: aci
'''
EXAMPLES = r'''
@ -313,8 +315,8 @@ def main():
mutually_exclusive=[['content', 'src']],
)
path = module.params['path']
content = module.params['content']
path = module.params['path']
src = module.params['src']
# Report missing file
@ -380,15 +382,16 @@ def main():
if aci.params['private_key'] is not None:
aci.cert_auth(path=path, payload=payload)
aci.method = aci.params['method'].upper()
# Perform request
resp, info = fetch_url(module, aci.url,
data=payload,
headers=aci.headers,
method=aci.params['method'].upper(),
method=aci.method,
timeout=aci.params['timeout'],
use_proxy=aci.params['use_proxy'])
aci.method = aci.params['method'].upper()
aci.response = info['msg']
aci.status = info['status']

@ -17,14 +17,14 @@ module: aci_static_binding_to_epg
short_description: Bind static paths to EPGs on Cisco ACI fabrics (fv:RsPathAtt)
description:
- Bind static paths to EPGs on Cisco ACI fabrics.
notes:
- The C(tenant), C(ap), C(epg) used must exist before using this module in your playbook.
The M(aci_tenant), M(aci_ap), M(aci_epg) modules can be used for this.
- More information from the internal APIC classes I(fv:RsPathAtt) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Bruno Calogero (@brunocalogero)
version_added: '2.5'
notes:
- The C(tenant), C(ap), C(epg) used must exist before using this module in your playbook.
The M(aci_tenant), M(aci_ap), M(aci_epg) modules can be used for this.
options:
tenant:
description:
@ -59,27 +59,31 @@ options:
interface_mode:
description:
- Determines how layer 2 tags will be read from and added to frames.
- Values C(802.1p) and C(native) are identical.
- Values C(access) and C(untagged) are identical.
- Values C(regular), C(tagged) and C(trunk) are identical.
- The APIC defaults the mode to C(trunk).
choices: [ untagged, 802.1p, trunk, regular, native, tagged, access ]
choices: [ 802.1p, access, native, regular, tagged, trunk, untagged ]
default: trunk
aliases: [ mode, interface_mode_name ]
aliases: [ interface_mode_name, mode ]
interface_type:
description:
- The type of interface for the static EPG deployement.
- The APIC defaults the C(interface_type) to C(switch_port).
choices: [ switch_port, vpc, port_channel, fex ]
choices: [ fex, port_channel, switch_port, vpc ]
default: switch_port
pod:
pod_id:
description:
- The pod number part of the tDn.
- C(pod) is usually an integer below 10.
aliases: [ pod_number ]
- C(pod_id) is usually an integer below 10.
aliases: [ pod, pod_number ]
leafs:
description:
- The switch ID(s) that the C(interface) belongs to.
- When C(interface_type) is C(switch_port), C(port_channel), or C(fex), then C(leafs) is a string of the leaf ID.
- When C(interface_type) is C(vpc), then C(leafs) is a list with both leaf IDs.
aliases: [ paths, leaves, nodes, switches ]
- The C(leafs) value is usually something like '101' or '101-102' depending on C(connection_type).
aliases: [ leaves, nodes, paths, switches ]
interface:
description:
- The C(interface) string value part of the tDn.
@ -109,9 +113,9 @@ EXAMPLES = r'''
epg: accessport_epg1
encap_id: 222
deploy_immediacy: lazy
interface_mode: access
interface_mode: untagged
interface_type: switch_port
pod: 1
pod_id: 1
leafs: 101
interface: '1/7'
state: present
@ -231,22 +235,18 @@ from ansible.module_utils.basic import AnsibleModule
def main():
argument_spec = aci_argument_spec()
argument_spec.update(
tenant=dict(type='str', aliases=['tenant_name']),
ap=dict(type='str', aliases=['app_profile', 'app_profile_name']),
epg=dict(type='str', aliases=['epg_name']),
tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects
ap=dict(type='str', aliases=['app_profile', 'app_profile_name']), # Not required for querying all objects
epg=dict(type='str', aliases=['epg_name']), # Not required for querying all objects
encap_id=dict(type='int', aliases=['vlan', 'vlan_id']),
primary_encap_id=dict(type='int', aliases=['primary_vlan', 'primary_vlan_id']),
deploy_immediacy=dict(type='str', choices=['immediate', 'lazy']),
interface_mode=dict(type='str', choices=['untagged', '802.1p', 'trunk', 'regular', 'native', 'tagged', 'access'],
aliases=['mode', 'interface_mode_name']),
interface_type=dict(type='str', choices=['switch_port', 'vpc', 'port_channel', 'fex'], required=True),
# NOTE: C(pod) is usually an integer below 10.
pod=dict(type='int', aliases=['pod_number']),
# NOTE: C(leafs) is usually something like '101' or '101-102' depending on C(connection_type).
leafs=dict(type='list', aliases=['paths', 'leaves', 'nodes', 'switches']),
# NOTE: C(interface) is usually a policy group like: "test-IntPolGrp" or an interface of the following format: "1/7" depending on C(interface_type).
interface_mode=dict(type='str', choices=['802.1p', 'access', 'native', 'regular', 'tagged', 'trunk', 'untagged'],
aliases=['interface_mode_name', 'mode']),
interface_type=dict(type='str', default='switch_port', choices=['fex', 'port_channel', 'switch_port', 'vpc']),
pod_id=dict(type='int', aliases=['pod', 'pod_number']), # Not required for querying all objects
leafs=dict(type='list', aliases=['leaves', 'nodes', 'paths', 'switches']),
interface=dict(type='str'),
# NOTE: C(extpaths) is only used if C(interface_type) is C(fex), it is usually something like '1011'(int)
extpaths=dict(type='int'),
state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
)
@ -255,9 +255,9 @@ def main():
argument_spec=argument_spec,
supports_check_mode=True,
required_if=[
['state', 'absent', ['tenant', 'ap', 'epg', 'interface_type', 'pod', 'leafs', 'interface']],
['state', 'present', ['tenant', 'ap', 'epg', 'encap_id', 'interface_type', 'pod', 'leafs', 'interface']],
['interface_type', 'fex', ['extpaths']],
['state', 'absent', ['ap', 'epg', 'interface', 'leafs', 'pod_id', 'tenant']],
['state', 'present', ['ap', 'encap_id', 'epg', 'interface', 'leafs', 'pod_id', 'tenant']],
],
)
@ -269,7 +269,7 @@ def main():
deploy_immediacy = module.params['deploy_immediacy']
interface_mode = module.params['interface_mode']
interface_type = module.params['interface_type']
pod = module.params['pod']
pod_id = module.params['pod_id']
# Users are likely to use integers for leaf IDs, which would raise an exception when using the join method
leafs = [str(leaf) for leaf in module.params['leafs']]
if leafs is not None:
@ -304,23 +304,20 @@ def main():
module.fail_json(msg='Valid VLAN assigments are from 1 to 4096')
INTERFACE_MODE_MAPPING = {
'802.1p': 'native',
'access': 'untagged',
'untagged': 'untagged',
'native': 'native',
'regular': 'regular',
'tagged': 'regular',
'trunk': 'regular',
'regular': 'regular',
'802.1p': 'native',
'native': 'native',
'untagged': 'untagged',
}
INTERFACE_TYPE_MAPPING = dict(
# NOTE: C(interface) can be a policy group like: 'test-IntPolGrp' or of following format: '1/7', C(leafs) can only be something like '101'
switch_port='topology/pod-{0}/paths-{1}/pathep-[eth{2}]'.format(pod, leafs, interface),
# NOTE: C(interface) can be a policy group like: 'test-IntPolGrp' or of following format: '1/7', C(leafs) can only be something like '101'
port_channel='topology/pod-{0}/paths-{1}/pathep-[eth{2}]'.format(pod, leafs, interface),
# NOTE: C(interface) can be a policy group like: 'test-IntPolGrp', C(leafs) can be something like '101-102'
vpc='topology/pod-{0}/protpaths-{1}/pathep-[{2}]'.format(pod, leafs, interface),
# NOTE: C(interface) can be of the following format: '1/7', C(leafs) can only be like '101', C(extpaths) can only be like '1011'
fex='topology/pod-{0}/paths-{1}/extpaths-{2}/pathep-[eth{3}]'.format(pod, leafs, extpaths, interface),
fex='topology/pod-{0}/paths-{1}/extpaths-{2}/pathep-[eth{3}]'.format(pod_id, leafs, extpaths, interface),
port_channel='topology/pod-{0}/paths-{1}/pathep-[eth{2}]'.format(pod_id, leafs, interface),
switch_port='topology/pod-{0}/paths-{1}/pathep-[eth{2}]'.format(pod_id, leafs, interface),
vpc='topology/pod-{0}/protpaths-{1}/pathep-[{2}]'.format(pod_id, leafs, interface),
)
static_path = INTERFACE_TYPE_MAPPING[interface_type]
@ -358,7 +355,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class='fvRsPathAtt',
class_config=dict(
@ -370,10 +366,8 @@ def main():
),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='fvRsPathAtt')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -17,14 +17,14 @@ module: aci_switch_leaf_selector
short_description: Add a leaf Selector with Node Block Range and Policy Group to a Switch Policy Leaf Profile on Cisco ACI fabrics
description:
- Add a leaf Selector with Node Block range and Policy Group to a Switch Policy Leaf Profile on Cisco ACI fabrics.
notes:
- This module is to be used with M(aci_switch_policy_leaf_profile)
One first creates a leaf profile (infra:NodeP) and then creates an associated selector (infra:LeafS),
- More information from the internal APIC class I(infra:LeafS), I(infra:NodeBlk), I(infra:RsAccNodePGrp) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Bruno Calogero (@brunocalogero)
version_added: '2.5'
notes:
- This module is to be used with M(aci_switch_policy_leaf_profile)
One first creates a leaf profile (infra:NodeP) and then creates an associated selector (infra:LeafS),
options:
description:
description:
@ -223,8 +223,8 @@ def main():
argument_spec = aci_argument_spec()
argument_spec.update({
'description': dict(type='str'),
'leaf_profile': dict(type='str', aliases=['leaf_profile_name']),
'leaf': dict(type='str', aliases=['name', 'leaf_name', 'leaf_profile_leaf_name', 'leaf_selector_name']),
'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'),
'from': dict(type='int', aliases=['node_blk_range_from', 'from_range', 'range_from']),
@ -268,14 +268,13 @@ def main():
module_object=leaf,
),
# NOTE: infraNodeBlk is not made into a subclass because there is a 1-1 mapping between node block and leaf selector name
child_classes=['infraNodeBlk', 'infraRsAccNodePGrp']
child_classes=['infraNodeBlk', 'infraRsAccNodePGrp'],
)
aci.get_existing()
if state == 'present':
# Filter out module params with null values
aci.payload(
aci_class='infraLeafS',
class_config=dict(
@ -290,23 +289,21 @@ def main():
name=leaf_node_blk,
from_=from_,
to_=to_,
)
)
),
),
),
dict(
infraRsAccNodePGrp=dict(
attributes=dict(
tDn='uni/infra/funcprof/accnodepgrp-{0}'.format(policy_group),
)
)
),
),
),
],
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='infraLeafS')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -17,6 +17,7 @@ module: aci_switch_policy_leaf_profile
short_description: Create switch policy leaf profiles on Cisco ACI fabrics (infra:NodeP)
description:
- Create switch policy leaf profiles on Cisco ACI fabrics.
notes:
- More information from the internal APIC class I(infra:NodeP) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
@ -26,7 +27,7 @@ options:
leaf_profile:
description:
- The name of the Leaf Profile.
aliases: [ name, leaf_profile_name ]
aliases: [ leaf_profile_name, name ]
description:
description:
- Description for the Leaf Profile.
@ -179,7 +180,7 @@ from ansible.module_utils.basic import AnsibleModule
def main():
argument_spec = aci_argument_spec()
argument_spec.update(
leaf_profile=dict(type='str', aliases=['name', 'leaf_profile_name']),
leaf_profile=dict(type='str', aliases=['name', 'leaf_profile_name']), # Not required for querying all objects
description=dict(type='str', aliases=['descr']),
state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
)
@ -203,26 +204,23 @@ def main():
aci_class='infraNodeP',
aci_rn='infra/nprof-{0}'.format(leaf_profile),
filter_target='eq(infraNodeP.name, "{0}")'.format(leaf_profile),
module_object=leaf_profile
)
module_object=leaf_profile,
),
)
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class='infraNodeP',
class_config=dict(
name=leaf_profile,
descr=description,
)
),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='infraNodeP')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -17,6 +17,7 @@ module: aci_switch_policy_vpc_protection_group
short_description: Create switch policy Explicit vPC Protection Group on Cisco ACI fabrics (fabric:ExplicitGEp, fabric:NodePEp).
description:
- Create switch policy Explicit vPC Protection Group on Cisco ACI fabrics.
notes:
- More information from the internal APIC class
I(fabric:ExplicitGEp) and I(fabric:NodePEp) at U(https://developer.cisco.com/site/aci/docs/apis/apic-mim-ref/).
author:
@ -188,7 +189,7 @@ from ansible.module_utils.basic import AnsibleModule
def main():
argument_spec = aci_argument_spec()
argument_spec.update(
protection_group=dict(type='str', aliases=['name', 'protection_group_name']),
protection_group=dict(type='str', aliases=['name', 'protection_group_name']), # Not required for querying all objects
protection_group_id=dict(type='int', aliases=['id']),
vpc_domain_policy=dict(type='str', aliases=['vpc_domain_policy_name']),
switch_1_id=dict(type='int'),
@ -226,7 +227,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class='fabricExplicitGEp',
class_config=dict(
@ -261,10 +261,8 @@ def main():
],
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='fabricExplicitGEp')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -17,14 +17,14 @@ module: aci_taboo_contract
short_description: Manage taboo contracts on Cisco ACI fabrics (vz:BrCP)
description:
- Manage taboo contracts on Cisco ACI fabrics.
notes:
- The C(tenant) used must exist before using this module in your playbook.
The M(aci_tenant) module can be used for this.
- More information from the internal APIC class I(vz:BrCP) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Dag Wieers (@dagwieers)
version_added: '2.4'
notes:
- The C(tenant) used must exist before using this module in your playbook.
The M(aci_tenant) module can be used for this.
options:
taboo_contract:
description:
@ -246,7 +246,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class='vzTaboo',
class_config=dict(
@ -256,10 +255,8 @@ def main():
),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='vzTaboo')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -16,6 +16,7 @@ module: aci_tenant
short_description: Manage tenants on Cisco ACI fabrics (fv:Tenant)
description:
- Manage tenants on Cisco ACI fabrics.
notes:
- More information from the internal APIC class I(fv:Tenant) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
@ -202,9 +203,9 @@ def main():
],
)
tenant = module.params['tenant']
description = module.params['description']
state = module.params['state']
tenant = module.params['tenant']
aci = ACIModule(module)
aci.construct_url(
@ -218,7 +219,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class='fvTenant',
class_config=dict(
@ -227,10 +227,8 @@ def main():
),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='fvTenant')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -16,14 +16,14 @@ module: aci_tenant_action_rule_profile
short_description: Manage action rule profiles on Cisco ACI fabrics (rtctrl:AttrP)
description:
- Manage action rule profiles on Cisco ACI fabrics.
notes:
- The C(tenant) used must exist before using this module in your playbook.
The M(aci_tenant) module can be used for this.
- More information from the internal APIC class I(rtctrl:AttrP) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Dag Wieers (@dagwieers)
version_added: '2.4'
notes:
- The C(tenant) used must exist before using this module in your playbook.
The M(aci_tenant) module can be used for this.
options:
action_rule:
description:
@ -210,20 +210,16 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class='rtctrlAttrP',
class_config=dict(
name=action_rule,
descr=description,
),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='rtctrlAttrP')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -16,14 +16,14 @@ module: aci_tenant_ep_retention_policy
short_description: Manage End Point (EP) retention protocol policies on Cisco ACI fabrics (fv:EpRetPol)
description:
- Manage End Point (EP) retention protocol policies on Cisco ACI fabrics.
notes:
- The C(tenant) used must exist before using this module in your playbook.
The M(aci_tenant) module can be used for this.
- More information from the internal APIC class I(fv:EpRetPol) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Swetha Chunduri (@schunduri)
version_added: '2.4'
notes:
- The C(tenant) used must exist before using this module in your playbook.
The M(aci_tenant) module can be used for this.
options:
tenant:
description:
@ -231,7 +231,7 @@ BOUNCE_TRIG_MAPPING = dict(coop='protocol', rarp='rarp-flood')
def main():
argument_spec = aci_argument_spec()
argument_spec.update(
tenant=dict(type='str', aliases=['tenant_name']), # not required for querying all EPRs
tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects
epr_policy=dict(type='str', aliases=['epr_name', 'name']),
bounce_age=dict(type='int'),
bounce_trigger=dict(type='str', choices=['coop', 'flood']),
@ -304,7 +304,6 @@ def main():
aci.get_existing()
if state == 'present':
# filter out module parameters with null values
aci.payload(
aci_class='fvEpRetPol',
class_config=dict(
@ -319,10 +318,8 @@ def main():
),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='fvEpRetPol')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -16,14 +16,14 @@ module: aci_tenant_span_dst_group
short_description: Manage SPAN destination groups on Cisco ACI fabrics (span:DestGrp)
description:
- Manage SPAN destination groups on Cisco ACI fabrics.
notes:
- The C(tenant) used must exist before using this module in your playbook.
The M(aci_tenant) module can be used for this.
- More information from the internal APIC class I(span:DestGrp) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Dag Wieers (@dagwieers)
version_added: '2.4'
notes:
- The C(tenant) used must exist before using this module in your playbook.
The M(aci_tenant) module can be used for this.
options:
dst_group:
description:
@ -212,7 +212,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class='spanDestGrp',
class_config=dict(
@ -221,10 +220,8 @@ def main():
),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='spanDestGrp')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -16,14 +16,14 @@ module: aci_tenant_span_src_group
short_description: Manage SPAN source groups on Cisco ACI fabrics (span:SrcGrp)
description:
- Manage SPAN source groups on Cisco ACI fabrics.
notes:
- The C(tenant) used must exist before using this module in your playbook.
The M(aci_tenant) module can be used for this.
- More information from the internal APIC class I(span:SrcGrp) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Jacob McGill (@jmcgill298)
version_added: '2.4'
notes:
- The C(tenant) used must exist before using this module in your playbook.
The M(aci_tenant) module can be used for this.
options:
admin_state:
description:
@ -225,7 +225,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class='spanSrcGrp',
class_config=dict(
@ -236,10 +235,8 @@ def main():
child_configs=[{'spanSpanLbl': {'attributes': {'name': dst_group}}}],
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='spanSrcGrp')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -16,14 +16,14 @@ module: aci_tenant_span_src_group_to_dst_group
short_description: Manage SPAN source group to destination group bindings on Cisco ACI fabrics (span:SpanLbl)
description:
- Manage SPAN source groups' associated destinaton group on Cisco ACI fabrics.
notes:
- The C(tenant), C(src_group), and C(dst_group) must exist before using this module in your playbook.
The M(aci_tenant), M(aci_tenant_span_src_group), and M(aci_tenant_span_dst_group) modules can be used for this.
- More information from the internal APIC class I(span:SrcGrp) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Jacob McGill (@jmcgill298)
version_added: '2.4'
notes:
- The C(tenant), C(src_group), and C(dst_group) must exist before using this module in your playbook.
The M(aci_tenant), M(aci_tenant_span_src_group), and M(aci_tenant_span_dst_group) modules can be used for this.
options:
description:
description:
@ -172,10 +172,10 @@ def main():
argument_spec = aci_argument_spec()
argument_spec.update(
description=dict(type='str', aliases=['descr']),
dst_group=dict(type='str'),
src_group=dict(type='str'),
dst_group=dict(type='str'), # Not required for querying all objects
src_group=dict(type='str'), # Not required for querying all objects
state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
tenant=dict(type='str', aliases=['tenant_name']),
tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects
method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6
protocol=dict(type='str', removed_in_version='2.6'), # Deprecated in v2.6
)
@ -220,7 +220,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class='spanSpanLbl',
class_config=dict(
@ -229,10 +228,8 @@ def main():
),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='spanSpanLbl')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -18,6 +18,7 @@ module: aci_vlan_pool
short_description: Manage VLAN pools on Cisco ACI fabrics (fvns:VlanInstP)
description:
- Manage VLAN pools on Cisco ACI fabrics.
notes:
- More information from the internal APIC class I(fvns:VlanInstP) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
@ -197,7 +198,7 @@ def main():
argument_spec = aci_argument_spec()
argument_spec.update(
description=dict(type='str', aliases=['descr']),
pool=dict(type='str', aliases=['name', 'pool_name']),
pool=dict(type='str', aliases=['name', 'pool_name']), # Not required for querying all objects
pool_allocation_mode=dict(type='str', aliases=['allocation_mode', 'mode'], choices=['dynamic', 'static']),
state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
)
@ -238,20 +239,17 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class='fvnsVlanInstP',
class_config=dict(
allocMode=pool_allocation_mode,
descr=description,
name=pool,
)
),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='fvnsVlanInstP')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -18,14 +18,14 @@ module: aci_vlan_pool_encap_block
short_description: Manage encap blocks assigned to VLAN pools on Cisco ACI fabrics (fvns:EncapBlk)
description:
- Manage VLAN encap blocks that are assigned to VLAN pools on Cisco ACI fabrics.
notes:
- The C(pool) must exist in order to add or delete a encap block.
- More information from the internal APIC class I(fvns:EncapBlk) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Jacob McGill (@jmcgill298)
- Dag Wieers (@dagwieers)
version_added: '2.5'
requirements:
- The C(pool) must exist in order to add or delete a encap block.
options:
allocation_mode:
description:
@ -227,11 +227,11 @@ def main():
argument_spec.update(
allocation_mode=dict(type='str', aliases=['mode'], choices=['dynamic', 'inherit', 'static']),
description=dict(type='str', aliases=['descr']),
pool=dict(type='str', aliases=['pool_name']),
pool=dict(type='str', aliases=['pool_name']), # Not required for querying all objects
pool_allocation_mode=dict(type='str', aliases=['pool_mode'], choices=['dynamic', 'static']),
block_name=dict(type='str', aliases=['name']),
block_end=dict(type='int', aliases=['end']),
block_start=dict(type='int', aliases=["start"]),
block_name=dict(type='str', aliases=['name']), # Not required for querying all objects
block_end=dict(type='int', aliases=['end']), # Not required for querying all objects
block_start=dict(type='int', aliases=["start"]), # Not required for querying all objects
state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
)
@ -327,7 +327,6 @@ def main():
aci.get_existing()
if state == 'present':
# Filter out module parameters with null values
aci.payload(
aci_class='fvnsEncapBlk',
class_config={
@ -336,13 +335,11 @@ def main():
"from": encap_start,
"name": block_name,
"to": encap_end,
}
},
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='fvnsEncapBlk')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -17,14 +17,14 @@ short_description: Manage VRF (private networks aka. contexts) on Cisco ACI fabr
description:
- Manage VRF (private networks aka. contexts) on Cisco ACI fabrics.
- Each context is a private network associated to a tenant, i.e. VRF.
notes:
- The C(tenant) used must exist before using this module in your playbook.
The M(aci_tenant) module can be used for this.
- More information from the internal APIC class I(fv:Ctx) at
U(https://developer.cisco.com/docs/apic-mim-ref/).
author:
- Jacob McGill (@jmcgill298)
version_added: '2.4'
notes:
- The C(tenant) used must exist before using this module in your playbook.
The M(aci_tenant) module can be used for this.
options:
tenant:
description:
@ -247,10 +247,10 @@ def main():
module_object=vrf,
),
)
aci.get_existing()
if state == 'present':
# Filter out module params with null values
aci.payload(
aci_class='fvCtx',
class_config=dict(
@ -261,10 +261,8 @@ def main():
),
)
# Generate config diff which will be used as POST request body
aci.get_diff(aci_class='fvCtx')
# Submit changes if module not in check_mode and the proposed is different than existing
aci.post_config()
elif state == 'absent':

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# Copyright 2017 Dag Wieers <dag@wieers.com>
# Copyright 2017 Swetha Chunduri (@schunduri)
# Copyright: (c) 2017, Dag Wieers (@dagwieers) <dag@wieers.com>
# Copyright: (c) 2017, Swetha Chunduri (@schunduri)
# This file is part of Ansible by Red Hat
#
@ -83,12 +83,6 @@ options:
type: bool
default: 'yes'
notes:
- By default, if an environment variable C(<protocol>_proxy) is set on
the target host, requests will be sent through that proxy. This
behaviour can be overridden by setting a variable for this task
(see `setting the environment
<http://docs.ansible.com/playbooks_environment.html>`_),
or by using the C(use_proxy) option.
- HTTP redirects can redirect from HTTP to HTTPS so you should be sure that
your proxy environment for both protocols is correct.
- Please read :ref:`the ACI guide <aci_guide>` for more detailed information
on how to manage your ACI infrastructure using Ansible.
'''

@ -1,5 +1,5 @@
# Test code for the ACI modules
# Copyright 2017, Bruno Calogero <bcalogero@cisco.com>
# Copyright: (c) 2017, Bruno Calogero <bcalogero@cisco.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

@ -1,5 +1,5 @@
# Test code for the ACI modules
# Copyright 2018, Dag Wieers (@dagwieers) <dag@wieers.com>
# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

@ -1,5 +1,5 @@
# Test code for the ACI modules
# Copyright 2017, Jacob McGill <jmcgill298
# Copyright: (c) 2017, Jacob McGill (@jmcgill298)
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

@ -1,5 +1,5 @@
# Test code for the ACI modules
# Copyright 2017, Jacob McGill <jmcgill298
# Copyright: (c) 2017, Jacob McGill (@jmcgill298)
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

@ -1,5 +1,5 @@
# Test code for the ACI modules
# Copyright 2017, Jacob McGill <jmcgill298
# Copyright: (c) 2017, Jacob McGill (@jmcgill298)
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

@ -1,5 +1,5 @@
# Test code for the ACI modules
# Copyright 2017, Jacob McGill <jmcgill298
# Copyright: (c) 2017, Jacob McGill (@jmcgill298)
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

@ -1,5 +1,5 @@
# Test code for the ACI modules
# Copyright 2017, Dag Wieers <dag@wieers.com>
# Copyright: (c) 2017, Dag Wieers (@dagwieers) <dag@wieers.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

@ -1,5 +1,5 @@
# Test code for the ACI modules
# Copyright 2017, Jacob McGill <jmcgill298
# Copyright: (c) 2017, Jacob McGill (@jmcgill298)
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

@ -1,5 +1,5 @@
# Test code for the ACI modules
# Copyright 2017, Jacob McGill <jmcgill298
# Copyright: (c) 2017, Jacob McGill (@jmcgill298)
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

@ -1,5 +1,5 @@
# Test code for the ACI modules
# Copyright 2017, Jacob McGill <jmcgill298
# Copyright: (c) 2017, Jacob McGill (@jmcgill298)
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

@ -1,5 +1,5 @@
# Test code for the ACI modules
# Copyright 2018, Dag Wieers (@dagwieers) <dag@wieers.com>
# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

@ -1,5 +1,5 @@
# Test code for the ACI modules
# Copyright 2018, Dag Wieers (@dagwieers) <dag@wieers.com>
# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

@ -1,5 +1,5 @@
# Test code for the ACI modules
# Copyright 2018, Dag Wieers (@dagwieers) <dag@wieers.com>
# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

@ -1,5 +1,5 @@
# Test code for the ACI modules
# Copyright 2018, Dag Wieers (@dagwieers) <dag@wieers.com>
# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

@ -1,5 +1,5 @@
# Test code for the ACI modules
# Copyright 2018, Dag Wieers (@dagwieers) <dag@wieers.com>
# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

@ -1,5 +1,5 @@
# Test code for the ACI modules
# Copyright 2018, Dag Wieers (@dagwieers) <dag@wieers.com>
# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

@ -1,5 +1,5 @@
# Test code for the ACI modules
# Copyright 2018, Dag Wieers (@dagwieers) <dag@wieers.com>
# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

@ -1,5 +1,5 @@
# Test code for the ACI modules
# Copyright 2017, Jacob McGill <jmcgill298
# Copyright: (c) 2017, Jacob McGill (@jmcgill298)
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

@ -1,5 +1,5 @@
# Test code for the ACI modules
# Copyright 2017, Jacob McGill <jmcgill298
# Copyright: (c) 2017, Jacob McGill (@jmcgill298)
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

@ -1,5 +1,5 @@
# Test code for the ACI modules
# Copyright 2017, Jacob McGill <jmcgill298
# Copyright: (c) 2017, Jacob McGill (@jmcgill298)
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

@ -1,5 +1,5 @@
# Test code for the ACI modules
# Copyright 2017, Jacob McGill <jmcgill298
# Copyright: (c) 2017, Jacob McGill (@jmcgill298)
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

@ -1,5 +1,5 @@
# Test code for the ACI modules
# Copyright 2017, Dag Wieers <dag@wieers.com>
# Copyright: (c) 2017, Dag Wieers (@dagwieers) <dag@wieers.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

@ -18,6 +18,7 @@
validate_certs: '{{ aci_validate_certs | default(false) }}'
use_ssl: '{{ aci_use_ssl | default(true) }}'
use_proxy: '{{ aci_use_proxy | default(true) }}'
output_level: info
serial: ansible_test
node_id: 105
state: absent
@ -32,6 +33,7 @@
validate_certs: '{{ aci_validate_certs | default(false) }}'
use_ssl: '{{ aci_use_ssl | default(true) }}'
use_proxy: '{{ aci_use_proxy | default(true) }}'
output_level: debug
serial: ansible_test
node_id: 105
switch: test
@ -132,9 +134,8 @@
- name: Verify query_all_fabric_nodes
assert:
that:
- cm_query_all_fabric_nodes.changed == nm_query_all_fabric_nodes.changed == false # doesn't return necessary information
# NOTE: Order of fabric_nodes is not stable between calls
#- cm_query_all_fabric_nodes == nm_query_all_fabric_nodes
- cm_query_all_fabric_nodes.changed == nm_query_all_fabric_nodes.changed == false
- cm_query_all_fabric_nodes == nm_query_all_fabric_nodes
# QUERY A FABRIC NODE
@ -149,7 +150,7 @@
aci_fabric_node:
<<: *aci_fabric_node_query
serial: ansible_test
register: nm_query_fabric_node # doesn't return necessary information
register: nm_query_fabric_node
- name: Verify query_fabric_node
assert:
@ -198,7 +199,6 @@
serial: ansible_test
register: nm_query_non_fabric_node
# TODO: Implement more tests
- name: Verify query_non_fabric_node
assert:
that:

@ -1,5 +1,5 @@
# Test code for the ACI modules
# Copyright 2017, Dag Wieers <dag@wieers.com>
# Copyright: (c) 2017, Dag Wieers (@dagwieers) <dag@wieers.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

@ -1,5 +1,5 @@
# Test code for the ACI modules
# Copyright 2017, Jacob McGill <jmcgill298
# Copyright: (c) 2017, Jacob McGill (@jmcgill298)
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

@ -1,5 +1,5 @@
# Test code for the ACI modules
# Copyright 2017, Bruno Calogero <bcaloger@cisco.com>
# Copyright: (c) 2017, Bruno Calogero <bcaloger@cisco.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

@ -1,5 +1,5 @@
# Test code for the ACI modules
# Copyright 2017, Bruno Calogero <bcaloger@cisco.com>
# Copyright: (c) 2017, Bruno Calogero <bcaloger@cisco.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

@ -1,5 +1,5 @@
# Test code for the ACI modules
# Copyright 2017, Bruno Calogero <bcalogero@cisco.com>
# Copyright: (c) 2017, Bruno Calogero <bcalogero@cisco.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

@ -1,5 +1,5 @@
# Test code for the ACI modules
# Copyright 2017, Bruno Calogero <bcaloger@cisco.com>
# Copyright: (c) 2017, Bruno Calogero <bcaloger@cisco.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

@ -1,5 +1,5 @@
# Test code for the ACI modules
# Copyright 2017, Bruno Calogero <bcaloger@cisco.com>
# Copyright: (c) 2017, Bruno Calogero <bcaloger@cisco.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

@ -1,5 +1,5 @@
# Test code for the ACI modules
# Copyright 2017, Bruno Calogero <brunocalogero@hotmail.com>
# Copyright: (c) 2017, Bruno Calogero <brunocalogero@hotmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

@ -1,5 +1,5 @@
# Test code for the ACI modules
# Copyright 2017, Dag Wieers <dag@wieers.com>
# Copyright: (c) 2017, Dag Wieers (@dagwieers) <dag@wieers.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

@ -1,5 +1,5 @@
# Test code for the ACI modules
# Copyright 2017, Jacob McGill <jmcgill298
# Copyright: (c) 2017, Jacob McGill (@jmcgill298)
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

Loading…
Cancel
Save