diff options
Diffstat (limited to 'collections-debian-merged/ansible_collections/cisco/aci/plugins/modules')
85 files changed, 26532 insertions, 0 deletions
diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/__init__.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/__init__.py diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_aaa_user.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_aaa_user.py new file mode 100644 index 00000000..a951ad4f --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_aaa_user.py @@ -0,0 +1,367 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2018, Dag Wieers (dagwieers) <dag@wieers.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_aaa_user +short_description: Manage AAA users (aaa:User) +description: +- Manage AAA users on Cisco ACI fabrics. +requirements: +- python-dateutil +options: + aaa_password: + description: + - The password of the locally-authenticated user. + type: str + aaa_password_lifetime: + description: + - The lifetime of the locally-authenticated user password. + type: int + aaa_password_update_required: + description: + - Whether this account needs password update. + type: bool + aaa_user: + description: + - The name of the locally-authenticated user user to add. + type: str + aliases: [ name, user ] + clear_password_history: + description: + - Whether to clear the password history of a locally-authenticated user. + type: bool + description: + description: + - Description for the AAA user. + type: str + aliases: [ descr ] + email: + description: + - The email address of the locally-authenticated user. + type: str + enabled: + description: + - The status of the locally-authenticated user account. + type: bool + expiration: + description: + - The expiration date of the locally-authenticated user account. + type: str + expires: + description: + - Whether to enable an expiration date for the locally-authenticated user account. + type: bool + first_name: + description: + - The first name of the locally-authenticated user. + type: str + last_name: + description: + - The last name of the locally-authenticated user. + type: str + phone: + description: + - The phone number of the locally-authenticated user. + type: str + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +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. The vendor has been informed. + More information in :ref:`the ACI documentation <aci_guide_known_issues>`. +seealso: +- module: cisco.aci.aci_aaa_user_certificate +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(aaa:User). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Dag Wieers (@dagwieers) +''' + +EXAMPLES = r''' +- name: Add a user + cisco.aci.aci_aaa_user: + host: apic + username: admin + password: SomeSecretPassword + aaa_user: dag + aaa_password: AnotherSecretPassword + expiration: never + expires: no + email: dag@wieers.com + phone: 1-234-555-678 + first_name: Dag + last_name: Wieers + state: present + delegate_to: localhost + +- name: Remove a user + cisco.aci.aci_aaa_user: + host: apic + username: admin + password: SomeSecretPassword + aaa_user: dag + state: absent + delegate_to: localhost + +- name: Query a user + cisco.aci.aci_aaa_user: + host: apic + username: admin + password: SomeSecretPassword + aaa_user: dag + state: query + delegate_to: localhost + register: query_result + +- name: Query all users + cisco.aci.aci_aaa_user: + host: apic + username: admin + password: SomeSecretPassword + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: '?rsp-prop-include=config-only' +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +try: + from dateutil.tz import tzutc + import dateutil.parser + HAS_DATEUTIL = True +except ImportError: + HAS_DATEUTIL = False + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + aaa_password=dict(type='str', no_log=True), + aaa_password_lifetime=dict(type='int'), + aaa_password_update_required=dict(type='bool'), + aaa_user=dict(type='str', aliases=['name']), # Not required for querying all objects + clear_password_history=dict(type='bool'), + description=dict(type='str', aliases=['descr']), + email=dict(type='str'), + enabled=dict(type='bool'), + expiration=dict(type='str'), + expires=dict(type='bool'), + first_name=dict(type='str'), + last_name=dict(type='str'), + phone=dict(type='str'), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['aaa_user']], + ['state', 'present', ['aaa_user']], + ['expires', True, ['expiration']], + ], + ) + + aci = ACIModule(module) + + if not HAS_DATEUTIL: + module.fail_json(msg='dateutil required for this module') + + aaa_password = module.params.get('aaa_password') + aaa_password_lifetime = module.params.get('aaa_password_lifetime') + aaa_password_update_required = aci.boolean(module.params.get('aaa_password_update_required')) + aaa_user = module.params.get('aaa_user') + clear_password_history = aci.boolean(module.params.get('clear_password_history'), 'yes', 'no') + description = module.params.get('description') + email = module.params.get('email') + enabled = aci.boolean(module.params.get('enabled'), 'active', 'inactive') + expires = aci.boolean(module.params.get('expires')) + first_name = module.params.get('first_name') + last_name = module.params.get('last_name') + phone = module.params.get('phone') + state = module.params.get('state') + name_alias = module.params.get('name_alias') + + expiration = module.params.get('expiration') + if expiration is not None and expiration != 'never': + try: + expiration = aci.iso8601_format(dateutil.parser.parse(expiration).replace(tzinfo=tzutc())) + except Exception as e: + module.fail_json(msg="Failed to parse date format '%s', %s" % (module.params.get('expiration'), e)) + + aci.construct_url( + root_class=dict( + aci_class='aaaUser', + aci_rn='userext/user-{0}'.format(aaa_user), + module_object=aaa_user, + target_filter={'name': aaa_user}, + ), + ) + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='aaaUser', + class_config=dict( + accountStatus=enabled, + clearPwdHistory=clear_password_history, + descr=description, + email=email, + expiration=expiration, + expires=expires, + firstName=first_name, + lastName=last_name, + name=aaa_user, + phone=phone, + pwd=aaa_password, + pwdLifeTime=aaa_password_lifetime, + pwdUpdateRequired=aaa_password_update_required, + nameAlias=name_alias, + ), + ) + + aci.get_diff(aci_class='aaaUser') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_aaa_user_certificate.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_aaa_user_certificate.py new file mode 100644 index 00000000..fc15e56f --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_aaa_user_certificate.py @@ -0,0 +1,298 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2018, Dag Wieers (dagwieers) <dag@wieers.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_aaa_user_certificate +short_description: Manage AAA user certificates (aaa:UserCert) +description: +- Manage AAA user certificates on Cisco ACI fabrics. +options: + aaa_user: + description: + - The name of the user to add a certificate to. + type: str + required: yes + aaa_user_type: + description: + - Whether this is a normal user or an appuser. + type: str + choices: [ appuser, user ] + default: user + certificate: + description: + - The PEM format public key extracted from the X.509 certificate. + type: str + aliases: [ cert_data, certificate_data ] + certificate_name: + description: + - The name of the user certificate entry in ACI. + type: str + aliases: [ cert_name ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- The C(aaa_user) must exist before using this module in your playbook. + The M(cisco.aci.aci_aaa_user) module can be used for this. +seealso: +- module: cisco.aci.aci_aaa_user +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(aaa:UserCert). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Dag Wieers (@dagwieers) +''' + +EXAMPLES = r''' +- name: Add a certificate to user + cisco.aci.aci_aaa_user_certificate: + host: apic + username: admin + password: SomeSecretPassword + aaa_user: admin + certificate_name: admin + certificate_data: '{{ lookup("file", "pki/admin.crt") }}' + state: present + delegate_to: localhost + +- name: Remove a certificate of a user + cisco.aci.aci_aaa_user_certificate: + host: apic + username: admin + password: SomeSecretPassword + aaa_user: admin + certificate_name: admin + state: absent + delegate_to: localhost + +- name: Query a certificate of a user + cisco.aci.aci_aaa_user_certificate: + host: apic + username: admin + password: SomeSecretPassword + aaa_user: admin + certificate_name: admin + state: query + delegate_to: localhost + register: query_result + +- name: Query all certificates of a user + cisco.aci.aci_aaa_user_certificate: + host: apic + username: admin + password: SomeSecretPassword + aaa_user: admin + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + +ACI_MAPPING = dict( + appuser=dict( + aci_class='aaaAppUser', + aci_mo='userext/appuser-', + ), + user=dict( + aci_class='aaaUser', + aci_mo='userext/user-', + ), +) + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + aaa_user=dict(type='str', required=True), + aaa_user_type=dict(type='str', default='user', choices=['appuser', 'user']), + certificate=dict(type='str', aliases=['cert_data', 'certificate_data']), + certificate_name=dict(type='str', aliases=['cert_name']), # Not required for querying all objects + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['aaa_user', 'certificate_name']], + ['state', 'present', ['aaa_user', 'certificate', 'certificate_name']], + ], + ) + + aaa_user = module.params.get('aaa_user') + aaa_user_type = module.params.get('aaa_user_type') + certificate = module.params.get('certificate') + certificate_name = module.params.get('certificate_name') + state = module.params.get('state') + name_alias = module.params.get('name_alias') + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class=ACI_MAPPING.get(aaa_user_type).get('aci_class'), + aci_rn=ACI_MAPPING.get(aaa_user_type).get('aci_mo') + aaa_user, + module_object=aaa_user, + target_filter={'name': aaa_user}, + ), + subclass_1=dict( + aci_class='aaaUserCert', + aci_rn='usercert-{0}'.format(certificate_name), + module_object=certificate_name, + target_filter={'name': certificate_name}, + ), + ) + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='aaaUserCert', + class_config=dict( + data=certificate, + name=certificate_name, + nameAlias=name_alias, + + ), + ) + + aci.get_diff(aci_class='aaaUserCert') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_access_port_block_to_access_port.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_access_port_block_to_access_port.py new file mode 100644 index 00000000..246c82f4 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_access_port_block_to_access_port.py @@ -0,0 +1,437 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2018, Simon Metzger <smnmtzgr@gmail.com> +# Copyright: (c) 2020, Shreyas Srish <ssrish@cisco.com> +# Copyright: (c) 2020, Zak Lantz (@manofcolombia) <zakodewald@gmail.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_access_port_block_to_access_port +short_description: Manage port blocks of Fabric interface policy leaf profile interface selectors (infra:HPortS, infra:PortBlk) +description: +- Manage port blocks of Fabric interface policy leaf profile interface selectors on Cisco ACI fabrics. +options: + interface_profile: + description: + - The name of the Fabric access policy leaf interface profile. + type: str + aliases: [ leaf_interface_profile_name, leaf_interface_profile, interface_profile_name ] + access_port_selector: + description: + - The name of the Fabric access policy leaf interface profile access port selector. + type: str + aliases: [ name, access_port_selector_name ] + port_blk: + description: + - The name of the Fabric access policy leaf interface profile access port block. + type: str + aliases: [ leaf_port_blk_name, leaf_port_blk ] + port_blk_description: + description: + - The description to assign to the C(leaf_port_blk). + type: str + aliases: [ leaf_port_blk_description ] + from_port: + description: + - The beginning (from-range) of the port range block for the leaf access port block. + type: str + aliases: [ from, fromPort, from_port_range ] + to_port: + description: + - The end (to-range) of the port range block for the leaf access port block. + type: str + aliases: [ to, toPort, to_port_range ] + from_card: + description: + - The beginning (from-range) of the card range block for the leaf access port block. + type: str + aliases: [ from_card_range ] + to_card: + description: + - The end (to-range) of the card range block for the leaf access port block. + type: str + aliases: [ to_card_range ] + type: + description: + - The type of access port block to be created under respective access port. + type: str + choices: [ fex, leaf ] + default: leaf + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- The C(interface_profile) and C(access_port_selector) must exist before using this module in your playbook. + The M(cisco.aci.aci_interface_policy_leaf_profile) and M(cisco.aci.aci_access_port_to_interface_policy_leaf_profile) modules can be used for this. +seealso: +- name: APIC Management Information Model reference + description: More information about the internal APIC classes B(infra:HPortS) and B(infra:PortBlk). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Simon Metzger (@smnmtzgr) +''' + +EXAMPLES = r''' +- name: Associate an access port block (single port) to an interface selector + cisco.aci.aci_access_port_block_to_access_port: + host: apic + username: admin + password: SomeSecretPassword + interface_profile: leafintprfname + access_port_selector: accessportselectorname + port_blk: leafportblkname + from_port: 13 + to_port: 13 + state: present + delegate_to: localhost + +- name: Associate an access port block (port range) to an interface selector + cisco.aci.aci_access_port_block_to_access_port: + host: apic + username: admin + password: SomeSecretPassword + interface_profile: leafintprfname + access_port_selector: accessportselectorname + port_blk: leafportblkname + from_port: 13 + to_port: 16 + state: present + delegate_to: localhost + +- name: Associate an access port block (single port) to an interface selector of type fex + cisco.aci.aci_access_port_block_to_access_port: + host: apic + username: admin + password: SomeSecretPassword + type: fex + interface_profile: leafintprfname_fex + access_port_selector: accessportselectorname_fex + port_blk: leafportblkname_fex + from_port: 13 + to_port: 13 + state: present + delegate_to: localhost + +- name: Associate an access port block (port range) to an interface selector of type fex + cisco.aci.aci_access_port_block_to_access_port: + host: apic + username: admin + password: SomeSecretPassword + type: fex + interface_profile: leafintprfname_fex + access_port_selector: accessportselectorname_fex + port_blk: leafportblkname_fex + from_port: 13 + to_port: 16 + state: present + delegate_to: localhost + +- name: Remove an access port block from an interface selector + cisco.aci.aci_access_port_block_to_access_port: + host: apic + username: admin + password: SomeSecretPassword + interface_profile: leafintprfname + access_port_selector: accessportselectorname + port_blk: leafportblkname + from_port: 13 + to_port: 13 + state: absent + delegate_to: localhost + +- name: Remove an access port block from an interface selector of type fex + cisco.aci.aci_access_port_block_to_access_port: + host: apic + username: admin + password: SomeSecretPassword + type: fex + interface_profile: leafintprfname_fex + access_port_selector: accessportselectorname_fex + port_blk: leafportblkname_fex + from_port: 13 + to_port: 13 + state: absent + delegate_to: localhost + +- name: Query Specific access port block under given access port selector + cisco.aci.aci_access_port_block_to_access_port: + host: apic + username: admin + password: SomeSecretPassword + interface_profile: leafintprfname + access_port_selector: accessportselectorname + port_blk: leafportblkname + state: query + delegate_to: localhost + register: query_result + +- name: Query Specific access port block under given access port selector of type fex + cisco.aci.aci_access_port_block_to_access_port: + host: apic + username: admin + password: SomeSecretPassword + type: fex + interface_profile: leafintprfname_fex + access_port_selector: accessportselectorname_fex + port_blk: leafportblkname_fex + state: query + delegate_to: localhost + register: query_result + +- name: Query all access port blocks under given leaf interface profile + cisco.aci.aci_access_port_block_to_access_port: + host: apic + username: admin + password: SomeSecretPassword + interface_profile: leafintprfname + state: query + delegate_to: localhost + register: query_result + +- name: Query all access port blocks under given leaf interface profile of type fex + cisco.aci.aci_access_port_block_to_access_port: + host: apic + username: admin + password: SomeSecretPassword + type: fex + interface_profile: leafintprfname_fex + state: query + delegate_to: localhost + register: query_result + +- name: Query all access port blocks in the fabric + cisco.aci.aci_access_port_block_to_access_port: + host: apic + username: admin + password: SomeSecretPassword + state: query + delegate_to: localhost + register: query_result + +- name: Query all access port blocks in the fabric of type fex + cisco.aci.aci_access_port_block_to_access_port: + host: apic + username: admin + password: SomeSecretPassword + type: fex + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + interface_profile=dict(type='str', aliases=['leaf_interface_profile_name', 'leaf_interface_profile', 'interface_profile_name']), + access_port_selector=dict(type='str', aliases=['name', 'access_port_selector_name']), # Not required for querying all objects + port_blk=dict(type='str', aliases=['leaf_port_blk_name', 'leaf_port_blk']), # Not required for querying all objects + port_blk_description=dict(type='str', aliases=['leaf_port_blk_description']), + from_port=dict(type='str', aliases=['from', 'fromPort', 'from_port_range']), + to_port=dict(type='str', aliases=['to', 'toPort', 'to_port_range']), + from_card=dict(type='str', aliases=['from_card_range']), + to_card=dict(type='str', aliases=['to_card_range']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + type=dict(type='str', default='leaf', choices=['fex', 'leaf']), # This parameter is not required for querying all objects + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['access_port_selector', 'port_blk', 'interface_profile']], + ['state', 'present', ['access_port_selector', 'port_blk', 'from_port', 'to_port', 'interface_profile']], + ], + ) + + interface_profile = module.params.get('interface_profile') + access_port_selector = module.params.get('access_port_selector') + port_blk = module.params.get('port_blk') + port_blk_description = module.params.get('port_blk_description') + from_port = module.params.get('from_port') + to_port = module.params.get('to_port') + from_card = module.params.get('from_card') + to_card = module.params.get('to_card') + state = module.params.get('state') + type_port = module.params.get('type') + + aci = ACIModule(module) + aci_class = 'infraAccPortP' + aci_rn = 'accportprof' + if type_port == 'fex': + aci_class = 'infraFexP' + aci_rn = 'fexprof' + aci.construct_url( + root_class=dict( + aci_class=aci_class, + aci_rn='infra/' + aci_rn + '-{0}'.format(interface_profile), + module_object=interface_profile, + target_filter={'name': interface_profile}, + ), + subclass_1=dict( + aci_class='infraHPortS', + # NOTE: normal rn: hports-{name}-typ-{type}, hence here hardcoded to range for purposes of module + aci_rn='hports-{0}-typ-range'.format(access_port_selector), + module_object=access_port_selector, + target_filter={'name': access_port_selector}, + ), + subclass_2=dict( + aci_class='infraPortBlk', + aci_rn='portblk-{0}'.format(port_blk), + module_object=port_blk, + target_filter={'name': port_blk}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='infraPortBlk', + class_config=dict( + descr=port_blk_description, + name=port_blk, + fromPort=from_port, + toPort=to_port, + fromCard=from_card, + toCard=to_card, + # type='range', + ), + ) + + aci.get_diff(aci_class='infraPortBlk') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_access_port_to_interface_policy_leaf_profile.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_access_port_to_interface_policy_leaf_profile.py new file mode 100644 index 00000000..f419c8b9 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_access_port_to_interface_policy_leaf_profile.py @@ -0,0 +1,429 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2017, Bruno Calogero <brunocalogero@hotmail.com> +# Copyright: (c) 2020, Shreyas Srish <ssrish@cisco.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_access_port_to_interface_policy_leaf_profile +short_description: Manage Fabric interface policy leaf profile interface selectors (infra:HPortS, infra:RsAccBaseGrp, infra:PortBlk) +description: +- Manage Fabric interface policy leaf profile interface selectors on Cisco ACI fabrics. +options: + interface_profile: + description: + - The name of the Fabric access policy leaf interface profile. + type: str + aliases: [ leaf_interface_profile_name, leaf_interface_profile, interface_profile_name ] + access_port_selector: + description: + - The name of the Fabric access policy leaf interface profile access port selector. + type: str + aliases: [ name, access_port_selector_name ] + description: + description: + - The description to assign to the C(access_port_selector) + type: str + port_blk: + description: + - B(Deprecated) + - Starting with Ansible 2.8 we recommend using M(cisco.aci.aci_access_port_block_to_access_port) instead. + - The parameter will be removed in Ansible 2.12. + - HORIZONTALLINE + - The name of the Fabric access policy leaf interface profile access port block. + type: str + aliases: [ leaf_port_blk_name, leaf_port_blk, port_blk_name ] + leaf_port_blk_description: + description: + - B(Deprecated) + - Starting with Ansible 2.8 we recommend using M(cisco.aci.aci_access_port_block_to_access_port) instead. + - The parameter will be removed in Ansible 2.12. + - HORIZONTALLINE + - The description to assign to the C(leaf_port_blk) + type: str + from_port: + description: + - B(Deprecated) + - Starting with Ansible 2.8 we recommend using M(cisco.aci.aci_access_port_block_to_access_port) instead. + - The parameter will be removed in Ansible 2.12. + - HORIZONTALLINE + - The beginning (from-range) of the port range block for the leaf access port block. + type: str + aliases: [ from, fromPort, from_port_range ] + to_port: + description: + - B(Deprecated) + - Starting with Ansible 2.8 we recommend using M(cisco.aci.aci_access_port_block_to_access_port) instead. + - The parameter will be removed in Ansible 2.12. + - HORIZONTALLINE + - The end (to-range) of the port range block for the leaf access port block. + type: str + aliases: [ to, toPort, to_port_range ] + from_card: + description: + - B(Deprecated) + - Starting with Ansible 2.8 we recommend using M(cisco.aci.aci_access_port_block_to_access_port) instead. + - The parameter will be removed in Ansible 2.12. + - HORIZONTALLINE + - The beginning (from-range) of the card range block for the leaf access port block. + type: str + aliases: [ from_card_range ] + to_card: + description: + - B(Deprecated) + - Starting with Ansible 2.8 we recommend using M(cisco.aci.aci_access_port_block_to_access_port) instead. + - The parameter will be removed in Ansible 2.12. + - HORIZONTALLINE + - The end (to-range) of the card range block for the leaf access port block. + type: str + aliases: [ to_card_range ] + policy_group: + description: + - The name of the fabric access policy group to be associated with the leaf interface profile interface selector. + type: str + aliases: [ policy_group_name ] + interface_type: + description: + - The type of interface for the static EPG deployment. + type: str + choices: [ breakout, fex, port_channel, switch_port, vpc ] + default: switch_port + type: + description: + - The type of access port to be created under respective profile. + type: str + choices: [ fex, leaf ] + default: leaf + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- The C(interface_profile) must exist before using this module in your playbook. + The M(cisco.aci.aci_interface_policy_leaf_profile) modules can be used for this. +seealso: +- module: cisco.aci.aci_access_port_block_to_access_port +- name: APIC Management Information Model reference + description: More information about the internal APIC classes B(infra:HPortS), B(infra:RsAccBaseGrp) and B(infra:PortBlk). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Bruno Calogero (@brunocalogero) +- Shreyas Srish (@shrsr) +''' + +EXAMPLES = r''' +- name: Associate an Interface Access Port Selector to an Interface Policy Leaf Profile with a Policy Group + cisco.aci.aci_access_port_to_interface_policy_leaf_profile: + host: apic + username: admin + password: SomeSecretPassword + interface_profile: leafintprfname + access_port_selector: accessportselectorname + port_blk: leafportblkname + from_port: 13 + to_port: 16 + policy_group: policygroupname + state: present + delegate_to: localhost + +- name: Associate an interface access port selector to an Interface Policy Leaf Profile (w/o policy group) (check if this works) + cisco.aci.aci_access_port_to_interface_policy_leaf_profile: + host: apic + username: admin + password: SomeSecretPassword + interface_profile: leafintprfname + access_port_selector: accessportselectorname + port_blk: leafportblkname + from_port: 13 + to_port: 16 + state: present + delegate_to: localhost + +- name: Remove an interface access port selector associated with an Interface Policy Leaf Profile + cisco.aci.aci_access_port_to_interface_policy_leaf_profile: + host: apic + username: admin + password: SomeSecretPassword + interface_profile: leafintprfname + access_port_selector: accessportselectorname + state: absent + delegate_to: localhost + +- name: Remove an interface access port selector associated with an Interface Policy Fex Profile + cisco.aci.aci_access_port_to_interface_policy_leaf_profile: + host: apic + username: admin + password: SomeSecretPassword + interface_profile: fexintprfname + access_port_selector: accessportselectorname + state: absent + delegate_to: localhost + +- name: Query Specific access_port_selector under given leaf_interface_profile + cisco.aci.aci_access_port_to_interface_policy_leaf_profile: + host: apic + username: admin + password: SomeSecretPassword + interface_profile: leafintprfname + access_port_selector: accessportselectorname + state: query + delegate_to: localhost + register: query_result + +- name: Query Specific access_port_selector under given Fex leaf_interface_profile + cisco.aci.aci_access_port_to_interface_policy_leaf_profile: + host: apic + username: admin + password: SomeSecretPassword + interface_profile: fexintprfname + access_port_selector: accessportselectorname + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + +INTERFACE_TYPE_MAPPING = dict( + breakout='uni/infra/funcprof/brkoutportgrp-{0}', + fex='uni/infra/funcprof/accportgrp-{0}', + port_channel='uni/infra/funcprof/accbundle-{0}', + switch_port='uni/infra/funcprof/accportgrp-{0}', + vpc='uni/infra/funcprof/accbundle-{0}', +) + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + interface_profile=dict(type='str', aliases=['leaf_interface_profile_name', 'leaf_interface_profile', 'interface_profile_name']), + access_port_selector=dict(type='str', aliases=['name', 'access_port_selector_name']), # Not required for querying all objects + description=dict(type='str'), + port_blk=dict(type='str', aliases=['leaf_port_blk_name', 'leaf_port_blk', 'port_blk_name']), + leaf_port_blk_description=dict(type='str'), + from_port=dict(type='str', aliases=['from', 'fromPort', 'from_port_range']), + to_port=dict(type='str', aliases=['to', 'toPort', 'to_port_range']), + from_card=dict(type='str', aliases=['from_card_range']), + to_card=dict(type='str', aliases=['to_card_range']), + policy_group=dict(type='str', aliases=['policy_group_name']), + interface_type=dict(type='str', default='switch_port', choices=['breakout', 'fex', 'port_channel', 'switch_port', 'vpc']), + type=dict(type='str', default='leaf', choices=['fex', 'leaf']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['interface_profile', 'access_port_selector']], + ['state', 'present', ['interface_profile', 'access_port_selector']], + ], + ) + + interface_profile = module.params.get('interface_profile') + access_port_selector = module.params.get('access_port_selector') + description = module.params.get('description') + port_blk = module.params.get('port_blk') + leaf_port_blk_description = module.params.get('leaf_port_blk_description') + from_port = module.params.get('from_port') + to_port = module.params.get('to_port') + from_card = module.params.get('from_card') + to_card = module.params.get('to_card') + policy_group = module.params.get('policy_group') + interface_type = module.params.get('interface_type') + state = module.params.get('state') + type_profile = module.params.get('type') + + # Build child_configs dynamically + child_configs = [dict( + infraPortBlk=dict( + attributes=dict( + descr=leaf_port_blk_description, + name=port_blk, + fromPort=from_port, + toPort=to_port, + fromCard=from_card, + toCard=to_card, + ), + ), + )] + + # Add infraRsAccBaseGrp only when policy_group was defined + if policy_group is not None: + child_configs.append(dict( + infraRsAccBaseGrp=dict( + attributes=dict( + tDn=INTERFACE_TYPE_MAPPING[interface_type].format(policy_group), + ), + ), + )) + + aci = ACIModule(module) + aci_class = 'infraAccPortP' + aci_rn = 'accportprof' + if type_profile == 'fex': + aci_class = 'infraFexP' + aci_rn = 'fexprof' + aci.construct_url( + root_class=dict( + aci_class=aci_class, + aci_rn='infra/' + aci_rn + '-{0}'.format(interface_profile), + module_object=interface_profile, + target_filter={'name': interface_profile}, + ), + subclass_1=dict( + aci_class='infraHPortS', + # NOTE: normal rn: hports-{name}-typ-{type}, hence here hardcoded to range for purposes of module + aci_rn='hports-{0}-typ-range'.format(access_port_selector), + module_object=access_port_selector, + target_filter={'name': access_port_selector}, + ), + child_classes=['infraPortBlk', 'infraRsAccBaseGrp'], + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='infraHPortS', + class_config=dict( + descr=description, + name=access_port_selector, + # type='range', + ), + child_configs=child_configs, + ) + + aci.get_diff(aci_class='infraHPortS') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_access_sub_port_block_to_access_port.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_access_sub_port_block_to_access_port.py new file mode 100644 index 00000000..7cbfdeab --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_access_sub_port_block_to_access_port.py @@ -0,0 +1,364 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2019, Simon Metzger <smnmtzgr@gmail.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_access_sub_port_block_to_access_port +short_description: Manage sub port blocks of Fabric interface policy leaf profile interface selectors (infra:HPortS, infra:SubPortBlk) +description: +- Manage sub port blocks of Fabric interface policy leaf profile interface selectors on Cisco ACI fabrics. +seealso: +- name: APIC Management Information Model reference + description: More information about the internal APIC classes B(infra:HPortS) and B(infra:SubPortBlk). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Simon Metzger (@smnmtzgr) +options: + leaf_interface_profile: + description: + - The name of the Fabric access policy leaf interface profile. + type: str + aliases: [ leaf_interface_profile_name ] + access_port_selector: + description: + - The name of the Fabric access policy leaf interface profile access port selector. + type: str + aliases: [ name, access_port_selector_name ] + leaf_port_blk: + description: + - The name of the Fabric access policy leaf interface profile access port block. + type: str + aliases: [ leaf_port_blk_name ] + leaf_port_blk_description: + description: + - The description to assign to the C(leaf_port_blk). + type: str + from_port: + description: + - The beginning (from-range) of the port range block for the leaf access port block. + type: str + aliases: [ from, fromPort, from_port_range ] + to_port: + description: + - The end (to-range) of the port range block for the leaf access port block. + type: str + aliases: [ to, toPort, to_port_range ] + from_sub_port: + description: + - The beginning (from-range) of the sub port range block for the leaf access port block. + type: str + aliases: [ fromSubPort, from_sub_port_range ] + to_sub_port: + description: + - The end (to-range) of the sub port range block for the leaf access port block. + type: str + aliases: [ toSubPort, to_sub_port_range ] + from_card: + description: + - The beginning (from-range) of the card range block for the leaf access port block. + type: str + aliases: [ from_card_range ] + to_card: + description: + - The end (to-range) of the card range block for the leaf access port block. + type: str + aliases: [ to_card_range ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present +extends_documentation_fragment: +- cisco.aci.aci + +''' + +EXAMPLES = r''' +- name: Associate an access sub port block (single port) to an interface selector + cisco.aci.aci_access_sub_port_block_to_access_port: + host: apic + username: admin + password: SomeSecretPassword + leaf_interface_profile: leafintprfname + access_port_selector: accessportselectorname + leaf_port_blk: leafportblkname + from_port: 13 + to_port: 13 + from_sub_port: 1 + to_sub_port: 1 + state: present + delegate_to: localhost + +- name: Associate an access sub port block (port range) to an interface selector + cisco.aci.aci_access_sub_port_block_to_access_port: + host: apic + username: admin + password: SomeSecretPassword + leaf_interface_profile: leafintprfname + access_port_selector: accessportselectorname + leaf_port_blk: leafportblkname + from_port: 13 + to_port: 13 + from_sub_port: 1 + to_sub_port: 3 + state: present + delegate_to: localhost + +- name: Remove an access sub port block from an interface selector + cisco.aci.aci_access_sub_port_block_to_access_port: + host: apic + username: admin + password: SomeSecretPassword + leaf_interface_profile: leafintprfname + access_port_selector: accessportselectorname + leaf_port_blk: leafportblkname + from_port: 13 + to_port: 13 + from_sub_port: 1 + to_sub_port: 1 + state: absent + delegate_to: localhost + +- name: Query Specific access sub port block under given access port selector + cisco.aci.aci_access_sub_port_block_to_access_port: + host: apic + username: admin + password: SomeSecretPassword + leaf_interface_profile: leafintprfname + access_port_selector: accessportselectorname + leaf_port_blk: leafportblkname + state: query + delegate_to: localhost + register: query_result + +- name: Query all access sub port blocks under given leaf interface profile + cisco.aci.aci_access_sub_port_block_to_access_port: + host: apic + username: admin + password: SomeSecretPassword + leaf_interface_profile: leafintprfname + state: query + delegate_to: localhost + register: query_result + +- name: Query all access sub port blocks in the fabric + cisco.aci.aci_access_sub_port_block_to_access_port: + host: apic + username: admin + password: SomeSecretPassword + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec +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']), # Not required for querying all objects + access_port_selector=dict(type='str', aliases=['name', 'access_port_selector_name']), # Not required for querying all objects + leaf_port_blk=dict(type='str', aliases=['leaf_port_blk_name']), # Not required for querying all objects + leaf_port_blk_description=dict(type='str'), + from_port=dict(type='str', aliases=['from', 'fromPort', 'from_port_range']), # Not required for querying all objects and deleting sub port blocks + to_port=dict(type='str', aliases=['to', 'toPort', 'to_port_range']), # Not required for querying all objects and deleting sub port blocks + from_sub_port=dict(type='str', aliases=['fromSubPort', 'from_sub_port_range']), # Not required for querying all objects and deleting sub port blocks + to_sub_port=dict(type='str', aliases=['toSubPort', 'to_sub_port_range']), # Not required for querying all objects and deleting sub port blocks + from_card=dict(type='str', aliases=['from_card_range']), + to_card=dict(type='str', aliases=['to_card_range']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['access_port_selector', 'leaf_port_blk', 'leaf_interface_profile']], + ['state', 'present', ['access_port_selector', 'leaf_port_blk', 'from_port', 'to_port', 'from_sub_port', 'to_sub_port', 'leaf_interface_profile']], + ], + ) + + leaf_interface_profile = module.params.get('leaf_interface_profile') + access_port_selector = module.params.get('access_port_selector') + leaf_port_blk = module.params.get('leaf_port_blk') + leaf_port_blk_description = module.params.get('leaf_port_blk_description') + from_port = module.params.get('from_port') + to_port = module.params.get('to_port') + from_sub_port = module.params.get('from_sub_port') + to_sub_port = module.params.get('to_sub_port') + from_card = module.params.get('from_card') + to_card = module.params.get('to_card') + state = module.params.get('state') + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='infraAccPortP', + aci_rn='infra/accportprof-{0}'.format(leaf_interface_profile), + module_object=leaf_interface_profile, + target_filter={'name': leaf_interface_profile}, + ), + subclass_1=dict( + aci_class='infraHPortS', + # NOTE: normal rn: hports-{name}-typ-{type}, hence here hardcoded to range for purposes of module + aci_rn='hports-{0}-typ-range'.format(access_port_selector), + module_object=access_port_selector, + target_filter={'name': access_port_selector}, + ), + subclass_2=dict( + aci_class='infraSubPortBlk', + aci_rn='subportblk-{0}'.format(leaf_port_blk), + module_object=leaf_port_blk, + target_filter={'name': leaf_port_blk}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='infraSubPortBlk', + class_config=dict( + descr=leaf_port_blk_description, + name=leaf_port_blk, + fromPort=from_port, + toPort=to_port, + fromSubPort=from_sub_port, + toSubPort=to_sub_port, + fromCard=from_card, + toCard=to_card, + # type='range', + ), + ) + + aci.get_diff(aci_class='infraSubPortBlk') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_aep.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_aep.py new file mode 100644 index 00000000..29db95a5 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_aep.py @@ -0,0 +1,286 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2020, Shreyas Srish <ssrish@cisco.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_aep +short_description: Manage attachable Access Entity Profile (AEP) objects (infra:AttEntityP, infra:ProvAcc) +description: +- Connect to external virtual and physical domains by using + attachable Access Entity Profiles (AEP) on Cisco ACI fabrics. +options: + aep: + description: + - The name of the Attachable Access Entity Profile. + type: str + aliases: [ aep_name, name ] + description: + description: + - Description for the AEP. + type: str + aliases: [ descr ] + infra_vlan: + description: + - Enable infrastructure VLAN. + - The hypervisor functions of the AEP. + - C(no) will disable the infrastructure vlan if it is enabled. + type: bool + aliases: [ infrastructure_vlan ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + default: present + choices: [ absent, present, query ] + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +seealso: +- module: cisco.aci.aci_aep_to_domain +- name: APIC Management Information Model reference + description: More information about the internal APIC classes B(infra:AttEntityP) and B(infra:ProvAcc). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Swetha Chunduri (@schunduri) +- Shreyas Srish (@shrsr) +''' + +EXAMPLES = r''' +- name: Add a new AEP + cisco.aci.aci_aep: + host: apic + username: admin + password: SomeSecretPassword + aep: ACI-AEP + description: default + infra_vlan: true + state: present + delegate_to: localhost + +- name: Remove an existing AEP + cisco.aci.aci_aep: + host: apic + username: admin + password: SomeSecretPassword + aep: ACI-AEP + state: absent + delegate_to: localhost + +- name: Query all AEPs + cisco.aci.aci_aep: + host: apic + username: admin + password: SomeSecretPassword + state: query + delegate_to: localhost + register: query_result + +- name: Query a specific AEP + cisco.aci.aci_aep: + host: apic + username: admin + password: SomeSecretPassword + aep: ACI-AEP + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + aep=dict(type='str', aliases=['name', 'aep_name']), # Not required for querying all objects + description=dict(type='str', aliases=['descr']), + infra_vlan=dict(type='bool', aliases=['infrastructure_vlan']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['aep']], + ['state', 'present', ['aep']], + ], + ) + + aep = module.params.get('aep') + description = module.params.get('description') + infra_vlan = module.params.get('infra_vlan') + state = module.params.get('state') + name_alias = module.params.get('name_alias') + if infra_vlan: + child_configs = [dict(infraProvAcc=dict(attributes=dict(name='provacc')))] + elif infra_vlan is False: + child_configs = [dict(infraProvAcc=dict(attributes=dict(name='provacc', status='deleted')))] + else: + child_configs = [] + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='infraAttEntityP', + aci_rn='infra/attentp-{0}'.format(aep), + module_object=aep, + target_filter={'name': aep}, + ), + child_classes=['infraProvAcc'] + ) + + aci.get_existing() + + try: + if len(aci.existing[0]['infraAttEntityP']) == 1 and infra_vlan is False: + child_configs = [] + except Exception: + pass + + if state == 'present': + + aci.payload( + aci_class='infraAttEntityP', + class_config=dict( + name=aep, + descr=description, + nameAlias=name_alias, + ), + child_configs=child_configs, + ) + + aci.get_diff(aci_class='infraAttEntityP') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_aep_to_domain.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_aep_to_domain.py new file mode 100644 index 00000000..716906d0 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_aep_to_domain.py @@ -0,0 +1,313 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2017, Dag Wieers <dag@wieers.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_aep_to_domain +short_description: Bind AEPs to Physical or Virtual Domains (infra:RsDomP) +description: +- Bind AEPs to Physical or Virtual Domains on Cisco ACI fabrics. +options: + aep: + description: + - The name of the Attachable Access Entity Profile. + type: str + aliases: [ aep_name ] + domain: + description: + - Name of the physical or virtual domain being associated with the AEP. + type: str + aliases: [ domain_name, domain_profile ] + domain_type: + description: + - Determines if the Domain is physical (phys) or virtual (vmm). + type: str + choices: [ fc, l2dom, l3dom, phys, vmm ] + aliases: [ type ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + vm_provider: + description: + - The VM platform for VMM Domains. + - Support for Kubernetes was added in ACI v3.0. + - Support for CloudFoundry, OpenShift and Red Hat was added in ACI v3.1. + type: str + choices: [ cloudfoundry, kubernetes, microsoft, openshift, openstack, redhat, vmware ] +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- The C(aep) and C(domain) parameters should exist before using this module. + The M(cisco.aci.aci_aep) and M(cisco.aci.aci_domain) can be used for these. +seealso: +- module: cisco.aci.aci_aep +- module: cisco.aci.aci_domain +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(infra:RsDomP). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Dag Wieers (@dagwieers) +''' + +EXAMPLES = r''' +- name: Add AEP to domain binding + cisco.aci.aci_aep_to_domain: &binding_present + host: apic + username: admin + password: SomeSecretPassword + aep: test_aep + domain: phys_dom + domain_type: phys + state: present + delegate_to: localhost + +- name: Remove AEP to domain binding + cisco.aci.aci_aep_to_domain: &binding_absent + host: apic + username: admin + password: SomeSecretPassword + aep: test_aep + domain: phys_dom + domain_type: phys + state: absent + delegate_to: localhost + +- name: Query our AEP to domain binding + cisco.aci.aci_aep_to_domain: + host: apic + username: admin + password: SomeSecretPassword + aep: test_aep + domain: phys_dom + domain_type: phys + state: query + delegate_to: localhost + register: query_result + +- name: Query all AEP to domain bindings + cisco.aci.aci_aep_to_domain: &binding_query + host: apic + username: admin + password: SomeSecretPassword + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + +VM_PROVIDER_MAPPING = dict( + cloudfoundry='CloudFoundry', + kubernetes='Kubernetes', + microsoft='Microsoft', + openshift='OpenShift', + openstack='OpenStack', + redhat='Redhat', + vmware='VMware', +) + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + aep=dict(type='str', aliases=['aep_name']), # Not required for querying all objects + domain=dict(type='str', aliases=['domain_name', 'domain_profile']), # Not required for querying all objects + domain_type=dict(type='str', choices=['fc', 'l2dom', 'l3dom', 'phys', 'vmm'], aliases=['type']), # Not required for querying all objects + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + vm_provider=dict(type='str', choices=['cloudfoundry', 'kubernetes', 'microsoft', 'openshift', 'openstack', 'redhat', 'vmware']), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['domain_type', 'vmm', ['vm_provider']], + ['state', 'absent', ['aep', 'domain', 'domain_type']], + ['state', 'present', ['aep', 'domain', 'domain_type']], + ], + required_together=[ + ['domain', 'domain_type'], + ], + ) + + aep = module.params.get('aep') + domain = module.params.get('domain') + domain_type = module.params.get('domain_type') + vm_provider = module.params.get('vm_provider') + state = module.params.get('state') + + # Report when vm_provider is set when type is not virtual + if domain_type != 'vmm' and vm_provider is not None: + module.fail_json(msg="Domain type '{0}' cannot have a 'vm_provider'".format(domain_type)) + + # Compile the full domain for URL building + if domain_type == 'fc': + domain_mo = 'uni/fc-{0}'.format(domain) + elif domain_type == 'l2dom': + domain_mo = 'uni/l2dom-{0}'.format(domain) + elif domain_type == 'l3dom': + domain_mo = 'uni/l3dom-{0}'.format(domain) + elif domain_type == 'phys': + domain_mo = 'uni/phys-{0}'.format(domain) + elif domain_type == 'vmm': + domain_mo = 'uni/vmmp-{0}/dom-{1}'.format(VM_PROVIDER_MAPPING[vm_provider], domain) + else: + domain_mo = None + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='infraAttEntityP', + aci_rn='infra/attentp-{0}'.format(aep), + module_object=aep, + target_filter={'name': aep}, + ), + subclass_1=dict( + aci_class='infraRsDomP', + aci_rn='rsdomP-[{0}]'.format(domain_mo), + module_object=domain_mo, + target_filter={'tDn': domain_mo}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='infraRsDomP', + class_config=dict(tDn=domain_mo), + ) + + aci.get_diff(aci_class='infraRsDomP') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_ap.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_ap.py new file mode 100644 index 00000000..0c10fbd4 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_ap.py @@ -0,0 +1,290 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_ap +short_description: Manage top level Application Profile (AP) objects (fv:Ap) +description: +- Manage top level Application Profile (AP) objects on Cisco ACI fabrics +options: + tenant: + description: + - The name of an existing tenant. + type: str + aliases: [ tenant_name ] + ap: + description: + - The name of the application network profile. + type: str + aliases: [ app_profile, app_profile_name, name ] + description: + description: + - Description for the AP. + type: str + aliases: [ descr ] + monitoring_policy: + description: + - The name of the monitoring policy. + type: str + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- This module does not manage EPGs, see M(cisco.aci.aci_epg) to do this. +- The used C(tenant) must exist before using this module in your playbook. + The M(cisco.aci.aci_tenant) module can be used for this. +seealso: +- module: cisco.aci.aci_tenant +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(fv:Ap). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Swetha Chunduri (@schunduri) +- Shreyas Srish (@shrsr) +''' + +EXAMPLES = r''' +- name: Add a new AP + cisco.aci.aci_ap: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + ap: default + description: default ap + monitoring_policy: default + state: present + delegate_to: localhost + +- name: Remove an AP + cisco.aci.aci_ap: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + ap: default + state: absent + delegate_to: localhost + +- name: Query an AP + cisco.aci.aci_ap: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + ap: default + state: query + delegate_to: localhost + register: query_result + +- name: Query all APs + cisco.aci.aci_ap: + host: apic + username: admin + password: SomeSecretPassword + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects + ap=dict(type='str', aliases=['app_profile', 'app_profile_name', 'name']), # Not required for querying all objects + description=dict(type='str', aliases=['descr']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + monitoring_policy=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['tenant', 'ap']], + ['state', 'present', ['tenant', 'ap']], + ], + ) + + ap = module.params.get('ap') + description = module.params.get('description') + state = module.params.get('state') + tenant = module.params.get('tenant') + name_alias = module.params.get('name_alias') + monitoring_policy = module.params.get('monitoring_policy') + + child_configs = [dict(fvRsApMonPol=dict(attributes=dict(tnMonEPGPolName=monitoring_policy)))] + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + module_object=tenant, + target_filter={'name': tenant}, + ), + subclass_1=dict( + aci_class='fvAp', + aci_rn='ap-{0}'.format(ap), + module_object=ap, + target_filter={'name': ap}, + ), + child_classes=['fvRsApMonPol'], + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='fvAp', + class_config=dict( + name=ap, + descr=description, + nameAlias=name_alias, + ), + child_configs=child_configs, + ) + + aci.get_diff(aci_class='fvAp') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_bd.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_bd.py new file mode 100644 index 00000000..02ba1aeb --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_bd.py @@ -0,0 +1,461 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_bd +short_description: Manage Bridge Domains (BD) objects (fv:BD) +description: +- Manages Bridge Domains (BD) on Cisco ACI fabrics. +options: + arp_flooding: + description: + - Determines if the Bridge Domain should flood ARP traffic. + - The APIC defaults to C(no) when unset during creation. + type: bool + bd: + description: + - The name of the Bridge Domain. + type: str + aliases: [ bd_name, name ] + bd_type: + description: + - The type of traffic on the Bridge Domain. + - The APIC defaults to C(ethernet) when unset during creation. + type: str + choices: [ ethernet, fc ] + description: + description: + - Description for the Bridge Domain. + type: str + enable_multicast: + description: + - Determines if PIM is enabled. + - The APIC defaults to C(no) when unset during creation. + type: bool + enable_routing: + description: + - Determines if IP forwarding should be allowed. + - The APIC defaults to C(yes) when unset during creation. + type: bool + endpoint_clear: + description: + - Clears all End Points in all Leaves when C(yes). + - The value is not reset to disabled once End Points have been cleared; that requires a second task. + - The APIC defaults to C(no) when unset during creation. + type: bool + endpoint_move_detect: + description: + - Determines if GARP should be enabled to detect when End Points move. + - The APIC defaults to C(garp) when unset during creation. + type: str + choices: [ default, garp ] + endpoint_retention_action: + description: + - Determines if the Bridge Domain should inherit or resolve the End Point Retention Policy. + - The APIC defaults to C(resolve) when unset during creation. + type: str + choices: [ inherit, resolve ] + endpoint_retention_policy: + description: + - The name of the End Point Retention Policy the Bridge Domain should use when + overriding the default End Point Retention Policy. + type: str + igmp_snoop_policy: + description: + - The name of the IGMP Snooping Policy the Bridge Domain should use when + overriding the default IGMP Snooping Policy. + type: str + ip_learning: + description: + - Determines if the Bridge Domain should learn End Point IPs. + - The APIC defaults to C(yes) when unset during creation. + type: bool + ipv6_nd_policy: + description: + - The name of the IPv6 Neighbor Discovery Policy the Bridge Domain should use when + overridding the default IPV6 ND Policy. + type: str + l2_unknown_unicast: + description: + - Determines what forwarding method to use for unknown l2 destinations. + - The APIC defaults to C(proxy) when unset during creation. + type: str + choices: [ proxy, flood ] + l3_unknown_multicast: + description: + - Determines the forwarding method to use for unknown multicast destinations. + - The APIC defaults to C(flood) when unset during creation. + type: str + choices: [ flood, opt-flood ] + limit_ip_learn: + description: + - Determines if the BD should limit IP learning to only subnets owned by the Bridge Domain. + - The APIC defaults to C(yes) when unset during creation. + type: bool + mac_address: + description: + - The MAC Address to assign to the C(bd) instead of using the default. + - The APIC defaults to C(00:22:BD:F8:19:FF) when unset during creation. + type: str + aliases: [ mac ] + multi_dest: + description: + - Determines the forwarding method for L2 multicast, broadcast, and link layer traffic. + - The APIC defaults to C(bd-flood) when unset during creation. + type: str + choices: [ bd-flood, drop, encap-flood ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str + tenant: + description: + - The name of the Tenant. + type: str + aliases: [ tenant_name ] + vrf: + description: + - The name of the VRF. + type: str + aliases: [ vrf_name ] +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- The C(tenant) used must exist before using this module in your playbook. + The M(cisco.aci.aci_tenant) module can be used for this. +seealso: +- module: cisco.aci.aci_tenant +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(fv:BD). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Jacob McGill (@jmcgill298) +''' + +EXAMPLES = r''' +- name: Add Bridge Domain + cisco.aci.aci_bd: + host: "{{ inventory_hostname }}" + username: "{{ username }}" + password: "{{ password }}" + validate_certs: no + tenant: prod + bd: web_servers + mac_address: 00:22:BD:F8:19:FE + vrf: prod_vrf + state: present + delegate_to: localhost + +- name: Add an FC Bridge Domain + cisco.aci.aci_bd: + host: "{{ inventory_hostname }}" + username: "{{ username }}" + password: "{{ password }}" + validate_certs: no + tenant: prod + bd: storage + bd_type: fc + vrf: fc_vrf + enable_routing: no + state: present + delegate_to: localhost + +- name: Modify a Bridge Domain + cisco.aci.aci_bd: + host: "{{ inventory_hostname }}" + username: "{{ username }}" + password: "{{ password }}" + validate_certs: yes + tenant: prod + bd: web_servers + arp_flooding: yes + l2_unknown_unicast: flood + state: present + delegate_to: localhost + +- name: Query All Bridge Domains + cisco.aci.aci_bd: + host: "{{ inventory_hostname }}" + username: "{{ username }}" + password: "{{ password }}" + validate_certs: yes + state: query + delegate_to: localhost + register: query_result + +- name: Query a Bridge Domain + cisco.aci.aci_bd: + host: "{{ inventory_hostname }}" + username: "{{ username }}" + password: "{{ password }}" + validate_certs: yes + tenant: prod + bd: web_servers + state: query + delegate_to: localhost + register: query_result + +- name: Delete a Bridge Domain + cisco.aci.aci_bd: + host: "{{ inventory_hostname }}" + username: "{{ username }}" + password: "{{ password }}" + validate_certs: yes + tenant: prod + bd: web_servers + state: absent + delegate_to: localhost +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + arp_flooding=dict(type='bool'), + bd=dict(type='str', aliases=['bd_name', 'name']), # Not required for querying all objects + bd_type=dict(type='str', choices=['ethernet', 'fc']), + description=dict(type='str'), + enable_multicast=dict(type='bool'), + enable_routing=dict(type='bool'), + endpoint_clear=dict(type='bool'), + endpoint_move_detect=dict(type='str', choices=['default', 'garp']), + endpoint_retention_action=dict(type='str', choices=['inherit', 'resolve']), + endpoint_retention_policy=dict(type='str'), + igmp_snoop_policy=dict(type='str'), + ip_learning=dict(type='bool'), + ipv6_nd_policy=dict(type='str'), + l2_unknown_unicast=dict(type='str', choices=['proxy', 'flood']), + l3_unknown_multicast=dict(type='str', choices=['flood', 'opt-flood']), + limit_ip_learn=dict(type='bool'), + mac_address=dict(type='str', aliases=['mac']), + multi_dest=dict(type='str', choices=['bd-flood', 'drop', 'encap-flood']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects + vrf=dict(type='str', aliases=['vrf_name']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['bd', 'tenant']], + ['state', 'present', ['bd', 'tenant']], + ], + ) + + aci = ACIModule(module) + + arp_flooding = aci.boolean(module.params.get('arp_flooding')) + bd = module.params.get('bd') + bd_type = module.params.get('bd_type') + if bd_type == 'ethernet': + # ethernet type is represented as regular, but that is not clear to the users + bd_type = 'regular' + description = module.params.get('description') + enable_multicast = aci.boolean(module.params.get('enable_multicast')) + enable_routing = aci.boolean(module.params.get('enable_routing')) + endpoint_clear = aci.boolean(module.params.get('endpoint_clear')) + endpoint_move_detect = module.params.get('endpoint_move_detect') + if endpoint_move_detect == 'default': + # the ACI default setting is an empty string, but that is not a good input value + endpoint_move_detect = '' + endpoint_retention_action = module.params.get('endpoint_retention_action') + endpoint_retention_policy = module.params.get('endpoint_retention_policy') + igmp_snoop_policy = module.params.get('igmp_snoop_policy') + ip_learning = aci.boolean(module.params.get('ip_learning')) + ipv6_nd_policy = module.params.get('ipv6_nd_policy') + l2_unknown_unicast = module.params.get('l2_unknown_unicast') + l3_unknown_multicast = module.params.get('l3_unknown_multicast') + limit_ip_learn = aci.boolean(module.params.get('limit_ip_learn')) + mac_address = module.params.get('mac_address') + multi_dest = module.params.get('multi_dest') + state = module.params.get('state') + tenant = module.params.get('tenant') + vrf = module.params.get('vrf') + name_alias = module.params.get('name_alias') + + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + module_object=tenant, + target_filter={'name': tenant}, + ), + subclass_1=dict( + aci_class='fvBD', + aci_rn='BD-{0}'.format(bd), + module_object=bd, + target_filter={'name': bd}, + ), + child_classes=['fvRsCtx', 'fvRsIgmpsn', 'fvRsBDToNdP', 'fvRsBdToEpRet'], + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='fvBD', + class_config=dict( + arpFlood=arp_flooding, + descr=description, + epClear=endpoint_clear, + epMoveDetectMode=endpoint_move_detect, + ipLearning=ip_learning, + limitIpLearnToSubnets=limit_ip_learn, + mac=mac_address, + mcastAllow=enable_multicast, + multiDstPktAct=multi_dest, + name=bd, + type=bd_type, + unicastRoute=enable_routing, + unkMacUcastAct=l2_unknown_unicast, + unkMcastAct=l3_unknown_multicast, + nameAlias=name_alias, + ), + child_configs=[ + {'fvRsCtx': {'attributes': {'tnFvCtxName': vrf}}}, + {'fvRsIgmpsn': {'attributes': {'tnIgmpSnoopPolName': igmp_snoop_policy}}}, + {'fvRsBDToNdP': {'attributes': {'tnNdIfPolName': ipv6_nd_policy}}}, + {'fvRsBdToEpRet': {'attributes': {'resolveAct': endpoint_retention_action, 'tnFvEpRetPolName': endpoint_retention_policy}}}, + ], + ) + + aci.get_diff(aci_class='fvBD') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_bd_dhcp_label.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_bd_dhcp_label.py new file mode 100644 index 00000000..7b226200 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_bd_dhcp_label.py @@ -0,0 +1,312 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2020, Dag Wieers (@dagwieers) +# Copyright: (c) 2020, sig9org (@sig9org) +# 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 +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + +DOCUMENTATION = r''' +--- +module: aci_bd_dhcp_label +short_description: Manage DHCP Labels (dhcp:Lbl) +description: +- Manage DHCP Labels on Cisco ACI fabrics. +options: + bd: + description: + - The name of the Bridge Domain. + type: str + aliases: [ bd_name ] + description: + description: + - The description for the DHCP Label. + type: str + aliases: [ descr ] + dhcp_label: + description: + - The name of the DHCP Relay Label. + type: str + aliases: [ name ] + dhcp_option: + description: + - Name of the DHCP Option Policy to be associated with the DCHP Relay Policy. + This policy need to be present in the same tenant as the bridge domain. + - The DHCP option is used to supply DHCP clients with configuration parameters + such as a domain, name server, subnet, and network address. + type: str + scope: + description: + - Represents the target relay servers ownership. + type: str + choices: [ infra, tenant ] + default: infra + aliases: [ owner ] + tenant: + description: + - The name of the Tenant. + type: str + aliases: [ tenant_name ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present +extends_documentation_fragment: cisco.aci.aci +notes: +- A DHCP relay label contains a C(name) for the label, the C(scope), and a DHCP option policy. + The scope is the C(owner) of the relay server and the DHCP option policy supplies DHCP clients + with configuration parameters such as domain, nameserver, and subnet router addresses. +- The C(tenant) and C(bd) used must exist before using this module in your playbook. + The M(cisco.aci.aci_tenant) module and M(cisco.aci.aci_bd) can be used for these. +seealso: +- module: cisco.aci.aci_bd +- module: cisco.aci.aci_tenant +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(dhcp:Lbl). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- sig9 (@sig9org) +- Dag Wieers (@dagwieers) +''' + +EXAMPLES = r''' +- name: Create a new DHCP Relay Label to a Bridge Domain + cisco.aci.aci_bd_dhcp_label: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + bd: database + dhcp_label: label1 + scope: infra + state: present + +- name: Query a DHCP Relay Label of a Bridge Domain + cisco.aci.aci_bd_dhcp_label: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + bd: database + dhcp_label: label1 + scope: infra + state: query + +- name: Query all DHCP Relay Labels of a Bridge Domain + cisco.aci.aci_bd_dhcp_label: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + bd: database + state: query + +- name: Remove a DHCP Relay Label for a Bridge Domain + cisco.aci.aci_bd_dhcp_label: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + bd: database + dhcp_label: label1 + scope: infra + state: absent +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + bd=dict(type='str', aliases=['bd_name']), # Not required for querying all objects + description=dict(type='str', aliases=['descr']), + dhcp_label=dict(type='str', aliases=['name']), # Not required for querying all objects + dhcp_option=dict(type='str'), + scope=dict(type='str', default='infra', choices=['infra', 'tenant'], aliases=['owner']), # Not required for querying all objects + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['bd', 'tenant', 'dhcp_label', 'scope']], + ['state', 'present', ['bd', 'tenant', 'dhcp_label', 'scope']], + ], + ) + + tenant = module.params.get('tenant') + bd = module.params.get('bd') + description = module.params.get('description') + dhcp_label = module.params.get('dhcp_label') + dhcp_option = module.params.get('dhcp_option') + scope = module.params.get('scope') + state = module.params.get('state') + + aci = ACIModule(module) + + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + module_object=tenant, + target_filter={'name': tenant}, + ), + subclass_1=dict( + aci_class='fvBD', + aci_rn='BD-{0}'.format(bd), + module_object=bd, + target_filter={'name': bd}, + ), + subclass_2=dict( + aci_class='dhcpLbl', + aci_rn='dhcplbl-{0}'.format(dhcp_label), + module_object=dhcp_label, + target_filter={'name': dhcp_label}, + ), + child_classes=['dhcpRsDhcpOptionPol'], + ) + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='dhcpLbl', + class_config=dict( + descr=description, + name=dhcp_label, + owner=scope, + ), + child_configs=[ + {'dhcpRsDhcpOptionPol': {'attributes': {'tnDhcpOptionPolName': dhcp_option}}}, + ], + ) + + aci.get_diff(aci_class='dhcpLbl') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_bd_subnet.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_bd_subnet.py new file mode 100644 index 00000000..ac305922 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_bd_subnet.py @@ -0,0 +1,467 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_bd_subnet +short_description: Manage Subnets (fv:Subnet) +description: +- Manage Subnets on Cisco ACI fabrics. +options: + bd: + description: + - The name of the Bridge Domain. + type: str + aliases: [ bd_name ] + description: + description: + - The description for the Subnet. + type: str + aliases: [ descr ] + enable_vip: + description: + - Determines if the Subnet should be treated as a VIP; used when the BD is extended to multiple sites. + - The APIC defaults to C(no) when unset during creation. + type: bool + gateway: + description: + - The IPv4 or IPv6 gateway address for the Subnet. + type: str + aliases: [ gateway_ip ] + mask: + description: + - The subnet mask for the Subnet. + - This is the number associated with CIDR notation. + - For IPv4 addresses, accepted values range between C(0) and C(32). + - For IPv6 addresses, accepted Values range between C(0) and C(128). + type: int + aliases: [ subnet_mask ] + nd_prefix_policy: + description: + - The IPv6 Neighbor Discovery Prefix Policy to associate with the Subnet. + type: str + preferred: + description: + - Determines if the Subnet is preferred over all available Subnets. Only one Subnet per Address Family (IPv4/IPv6). + can be preferred in the Bridge Domain. + - The APIC defaults to C(no) when unset during creation. + type: bool + route_profile: + description: + - The Route Profile to the associate with the Subnet. + type: str + route_profile_l3_out: + description: + - The L3 Out that contains the associated Route Profile. + type: str + scope: + description: + - Determines the scope of the Subnet. + - The C(private) option only allows communication with hosts in the same VRF. + - The C(public) option allows the Subnet to be advertised outside of the ACI Fabric, and allows communication with + hosts in other VRFs. + - The shared option limits communication to hosts in either the same VRF or the shared VRF. + - The value is a list of options, C(private) and C(public) are mutually exclusive, but both can be used with C(shared). + - The APIC defaults to C(private) when unset during creation. + type: list + elements: str + choices: + - private + - public + - shared + subnet_control: + description: + - Determines the Subnet's Control State. + - The C(querier_ip) option is used to treat the gateway_ip as an IGMP querier source IP. + - The C(nd_ra) option is used to treat the gateway_ip address as a Neighbor Discovery Router Advertisement Prefix. + - The C(no_gw) option is used to remove default gateway functionality from the gateway address. + - The APIC defaults to C(nd_ra) when unset during creation. + type: str + choices: [ nd_ra, no_gw, querier_ip, unspecified ] + subnet_name: + description: + - The name of the Subnet. + type: str + aliases: [ name ] + tenant: + description: + - The name of the Tenant. + type: str + aliases: [ tenant_name ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +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(cisco.aci.aci_tenant) module and M(cisco.aci.aci_bd) can be used for these. +seealso: +- module: cisco.aci.aci_bd +- module: cisco.aci.aci_tenant +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(fv:Subnet). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Jacob McGill (@jmcgill298) +''' + +EXAMPLES = r''' +- name: Create a tenant + cisco.aci.aci_tenant: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + state: present + delegate_to: localhost + +- name: Create a bridge domain + cisco.aci.aci_bd: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + bd: database + state: present + delegate_to: localhost + +- name: Create a subnet + cisco.aci.aci_bd_subnet: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + bd: database + gateway: 10.1.1.1 + mask: 24 + state: present + delegate_to: localhost + +- name: Create a subnet with options + cisco.aci.aci_bd_subnet: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + bd: database + subnet_name: sql + gateway: 10.1.2.1 + mask: 23 + description: SQL Servers + scope: public + route_profile_l3_out: corp + route_profile: corp_route_profile + state: present + delegate_to: localhost + +- name: Update a subnets scope to private and shared + cisco.aci.aci_bd_subnet: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + bd: database + gateway: 10.1.1.1 + mask: 24 + scope: [private, shared] + state: present + delegate_to: localhost + +- name: Get all subnets + cisco.aci.aci_bd_subnet: + host: apic + username: admin + password: SomeSecretPassword + state: query + delegate_to: localhost + +- name: Get all subnets of specific gateway in specified tenant + cisco.aci.aci_bd_subnet: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + gateway: 10.1.1.1 + mask: 24 + state: query + delegate_to: localhost + register: query_result + +- name: Get specific subnet + cisco.aci.aci_bd_subnet: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + bd: database + gateway: 10.1.1.1 + mask: 24 + state: query + delegate_to: localhost + register: query_result + +- name: Delete a subnet + cisco.aci.aci_bd_subnet: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + bd: database + gateway: 10.1.1.1 + mask: 24 + state: absent + delegate_to: localhost +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + +SUBNET_CONTROL_MAPPING = dict( + nd_ra='nd', + no_gw='no-default-gateway', + querier_ip='querier', + unspecified='', +) + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + bd=dict(type='str', aliases=['bd_name']), # Not required for querying all objects + description=dict(type='str', aliases=['descr']), + enable_vip=dict(type='bool'), + gateway=dict(type='str', aliases=['gateway_ip']), # Not required for querying all objects + mask=dict(type='int', aliases=['subnet_mask']), # Not required for querying all objects + subnet_name=dict(type='str', aliases=['name']), + nd_prefix_policy=dict(type='str'), + preferred=dict(type='bool'), + route_profile=dict(type='str'), + route_profile_l3_out=dict(type='str'), + scope=dict(type='list', elements='str', choices=['private', 'public', 'shared']), + subnet_control=dict(type='str', choices=['nd_ra', 'no_gw', 'querier_ip', 'unspecified']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_together=[['gateway', 'mask']], + required_if=[ + ['state', 'present', ['bd', 'gateway', 'mask', 'tenant']], + ['state', 'absent', ['bd', 'gateway', 'mask', 'tenant']], + ], + ) + + aci = ACIModule(module) + + description = module.params.get('description') + enable_vip = aci.boolean(module.params.get('enable_vip')) + tenant = module.params.get('tenant') + bd = module.params.get('bd') + gateway = module.params.get('gateway') + mask = module.params.get('mask') + if mask is not None and mask not in range(0, 129): + # TODO: split checks between IPv4 and IPv6 Addresses + module.fail_json(msg='Valid Subnet Masks are 0 to 32 for IPv4 Addresses and 0 to 128 for IPv6 addresses') + if gateway is not None: + gateway = '{0}/{1}'.format(gateway, str(mask)) + subnet_name = module.params.get('subnet_name') + nd_prefix_policy = module.params.get('nd_prefix_policy') + preferred = aci.boolean(module.params.get('preferred')) + route_profile = module.params.get('route_profile') + route_profile_l3_out = module.params.get('route_profile_l3_out') + scope = module.params.get('scope') + if scope is not None: + if 'private' in scope and 'public' in scope: + module.fail_json(msg="Parameter 'scope' cannot be both 'private' and 'public', got: %s" % scope) + else: + scope = ','.join(sorted(scope)) + state = module.params.get('state') + subnet_control = module.params.get('subnet_control') + if subnet_control: + subnet_control = SUBNET_CONTROL_MAPPING[subnet_control] + name_alias = module.params.get('name_alias') + + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + module_object=tenant, + target_filter={'name': tenant}, + ), + subclass_1=dict( + aci_class='fvBD', + aci_rn='BD-{0}'.format(bd), + module_object=bd, + target_filter={'name': bd}, + ), + subclass_2=dict( + aci_class='fvSubnet', + aci_rn='subnet-[{0}]'.format(gateway), + module_object=gateway, + target_filter={'ip': gateway}, + ), + child_classes=['fvRsBDSubnetToProfile', 'fvRsNdPfxPol'], + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='fvSubnet', + class_config=dict( + ctrl=subnet_control, + descr=description, + ip=gateway, + name=subnet_name, + preferred=preferred, + scope=scope, + virtual=enable_vip, + nameAlias=name_alias, + ), + child_configs=[ + {'fvRsBDSubnetToProfile': {'attributes': {'tnL3extOutName': route_profile_l3_out, 'tnRtctrlProfileName': route_profile}}}, + {'fvRsNdPfxPol': {'attributes': {'tnNdPfxPolName': nd_prefix_policy}}}, + ], + ) + + aci.get_diff(aci_class='fvSubnet') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_bd_to_l3out.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_bd_to_l3out.py new file mode 100644 index 00000000..c50bafad --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_bd_to_l3out.py @@ -0,0 +1,240 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_bd_to_l3out +short_description: Bind Bridge Domain to L3 Out (fv:RsBDToOut) +description: +- Bind Bridge Domain to L3 Out on Cisco ACI fabrics. +options: + bd: + description: + - The name of the Bridge Domain. + type: str + aliases: [ bd_name, bridge_domain ] + l3out: + description: + - The name of the l3out to associate with th Bridge Domain. + type: str + tenant: + description: + - The name of the Tenant. + type: str + aliases: [ tenant_name ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- The C(bd) and C(l3out) parameters should exist before using this module. + The M(cisco.aci.aci_bd) and C(aci_l3out) can be used for these. +seealso: +- module: cisco.aci.aci_bd +- module: cisco.aci.aci_l3out +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(fv:RsBDToOut). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Jacob McGill (@jmcgill298) +''' + +# FIXME: Add examples +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + +SUBNET_CONTROL_MAPPING = dict( + nd_ra='nd', + no_gw='no-default-gateway', + querier_ip='querier', + unspecified='', +) + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + bd=dict(type='str', aliases=['bd_name', 'bridge_domain']), # Not required for querying all objects + l3out=dict(type='str'), # Not required for querying all objects + tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'present', ['bd', 'l3out', 'tenant']], + ['state', 'absent', ['bd', 'l3out', 'tenant']], + ], + ) + + bd = module.params.get('bd') + l3out = module.params.get('l3out') + state = module.params.get('state') + tenant = module.params.get('tenant') + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + module_object=tenant, + target_filter={'name': tenant}, + ), + subclass_1=dict( + aci_class='fvBD', + aci_rn='BD-{0}'.format(bd), + module_object=bd, + target_filter={'name': bd}, + ), + subclass_2=dict( + aci_class='fvRsBDToOut', + aci_rn='rsBDToOut-{0}'.format(l3out), + module_object=l3out, + target_filter={'tnL3extOutName': l3out}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='fvRsBDToOut', + class_config=dict(tnL3extOutName=l3out), + ) + + aci.get_diff(aci_class='fvRsBDToOut') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_cloud_cidr.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_cloud_cidr.py new file mode 100644 index 00000000..8a8cbc49 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_cloud_cidr.py @@ -0,0 +1,292 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2020, nkatarmal-crest <nirav.katarmal@crestdatasys.com> +# Copyright: (c) 2020, Cindy Zhao <cizhao@cisco.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = r''' +--- +module: aci_cloud_cidr +short_description: Manage CIDR under Cloud Context Profile (cloud:Cidr) +description: +- Manage Cloud CIDR on Cisco Cloud ACI. +author: +- Nirav (@nirav) +- Cindy Zhao (@cizhao) +options: + address: + description: + - CIDR ip and its netmask. + type: str + aliases: [ cidr ] + description: + description: + - Description of the Cloud CIDR. + type: str + name_alias: + description: + - An alias for the name of the current object. This relates to the nameAlias field in ACI and is used to rename object without changing the DN. + type: str + tenant: + description: + - The name of the Tenant. + type: str + required: yes + cloud_context_profile: + description: + - The name of the Cloud Context Profile. + type: str + required: yes + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + choices: [ absent, present, query ] + default: present + type: str +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- This module is only used to manage non_primary Cloud CIDR, see M(cisco.aci.aci_cloud_ctx_profile) to create the primary CIDR. +- More information about the internal APIC class B(cloud:Cidr) from + L(the APIC Management Information Model reference,https://developer.cisco.com/docs/apic-mim-ref/). +''' + +EXAMPLES = r''' +- name: Create non_primary CIDR + cisco.aci.aci_cloud_cidr: + host: apic + username: admin + password: SomeSecretPassword + tenant: tenantName + address: 10.10.0.0/16 + cloud_context_profile: ctxProfileName + state: present + delegate_to: localhost + +- name: Remove non_primary CIDR + cisco.aci.aci_cloud_cidr: + host: apic + username: admin + password: SomeSecretPassword + tenant: tenantName + address: 10.10.0.0/16 + cloud_context_profile: ctxProfileName + state: absent + delegate_to: localhost + +- name: Query all CIDRs under given cloud context profile + cisco.aci.aci_cloud_cidr: + host: apic + username: admin + password: SomeSecretPassword + tenant: tenantName + cloud_context_profile: ctxProfileName + state: query + delegate_to: localhost + +- name: Query specific CIDR under given cloud context profile + cisco.aci.aci_cloud_cidr: + host: apic + username: admin + password: SomeSecretPassword + tenant: tenantName + cloud_context_profile: ctxProfileName + address: 10.10.0.0/16 + state: query + delegate_to: localhost +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec +from ansible.module_utils.basic import AnsibleModule + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + address=dict(type='str', aliases=['cidr']), + description=dict(type='str'), + name_alias=dict(type='str'), + tenant=dict(type='str', required=True), + cloud_context_profile=dict(type='str', required=True), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['address']], + ['state', 'present', ['address']], + ], + ) + + address = module.params.get('address') + description = module.params.get('description') + name_alias = module.params.get('name_alias') + tenant = module.params.get('tenant') + cloud_context_profile = module.params.get('cloud_context_profile') + state = module.params.get('state') + child_configs = [] + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + target_filter='eq(fvTenant.name, "{0}")'.format(tenant), + module_object=tenant + ), + subclass_1=dict( + aci_class='cloudCtxProfile', + aci_rn='ctxprofile-{0}'.format(cloud_context_profile), + target_filter='eq(cloudCtxProfile.name, "{0}")'.format(cloud_context_profile), + module_object=cloud_context_profile + ), + subclass_2=dict( + aci_class='cloudCidr', + aci_rn='cidr-[{0}]'.format(address), + target_filter='eq(cloudCidr.addr, "{0}")'.format(address), + module_object=address + ), + + child_classes=[] + + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='cloudCidr', + class_config=dict( + addr=address, + descr=description, + nameAlias=name_alias, + primary='no', + ), + child_configs=child_configs + ) + + aci.get_diff(aci_class='cloudCidr') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_cloud_ctx_profile.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_cloud_ctx_profile.py new file mode 100644 index 00000000..7fdb3b08 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_cloud_ctx_profile.py @@ -0,0 +1,318 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2020, nkatarmal-crest <nirav.katarmal@crestdatasys.com> +# Copyright: (c) 2020, Cindy Zhao <cizhao@cisco.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = r''' +--- +module: aci_cloud_ctx_profile +short_description: Manage Cloud Context Profile (cloud:CtxProfile) +description: +- Manage the Cloud Context Profile objects on Cisco Cloud ACI. +notes: +- More information about the internal APIC class B(cloud:CtxProfile) from + L(the APIC Management Information Model reference,https://developer.cisco.com/docs/apic-mim-ref/). +author: +- Nirav (@crestdatasys) +- Cindy Zhao (@cizhao) +options: + name: + description: + - The name of the Cloud Context Profile + type: str + aliases: [ cloud_context_profile ] + description: + description: + - Description of the Cloud Context Profile + type: str + name_alias: + description: + - An alias for the name of the current object. This relates to the nameAlias field in ACI and is used to rename object without changing the DN + type: str + tenant: + description: + - The name of the Tenant. + type: str + primary_cidr: + description: + - The subnet with netmask to use as primary CIDR block for the Cloud Context Profile. + type: str + vrf: + description: + - The name of the VRF. + type: str + region: + description: + - The name of the cloud region in which to deploy the network construct. + type: str + cloud: + description: + - The cloud vendor in which the controller runs. + choices: [ aws, azure ] + type: str + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + choices: [ absent, present, query ] + type: str + default: present + +extends_documentation_fragment: +- cisco.aci.aci +''' + +EXAMPLES = r''' +- name: Add a new aci cloud ctx profile + cisco.aci.aci_cloud_ctx_profile: + host: apic_host + username: admin + password: SomeSecretPassword + tenant: tenant_1 + name: cloud_ctx_profile + vrf: VRF1 + region: us-west-1 + cloud: aws + primary_cidr: '10.0.10.1/16' + state: present + delegate_to: localhost + +- name: Remove an aci cloud ctx profile + cisco.aci.aci_cloud_ctx_profile: + host: apic_host + username: admin + password: SomeSecretPassword + tenant: tenant_1 + name: cloud_ctx_profile + state: absent + delegate_to: localhost + +- name: Query a specific aci cloud ctx profile + cisco.aci.aci_cloud_ctx_profile: + host: apic_host + username: admin + password: SomeSecretPassword + tenant: anstest + name: ctx_profile_1 + state: query + delegate_to: localhost + +- name: Query all aci cloud ctx profile + cisco.aci.aci_cloud_ctx_profile: + host: apic_host + username: admin + password: SomeSecretPassword + tenant: anstest + state: query + delegate_to: localhost +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec +from ansible.module_utils.basic import AnsibleModule + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + description=dict(type='str',), + name=dict(type='str', aliases=['cloud_context_profile']), + name_alias=dict(type='str',), + tenant=dict(type='str',), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + primary_cidr=dict(type='str',), + # FIXME: didn't find the flow_log in UI + # flow_log=dict(type='str'), + vrf=dict(type='str'), + region=dict(type='str'), + cloud=dict(type='str', choices=['aws', 'azure']) + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['name', 'tenant']], + ['state', 'present', ['name', 'tenant', 'vrf', 'region', 'primary_cidr', 'cloud']], + ], + ) + + description = module.params.get('description') + name = module.params.get('name') + name_alias = module.params.get('name_alias') + tenant = module.params.get('tenant') + state = module.params.get('state') + primary_cidr = module.params.get('primary_cidr') + child_configs = [] + + vrf = module.params.get('vrf') + region = module.params.get('region') + cloud = module.params.get('cloud') + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + target_filter='eq(fvTenant.name, "{0}")'.format(tenant), + module_object=tenant + ), + subclass_1=dict( + aci_class='cloudCtxProfile', + aci_rn='ctxprofile-{0}'.format(name), + target_filter='eq(cloudCtxProfile.name, "{0}")'.format(name), + module_object=name + ), + child_classes=['cloudRsToCtx', 'cloudRsCtxProfileToRegion', 'cloudRouterP', 'cloudCidr'] + ) + + aci.get_existing() + + if state == 'present': + child_configs.append(dict(cloudRsToCtx=dict(attributes=dict(tnFvCtxName=vrf)))) + child_configs.append(dict( + cloudRsCtxProfileToRegion=dict( + attributes=dict( + tDn="uni/clouddomp/provp-{0}/region-{1}".format(cloud, region) + ) + ) + )) + child_configs.append(dict( + cloudCidr=dict( + attributes=dict( + addr=primary_cidr, + primary="yes" + ) + ) + )) + aci.payload( + aci_class='cloudCtxProfile', + class_config=dict( + descr=description, + name=name, + name_alias=name_alias, + type='regular', + ), + child_configs=child_configs + ) + + aci.get_diff(aci_class='cloudCtxProfile') + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_cloud_provider.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_cloud_provider.py new file mode 100644 index 00000000..a236d34d --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_cloud_provider.py @@ -0,0 +1,178 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2020, Lionel Hercot (@lhercot) <lhercot@cisco.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = r''' +--- +module: aci_cloud_provider +short_description: Query Cloud Provider information (cloud:ProvP) +description: +- Query Cloud Provider information (cloud:ProvP) on Cisco Cloud ACI. +author: +- Lionel Hercot (@lhercot) +options: + state: + description: + - Use C(query) for listing an object or multiple objects. + choices: [ query ] + default: query + type: str +notes: +- More information about the internal APIC class B(cloud:ProvP) from + L(the APIC Management Information Model reference,https://developer.cisco.com/docs/apic-mim-ref/). +- This module is used to query Cloud Provider information. + +extends_documentation_fragment: +- cisco.aci.aci +''' + +EXAMPLES = r''' +- name: Query cloud provider information + cisco.aci.aci_cloud_provider: + host: apic + username: userName + password: somePassword + validate_certs: no + state: query + delegate_to: localhost +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec +from ansible.module_utils.basic import AnsibleModule + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + state=dict(type='str', default='query', choices=['query']), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + ) + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='cloudProvP' + ) + ) + + aci.get_existing() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_cloud_region.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_cloud_region.py new file mode 100644 index 00000000..6ae8dad0 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_cloud_region.py @@ -0,0 +1,219 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2020, nkatarmal-crest <nirav.katarmal@crestdatasys.com> +# Copyright: (c) 2020, Cindy Zhao <cizhao@cisco.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = r''' +--- +module: aci_cloud_region +short_description: Manage Cloud Providers Region (cloud:Region) +description: +- Manage Cloud Providers Region on Cisco Cloud ACI. +author: +- Nirav (@nirav) +- Cindy Zhao (@cizhao) +options: + region: + description: + - The name of the cloud provider's region. + aliases: [ name ] + type: str + cloud: + description: + - The vendor of the controller + choices: [ aws, azure ] + type: str + required: yes + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + choices: [ query ] + default: query + type: str +notes: +- More information about the internal APIC class B(cloud:Region) from + L(the APIC Management Information Model reference,https://developer.cisco.com/docs/apic-mim-ref/). +- This module is used to query Cloud Providers Region. + +extends_documentation_fragment: +- cisco.aci.aci +''' + +EXAMPLES = r''' +- name: Query all regions + cisco.aci.aci_cloud_region: + host: apic + username: userName + password: somePassword + validate_certs: no + cloud: 'aws' + state: query + delegate_to: localhost + +- name: Query a specific region + cisco.aci.aci_cloud_region: + host: apic + username: userName + password: somePassword + validate_certs: no + cloud: 'aws' + region: eu-west-2 + state: query + delegate_to: localhost +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec +from ansible.module_utils.basic import AnsibleModule + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + region=dict(type='str', aliases=["name"]), + cloud=dict(type='str', choices=['aws', 'azure'], required=True), + state=dict(type='str', default='query', choices=['query']), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + ) + + region = module.params.get('region') + cloud = module.params.get('cloud') + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='cloudProvP', + aci_rn='clouddomp/provp-{0}'.format(cloud), + target_filter='eq(cloudProvP.vendor, "{0}")'.format(cloud), + module_object=cloud + ), + subclass_1=dict( + aci_class='cloudRegion', + aci_rn='region-{0}'.format(region), + target_filter='eq(cloudRegion.name, "{0}")'.format(region), + module_object=region + ), + child_classes=[] + ) + + aci.get_existing() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_cloud_subnet.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_cloud_subnet.py new file mode 100644 index 00000000..4d17d80b --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_cloud_subnet.py @@ -0,0 +1,330 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2020, nkatarmal-crest <nirav.katarmal@crestdatasys.com> +# Copyright: (c) 2020, Cindy Zhao <cizhao@cisco.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = r''' +--- +module: aci_cloud_subnet +short_description: Manage Cloud Subnet (cloud:Subnet) +description: +- Manage Cloud Subnet on Cisco Cloud ACI. +notes: +- More information about the internal APIC class B(cloud:Subnet) from + L(the APIC Management Information Model reference,https://developer.cisco.com/docs/apic-mim-ref/). +author: +- Nirav (@nirav) +- Cindy Zhao (@cizhao) +options: + name: + description: + - The name of the Cloud Subnet. + type: str + description: + description: + - Description of the Cloud Subnet. + type: str + address: + description: + - Ip address of the Cloud Subnet. + type: str + aliases: [subnet] + name_alias: + description: + - An alias for the name of the current object. This relates to the nameAlias field in ACI and is used to rename object without changing the DN. + type: str + tenant: + description: + - The name of tenant. + type: str + required: yes + cloud_context_profile: + description: + - The name of cloud context profile. + type: str + required: yes + cidr: + description: + - Address of cloud cidr. + type: str + required: yes + availability_zone: + description: + - The cloud zone which is attached to the given cloud context profile. + - Only used when it is an aws cloud apic. + type: str + vnet_gateway: + description: + - Determine if a vNet Gateway Router will be deployed or not. + - Only used when it is an azure cloud apic. + type: bool + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + choices: [ absent, present, query ] + default: present + type: str + +extends_documentation_fragment: +- cisco.aci.aci +''' + +EXAMPLES = r''' +- name: Create aci cloud subnet + cisco.aci.aci_cloud_subnet: + host: apic + username: userName + password: somePassword + validate_certs: no + tenant: anstest + cloud_context_profile: aws_cloudCtxProfile + cidr: '10.10.0.0/16' + availability_zone: us-west-1a + address: 10.10.0.1 + delegate_to: localhost + +- name: Query a specific subnet + cisco.aci.aci_cloud_subnet: + host: apic + username: userName + password: somePassword + validate_certs: no + tenant: anstest + cloud_context_profile: ctx_profile_1 + cidr: '10.10.0.0/16' + address: 10.10.0.1 + state: query + delegate_to: localhost + +- name: Query all subnets + cisco.aci.aci_cloud_subnet: + host: apic + username: userName + password: somePassword + validate_certs: no + tenant: anstest + cloud_context_profile: ctx_profile_1 + cidr: '10.10.0.0/16' + state: query + delegate_to: localhost +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec +from ansible.module_utils.basic import AnsibleModule + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + name=dict(type='str', aliases=['subnet']), + description=dict(type='str'), + address=dict(type='str'), + name_alias=dict(type='str'), + vnet_gateway=dict(type='bool', default=False), + tenant=dict(type='str', required=True), + cloud_context_profile=dict(type='str', required=True), + cidr=dict(type='str', required=True), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + availability_zone=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['address']], + ['state', 'present', ['address']], + ], + ) + + name = module.params.get('name') + description = module.params.get('description') + address = module.params.get('address') + name_alias = module.params.get('name_alias') + vnet_gateway = module.params.get('vnet_gateway') + tenant = module.params.get('tenant') + cloud_context_profile = module.params.get('cloud_context_profile') + cidr = module.params.get('cidr') + state = module.params.get('state') + availability_zone = module.params.get('availability_zone') + child_configs = [] + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + target_filter='eq(fvTenant.name, "{0}")'.format(tenant), + module_object=tenant + ), + subclass_1=dict( + aci_class='cloudCtxProfile', + aci_rn='ctxprofile-{0}'.format(cloud_context_profile), + target_filter='eq(cloudCtxProfile.name, "{0}")'.format(cloud_context_profile), + module_object=cloud_context_profile + ), + subclass_2=dict( + aci_class='cloudCidr', + aci_rn='cidr-[{0}]'.format(cidr), + target_filter='eq(cloudCidr.addr, "{0}")'.format(cidr), + module_object=cidr + ), + subclass_3=dict( + aci_class='cloudSubnet', + aci_rn='subnet-[{0}]'.format(address), + target_filter='eq(cloudSubnet.ip, "{0}")'.format(address), + module_object=address + ), + child_classes=['cloudRsZoneAttach'] + ) + + aci.get_existing() + + if state == 'present': + # in aws cloud apic + if availability_zone: + region = availability_zone[:-1] + tDn = 'uni/clouddomp/provp-aws/region-{0}/zone-{1}'.format(region, availability_zone) + child_configs.append({'cloudRsZoneAttach': {'attributes': {'tDn': tDn}}}) + # in azure cloud apic + if vnet_gateway: + usage = 'gateway' + else: + usage = 'user' + + aci.payload( + aci_class='cloudSubnet', + class_config=dict( + name=name, + descr=description, + ip=address, + nameAlias=name_alias, + scope='private', + usage=usage, + ), + child_configs=child_configs + ) + + aci.get_diff(aci_class='cloudSubnet') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_cloud_vpn_gateway.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_cloud_vpn_gateway.py new file mode 100644 index 00000000..9b286dc8 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_cloud_vpn_gateway.py @@ -0,0 +1,253 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2020, Cindy Zhao <cizhao@cisco.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = r''' +--- +module: aci_cloud_vpn_gateway +short_description: Manage cloudRouterP in Cloud Context Profile (cloud:cloudRouterP) +description: +- Manage cloudRouterP objects on Cisco Cloud ACI. +notes: +- More information about the internal APIC class B(cloud:cloudRouterP) from + L(the APIC Management Information Model reference,https://developer.cisco.com/docs/apic-mim-ref/). +author: +- Cindy Zhao (@cizhao) +options: + tenant: + description: + - The name of tenant. + type: str + required: yes + cloud_context_profile: + description: + - The name of cloud context profile. + type: str + required: yes + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + choices: [ absent, present, query ] + type: str + default: query + +extends_documentation_fragment: +- cisco.aci.aci +''' + +EXAMPLES = r''' +- name: Enable VpnGateway + cisco.aci.aci_cloud_vpn_gateway: + host: apic_host + username: admin + password: SomeSecretPassword + tenant: ansible_test + cloud_context_profile: ctx_profile_1 + state: present + delegate_to: localhost + +- name: Disable VpnGateway + cisco.aci.aci_cloud_vpn_gateway: + host: apic_host + username: admin + password: SomeSecretPassword + tenant: ansible_test + cloud_context_profile: ctx_profile_1 + state: absent + delegate_to: localhost + +- name: Query VpnGateway + cisco.aci.aci_cloud_vpn_gateway: + host: apic_host + username: admin + password: SomeSecretPassword + tenant: ansible_test + cloud_context_profile: ctx_profile_1 + delegate_to: localhost +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec +from ansible.module_utils.basic import AnsibleModule + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + tenant=dict(type='str', required=True), + cloud_context_profile=dict(type='str', required=True), + state=dict(type='str', default='query', choices=['absent', 'present', 'query']), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + ) + + tenant = module.params.get('tenant') + cloud_context_profile = module.params.get('cloud_context_profile') + state = module.params.get('state') + child_configs = [] + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + target_filter='eq(fvTenant.name, "{0}")'.format(tenant), + module_object=tenant + ), + subclass_1=dict( + aci_class='cloudCtxProfile', + aci_rn='ctxprofile-{0}'.format(cloud_context_profile), + target_filter='eq(cloudCtxProfile.name, "{0}")'.format(cloud_context_profile), + module_object=cloud_context_profile + ), + subclass_2=dict( + aci_class='cloudRouterP', + aci_rn="routerp-default", + target_filter='eq(cloudRouterP.name, "default")', + module_object="default" + ), + child_classes=['cloudRsToVpnGwPol', 'cloudRsToHostRouterPol', 'cloudIntNetworkP'] + ) + + aci.get_existing() + + if state == 'present': + child_configs.append(dict( + cloudIntNetworkP=dict( + attributes=dict( + name="default" + ) + ) + )) + aci.payload( + aci_class='cloudRouterP', + class_config=dict( + name="default" + ), + child_configs=child_configs + ) + + aci.get_diff(aci_class='cloudRouterP') + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_cloud_zone.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_cloud_zone.py new file mode 100644 index 00000000..be85f18e --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_cloud_zone.py @@ -0,0 +1,233 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2020, nkatarmal-crest <nirav.katarmal@crestdatasys.com> +# Copyright: (c) 2020, Cindy Zhao <cizhao@cisco.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = r''' +--- +module: aci_cloud_zone +short_description: Manage Cloud Availability Zone (cloud:Zone) +description: +- Manage Cloud Availability Zone on Cisco Cloud ACI. +notes: +- More information about the internal APIC class B(cloud:Zone) from + L(the APIC Management Information Model reference,https://developer.cisco.com/docs/apic-mim-ref/). +- This module is used to query Cloud Availability Zone. +author: +- Nirav (@nirav) +- Cindy Zhao (@cizhao) +options: + name: + description: + - object name + aliases: [ zone ] + type: str + cloud: + description: + - The cloud provider. + choices: [ aws, azure ] + type: str + required: yes + region: + description: + - The name of the cloud provider's region. + type: str + required: yes + state: + description: + - Use C(query) for listing an object or multiple objects. + choices: [ query ] + default: query + type: str + +extends_documentation_fragment: +- cisco.aci.aci +''' + +EXAMPLES = r''' +- name: Query all zones in a region + cisco.aci.aci_cloud_zone: + host: apic + username: userName + password: somePassword + validate_certs: no + cloud: 'aws' + region: regionName + state: query + delegate_to: localhost + +- name: Query a specific zone + cisco.aci.aci_cloud_zone: + host: apic + username: userName + password: somePassword + validate_certs: no + cloud: 'aws' + region: regionName + zone: zoneName + state: query + delegate_to: localhost +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec +from ansible.module_utils.basic import AnsibleModule + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + name=dict(type='str', aliases=['zone']), + cloud=dict(type='str', choices=['aws', 'azure'], required=True), + region=dict(type='str', required=True), + state=dict(type='str', default='query', choices=['query']), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + ) + + name = module.params.get('name') + cloud = module.params.get('cloud') + region = module.params.get('region') + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='cloudProvP', + aci_rn='clouddomp/provp-{0}'.format(cloud), + target_filter='eq(cloudProvP.vendor, "{0}")'.format(cloud), + module_object=cloud + ), + subclass_1=dict( + aci_class='cloudRegion', + aci_rn='region-{0}'.format(region), + target_filter='eq(cloudRegion.name, "{0}")'.format(region), + module_object=region + ), + subclass_2=dict( + aci_class='cloudZone', + aci_rn='zone-{0}'.format(name), + target_filter='eq(cloudZone.name, "{0}")'.format(name), + module_object=name + ), + child_classes=[] + ) + + aci.get_existing() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_config_rollback.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_config_rollback.py new file mode 100644 index 00000000..fb8ffc19 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_config_rollback.py @@ -0,0 +1,321 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_config_rollback +short_description: Provides rollback and rollback preview functionality (config:ImportP) +description: +- Provides rollback and rollback preview functionality for Cisco ACI fabrics. +- Config Rollbacks are done using snapshots C(aci_snapshot) with the configImportP class. +options: + compare_export_policy: + description: + - The export policy that the C(compare_snapshot) is associated to. + type: str + compare_snapshot: + description: + - The name of the snapshot to compare with C(snapshot). + type: str + description: + description: + - The description for the Import Policy. + type: str + aliases: [ descr ] + export_policy: + description: + - The export policy that the C(snapshot) is associated to. + type: str + fail_on_decrypt: + description: + - Determines if the APIC should fail the rollback if unable to decrypt secured data. + - The APIC defaults to C(yes) when unset. + type: bool + import_mode: + description: + - Determines how the import should be handled by the APIC. + - The APIC defaults to C(atomic) when unset. + type: str + choices: [ atomic, best-effort ] + import_policy: + description: + - The name of the Import Policy to use for config rollback. + type: str + import_type: + description: + - Determines how the current and snapshot configuration should be compared for replacement. + - The APIC defaults to C(replace) when unset. + type: str + choices: [ merge, replace ] + snapshot: + description: + - The name of the snapshot to rollback to, or the base snapshot to use for comparison. + - The C(aci_snapshot) module can be used to query the list of available snapshots. + type: str + required: yes + state: + description: + - Use C(preview) for previewing the diff between two snapshots. + - Use C(rollback) for reverting the configuration to a previous snapshot. + type: str + choices: [ preview, rollback ] + default: rollback +extends_documentation_fragment: +- cisco.aci.aci + +seealso: +- module: cisco.aci.aci_config_snapshot +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(config:ImportP). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Jacob McGill (@jmcgill298) +''' + +EXAMPLES = r''' +--- +- name: Create a Snapshot + cisco.aci.aci_config_snapshot: + host: apic + username: admin + password: SomeSecretPassword + export_policy: config_backup + state: present + delegate_to: localhost + +- name: Query Existing Snapshots + cisco.aci.aci_config_snapshot: + host: apic + username: admin + password: SomeSecretPassword + export_policy: config_backup + state: query + delegate_to: localhost + +- name: Compare Snapshot Files + cisco.aci.aci_config_rollback: + host: apic + username: admin + password: SomeSecretPassword + export_policy: config_backup + snapshot: run-2017-08-28T06-24-01 + compare_export_policy: config_backup + compare_snapshot: run-2017-08-27T23-43-56 + state: preview + delegate_to: localhost + +- name: Rollback Configuration + cisco.aci.aci_config_rollback: + host: apic + username: admin + password: SomeSecretPassword + import_policy: rollback_config + export_policy: config_backup + snapshot: run-2017-08-28T06-24-01 + state: rollback + delegate_to: localhost + +- name: Rollback Configuration + cisco.aci.aci_config_rollback: + host: apic + username: admin + password: SomeSecretPassword + import_policy: rollback_config + export_policy: config_backup + snapshot: run-2017-08-28T06-24-01 + description: Rollback 8-27 changes + import_mode: atomic + import_type: replace + fail_on_decrypt: yes + state: rollback + delegate_to: localhost +''' + +RETURN = r''' +preview: + description: A preview between two snapshots + returned: when state is preview + type: str +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: str + sample: '<?xml version="1.0" encoding="UTF-8"?><imdata totalCount="1"><error code="122" text="unknown managed object class foo"/></imdata>' +filter_string: + description: The filter string used for the request + returned: failure or debug + type: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils._text import to_bytes +from ansible.module_utils.urls import fetch_url + +# Optional, only used for rollback preview +try: + import lxml.etree + from xmljson import cobra + XML_TO_JSON = True +except ImportError: + XML_TO_JSON = False + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + compare_export_policy=dict(type='str'), + compare_snapshot=dict(type='str'), + description=dict(type='str', aliases=['descr']), + export_policy=dict(type='str'), + fail_on_decrypt=dict(type='bool'), + import_mode=dict(type='str', choices=['atomic', 'best-effort']), + import_policy=dict(type='str'), + import_type=dict(type='str', choices=['merge', 'replace']), + snapshot=dict(type='str', required=True), + state=dict(type='str', default='rollback', choices=['preview', 'rollback']), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=False, + required_if=[ + ['state', 'preview', ['compare_export_policy', 'compare_snapshot']], + ['state', 'rollback', ['import_policy']], + ], + ) + + aci = ACIModule(module) + + description = module.params.get('description') + export_policy = module.params.get('export_policy') + fail_on_decrypt = aci.boolean(module.params.get('fail_on_decrypt')) + import_mode = module.params.get('import_mode') + import_policy = module.params.get('import_policy') + import_type = module.params.get('import_type') + snapshot = module.params.get('snapshot') + state = module.params.get('state') + + if state == 'rollback': + if snapshot.startswith('run-'): + snapshot = snapshot.replace('run-', '', 1) + + if not snapshot.endswith('.tar.gz'): + snapshot += '.tar.gz' + + filename = 'ce2_{0}-{1}'.format(export_policy, snapshot) + + aci.construct_url( + root_class=dict( + aci_class='configImportP', + aci_rn='fabric/configimp-{0}'.format(import_policy), + module_object=import_policy, + target_filter={'name': import_policy}, + ), + ) + + aci.get_existing() + + aci.payload( + aci_class='configImportP', + class_config=dict( + adminSt='triggered', + descr=description, + failOnDecryptErrors=fail_on_decrypt, + fileName=filename, + importMode=import_mode, + importType=import_type, + name=import_policy, + snapshot='yes', + ), + ) + + aci.get_diff(aci_class='configImportP') + + aci.post_config() + + elif state == 'preview': + aci.url = '%(protocol)s://%(host)s/mqapi2/snapshots.diff.xml' % module.params + aci.filter_string = ( + '?s1dn=uni/backupst/snapshots-[uni/fabric/configexp-%(export_policy)s]/snapshot-%(snapshot)s&' + 's2dn=uni/backupst/snapshots-[uni/fabric/configexp-%(compare_export_policy)s]/snapshot-%(compare_snapshot)s' + ) % module.params + + # Generate rollback comparison + get_preview(aci) + + aci.exit_json() + + +def get_preview(aci): + ''' + This function is used to generate a preview between two snapshots and add the parsed results to the aci module return data. + ''' + uri = aci.url + aci.filter_string + resp, info = fetch_url(aci.module, uri, headers=aci.headers, method='GET', timeout=aci.module.params.get('timeout'), + use_proxy=aci.module.params.get('use_proxy')) + aci.method = 'GET' + aci.response = info.get('msg') + aci.status = info.get('status') + + # Handle APIC response + if info.get('status') == 200: + xml_to_json(aci, resp.read()) + else: + aci.result['raw'] = resp.read() + aci.fail_json(msg="Request failed: %(code)s %(text)s (see 'raw' output)" % aci.error) + + +def xml_to_json(aci, response_data): + ''' + This function is used to convert preview XML data into JSON. + ''' + if XML_TO_JSON: + xml = lxml.etree.fromstring(to_bytes(response_data)) + xmldata = cobra.data(xml) + aci.result['preview'] = xmldata + else: + aci.result['preview'] = response_data + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_config_snapshot.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_config_snapshot.py new file mode 100644 index 00000000..8f71ca01 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_config_snapshot.py @@ -0,0 +1,337 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_config_snapshot +short_description: Manage Config Snapshots (config:Snapshot, config:ExportP) +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. +options: + description: + description: + - The description for the Config Export Policy. + type: str + aliases: [ descr ] + export_policy: + description: + - The name of the Export Policy to use for Config Snapshots. + type: str + aliases: [ name ] + format: + description: + - Sets the config backup to be formatted in JSON or XML. + - The APIC defaults to C(json) when unset. + type: str + choices: [ json, xml ] + include_secure: + description: + - Determines if secure information should be included in the backup. + - The APIC defaults to C(yes) when unset. + type: bool + max_count: + description: + - Determines how many snapshots can exist for the Export Policy before the APIC starts to rollover. + - Accepted values range between C(1) and C(10). + - The APIC defaults to C(3) when unset. + type: int + snapshot: + description: + - The name of the snapshot to delete. + type: str + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present +extends_documentation_fragment: +- cisco.aci.aci + +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>.' +seealso: +- module: cisco.aci.aci_config_rollback +- name: APIC Management Information Model reference + description: More information about the internal APIC classes B(config:Snapshot) and B(config:ExportP). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Jacob McGill (@jmcgill298) +''' + +EXAMPLES = r''' +- name: Create a Snapshot + cisco.aci.aci_config_snapshot: + host: apic + username: admin + password: SomeSecretPassword + state: present + export_policy: config_backup + max_count: 10 + description: Backups taken before new configs are applied. + delegate_to: localhost + +- name: Query all Snapshots + cisco.aci.aci_config_snapshot: + host: apic + username: admin + password: SomeSecretPassword + state: query + delegate_to: localhost + register: query_result + +- name: Query Snapshots associated with a particular Export Policy + cisco.aci.aci_config_snapshot: + host: apic + username: admin + password: SomeSecretPassword + export_policy: config_backup + state: query + delegate_to: localhost + register: query_result + +- name: Delete a Snapshot + cisco.aci.aci_config_snapshot: + host: apic + username: admin + password: SomeSecretPassword + export_policy: config_backup + snapshot: run-2017-08-24T17-20-05 + state: absent + delegate_to: localhost +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + description=dict(type='str', aliases=['descr']), + export_policy=dict(type='str', aliases=['name']), # Not required for querying all objects + format=dict(type='str', choices=['json', 'xml']), + include_secure=dict(type='bool'), + max_count=dict(type='int'), + snapshot=dict(type='str'), + state=dict(type='str', choices=['absent', 'present', 'query'], default='present'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=False, + required_if=[ + ['state', 'absent', ['export_policy', 'snapshot']], + ['state', 'present', ['export_policy']], + ], + ) + + aci = ACIModule(module) + + description = module.params.get('description') + export_policy = module.params.get('export_policy') + file_format = module.params.get('format') + include_secure = aci.boolean(module.params.get('include_secure')) + max_count = module.params.get('max_count') + if max_count is not None: + if max_count in range(1, 11): + max_count = str(max_count) + else: + module.fail_json(msg="Parameter 'max_count' must be a number between 1 and 10") + snapshot = module.params.get('snapshot') + if snapshot is not None and not snapshot.startswith('run-'): + snapshot = 'run-' + snapshot + state = module.params.get('state') + + if state == 'present': + aci.construct_url( + root_class=dict( + aci_class='configExportP', + aci_rn='fabric/configexp-{0}'.format(export_policy), + module_object=export_policy, + target_filter={'name': export_policy}, + ), + ) + + aci.get_existing() + + aci.payload( + aci_class='configExportP', + class_config=dict( + adminSt='triggered', + descr=description, + format=file_format, + includeSecureFields=include_secure, + maxSnapshotCount=max_count, + name=export_policy, + snapshot='yes', + ), + ) + + aci.get_diff('configExportP') + + # Create a new Snapshot + aci.post_config() + + else: + # Prefix the proper url to export_policy + if export_policy is not None: + export_policy = 'uni/fabric/configexp-{0}'.format(export_policy) + + aci.construct_url( + root_class=dict( + aci_class='configSnapshotCont', + aci_rn='backupst/snapshots-[{0}]'.format(export_policy), + module_object=export_policy, + target_filter={'name': export_policy}, + ), + subclass_1=dict( + aci_class='configSnapshot', + aci_rn='snapshot-{0}'.format(snapshot), + module_object=snapshot, + target_filter={'name': snapshot}, + ), + ) + + aci.get_existing() + + if state == 'absent': + # Build POST request to used to remove Snapshot + aci.payload( + aci_class='configSnapshot', + class_config=dict( + name=snapshot, + retire="yes", + ), + ) + + if aci.existing: + aci.get_diff('configSnapshot') + + # Mark Snapshot for Deletion + aci.post_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_contract.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_contract.py new file mode 100644 index 00000000..36f6e00f --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_contract.py @@ -0,0 +1,312 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_contract +short_description: Manage contract resources (vz:BrCP) +description: +- Manage Contract resources on Cisco ACI fabrics. +options: + contract: + description: + - The name of the contract. + type: str + aliases: [ contract_name, name ] + description: + description: + - Description for the contract. + type: str + aliases: [ descr ] + tenant: + description: + - The name of the tenant. + type: str + aliases: [ tenant_name ] + scope: + description: + - The scope of a service contract. + - The APIC defaults to C(context) when unset during creation. + type: str + choices: [ application-profile, context, global, tenant ] + priority: + description: + - The desired QoS class to be used. + - The APIC defaults to C(unspecified) when unset during creation. + type: str + choices: [ level1, level2, level3, unspecified ] + dscp: + description: + - The target Differentiated Service (DSCP) value. + - The APIC defaults to C(unspecified) when unset during creation. + type: str + choices: [ AF11, AF12, AF13, AF21, AF22, AF23, AF31, AF32, AF33, AF41, AF42, AF43, CS0, CS1, CS2, CS3, CS4, CS5, CS6, CS7, EF, VA, unspecified ] + aliases: [ target ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- This module does not manage Contract Subjects, see M(cisco.aci.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(cisco.aci.aci_tenant) module can be used for this. +seealso: +- module: cisco.aci.aci_contract_subject +- module: cisco.aci.aci_tenant +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(vz:BrCP). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Dag Wieers (@dagwieers) +''' + +EXAMPLES = r''' +- name: Add a new contract + cisco.aci.aci_contract: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + contract: web_to_db + description: Communication between web-servers and database + scope: application-profile + state: present + delegate_to: localhost + +- name: Remove an existing contract + cisco.aci.aci_contract: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + contract: web_to_db + state: absent + delegate_to: localhost + +- name: Query a specific contract + cisco.aci.aci_contract: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + contract: web_to_db + state: query + delegate_to: localhost + register: query_result + +- name: Query all contracts + cisco.aci.aci_contract: + host: apic + username: admin + password: SomeSecretPassword + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + contract=dict(type='str', aliases=['contract_name', 'name']), # Not required for querying all objects + tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects + description=dict(type='str', aliases=['descr']), + scope=dict(type='str', choices=['application-profile', 'context', 'global', 'tenant']), + priority=dict(type='str', choices=['level1', 'level2', 'level3', 'unspecified']), # No default provided on purpose + dscp=dict(type='str', + choices=['AF11', 'AF12', 'AF13', 'AF21', 'AF22', 'AF23', 'AF31', 'AF32', 'AF33', 'AF41', 'AF42', 'AF43', + 'CS0', 'CS1', 'CS2', 'CS3', 'CS4', 'CS5', 'CS6', 'CS7', 'EF', 'VA', 'unspecified'], + aliases=['target']), # No default provided on purpose + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['contract', 'tenant']], + ['state', 'present', ['contract', 'tenant']], + ], + ) + + contract = module.params.get('contract') + description = module.params.get('description') + scope = module.params.get('scope') + priority = module.params.get('priority') + dscp = module.params.get('dscp') + state = module.params.get('state') + tenant = module.params.get('tenant') + name_alias = module.params.get('name_alias') + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + module_object=tenant, + target_filter={'name': tenant}, + ), + subclass_1=dict( + aci_class='vzBrCP', + aci_rn='brc-{0}'.format(contract), + module_object=contract, + target_filter={'name': contract}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='vzBrCP', + class_config=dict( + name=contract, + descr=description, + scope=scope, + prio=priority, + targetDscp=dscp, + nameAlias=name_alias, + ), + ) + + aci.get_diff(aci_class='vzBrCP') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_contract_subject.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_contract_subject.py new file mode 100644 index 00000000..24fc8ed0 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_contract_subject.py @@ -0,0 +1,358 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_contract_subject +short_description: Manage initial Contract Subjects (vz:Subj) +description: +- Manage initial Contract Subjects on Cisco ACI fabrics. +options: + tenant: + description: + - The name of the tenant. + type: str + aliases: [ tenant_name ] + subject: + description: + - The contract subject name. + type: str + aliases: [ contract_subject, name, subject_name ] + contract: + description: + - The name of the Contract. + type: str + aliases: [ contract_name ] + reverse_filter: + description: + - Determines if the APIC should reverse the src and dst ports to allow the + return traffic back, since ACI is stateless filter. + - The APIC defaults to C(yes) when unset during creation. + type: bool + priority: + description: + - The QoS class. + - The APIC defaults to C(unspecified) when unset during creation. + type: str + choices: [ level1, level2, level3, unspecified ] + dscp: + description: + - The target DSCP. + - The APIC defaults to C(unspecified) when unset during creation. + type: str + choices: [ AF11, AF12, AF13, AF21, AF22, AF23, AF31, AF32, AF33, AF41, AF42, AF43, + CS0, CS1, CS2, CS3, CS4, CS5, CS6, CS7, EF, VA, unspecified ] + aliases: [ target ] + description: + description: + - Description for the contract subject. + type: str + aliases: [ descr ] + consumer_match: + description: + - The match criteria across consumers. + - The APIC defaults to C(at_least_one) when unset during creation. + type: str + choices: [ all, at_least_one, at_most_one, none ] + provider_match: + description: + - The match criteria across providers. + - The APIC defaults to C(at_least_one) when unset during creation. + type: str + choices: [ all, at_least_one, at_most_one, none ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- The C(tenant) and C(contract) used must exist before using this module in your playbook. + The M(cisco.aci.aci_tenant) and M(cisco.aci.aci_contract) modules can be used for this. +seealso: +- module: cisco.aci.aci_contract +- module: cisco.aci.aci_tenant +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(vz:Subj). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Swetha Chunduri (@schunduri) +''' + +EXAMPLES = r''' +- name: Add a new contract subject + cisco.aci.aci_contract_subject: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + contract: web_to_db + subject: default + description: test + reverse_filter: yes + priority: level1 + dscp: unspecified + state: present + register: query_result + +- name: Remove a contract subject + cisco.aci.aci_contract_subject: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + contract: web_to_db + subject: default + state: absent + delegate_to: localhost + +- name: Query a contract subject + cisco.aci.aci_contract_subject: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + contract: web_to_db + subject: default + state: query + delegate_to: localhost + register: query_result + +- name: Query all contract subjects + cisco.aci.aci_contract_subject: + host: apic + username: admin + password: SomeSecretPassword + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + +MATCH_MAPPING = dict( + all='All', + at_least_one='AtleastOne', + at_most_one='AtmostOne', + none='None', +) + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + 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'], + choices=['AF11', 'AF12', 'AF13', 'AF21', 'AF22', 'AF23', 'AF31', 'AF32', 'AF33', 'AF41', 'AF42', 'AF43', + 'CS0', 'CS1', 'CS2', 'CS3', 'CS4', 'CS5', 'CS6', 'CS7', 'EF', 'VA', 'unspecified']), + description=dict(type='str', aliases=['descr']), + consumer_match=dict(type='str', choices=['all', 'at_least_one', 'at_most_one', 'none']), + provider_match=dict(type='str', choices=['all', 'at_least_one', 'at_most_one', 'none']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['contract', 'subject', 'tenant']], + ['state', 'present', ['contract', 'subject', 'tenant']], + ], + ) + + aci = ACIModule(module) + + subject = module.params.get('subject') + priority = module.params.get('priority') + reverse_filter = aci.boolean(module.params.get('reverse_filter')) + contract = module.params.get('contract') + dscp = module.params.get('dscp') + description = module.params.get('description') + consumer_match = module.params.get('consumer_match') + if consumer_match is not None: + consumer_match = MATCH_MAPPING.get(consumer_match) + provider_match = module.params.get('provider_match') + if provider_match is not None: + provider_match = MATCH_MAPPING.get(provider_match) + state = module.params.get('state') + tenant = module.params.get('tenant') + name_alias = module.params.get('name_alias') + + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + module_object=tenant, + target_filter={'name': tenant}, + ), + subclass_1=dict( + aci_class='vzBrCP', + aci_rn='brc-{0}'.format(contract), + module_object=contract, + target_filter={'name': contract}, + ), + subclass_2=dict( + aci_class='vzSubj', + aci_rn='subj-{0}'.format(subject), + module_object=subject, + target_filter={'name': subject}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='vzSubj', + class_config=dict( + name=subject, + prio=priority, + revFltPorts=reverse_filter, + targetDscp=dscp, + consMatchT=consumer_match, + provMatchT=provider_match, + descr=description, + nameAlias=name_alias, + ), + ) + + aci.get_diff(aci_class='vzSubj') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_contract_subject_to_filter.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_contract_subject_to_filter.py new file mode 100644 index 00000000..5698295a --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_contract_subject_to_filter.py @@ -0,0 +1,319 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_contract_subject_to_filter +short_description: Bind Contract Subjects to Filters (vz:RsSubjFiltAtt) +description: +- Bind Contract Subjects to Filters on Cisco ACI fabrics. +options: + contract: + description: + - The name of the contract. + type: str + aliases: [ contract_name ] + filter: + description: + - The name of the Filter to bind to the Subject. + type: str + aliases: [ filter_name ] + log: + description: + - Determines if the binding should be set to log. + - The APIC defaults to C(none) when unset during creation. + type: str + choices: [ log, none ] + aliases: [ directive ] + subject: + description: + - The name of the Contract Subject. + type: str + aliases: [ contract_subject, subject_name ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + tenant: + description: + - The name of the tenant. + type: str + aliases: [ tenant_name ] +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- The C(tenant), C(contract), C(subject), and C(filter_name) must exist before using this module in your playbook. + The M(cisco.aci.aci_tenant), M(cisco.aci.aci_contract), M(cisco.aci.aci_contract_subject), and M(cisco.aci.aci_filter) modules can be used for these. +seealso: +- module: cisco.aci.aci_contract_subject +- module: cisco.aci.aci_filter +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(vz:RsSubjFiltAtt). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Jacob McGill (@jmcgill298) +''' + +EXAMPLES = r''' +- name: Add a new contract subject to filer binding + cisco.aci.aci_contract_subject_to_filter: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + contract: web_to_db + subject: test + filter: '{{ filter }}' + log: '{{ log }}' + state: present + delegate_to: localhost + +- name: Remove an existing contract subject to filter binding + cisco.aci.aci_contract_subject_to_filter: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + contract: web_to_db + subject: test + filter: '{{ filter }}' + log: '{{ log }}' + state: present + delegate_to: localhost + +- name: Query a specific contract subject to filter binding + cisco.aci.aci_contract_subject_to_filter: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + contract: web_to_db + subject: test + filter: '{{ filter }}' + state: query + delegate_to: localhost + register: query_result + +- name: Query all contract subject to filter bindings + cisco.aci.aci_contract_subject_to_filter: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + contract: web_to_db + subject: test + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + contract=dict(type='str', aliases=['contract_name']), # Not required for querying all objects + filter=dict(type='str', aliases=['filter_name']), # Not required for querying all objects + subject=dict(type='str', aliases=['contract_subject', 'subject_name']), # Not required for querying all objects + tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects + log=dict(type='str', choices=['log', 'none'], aliases=['directive']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['contract', 'filter', 'subject', 'tenant']], + ['state', 'present', ['contract', 'filter', 'subject', 'tenant']], + ], + ) + + contract = module.params.get('contract') + filter_name = module.params.get('filter') + log = module.params.get('log') + subject = module.params.get('subject') + tenant = module.params.get('tenant') + state = module.params.get('state') + + # Add subject_filter key to modul.params for building the URL + module.params['subject_filter'] = filter_name + + # Convert log to empty string if none, as that is what API expects. An empty string is not a good option to present the user. + if log == 'none': + log = '' + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + module_object=tenant, + target_filter={'name': tenant}, + ), + subclass_1=dict( + aci_class='vzBrCP', + aci_rn='brc-{0}'.format(contract), + module_object=contract, + target_filter={'name': contract}, + ), + subclass_2=dict( + aci_class='vzSubj', + aci_rn='subj-{0}'.format(subject), + module_object=subject, + target_filter={'name': subject}, + ), + subclass_3=dict( + aci_class='vzRsSubjFiltAtt', + aci_rn='rssubjFiltAtt-{0}'.format(filter_name), + module_object=filter_name, + target_filter={'tnVzFilterName': filter_name}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='vzRsSubjFiltAtt', + class_config=dict( + tnVzFilterName=filter_name, + directives=log, + ), + ) + + aci.get_diff(aci_class='vzRsSubjFiltAtt') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + # Remove subject_filter used to build URL from module.params + module.params.pop('subject_filter') + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_domain.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_domain.py new file mode 100644 index 00000000..82ee9a32 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_domain.py @@ -0,0 +1,395 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_domain +short_description: Manage physical, virtual, bridged, routed or FC domain profiles (phys:DomP, vmm:DomP, l2ext:DomP, l3ext:DomP, fc:DomP) +description: +- Manage physical, virtual, bridged, routed or FC domain profiles on Cisco ACI fabrics. +options: + domain: + description: + - Name of the physical, virtual, bridged routed or FC domain profile. + type: str + aliases: [ domain_name, domain_profile, name ] + domain_type: + description: + - The type of domain profile. + - 'C(fc): The FC domain profile is a policy pertaining to single FC Management domain' + - 'C(l2dom): The external bridged domain profile is a policy for managing L2 bridged infrastructure bridged outside the fabric.' + - 'C(l3dom): The external routed domain profile is a policy for managing L3 routed infrastructure outside the fabric.' + - 'C(phys): The physical domain profile stores the physical resources and encap resources that should be used for EPGs associated with this domain.' + - 'C(vmm): The VMM domain profile is a policy for grouping VM controllers with similar networking policy requirements.' + type: str + required: yes + choices: [ fc, l2dom, l3dom, phys, vmm ] + aliases: [ type ] + dscp: + description: + - The target Differentiated Service (DSCP) value. + - The APIC defaults to C(unspecified) when unset during creation. + type: str + choices: [ AF11, AF12, AF13, AF21, AF22, AF23, AF31, AF32, AF33, AF41, AF42, AF43, CS0, CS1, CS2, CS3, CS4, CS5, CS6, CS7, EF, VA, unspecified ] + aliases: [ target ] + encap_mode: + description: + - The layer 2 encapsulation protocol to use with the virtual switch. + type: str + choices: [ unknown, vlan, vxlan ] + multicast_address: + description: + - The multicast IP address to use for the virtual switch. + type: str + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str + vm_provider: + description: + - The VM platform for VMM Domains. + - Support for Kubernetes was added in ACI v3.0. + - Support for CloudFoundry, OpenShift and Red Hat was added in ACI v3.1. + type: str + choices: [ cloudfoundry, kubernetes, microsoft, openshift, openstack, redhat, vmware ] + vswitch: + description: + - The virtual switch to use for vmm domains. + - The APIC defaults to C(default) when unset during creation. + type: str + choices: [ avs, default, dvs, unknown ] +extends_documentation_fragment: +- cisco.aci.aci + +seealso: +- module: cisco.aci.aci_aep_to_domain +- module: cisco.aci.aci_domain_to_encap_pool +- module: cisco.aci.aci_domain_to_vlan_pool +- name: APIC Management Information Model reference + description: More information about the internal APIC classes B(phys:DomP), + B(vmm:DomP), B(l2ext:DomP), B(l3ext:DomP) and B(fc:DomP) + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Dag Wieers (@dagwieers) +''' + +EXAMPLES = r''' +- name: Add a new physical domain + cisco.aci.aci_domain: + host: apic + username: admin + password: SomeSecretPassword + domain: phys_dom + domain_type: phys + state: present + +- name: Remove a physical domain + cisco.aci.aci_domain: + host: apic + username: admin + password: SomeSecretPassword + domain: phys_dom + domain_type: phys + state: absent + +- name: Add a new VMM domain + cisco.aci.aci_domain: + host: apic + username: admin + password: SomeSecretPassword + domain: hyperv_dom + domain_type: vmm + vm_provider: microsoft + state: present + delegate_to: localhost + +- name: Remove a VMM domain + cisco.aci.aci_domain: + host: apic + username: admin + password: SomeSecretPassword + domain: hyperv_dom + domain_type: vmm + vm_provider: microsoft + state: absent + delegate_to: localhost + +- name: Query a specific physical domain + cisco.aci.aci_domain: + host: apic + username: admin + password: SomeSecretPassword + domain: phys_dom + domain_type: phys + state: query + delegate_to: localhost + register: query_result + +- name: Query all domains + cisco.aci.aci_domain: + host: apic + username: admin + password: SomeSecretPassword + domain_type: phys + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + +VM_PROVIDER_MAPPING = dict( + cloudfoundry='CloudFoundry', + kubernetes='Kubernetes', + microsoft='Microsoft', + openshift='OpenShift', + openstack='OpenStack', + redhat='Redhat', + vmware='VMware', +) + +VSWITCH_MAPPING = dict( + avs='n1kv', + default='default', + dvs='default', + unknown='unknown', +) + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + domain_type=dict(type='str', required=True, choices=['fc', 'l2dom', 'l3dom', 'phys', 'vmm'], aliases=['type']), + domain=dict(type='str', aliases=['domain_name', 'domain_profile', 'name']), # Not required for querying all objects + dscp=dict(type='str', + choices=['AF11', 'AF12', 'AF13', 'AF21', 'AF22', 'AF23', 'AF31', 'AF32', 'AF33', 'AF41', 'AF42', 'AF43', + 'CS0', 'CS1', 'CS2', 'CS3', 'CS4', 'CS5', 'CS6', 'CS7', 'EF', 'VA', 'unspecified'], + aliases=['target']), + encap_mode=dict(type='str', choices=['unknown', 'vlan', 'vxlan']), + multicast_address=dict(type='str'), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + vm_provider=dict(type='str', choices=['cloudfoundry', 'kubernetes', 'microsoft', 'openshift', 'openstack', 'redhat', 'vmware']), + vswitch=dict(type='str', choices=['avs', 'default', 'dvs', 'unknown']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['domain_type', 'vmm', ['vm_provider']], + ['state', 'absent', ['domain', 'domain_type']], + ['state', 'present', ['domain', 'domain_type']], + ], + ) + + dscp = module.params.get('dscp') + domain = module.params.get('domain') + domain_type = module.params.get('domain_type') + encap_mode = module.params.get('encap_mode') + multicast_address = module.params.get('multicast_address') + vm_provider = module.params.get('vm_provider') + vswitch = module.params.get('vswitch') + if vswitch is not None: + vswitch = VSWITCH_MAPPING.get(vswitch) + state = module.params.get('state') + name_alias = module.params.get('name_alias') + + if domain_type != 'vmm': + if vm_provider is not None: + module.fail_json(msg="Domain type '{0}' cannot have parameter 'vm_provider'".format(domain_type)) + if encap_mode is not None: + module.fail_json(msg="Domain type '{0}' cannot have parameter 'encap_mode'".format(domain_type)) + if multicast_address is not None: + module.fail_json(msg="Domain type '{0}' cannot have parameter 'multicast_address'".format(domain_type)) + if vswitch is not None: + module.fail_json(msg="Domain type '{0}' cannot have parameter 'vswitch'".format(domain_type)) + + if dscp is not None and domain_type not in ['l2dom', 'l3dom']: + module.fail_json(msg="DSCP values can only be assigned to 'l2ext and 'l3ext' domains") + + # Compile the full domain for URL building + if domain_type == 'fc': + domain_class = 'fcDomP' + domain_mo = 'uni/fc-{0}'.format(domain) + domain_rn = 'fc-{0}'.format(domain) + elif domain_type == 'l2dom': + domain_class = 'l2extDomP' + domain_mo = 'uni/l2dom-{0}'.format(domain) + domain_rn = 'l2dom-{0}'.format(domain) + elif domain_type == 'l3dom': + domain_class = 'l3extDomP' + domain_mo = 'uni/l3dom-{0}'.format(domain) + domain_rn = 'l3dom-{0}'.format(domain) + elif domain_type == 'phys': + domain_class = 'physDomP' + domain_mo = 'uni/phys-{0}'.format(domain) + domain_rn = 'phys-{0}'.format(domain) + elif domain_type == 'vmm': + domain_class = 'vmmDomP' + domain_mo = 'uni/vmmp-{0}/dom-{1}'.format(VM_PROVIDER_MAPPING.get(vm_provider), domain) + domain_rn = 'vmmp-{0}/dom-{1}'.format(VM_PROVIDER_MAPPING.get(vm_provider), domain) + + # Ensure that querying all objects works when only domain_type is provided + if domain is None: + domain_mo = None + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class=domain_class, + aci_rn=domain_rn, + module_object=domain_mo, + target_filter={'name': domain}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class=domain_class, + class_config=dict( + encapMode=encap_mode, + mcastAddr=multicast_address, + mode=vswitch, + name=domain, + targetDscp=dscp, + nameAlias=name_alias, + ), + ) + + aci.get_diff(aci_class=domain_class) + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_domain_to_encap_pool.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_domain_to_encap_pool.py new file mode 100644 index 00000000..a571cfb3 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_domain_to_encap_pool.py @@ -0,0 +1,378 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2017, Dag Wieers <dag@wieers.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_domain_to_encap_pool +short_description: Bind Domain to Encap Pools (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(cisco.aci.aci_domain) and M(cisco.aci.aci_encap_pool) can be used for these. +options: + domain: + description: + - Name of the domain being associated with the Encap Pool. + type: str + aliases: [ domain_name, domain_profile ] + domain_type: + description: + - Determines if the Domain is physical (phys) or virtual (vmm). + type: str + required: yes + choices: [ fc, l2dom, l3dom, phys, vmm ] + pool: + description: + - The name of the pool. + type: str + aliases: [ pool_name ] + pool_allocation_mode: + description: + - The method used for allocating encaps to resources. + - Only vlan and vsan support allocation modes. + type: str + choices: [ dynamic, static] + aliases: [ allocation_mode, mode ] + pool_type: + description: + - The encap type of C(pool). + type: str + required: yes + choices: [ vlan, vsan, vxlan ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + vm_provider: + description: + - The VM platform for VMM Domains. + - Support for Kubernetes was added in ACI v3.0. + - Support for CloudFoundry, OpenShift and Red Hat was added in ACI v3.1. + type: str + choices: [ cloudfoundry, kubernetes, microsoft, openshift, openstack, redhat, vmware ] +extends_documentation_fragment: +- cisco.aci.aci + +seealso: +- module: cisco.aci.aci_domain +- module: cisco.aci.aci_encap_pool +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(infra:RsVlanNs). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Dag Wieers (@dagwieers) +''' + +EXAMPLES = r''' +- name: Add domain to VLAN pool binding + cisco.aci.aci_domain_to_encap_pool: + host: apic + username: admin + password: SomeSecretPassword + domain: phys_dom + domain_type: phys + pool: test_pool + pool_type: vlan + pool_allocation_mode: dynamic + state: present + delegate_to: localhost + +- name: Remove domain to VLAN pool binding + cisco.aci.aci_domain_to_encap_pool: + host: apic + username: admin + password: SomeSecretPassword + domain: phys_dom + domain_type: phys + pool: test_pool + pool_type: vlan + pool_allocation_mode: dynamic + state: absent + delegate_to: localhost + +- name: Query our domain to VLAN pool binding + cisco.aci.aci_domain_to_encap_pool: + host: apic + username: admin + password: SomeSecretPassword + domain: phys_dom + pool: test_pool + pool_type: vlan + pool_allocation_mode: dynamic + state: query + delegate_to: localhost + register: query_result + +- name: Query all domain to VLAN pool bindings + cisco.aci.aci_domain_to_encap_pool: + host: apic + username: admin + password: SomeSecretPassword + domain_type: phys + pool_type: vlan + pool_allocation_mode: dynamic + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + +VM_PROVIDER_MAPPING = dict( + cloudfoundry='CloudFoundry', + kubernetes='Kubernetes', + microsoft='Microsoft', + openshift='OpenShift', + openstack='OpenStack', + redhat='Redhat', + vmware='VMware', +) + +POOL_MAPPING = dict( + vlan=dict( + aci_mo='uni/infra/vlanns-{0}', + child_class='infraRsVlanNs', + ), + vxlan=dict( + aci_mo='uni/infra/vxlanns-{0}', + child_class='vmmRsVxlanNs', + ), + vsan=dict( + aci_mo='uni/infra/vsanns-{0}', + child_class='fcRsVsanNs', + ), +) + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + domain_type=dict(type='str', required=True, choices=['fc', 'l2dom', 'l3dom', 'phys', 'vmm']), + pool_type=dict(type='str', required=True, choices=['vlan', 'vsan', 'vxlan']), + domain=dict(type='str', aliases=['domain_name', 'domain_profile']), # Not required for querying all objects + pool=dict(type='str', aliases=['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']), + vm_provider=dict(type='str', choices=['cloudfoundry', 'kubernetes', 'microsoft', 'openshift', 'openstack', 'redhat', 'vmware']), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['domain_type', 'vmm', ['vm_provider']], + ['state', 'absent', ['domain', 'domain_type', 'pool', 'pool_type']], + ['state', 'present', ['domain', 'domain_type', 'pool', 'pool_type']], + ], + ) + + domain = module.params.get('domain') + domain_type = module.params.get('domain_type') + pool = module.params.get('pool') + pool_allocation_mode = module.params.get('pool_allocation_mode') + pool_type = module.params.get('pool_type') + vm_provider = module.params.get('vm_provider') + state = module.params.get('state') + + # Report when vm_provider is set when type is not virtual + if domain_type != 'vmm' and vm_provider is not None: + module.fail_json(msg="Domain type '{0}' cannot have a 'vm_provider'".format(domain_type)) + + # ACI Pool URL requires the allocation mode for vlan and vsan pools (ex: uni/infra/vlanns-[poolname]-static) + pool_name = pool + if pool_type != 'vxlan' and pool is not None: + if pool_allocation_mode is not None: + pool_name = '[{0}]-{1}'.format(pool, pool_allocation_mode) + else: + module.fail_json(msg="ACI requires the 'pool_allocation_mode' for 'pool_type' of 'vlan' and 'vsan' when 'pool' is provided") + + # Vxlan pools do not support allocation modes + if pool_type == 'vxlan' and pool_allocation_mode is not None: + module.fail_json(msg='vxlan pools do not support setting the allocation_mode; please remove this parameter from the task') + + # Compile the full domain for URL building + if domain_type == 'fc': + domain_class = 'fcDomP' + domain_mo = 'uni/fc-{0}'.format(domain) + domain_rn = 'fc-{0}'.format(domain) + elif domain_type == 'l2dom': + domain_class = 'l2extDomP' + domain_mo = 'uni/l2dom-{0}'.format(domain) + domain_rn = 'l2dom-{0}'.format(domain) + elif domain_type == 'l3dom': + domain_class = 'l3extDomP' + domain_mo = 'uni/l3dom-{0}'.format(domain) + domain_rn = 'l3dom-{0}'.format(domain) + elif domain_type == 'phys': + domain_class = 'physDomP' + domain_mo = 'uni/phys-{0}'.format(domain) + domain_rn = 'phys-{0}'.format(domain) + elif domain_type == 'vmm': + domain_class = 'vmmDomP' + domain_mo = 'uni/vmmp-{0}/dom-{1}'.format(VM_PROVIDER_MAPPING[vm_provider], domain) + domain_rn = 'vmmp-{0}/dom-{1}'.format(VM_PROVIDER_MAPPING[vm_provider], domain) + + # Ensure that querying all objects works when only domain_type is provided + if domain is None: + domain_mo = None + + pool_mo = POOL_MAPPING[pool_type]['aci_mo'].format(pool_name) + child_class = POOL_MAPPING[pool_type]['child_class'] + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class=domain_class, + aci_rn=domain_rn, + module_object=domain_mo, + target_filter={'name': domain}, + ), + child_classes=[child_class], + ) + + aci.get_existing() + + if state == 'present': + # Filter out module params with null values + aci.payload( + aci_class=domain_class, + class_config=dict(name=domain), + child_configs=[ + {child_class: {'attributes': {'tDn': pool_mo}}}, + ] + ) + + # Generate config diff which will be used as POST request body + aci.get_diff(aci_class=domain_class) + + # Submit changes if module not in check_mode and the proposed is different than existing + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_domain_to_vlan_pool.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_domain_to_vlan_pool.py new file mode 100644 index 00000000..0e213128 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_domain_to_vlan_pool.py @@ -0,0 +1,366 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2017, Dag Wieers <dag@wieers.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_domain_to_vlan_pool +short_description: Bind Domain to VLAN Pools (infra:RsVlanNs) +description: +- Bind Domain to VLAN Pools on Cisco ACI fabrics. +options: + domain: + description: + - Name of the domain being associated with the VLAN Pool. + type: str + aliases: [ domain_name, domain_profile ] + domain_type: + description: + - Determines if the Domain is physical (phys) or virtual (vmm). + type: str + required: yes + choices: [ fc, l2dom, l3dom, phys, vmm ] + pool: + description: + - The name of the pool. + type: str + aliases: [ pool_name, vlan_pool ] + pool_allocation_mode: + description: + - The method used for allocating VLANs to resources. + type: str + required: yes + choices: [ dynamic, static] + aliases: [ allocation_mode, mode ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + vm_provider: + description: + - The VM platform for VMM Domains. + - Support for Kubernetes was added in ACI v3.0. + - Support for CloudFoundry, OpenShift and Red Hat was added in ACI v3.1. + type: str + choices: [ cloudfoundry, kubernetes, microsoft, openshift, openstack, redhat, vmware ] +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- The C(domain) and C(vlan_pool) parameters should exist before using this module. + The M(cisco.aci.aci_domain) and M(cisco.aci.aci_vlan_pool) can be used for these. +seealso: +- module: cisco.aci.aci_domain +- module: cisco.aci.aci_vlan_pool +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(infra:RsVlanNs). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Dag Wieers (@dagwieers) +''' + +EXAMPLES = r''' +- name: Bind a VMM domain to VLAN pool + cisco.aci.aci_domain_to_vlan_pool: + host: apic + username: admin + password: SomeSecretPassword + domain: vmw_dom + domain_type: vmm + pool: vmw_pool + pool_allocation_mode: dynamic + vm_provider: vmware + state: present + delegate_to: localhost + +- name: Remove a VMM domain to VLAN pool binding + cisco.aci.aci_domain_to_vlan_pool: + host: apic + username: admin + password: SomeSecretPassword + domain: vmw_dom + domain_type: vmm + pool: vmw_pool + pool_allocation_mode: dynamic + vm_provider: vmware + state: absent + delegate_to: localhost + +- name: Bind a physical domain to VLAN pool + cisco.aci.aci_domain_to_vlan_pool: + host: apic + username: admin + password: SomeSecretPassword + domain: phys_dom + domain_type: phys + pool: phys_pool + pool_allocation_mode: static + state: present + delegate_to: localhost + +- name: Bind a physical domain to VLAN pool + cisco.aci.aci_domain_to_vlan_pool: + host: apic + username: admin + password: SomeSecretPassword + domain: phys_dom + domain_type: phys + pool: phys_pool + pool_allocation_mode: static + state: absent + delegate_to: localhost + +- name: Query an domain to VLAN pool binding + cisco.aci.aci_domain_to_vlan_pool: + host: apic + username: admin + password: SomeSecretPassword + domain: phys_dom + domain_type: phys + pool: phys_pool + pool_allocation_mode: static + state: query + delegate_to: localhost + register: query_result + +- name: Query all domain to VLAN pool bindings + cisco.aci.aci_domain_to_vlan_pool: + host: apic + username: admin + password: SomeSecretPassword + domain_type: phys + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + +VM_PROVIDER_MAPPING = dict( + cloudfoundry='CloudFoundry', + kubernetes='Kubernetes', + microsoft='Microsoft', + openshift='OpenShift', + openstack='OpenStack', + redhat='Redhat', + vmware='VMware', +) + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + domain_type=dict(type='str', required=True, choices=['fc', 'l2dom', 'l3dom', 'phys', 'vmm']), + domain=dict(type='str', aliases=['domain_name', 'domain_profile']), # Not required for querying all objects + pool=dict(type='str', aliases=['pool_name', 'vlan_pool']), # Not required for querying all objects + pool_allocation_mode=dict(type='str', required=True, aliases=['allocation_mode', 'mode'], choices=['dynamic', 'static']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + vm_provider=dict(type='str', choices=['cloudfoundry', 'kubernetes', 'microsoft', 'openshift', 'openstack', 'redhat', 'vmware']), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['domain_type', 'vmm', ['vm_provider']], + ['state', 'absent', ['domain', 'domain_type', 'pool']], + ['state', 'present', ['domain', 'domain_type', 'pool']], + ], + ) + + domain = module.params.get('domain') + domain_type = module.params.get('domain_type') + pool = module.params.get('pool') + pool_allocation_mode = module.params.get('pool_allocation_mode') + vm_provider = module.params.get('vm_provider') + state = module.params.get('state') + + # Report when vm_provider is set when type is not virtual + if domain_type != 'vmm' and vm_provider is not None: + module.fail_json(msg="Domain type '{0}' cannot have a 'vm_provider'".format(domain_type)) + + # ACI Pool URL requires the allocation mode for vlan and vsan pools (ex: uni/infra/vlanns-[poolname]-static) + pool_name = pool + if pool is not None: + pool_name = '[{0}]-{1}'.format(pool, pool_allocation_mode) + + # Compile the full domain for URL building + if domain_type == 'fc': + domain_class = 'fcDomP' + domain_mo = 'uni/fc-{0}'.format(domain) + domain_rn = 'fc-{0}'.format(domain) + elif domain_type == 'l2dom': + domain_class = 'l2extDomP' + domain_mo = 'uni/l2dom-{0}'.format(domain) + domain_rn = 'l2dom-{0}'.format(domain) + elif domain_type == 'l3dom': + domain_class = 'l3extDomP' + domain_mo = 'uni/l3dom-{0}'.format(domain) + domain_rn = 'l3dom-{0}'.format(domain) + elif domain_type == 'phys': + domain_class = 'physDomP' + domain_mo = 'uni/phys-{0}'.format(domain) + domain_rn = 'phys-{0}'.format(domain) + elif domain_type == 'vmm': + domain_class = 'vmmDomP' + domain_mo = 'uni/vmmp-{0}/dom-{1}'.format(VM_PROVIDER_MAPPING[vm_provider], domain) + domain_rn = 'vmmp-{0}/dom-{1}'.format(VM_PROVIDER_MAPPING[vm_provider], domain) + + # Ensure that querying all objects works when only domain_type is provided + if domain is None: + domain_mo = None + + aci_mo = 'uni/infra/vlanns-{0}'.format(pool_name) + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class=domain_class, + aci_rn=domain_rn, + module_object=domain_mo, + target_filter={'name': domain}, + ), + child_classes=['infraRsVlanNs'], + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class=domain_class, + class_config=dict(name=domain), + child_configs=[ + {'infraRsVlanNs': {'attributes': {'tDn': aci_mo}}}, + ] + ) + + aci.get_diff(aci_class=domain_class) + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_encap_pool.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_encap_pool.py new file mode 100644 index 00000000..f35b9342 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_encap_pool.py @@ -0,0 +1,316 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_encap_pool +short_description: Manage encap pools (fvns:VlanInstP, fvns:VxlanInstP, fvns:VsanInstP) +description: +- Manage vlan, vxlan, and vsan pools on Cisco ACI fabrics. +options: + description: + description: + - Description for the C(pool). + type: str + aliases: [ descr ] + pool: + description: + - The name of the pool. + type: str + aliases: [ name, pool_name ] + pool_allocation_mode: + description: + - The method used for allocating encaps to resources. + - Only vlan and vsan support allocation modes. + type: str + choices: [ dynamic, static ] + aliases: [ allocation_mode, mode ] + pool_type: + description: + - The encap type of C(pool). + type: str + required: yes + aliases: [ type ] + choices: [ vlan, vsan, vxlan ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +seealso: +- module: cisco.aci.aci_encap_pool_range +- module: cisco.aci.aci_vlan_pool +- name: APIC Management Information Model reference + description: More information about the internal APIC classes B(fvns:VlanInstP), + B(fvns:VxlanInstP) and B(fvns:VsanInstP) + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Jacob McGill (@jmcgill298) +''' + +EXAMPLES = r''' +- name: Add a new vlan pool + cisco.aci.aci_encap_pool: + host: apic + username: admin + password: SomeSecretPassword + pool: production + pool_type: vlan + description: Production VLANs + state: present + delegate_to: localhost + +- name: Remove a vlan pool + cisco.aci.aci_encap_pool: + host: apic + username: admin + password: SomeSecretPassword + pool: production + pool_type: vlan + state: absent + delegate_to: localhost + +- name: Query a vlan pool + cisco.aci.aci_encap_pool: + host: apic + username: admin + password: SomeSecretPassword + pool: production + pool_type: vlan + state: query + delegate_to: localhost + register: query_result + +- name: Query all vlan pools + cisco.aci.aci_encap_pool: + host: apic + username: admin + password: SomeSecretPassword + pool_type: vlan + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + +ACI_POOL_MAPPING = dict( + vlan=dict( + aci_class='fvnsVlanInstP', + aci_mo='infra/vlanns-', + ), + vxlan=dict( + aci_class='fvnsVxlanInstP', + aci_mo='infra/vxlanns-', + ), + vsan=dict( + aci_class='fvnsVsanInstP', + aci_mo='infra/vsanns-', + ), +) + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + pool_type=dict(type='str', required=True, aliases=['type'], choices=['vlan', 'vsan', 'vxlan']), + description=dict(type='str', aliases=['descr']), + pool=dict(type='str', aliases=['name', 'pool_name']), # Not required for querying all objects + pool_allocation_mode=dict(type='str', aliases=['allocation_mode', 'mode'], choices=['dynamic', 'static']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['pool']], + ['state', 'present', ['pool']], + ], + ) + + description = module.params.get('description') + pool = module.params.get('pool') + pool_type = module.params.get('pool_type') + pool_allocation_mode = module.params.get('pool_allocation_mode') + state = module.params.get('state') + name_alias = module.params.get('name_alias') + + aci_class = ACI_POOL_MAPPING[pool_type]['aci_class'] + aci_mo = ACI_POOL_MAPPING[pool_type]['aci_mo'] + pool_name = pool + + # ACI Pool URL requires the pool_allocation mode for vlan and vsan pools (ex: uni/infra/vlanns-[poolname]-static) + if pool_type != 'vxlan' and pool is not None: + if pool_allocation_mode is not None: + pool_name = '[{0}]-{1}'.format(pool, pool_allocation_mode) + else: + module.fail_json(msg="ACI requires parameter 'pool_allocation_mode' for 'pool_type' of 'vlan' and 'vsan' when parameter 'pool' is provided") + + # Vxlan pools do not support pool allocation modes + if pool_type == 'vxlan' and pool_allocation_mode is not None: + module.fail_json(msg="vxlan pools do not support setting the 'pool_allocation_mode'; please remove this parameter from the task") + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class=aci_class, + aci_rn='{0}{1}'.format(aci_mo, pool_name), + module_object=pool, + target_filter={'name': pool}, + ), + ) + + aci.get_existing() + + if state == 'present': + # Filter out module parameters with null values + aci.payload( + aci_class=aci_class, + class_config=dict( + allocMode=pool_allocation_mode, + descr=description, + name=pool, + nameAlias=name_alias, + ) + ) + + # Generate config diff which will be used as POST request body + aci.get_diff(aci_class=aci_class) + + # Submit changes if module not in check_mode and the proposed is different than existing + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_encap_pool_range.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_encap_pool_range.py new file mode 100644 index 00000000..8e24fadc --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_encap_pool_range.py @@ -0,0 +1,449 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_encap_pool_range +short_description: Manage encap ranges assigned to pools (fvns:EncapBlk, fvns:VsanEncapBlk) +description: +- Manage vlan, vxlan, and vsan ranges that are assigned to pools on Cisco ACI fabrics. +options: + allocation_mode: + description: + - The method used for allocating encaps to resources. + - Only vlan and vsan support allocation modes. + type: str + choices: [ dynamic, inherit, static] + aliases: [ mode ] + description: + description: + - Description for the pool range. + type: str + aliases: [ descr ] + pool: + description: + - The name of the pool that the range should be assigned to. + type: str + aliases: [ pool_name ] + pool_allocation_mode: + description: + - The method used for allocating encaps to resources. + - Only vlan and vsan support allocation modes. + type: str + choices: [ dynamic, static] + aliases: [ pool_mode ] + pool_type: + description: + - The encap type of C(pool). + type: str + required: yes + aliases: [ type ] + choices: [ vlan, vxlan, vsan] + range_end: + description: + - The end of encap range. + type: int + aliases: [ end ] + range_name: + description: + - The name to give to the encap range. + type: str + aliases: [ name, range ] + range_start: + description: + - The start of the encap range. + type: int + aliases: [ start ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- The C(pool) must exist in order to add or delete a range. +seealso: +- module: cisco.aci.aci_encap_pool +- module: cisco.aci.aci_vlan_pool_encap_block +- name: APIC Management Information Model reference + description: More information about the internal APIC classes B(fvns:EncapBlk) and B(fvns:VsanEncapBlk). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Jacob McGill (@jmcgill298) +''' + +EXAMPLES = r''' +- name: Add a new VLAN pool range + cisco.aci.aci_encap_pool_range: + host: apic + username: admin + password: SomeSecretPassword + pool: production + pool_type: vlan + pool_allocation_mode: static + range_name: anstest + range_start: 20 + range_end: 40 + allocation_mode: inherit + state: present + delegate_to: localhost + +- name: Remove a VLAN pool range + cisco.aci.aci_encap_pool_range: + host: apic + username: admin + password: SomeSecretPassword + pool: production + pool_type: vlan + pool_allocation_mode: static + range_name: anstest + range_start: 20 + range_end: 40 + state: absent + delegate_to: localhost + +- name: Query a VLAN range + cisco.aci.aci_encap_pool_range: + host: apic + username: admin + password: SomeSecretPassword + pool: production + pool_type: vlan + pool_allocation_mode: static + range_name: anstest + range_start: 20 + range_end: 50 + state: query + delegate_to: localhost + register: query_result + +- name: Query a VLAN pool for ranges by range_name + cisco.aci.aci_encap_pool_range: + host: apic + username: admin + password: SomeSecretPassword + pool_type: vlan + range_name: anstest + state: query + delegate_to: localhost + register: query_result + +- name: Query a VLAN pool for ranges by range_start + cisco.aci.aci_encap_pool_range: + host: apic + username: admin + password: SomeSecretPassword + pool_type: vlan + range_start: 20 + state: query + delegate_to: localhost + register: query_result + +- name: Query a VLAN pool for ranges by range_start and range_end + cisco.aci.aci_encap_pool_range: + host: apic + username: admin + password: SomeSecretPassword + pool_type: vlan + range_start: 20 + range_end: 40 + state: query + delegate_to: localhost + register: query_result + +- name: Query all VLAN pool ranges + cisco.aci.aci_encap_pool_range: + host: apic + username: admin + password: SomeSecretPassword + pool_type: vlan + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + +ACI_POOL_MAPPING = dict( + vlan=dict( + aci_class='fvnsVlanInstP', + aci_mo='infra/vlanns-', + ), + vxlan=dict( + aci_class='fvnsVxlanInstP', + aci_mo='infra/vxlanns-', + ), + vsan=dict( + aci_class='fvnsVsanInstP', + aci_mo='infra/vsanns-', + ), +) + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + pool_type=dict(type='str', required=True, aliases=['type'], choices=['vlan', 'vxlan', 'vsan']), + allocation_mode=dict(type='str', aliases=['mode'], choices=['dynamic', 'inherit', 'static']), + description=dict(type='str', aliases=['descr']), + pool=dict(type='str', aliases=['pool_name']), # Not required for querying all objects + pool_allocation_mode=dict(type='str', aliases=['pool_mode'], choices=['dynamic', 'static']), + 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']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['pool', 'range_end', 'range_name', 'range_start']], + ['state', 'present', ['pool', 'range_end', 'range_name', 'range_start']], + ], + ) + + allocation_mode = module.params.get('allocation_mode') + description = module.params.get('description') + pool = module.params.get('pool') + pool_allocation_mode = module.params.get('pool_allocation_mode') + pool_type = module.params.get('pool_type') + range_end = module.params.get('range_end') + range_name = module.params.get('range_name') + range_start = module.params.get('range_start') + state = module.params.get('state') + name_alias = module.params.get('name_alias') + + if range_end is not None: + encap_end = '{0}-{1}'.format(pool_type, range_end) + else: + encap_end = None + + if range_start is not None: + encap_start = '{0}-{1}'.format(pool_type, range_start) + else: + encap_start = None + + ACI_RANGE_MAPPING = dict( + vlan=dict( + aci_class='fvnsEncapBlk', + aci_mo='from-[{0}]-to-[{1}]'.format(encap_start, encap_end), + ), + vxlan=dict( + aci_class='fvnsEncapBlk', + aci_mo='from-[{0}]-to-[{1}]'.format(encap_start, encap_end), + ), + vsan=dict( + aci_class='fvnsVsanEncapBlk', + aci_mo='vsanfrom-[{0}]-to-[{1}]'.format(encap_start, encap_end), + ), + ) + + # Collect proper class and mo information based on pool_type + aci_range_class = ACI_RANGE_MAPPING[pool_type]["aci_class"] + aci_range_mo = ACI_RANGE_MAPPING[pool_type]["aci_mo"] + aci_pool_class = ACI_POOL_MAPPING[pool_type]["aci_class"] + aci_pool_mo = ACI_POOL_MAPPING[pool_type]["aci_mo"] + pool_name = pool + + # Validate range_end and range_start are valid for its respective encap type + for encap_id in range_end, range_start: + if encap_id is not None: + if pool_type == 'vlan': + if not 1 <= encap_id <= 4094: + module.fail_json(msg='vlan pools must have "range_start" and "range_end" values between 1 and 4094') + elif pool_type == 'vxlan': + if not 5000 <= encap_id <= 16777215: + module.fail_json(msg='vxlan pools must have "range_start" and "range_end" values between 5000 and 16777215') + elif pool_type == 'vsan': + if not 1 <= encap_id <= 4093: + module.fail_json(msg='vsan pools must have "range_start" and "range_end" values between 1 and 4093') + + if range_end is not None and range_start is not None: + # Validate range_start is less than range_end + if range_start > range_end: + module.fail_json(msg='The "range_start" must be less than or equal to the "range_end"') + + elif range_end is None and range_start is None: + if range_name is None: + # Reset range managed object to None for aci util to properly handle query + aci_range_mo = None + + # Vxlan does not support setting the allocation mode + if pool_type == 'vxlan' and allocation_mode is not None: + module.fail_json(msg='vxlan pools do not support setting the "allocation_mode"; please omit this parameter for vxlan pools') + + # ACI Pool URL requires the allocation mode for vlan and vsan pools (ex: uni/infra/vlanns-[poolname]-static) + if pool_type != 'vxlan' and pool is not None: + if pool_allocation_mode is not None: + pool_name = '[{0}]-{1}'.format(pool, pool_allocation_mode) + else: + module.fail_json(msg='ACI requires the "pool_allocation_mode" for "pool_type" of "vlan" and "vsan" when the "pool" is provided') + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class=aci_pool_class, + aci_rn='{0}{1}'.format(aci_pool_mo, pool_name), + module_object=pool, + target_filter={'name': pool}, + ), + subclass_1=dict( + aci_class=aci_range_class, + aci_rn='{0}'.format(aci_range_mo), + module_object=aci_range_mo, + target_filter={'from': encap_start, 'to': encap_end, 'name': range_name}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class=aci_range_class, + class_config={ + "allocMode": allocation_mode, + "descr": description, + "from": encap_start, + "name": range_name, + "to": encap_end, + "nameAlias": name_alias, + }, + ) + + aci.get_diff(aci_class=aci_range_class) + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_epg.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_epg.py new file mode 100644 index 00000000..986206a8 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_epg.py @@ -0,0 +1,398 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_epg +short_description: Manage End Point Groups (EPG) objects (fv:AEPg) +description: +- Manage End Point Groups (EPG) on Cisco ACI fabrics. +options: + tenant: + description: + - Name of an existing tenant. + type: str + aliases: [ tenant_name ] + ap: + description: + - Name of an existing application network profile, that will contain the EPGs. + type: str + aliases: [ app_profile, app_profile_name ] + epg: + description: + - Name of the end point group. + type: str + aliases: [ epg_name, name ] + bd: + description: + - Name of the bridge domain being associated with the EPG. + type: str + aliases: [ bd_name, bridge_domain ] + priority: + description: + - The QoS class. + - The APIC defaults to C(unspecified) when unset during creation. + type: str + choices: [ level1, level2, level3, unspecified ] + intra_epg_isolation: + description: + - The Intra EPG Isolation. + - The APIC defaults to C(unenforced) when unset during creation. + type: str + choices: [ enforced, unenforced ] + description: + description: + - Description for the EPG. + type: str + aliases: [ descr ] + fwd_control: + description: + - The forwarding control used by the EPG. + - The APIC defaults to C(none) when unset during creation. + type: str + choices: [ none, proxy-arp ] + preferred_group: + description: + - Whether ot not the EPG is part of the Preferred Group and can communicate without contracts. + - This is very convenient for migration scenarios, or when ACI is used for network automation but not for policy. + - The APIC defaults to C(no) when unset during creation. + type: bool + monitoring_policy: + description: + - The name of the monitoring policy. + type: str + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- The C(tenant) and C(app_profile) used must exist before using this module in your playbook. + The M(cisco.aci.aci_tenant) and M(cisco.aci.aci_ap) modules can be used for this. +seealso: +- module: cisco.aci.aci_tenant +- module: cisco.aci.aci_ap +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(fv:AEPg). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Swetha Chunduri (@schunduri) +- Shreyas Srish (@shrsr) +''' + +EXAMPLES = r''' +- name: Add a new EPG + cisco.aci.aci_epg: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + ap: intranet + epg: web_epg + description: Web Intranet EPG + bd: prod_bd + monitoring_policy: default + preferred_group: yes + state: present + delegate_to: localhost + +- aci_epg: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + ap: ticketing + epg: "{{ item.epg }}" + description: Ticketing EPG + bd: "{{ item.bd }}" + priority: unspecified + intra_epg_isolation: unenforced + state: present + delegate_to: localhost + with_items: + - epg: web + bd: web_bd + - epg: database + bd: database_bd + +- name: Remove an EPG + cisco.aci.aci_epg: + host: apic + username: admin + password: SomeSecretPassword + validate_certs: no + tenant: production + app_profile: intranet + epg: web_epg + monitoring_policy: default + state: absent + delegate_to: localhost + +- name: Query an EPG + cisco.aci.aci_epg: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + ap: ticketing + epg: web_epg + state: query + delegate_to: localhost + register: query_result + +- name: Query all EPGs + cisco.aci.aci_epg: + host: apic + username: admin + password: SomeSecretPassword + state: query + delegate_to: localhost + register: query_result + +- name: Query all EPGs with a Specific Name + cisco.aci.aci_epg: + host: apic + username: admin + password: SomeSecretPassword + validate_certs: no + epg: web_epg + state: query + delegate_to: localhost + register: query_result + +- name: Query all EPGs of an App Profile + cisco.aci.aci_epg: + host: apic + username: admin + password: SomeSecretPassword + validate_certs: no + ap: ticketing + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + epg=dict(type='str', aliases=['epg_name', 'name']), # Not required for querying all objects + bd=dict(type='str', aliases=['bd_name', 'bridge_domain']), + ap=dict(type='str', aliases=['app_profile', 'app_profile_name']), # Not required for querying all objects + tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects + description=dict(type='str', aliases=['descr']), + priority=dict(type='str', choices=['level1', 'level2', 'level3', 'unspecified']), + intra_epg_isolation=dict(choices=['enforced', 'unenforced']), + fwd_control=dict(type='str', choices=['none', 'proxy-arp']), + preferred_group=dict(type='bool'), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + monitoring_policy=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['ap', 'epg', 'tenant']], + ['state', 'present', ['ap', 'epg', 'tenant']], + ], + ) + + aci = ACIModule(module) + + epg = module.params.get('epg') + bd = module.params.get('bd') + description = module.params.get('description') + priority = module.params.get('priority') + intra_epg_isolation = module.params.get('intra_epg_isolation') + fwd_control = module.params.get('fwd_control') + preferred_group = aci.boolean(module.params.get('preferred_group'), 'include', 'exclude') + state = module.params.get('state') + tenant = module.params.get('tenant') + ap = module.params.get('ap') + name_alias = module.params.get('name_alias') + monitoring_policy = module.params.get('monitoring_policy') + + child_configs = [ + dict(fvRsBd=dict(attributes=dict(tnFvBDName=bd))), + dict(fvRsAEPgMonPol=dict(attributes=dict(tnMonEPGPolName=monitoring_policy))) + ] + + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + module_object=tenant, + target_filter={'name': tenant}, + ), + subclass_1=dict( + aci_class='fvAp', + aci_rn='ap-{0}'.format(ap), + module_object=ap, + target_filter={'name': ap}, + ), + subclass_2=dict( + aci_class='fvAEPg', + aci_rn='epg-{0}'.format(epg), + module_object=epg, + target_filter={'name': epg}, + ), + child_classes=['fvRsBd', 'fvRsAEPgMonPol'], + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='fvAEPg', + class_config=dict( + name=epg, + descr=description, + prio=priority, + pcEnfPref=intra_epg_isolation, + fwdCtrl=fwd_control, + prefGrMemb=preferred_group, + nameAlias=name_alias, + ), + child_configs=child_configs, + ) + + aci.get_diff(aci_class='fvAEPg') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_epg_monitoring_policy.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_epg_monitoring_policy.py new file mode 100644 index 00000000..aaef8e37 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_epg_monitoring_policy.py @@ -0,0 +1,246 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_epg_monitoring_policy +short_description: Manage monitoring policies (mon:EPGPol) +description: +- Manage monitoring policies on Cisco ACI fabrics. +options: + monitoring_policy: + description: + - The name of the monitoring policy. + type: str + aliases: [ name ] + description: + description: + - Description for the monitoring policy. + type: str + aliases: [ descr ] + tenant: + description: + - The name of the tenant. + type: str + aliases: [ tenant_name ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- The C(tenant) used must exist before using this module in your playbook. + The M(cisco.aci.aci_tenant) module can be used for this. +seealso: +- module: cisco.aci.aci_tenant +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(mon:EPGPol). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Dag Wieers (@dagwieers) +''' + +# FIXME: Add more, better examples +EXAMPLES = r''' +- cisco.aci.aci_epg_monitoring_policy: + host: '{{ hostname }}' + username: '{{ username }}' + password: '{{ password }}' + monitoring_policy: '{{ monitoring_policy }}' + description: '{{ description }}' + tenant: '{{ tenant }}' + delegate_to: localhost +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + monitoring_policy=dict(type='str', aliases=['name']), # Not required for querying all objects + tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects + description=dict(type='str', aliases=['descr']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['monitoring_policy', 'tenant']], + ['state', 'present', ['monitoring_policy', 'tenant']], + ], + ) + + monitoring_policy = module.params.get('monitoring_policy') + description = module.params.get('description') + state = module.params.get('state') + tenant = module.params.get('tenant') + name_alias = module.params.get('name_alias') + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + module_object=tenant, + target_filter={'name': tenant}, + ), + subclass_1=dict( + aci_class='monEPGPol', + aci_rn='monepg-{0}'.format(monitoring_policy), + module_object=monitoring_policy, + target_filter={'name': monitoring_policy}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='monEPGPol', + class_config=dict( + name=monitoring_policy, + descr=description, + nameAlias=name_alias, + ), + ) + + aci.get_diff(aci_class='monEPGPol') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_epg_to_contract.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_epg_to_contract.py new file mode 100644 index 00000000..45be2dd1 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_epg_to_contract.py @@ -0,0 +1,351 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_epg_to_contract +short_description: Bind EPGs to Contracts (fv:RsCons, 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(cisco.aci.aci_tenant), M(cisco.aci.aci_ap), M(cisco.aci.aci_epg), and M(cisco.aci.aci_contract) modules can be used for this. +options: + ap: + description: + - Name of an existing application network profile, that will contain the EPGs. + type: str + aliases: [ app_profile, app_profile_name ] + contract: + description: + - The name of the contract. + type: str + aliases: [ contract_name ] + contract_type: + description: + - Determines if the EPG should Provide or Consume the Contract. + type: str + required: yes + choices: [ consumer, provider ] + epg: + description: + - The name of the end point group. + type: str + aliases: [ epg_name ] + priority: + description: + - QoS class. + - The APIC defaults to C(unspecified) when unset during creation. + type: str + choices: [ level1, level2, level3, unspecified ] + provider_match: + description: + - The matching algorithm for Provided Contracts. + - The APIC defaults to C(at_least_one) when unset during creation. + type: str + choices: [ all, at_least_one, at_most_one, none ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + tenant: + description: + - Name of an existing tenant. + type: str + aliases: [ tenant_name ] +extends_documentation_fragment: +- cisco.aci.aci + +seealso: +- module: cisco.aci.aci_ap +- module: cisco.aci.aci_epg +- module: cisco.aci.aci_contract +- name: APIC Management Information Model reference + description: More information about the internal APIC classes B(fv:RsCons) and B(fv:RsProv). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Jacob McGill (@jmcgill298) +''' + +EXAMPLES = r''' +- name: Add a new contract to EPG binding + cisco.aci.aci_epg_to_contract: + host: apic + username: admin + password: SomeSecretPassword + tenant: anstest + ap: anstest + epg: anstest + contract: anstest_http + contract_type: provider + state: present + delegate_to: localhost + +- name: Remove an existing contract to EPG binding + cisco.aci.aci_epg_to_contract: + host: apic + username: admin + password: SomeSecretPassword + tenant: anstest + ap: anstest + epg: anstest + contract: anstest_http + contract_type: provider + state: absent + delegate_to: localhost + +- name: Query a specific contract to EPG binding + cisco.aci.aci_epg_to_contract: + host: apic + username: admin + password: SomeSecretPassword + tenant: anstest + ap: anstest + epg: anstest + contract: anstest_http + contract_type: provider + state: query + delegate_to: localhost + register: query_result + +- name: Query all provider contract to EPG bindings + cisco.aci.aci_epg_to_contract: + host: apic + username: admin + password: SomeSecretPassword + contract_type: provider + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + +ACI_CLASS_MAPPING = dict( + consumer={ + 'class': 'fvRsCons', + 'rn': 'rscons-', + }, + provider={ + 'class': 'fvRsProv', + 'rn': 'rsprov-', + }, +) + +PROVIDER_MATCH_MAPPING = dict( + all='All', + at_least_one='AtleastOne', + at_most_one='AtmostOne', + none='None', +) + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + contract_type=dict(type='str', required=True, choices=['consumer', 'provider']), + 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 + 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']), # Not required for querying all objects + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['ap', 'contract', 'epg', 'tenant']], + ['state', 'present', ['ap', 'contract', 'epg', 'tenant']], + ], + ) + + ap = module.params.get('ap') + contract = module.params.get('contract') + contract_type = module.params.get('contract_type') + epg = module.params.get('epg') + priority = module.params.get('priority') + provider_match = module.params.get('provider_match') + if provider_match is not None: + provider_match = PROVIDER_MATCH_MAPPING[provider_match] + state = module.params.get('state') + tenant = module.params.get('tenant') + + aci_class = ACI_CLASS_MAPPING[contract_type]["class"] + aci_rn = ACI_CLASS_MAPPING[contract_type]["rn"] + + if contract_type == "consumer" and provider_match is not None: + module.fail_json(msg="the 'provider_match' is only configurable for Provided Contracts") + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + module_object=tenant, + target_filter={'name': tenant}, + ), + subclass_1=dict( + aci_class='fvAp', + aci_rn='ap-{0}'.format(ap), + module_object=ap, + target_filter={'name': ap}, + ), + subclass_2=dict( + aci_class='fvAEPg', + aci_rn='epg-{0}'.format(epg), + module_object=epg, + target_filter={'name': epg}, + ), + subclass_3=dict( + aci_class=aci_class, + aci_rn='{0}{1}'.format(aci_rn, contract), + module_object=contract, + target_filter={'tnVzBrCPName': contract}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class=aci_class, + class_config=dict( + matchT=provider_match, + prio=priority, + tnVzBrCPName=contract, + ), + ) + + aci.get_diff(aci_class=aci_class) + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_epg_to_contract_master.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_epg_to_contract_master.py new file mode 100644 index 00000000..d2368f7d --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_epg_to_contract_master.py @@ -0,0 +1,302 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2020, Cindy Zhao <cizhao@cisco.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_epg_to_contract_master +short_description: Manage End Point Group (EPG) contract master relationships (fv:RsSecInherited) +description: +- Manage End Point Groups (EPG) contract master relationships on Cisco ACI fabrics. +options: + tenant: + description: + - Name of an existing tenant. + type: str + aliases: [ tenant_name ] + required: yes + ap: + description: + - Name of an existing application network profile, that will contain the EPGs. + type: str + required: yes + aliases: [ app_profile, app_profile_name ] + epg: + description: + - Name of the end point group. + type: str + required: yes + aliases: [ epg_name, name ] + contract_master_ap: + description: + - Name of the application profile where the contract master EPG is. + type: str + contract_master_epg: + description: + - Name of the end point group which serves as contract master. + type: str + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- The C(tenant) and C(app_profile) used must exist before using this module in your playbook. + The M(cisco.aci.aci_tenant) and M(cisco.aci.aci_ap) modules can be used for this. +seealso: +- module: cisco.aci.aci_epg +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(fv:AEPg). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Cindy Zhao (@cizhao) +''' + +EXAMPLES = r''' +- name: Add contract master + cisco.aci.aci_epg_to_contract_master: + host: apic_host + username: admin + password: SomeSecretPassword + tenant: anstest + ap: apName + epg: epgName + contract_master_ap: ap + contract_master_epg: epg + state: present + delegate_to: localhost + +- name: Remove contract master + cisco.aci.aci_epg_to_contract_master: + host: apic_host + username: admin + password: SomeSecretPassword + tenant: anstest + ap: apName + epg: epgName + contract_master_ap: ap + contract_master_epg: epg + state: absent + delegate_to: localhost + +- name: Query contract master + cisco.aci.aci_epg_to_contract_master: + host: apic_host + username: admin + password: SomeSecretPassword + tenant: anstest + ap: apName + epg: epgName + contract_master_ap: ap + contract_master_epg: epg + state: query + delegate_to: localhost +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + tenant=dict(type='str', aliases=['tenant_name'], required=True), + ap=dict(type='str', aliases=['app_profile', 'app_profile_name'], required=True), + epg=dict(type='str', aliases=['epg_name', 'name'], required=True), + contract_master_ap=dict(type='str'), + contract_master_epg=dict(type='str'), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['contract_master_ap', 'contract_master_epg']], + ['state', 'present', ['contract_master_ap', 'contract_master_epg']], + ], + ) + + aci = ACIModule(module) + + tenant = module.params.get('tenant') + ap = module.params.get('ap') + epg = module.params.get('epg') + contract_master_ap = module.params.get('contract_master_ap') + contract_master_epg = module.params.get('contract_master_epg') + state = module.params.get('state') + + contract_master = 'uni/tn-{0}/ap-{1}/epg-{2}'.format(tenant, contract_master_ap, contract_master_epg) + + child_configs = [] + + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + module_object=tenant, + target_filter={'name': tenant}, + ), + subclass_1=dict( + aci_class='fvAp', + aci_rn='ap-{0}'.format(ap), + module_object=ap, + target_filter={'name': ap}, + ), + subclass_2=dict( + aci_class='fvAEPg', + aci_rn='epg-{0}'.format(epg), + module_object=epg, + target_filter={'name': epg}, + ), + subclass_3=dict( + aci_class='fvRsSecInherited', + aci_rn='rssecInherited-[{0}]'.format(contract_master), + module_object=contract_master, + target_filter={'tDn': contract_master}, + ), + child_classes=[], + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='fvRsSecInherited', + class_config=dict( + tDn=contract_master + ), + child_configs=child_configs + ) + + aci.get_diff(aci_class='fvRsSecInherited') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_epg_to_domain.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_epg_to_domain.py new file mode 100644 index 00000000..d4b8ea58 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_epg_to_domain.py @@ -0,0 +1,441 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2020, Jacob McGill <jmcgill298> +# Copyright: (c) 2020, Shreyas Srish <ssrish@cisco.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_epg_to_domain +short_description: Bind EPGs to Domains (fv:RsDomAtt) +description: +- Bind EPGs to Physical and Virtual Domains on Cisco ACI fabrics. +options: + allow_useg: + description: + - Allows micro-segmentation. + - The APIC defaults to C(encap) when unset during creation. + type: str + choices: [ encap, useg ] + ap: + description: + - Name of an existing application network profile, that will contain the EPGs. + type: str + aliases: [ app_profile, app_profile_name ] + deploy_immediacy: + description: + - Determines when the policy is pushed to hardware Policy CAM. + - The APIC defaults to C(lazy) when unset during creation. + type: str + choices: [ immediate, lazy ] + domain: + description: + - Name of the physical or virtual domain being associated with the EPG. + type: str + aliases: [ domain_name, domain_profile ] + domain_type: + description: + - Specify whether the Domain is a physical (phys), a virtual (vmm) or an L2 external domain association (l2dom). + type: str + choices: [ l2dom, phys, vmm ] + aliases: [ type ] + encap: + description: + - The VLAN encapsulation for the EPG when binding a VMM Domain with static C(encap_mode). + - This acts as the secondary encap when using useg. + - Accepted values range between C(1) and C(4096). + type: int + encap_mode: + description: + - The encapsulation method to be used. + - The APIC defaults to C(auto) when unset during creation. + - If vxlan is selected, switching_mode must be "AVE". + type: str + choices: [ auto, vlan, vxlan ] + switching_mode: + description: + - Switching Mode used by the switch + type: str + choices: [ AVE, native ] + default: native + epg: + description: + - Name of the end point group. + type: str + aliases: [ epg_name, name ] + netflow: + description: + - Determines if netflow should be enabled. + - The APIC defaults to C(no) when unset during creation. + type: bool + primary_encap: + description: + - Determines the primary VLAN ID when using useg. + - Accepted values range between C(1) and C(4096). + type: int + resolution_immediacy: + description: + - Determines when the policies should be resolved and available. + - The APIC defaults to C(lazy) when unset during creation. + type: str + choices: [ immediate, lazy, pre-provision ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + tenant: + description: + - Name of an existing tenant. + type: str + aliases: [ tenant_name ] + promiscuous: + description: + - Allow/Disallow promiscuous mode in vmm domain + type: str + choices: [ accept, reject ] + default: reject + vm_provider: + description: + - The VM platform for VMM Domains. + - Support for Kubernetes was added in ACI v3.0. + - Support for CloudFoundry, OpenShift and Red Hat was added in ACI v3.1. + type: str + choices: [ cloudfoundry, kubernetes, microsoft, openshift, openstack, redhat, vmware ] +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- The C(tenant), C(ap), C(epg), and C(domain) used must exist before using this module in your playbook. + The M(cisco.aci.aci_tenant) M(cisco.aci.aci_ap), M(cisco.aci.aci_epg) M(cisco.aci.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. +seealso: +- module: cisco.aci.aci_ap +- module: cisco.aci.aci_epg +- module: cisco.aci.aci_domain +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(fv:RsDomAtt). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Jacob McGill (@jmcgill298) +- Shreyas Srish (@shrsr) +''' + +EXAMPLES = r''' +- name: Add a new physical domain to EPG binding + cisco.aci.aci_epg_to_domain: + host: apic + username: admin + password: SomeSecretPassword + tenant: anstest + ap: anstest + epg: anstest + domain: anstest + domain_type: phys + state: present + delegate_to: localhost + +- name: Remove an existing physical domain to EPG binding + cisco.aci.aci_epg_to_domain: + host: apic + username: admin + password: SomeSecretPassword + tenant: anstest + ap: anstest + epg: anstest + domain: anstest + domain_type: phys + state: absent + delegate_to: localhost + +- name: Query a specific physical domain to EPG binding + cisco.aci.aci_epg_to_domain: + host: apic + username: admin + password: SomeSecretPassword + tenant: anstest + ap: anstest + epg: anstest + domain: anstest + domain_type: phys + state: query + delegate_to: localhost + register: query_result + +- name: Query all domain to EPG bindings + cisco.aci.aci_epg_to_domain: + host: apic + username: admin + password: SomeSecretPassword + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + +VM_PROVIDER_MAPPING = dict( + cloudfoundry='CloudFoundry', + kubernetes='Kubernetes', + microsoft='Microsoft', + openshift='OpenShift', + openstack='OpenStack', + redhat='Redhat', + vmware='VMware', +) + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + allow_useg=dict(type='str', choices=['encap', 'useg']), + ap=dict(type='str', aliases=['app_profile', 'app_profile_name']), # Not required for querying all objects + deploy_immediacy=dict(type='str', choices=['immediate', 'lazy']), + domain=dict(type='str', aliases=['domain_name', 'domain_profile']), # Not required for querying all objects + domain_type=dict(type='str', choices=['l2dom', 'phys', 'vmm'], aliases=['type']), # Not required for querying all objects + encap=dict(type='int'), + encap_mode=dict(type='str', choices=['auto', 'vlan', 'vxlan']), + switching_mode=dict(type='str', default='native', choices=['AVE', 'native']), + epg=dict(type='str', aliases=['name', 'epg_name']), # Not required for querying all objects + netflow=dict(type='bool'), + primary_encap=dict(type='int'), + resolution_immediacy=dict(type='str', choices=['immediate', 'lazy', 'pre-provision']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects + vm_provider=dict(type='str', choices=['cloudfoundry', 'kubernetes', 'microsoft', 'openshift', 'openstack', 'redhat', 'vmware']), + promiscuous=dict(type='str', default='reject', choices=['accept', 'reject']), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['domain_type', 'vmm', ['vm_provider']], + ['state', 'absent', ['ap', 'domain', 'domain_type', 'epg', 'tenant']], + ['state', 'present', ['ap', 'domain', 'domain_type', 'epg', 'tenant']], + ], + ) + + aci = ACIModule(module) + + allow_useg = module.params.get('allow_useg') + ap = module.params.get('ap') + deploy_immediacy = module.params.get('deploy_immediacy') + domain = module.params.get('domain') + domain_type = module.params.get('domain_type') + vm_provider = module.params.get('vm_provider') + promiscuous = module.params.get('promiscuous') + encap = module.params.get('encap') + if encap is not None: + if encap in range(1, 4097): + encap = 'vlan-{0}'.format(encap) + else: + module.fail_json(msg='Valid VLAN assignments are from 1 to 4096') + encap_mode = module.params.get('encap_mode') + switching_mode = module.params.get('switching_mode') + epg = module.params.get('epg') + netflow = aci.boolean(module.params.get('netflow'), 'enabled', 'disabled') + primary_encap = module.params.get('primary_encap') + if primary_encap is not None: + if primary_encap in range(1, 4097): + primary_encap = 'vlan-{0}'.format(primary_encap) + else: + module.fail_json(msg='Valid VLAN assignments are from 1 to 4096') + resolution_immediacy = module.params.get('resolution_immediacy') + state = module.params.get('state') + tenant = module.params.get('tenant') + + if domain_type in ['l2dom', 'phys'] and vm_provider is not None: + module.fail_json(msg="Domain type '%s' cannot have a 'vm_provider'" % domain_type) + + child_classes = None + child_configs = None + + # Compile the full domain for URL building + if domain_type == 'vmm': + epg_domain = 'uni/vmmp-{0}/dom-{1}'.format(VM_PROVIDER_MAPPING[vm_provider], domain) + child_configs = [dict(vmmSecP=dict(attributes=dict(allowPromiscuous=promiscuous)))] + child_classes = ['vmmSecP'] + elif domain_type == 'l2dom': + epg_domain = 'uni/l2dom-{0}'.format(domain) + elif domain_type == 'phys': + epg_domain = 'uni/phys-{0}'.format(domain) + else: + epg_domain = None + + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + module_object=tenant, + target_filter={'name': tenant}, + ), + subclass_1=dict( + aci_class='fvAp', + aci_rn='ap-{0}'.format(ap), + module_object=ap, + target_filter={'name': ap}, + ), + subclass_2=dict( + aci_class='fvAEPg', + aci_rn='epg-{0}'.format(epg), + module_object=epg, + target_filter={'name': epg}, + ), + subclass_3=dict( + aci_class='fvRsDomAtt', + aci_rn='rsdomAtt-[{0}]'.format(epg_domain), + module_object=epg_domain, + target_filter={'tDn': epg_domain}, + ), + child_classes=child_classes, + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='fvRsDomAtt', + class_config=dict( + classPref=allow_useg, + encap=encap, + encapMode=encap_mode, + switchingMode=switching_mode, + instrImedcy=deploy_immediacy, + netflowPref=netflow, + primaryEncap=primary_encap, + resImedcy=resolution_immediacy, + ), + child_configs=child_configs, + ) + + aci.get_diff(aci_class='fvRsDomAtt') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_fabric_node.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_fabric_node.py new file mode 100644 index 00000000..b1ea5f91 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_fabric_node.py @@ -0,0 +1,288 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2017, Bruno Calogero <brunocalogero@hotmail.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_fabric_node +short_description: Manage Fabric Node Members (fabric:NodeIdentP) +description: +- Manage Fabric Node Members on Cisco ACI fabrics. +options: + pod_id: + description: + - The pod id of the new Fabric Node Member. + type: int + serial: + description: + - Serial Number for the new Fabric Node Member. + type: str + aliases: [ serial_number ] + node_id: + description: + - Node ID Number for the new Fabric Node Member. + type: int + switch: + description: + - Switch Name for the new Fabric Node Member. + type: str + aliases: [ name, switch_name ] + description: + description: + - Description for the new Fabric Node Member. + type: str + aliases: [ descr ] + role: + description: + - Role for the new Fabric Node Member. + type: str + aliases: [ role_name ] + choices: [ leaf, spine, unspecified ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +seealso: +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(fabric:NodeIdentP). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Bruno Calogero (@brunocalogero) +''' + +EXAMPLES = r''' +- name: Add fabric node + cisco.aci.aci_fabric_node: + host: apic + username: admin + password: SomeSecretPassword + serial: FDO2031124L + node_id: 1011 + switch: fab4-sw1011 + state: present + delegate_to: localhost + +- name: Remove fabric node + cisco.aci.aci_fabric_node: + host: apic + username: admin + password: SomeSecretPassword + serial: FDO2031124L + node_id: 1011 + state: absent + delegate_to: localhost + +- name: Query fabric nodes + cisco.aci.aci_fabric_node: + host: apic + username: admin + password: SomeSecretPassword + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: '?rsp-prop-include=config-only' +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +# NOTE: (This problem is also present on the APIC GUI) +# NOTE: When specifying a C(role) the new Fabric Node Member will be created but Role on GUI will be "unknown", hence not what seems to be a module problem + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + description=dict(type='str', aliases=['descr']), + node_id=dict(type='int'), # Not required for querying all objects + pod_id=dict(type='int'), + role=dict(type='str', choices=['leaf', 'spine', 'unspecified'], aliases=['role_name']), + serial=dict(type='str', aliases=['serial_number']), # Not required for querying all objects + switch=dict(type='str', aliases=['name', 'switch_name']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['node_id', 'serial']], + ['state', 'present', ['node_id', 'serial']], + ], + ) + + pod_id = module.params.get('pod_id') + serial = module.params.get('serial') + node_id = module.params.get('node_id') + switch = module.params.get('switch') + description = module.params.get('description') + role = module.params.get('role') + state = module.params.get('state') + name_alias = module.params.get('name_alias') + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='fabricNodeIdentP', + aci_rn='controller/nodeidentpol/nodep-{0}'.format(serial), + module_object=serial, + target_filter={'serial': serial}, + ) + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='fabricNodeIdentP', + class_config=dict( + descr=description, + name=switch, + nodeId=node_id, + podId=pod_id, + # NOTE: Originally we were sending 'rn', but now we need 'dn' for idempotency + # FIXME: Did this change with ACI version ? + dn='uni/controller/nodeidentpol/nodep-{0}'.format(serial), + # rn='nodep-{0}'.format(serial), + role=role, + serial=serial, + nameAlias=name_alias, + ) + ) + + aci.get_diff(aci_class='fabricNodeIdentP') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json(**aci.result) + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_fabric_scheduler.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_fabric_scheduler.py new file mode 100644 index 00000000..ecc91330 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_fabric_scheduler.py @@ -0,0 +1,331 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = { + 'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community' +} + +DOCUMENTATION = ''' +--- +module: aci_fabric_scheduler + +short_description: This modules creates ACI schedulers. + + +description: + - With the module you can create schedule policies that can be a shell, onetime execution or recurring + +options: + name: + description: + - The name of the Scheduler. + type: str + aliases: [ scheduler_name ] + description: + description: + - Description for the Scheduler. + type: str + aliases: [ descr ] + recurring: + description: + - If you want to make the Scheduler a recurring it would be a "True" and for a + oneTime execution it would be "False". For a shell just exclude this option from + the task + type: bool + default: 'no' + windowname: + description: + - This is the name for your what recurring or oneTime execution + type: str + concurCap: + description: + - This is the amount of devices that can be executed on at a time + type: int + maxTime: + description: + - This is the amount MAX amount of time a process can be executed + type: str + date: + description: + - This is the date and time that the scheduler will execute + type: str + hour: + description: + - This set the hour of execution + type: int + minute: + description: + - This sets the minute of execution, used in conjunction with hour + type: int + day: + description: + - This sets the day when execution will take place + type: str + default: "every-day" + choices: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday','Sunday', 'even-day', 'odd-day', 'every-day'] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + default: present + choices: [ absent, present, query ] + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + + +author: + - Steven Gerhart (@sgerhart) +''' + +EXAMPLES = r''' + - name: Simple Scheduler (Empty) + cisco.aci.aci_fabric_scheduler: + host: "{{ inventory_hostname }}" + username: "{{ user }}" + password: "{{ pass }}" + validate_certs: no + name: simpleScheduler + state: present + - name: Remove Simple Scheduler + cisco.aci.aci_fabric_scheduler: + host: "{{ inventory_hostname }}" + username: "{{ user }}" + password: "{{ pass }}" + validate_certs: no + name: simpleScheduler + state: absent + - name: One Time Scheduler + cisco.aci.aci_fabric_scheduler: + host: "{{ inventory_hostname }}" + username: "{{ user }}" + password: "{{ pass }}" + validate_certs: no + name: OneTime + windowname: OneTime + recurring: False + concurCap: 20 + date: "2018-11-20T24:00:00" + state: present + - name: Recurring Scheduler + cisco.aci.aci_fabric_scheduler: + host: "{{ inventory_hostname }}" + username: "{{ user }}" + password: "{{ pass }}" + validate_certs: no + name: Recurring + windowname: Recurring + recurring: True + concurCap: 20 + hour: 13 + minute: 30 + day: Tuesday + state: present +''' + +RETURN = ''' +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec +from ansible.module_utils.basic import AnsibleModule + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + name=dict(type='str', aliases=['scheduler_name']), # Not required for querying all objects + description=dict(type='str', aliases=['descr']), + windowname=dict(type='str'), + recurring=dict(type='bool'), + concurCap=dict(type='int'), # Number of devices it will run against concurrently + maxTime=dict(type='str'), # The amount of minutes a process will be able to run (unlimited or dd:hh:mm:ss) + date=dict(type='str'), # The date the process will run YYYY-MM-DDTHH:MM:SS + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + hour=dict(type='int'), + minute=dict(type='int'), + day=dict(type='str', default='every-day', choices=['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', + 'Saturday', 'Sunday', 'every-day', 'even-day', 'odd-day']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['name']], + ['state', 'present', ['name']], + ], + ) + + state = module.params.get('state') + name = module.params.get('name') + windowname = module.params.get('windowname') + recurring = module.params.get('recurring') + date = module.params.get('date') + hour = module.params.get('hour') + minute = module.params.get('minute') + maxTime = module.params.get('maxTime') + concurCap = module.params.get('concurCap') + day = module.params.get('day') + description = module.params.get('description') + name_alias = module.params.get('name_alias') + + if recurring: + child_configs = [dict(trigRecurrWindowP=dict(attributes=dict(name=windowname, hour=hour, minute=minute, + procCa=maxTime, concurCap=concurCap, day=day,)))] + elif recurring is False: + child_configs = [dict(trigAbsWindowP=dict(attributes=dict(name=windowname, procCap=maxTime, + concurCap=concurCap, date=date,)))] + else: + child_configs = [] + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='trigSchedP', + aci_rn='fabric/schedp-{0}'.format(name), + target_filter={'name': name}, + module_object=name, + ), + + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='trigSchedP', + class_config=dict( + name=name, + descr=description, + nameAlias=name_alias, + ), + child_configs=child_configs, + + ) + + aci.get_diff(aci_class='trigSchedP') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_filter.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_filter.py new file mode 100644 index 00000000..9b79eae9 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_filter.py @@ -0,0 +1,279 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_filter +short_description: Manages top level filter objects (vz:Filter) +description: +- Manages top level filter objects on Cisco ACI fabrics. +- This modules does not manage filter entries, see M(cisco.aci.aci_filter_entry) for this functionality. +options: + filter: + description: + - The name of the filter. + type: str + aliases: [ filter_name, name ] + description: + description: + - Description for the filter. + type: str + aliases: [ descr ] + tenant: + description: + - The name of the tenant. + type: str + aliases: [ tenant_name ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- The C(tenant) used must exist before using this module in your playbook. + The M(cisco.aci.aci_tenant) module can be used for this. +seealso: +- module: cisco.aci.aci_tenant +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(vz:Filter). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Dag Wieers (@dagwieers) +''' + +EXAMPLES = r''' +- name: Add a new filter to a tenant + cisco.aci.aci_filter: + host: apic + username: admin + password: SomeSecretPassword + filter: web_filter + description: Filter for web protocols + tenant: production + state: present + delegate_to: localhost + +- name: Remove a filter for a tenant + cisco.aci.aci_filter: + host: apic + username: admin + password: SomeSecretPassword + filter: web_filter + tenant: production + state: absent + delegate_to: localhost + +- name: Query a filter of a tenant + cisco.aci.aci_filter: + host: apic + username: admin + password: SomeSecretPassword + filter: web_filter + tenant: production + state: query + delegate_to: localhost + register: query_result + +- name: Query all filters for a tenant + cisco.aci.aci_filter: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + filter=dict(type='str', aliases=['name', 'filter_name']), # Not required for querying all objects + tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects + description=dict(type='str', aliases=['descr']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['filter', 'tenant']], + ['state', 'present', ['filter', 'tenant']], + ], + ) + + filter_name = module.params.get('filter') + description = module.params.get('description') + state = module.params.get('state') + tenant = module.params.get('tenant') + name_alias = module.params.get('name_alias') + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + module_object=tenant, + target_filter={'name': tenant}, + ), + subclass_1=dict( + aci_class='vzFilter', + aci_rn='flt-{0}'.format(filter_name), + module_object=filter_name, + target_filter={'name': filter_name}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='vzFilter', + class_config=dict( + name=filter_name, + descr=description, + nameAlias=name_alias, + ), + ) + + aci.get_diff(aci_class='vzFilter') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_filter_entry.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_filter_entry.py new file mode 100644 index 00000000..babf6d9d --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_filter_entry.py @@ -0,0 +1,376 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_filter_entry +short_description: Manage filter entries (vz:Entry) +description: +- Manage filter entries for a filter on Cisco ACI fabrics. +options: + arp_flag: + description: + - The arp flag to use when the ether_type is arp. + - The APIC defaults to C(unspecified) when unset during creation. + type: str + choices: [ arp_reply, arp_request, unspecified ] + description: + description: + - Description for the Filter Entry. + type: str + aliases: [ descr ] + dst_port: + description: + - Used to set both destination start and end ports to the same value when ip_protocol is tcp or udp. + - Accepted values are any valid TCP/UDP port range. + - The APIC defaults to C(unspecified) when unset during creation. + type: str + dst_port_end: + description: + - Used to set the destination end port when ip_protocol is tcp or udp. + - Accepted values are any valid TCP/UDP port range. + - The APIC defaults to C(unspecified) when unset during creation. + type: str + dst_port_start: + description: + - Used to set the destination start port when ip_protocol is tcp or udp. + - Accepted values are any valid TCP/UDP port range. + - The APIC defaults to C(unspecified) when unset during creation. + type: str + entry: + description: + - Then name of the Filter Entry. + type: str + aliases: [ entry_name, filter_entry, name ] + ether_type: + description: + - The Ethernet type. + - The APIC defaults to C(unspecified) when unset during creation. + type: str + choices: [ arp, fcoe, ip, mac_security, mpls_ucast, trill, unspecified ] + filter: + description: + - The name of Filter that the entry should belong to. + type: str + aliases: [ filter_name ] + icmp_msg_type: + description: + - ICMPv4 message type; used when ip_protocol is icmp. + - The APIC defaults to C(unspecified) when unset during creation. + type: str + choices: [ dst_unreachable, echo, echo_reply, src_quench, time_exceeded, unspecified ] + icmp6_msg_type: + description: + - ICMPv6 message type; used when ip_protocol is icmpv6. + - The APIC defaults to C(unspecified) when unset during creation. + type: str + choices: [ dst_unreachable, echo_request, echo_reply, neighbor_advertisement, neighbor_solicitation, redirect, time_exceeded, unspecified ] + ip_protocol: + description: + - The IP Protocol type when ether_type is ip. + - The APIC defaults to C(unspecified) when unset during creation. + type: str + choices: [ eigrp, egp, icmp, icmpv6, igmp, igp, l2tp, ospfigp, pim, tcp, udp, unspecified ] + state: + description: + - present, absent, query + type: str + default: present + choices: [ absent, present, query ] + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str + stateful: + description: + - Determines the statefulness of the filter entry. + type: bool + tenant: + description: + - The name of the tenant. + type: str + aliases: [ tenant_name ] +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- The C(tenant) and C(filter) used must exist before using this module in your playbook. + The M(cisco.aci.aci_tenant) and M(cisco.aci.aci_filter) modules can be used for this. +seealso: +- module: cisco.aci.aci_tenant +- module: cisco.aci.aci_filter +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(vz:Entry). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Jacob McGill (@jmcgill298) +''' + +# FIXME: Add more, better examples +EXAMPLES = r''' +- cisco.aci.aci_filter_entry: + host: "{{ inventory_hostname }}" + username: "{{ user }}" + password: "{{ pass }}" + state: "{{ state }}" + entry: "{{ entry }}" + tenant: "{{ tenant }}" + ether_name: "{{ ether_name }}" + icmp_msg_type: "{{ icmp_msg_type }}" + filter: "{{ filter }}" + descr: "{{ descr }}" + delegate_to: localhost +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + +VALID_ARP_FLAGS = ['arp_reply', 'arp_request', 'unspecified'] +VALID_ETHER_TYPES = ['arp', 'fcoe', 'ip', 'mac_security', 'mpls_ucast', 'trill', 'unspecified'] +VALID_ICMP_TYPES = ['dst_unreachable', 'echo', 'echo_reply', 'src_quench', 'time_exceeded', 'unspecified'] +VALID_ICMP6_TYPES = ['dst_unreachable', 'echo_request', 'echo_reply', 'neighbor_advertisement', + 'neighbor_solicitation', 'redirect', 'time_exceeded', 'unspecified'] +VALID_IP_PROTOCOLS = ['eigrp', 'egp', 'icmp', 'icmpv6', 'igmp', 'igp', 'l2tp', 'ospfigp', 'pim', 'tcp', 'udp', 'unspecified'] + +# mapping dicts are used to normalize the proposed data to what the APIC expects, which will keep diffs accurate +ARP_FLAG_MAPPING = dict(arp_reply='reply', arp_request='req', unspecified=None) +FILTER_PORT_MAPPING = {'443': 'https', '25': 'smtp', '80': 'http', '20': 'ftpData', '53': 'dns', '110': 'pop3', '554': 'rtsp'} +ICMP_MAPPING = {'dst_unreachable': 'dst-unreach', 'echo': 'echo', 'echo_reply': 'echo-rep', 'src_quench': 'src-quench', + 'time_exceeded': 'time-exceeded', 'unspecified': 'unspecified', 'echo-rep': 'echo-rep', 'dst-unreach': 'dst-unreach'} +ICMP6_MAPPING = dict(dst_unreachable='dst-unreach', echo_request='echo-req', echo_reply='echo-rep', neighbor_advertisement='nbr-advert', + neighbor_solicitation='nbr-solicit', redirect='redirect', time_exceeded='time-exceeded', unspecified='unspecified') + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + arp_flag=dict(type='str', choices=VALID_ARP_FLAGS), + description=dict(type='str', aliases=['descr']), + dst_port=dict(type='str'), + dst_port_end=dict(type='str'), + dst_port_start=dict(type='str'), + entry=dict(type='str', aliases=['entry_name', 'filter_entry', 'name']), # Not required for querying all objects + ether_type=dict(choices=VALID_ETHER_TYPES, type='str'), + filter=dict(type='str', aliases=['filter_name']), # Not required for querying all objects + icmp_msg_type=dict(type='str', choices=VALID_ICMP_TYPES), + icmp6_msg_type=dict(type='str', choices=VALID_ICMP6_TYPES), + ip_protocol=dict(choices=VALID_IP_PROTOCOLS, type='str'), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + stateful=dict(type='bool'), + tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['entry', 'filter', 'tenant']], + ['state', 'present', ['entry', 'filter', 'tenant']], + ], + ) + + aci = ACIModule(module) + + arp_flag = module.params.get('arp_flag') + if arp_flag is not None: + arp_flag = ARP_FLAG_MAPPING.get(arp_flag) + description = module.params.get('description') + dst_port = module.params.get('dst_port') + if FILTER_PORT_MAPPING.get(dst_port) is not None: + dst_port = FILTER_PORT_MAPPING.get(dst_port) + dst_end = module.params.get('dst_port_end') + if FILTER_PORT_MAPPING.get(dst_end) is not None: + dst_end = FILTER_PORT_MAPPING.get(dst_end) + dst_start = module.params.get('dst_port_start') + if FILTER_PORT_MAPPING.get(dst_start) is not None: + dst_start = FILTER_PORT_MAPPING.get(dst_start) + entry = module.params.get('entry') + ether_type = module.params.get('ether_type') + filter_name = module.params.get('filter') + icmp_msg_type = module.params.get('icmp_msg_type') + if icmp_msg_type is not None: + icmp_msg_type = ICMP_MAPPING.get(icmp_msg_type) + icmp6_msg_type = module.params.get('icmp6_msg_type') + if icmp6_msg_type is not None: + icmp6_msg_type = ICMP6_MAPPING.get(icmp6_msg_type) + ip_protocol = module.params.get('ip_protocol') + state = module.params.get('state') + stateful = aci.boolean(module.params.get('stateful')) + tenant = module.params.get('tenant') + name_alias = module.params.get('name_alias') + + # validate that dst_port is not passed with dst_start or dst_end + if dst_port is not None and (dst_end is not None or dst_start is not None): + module.fail_json(msg="Parameter 'dst_port' cannot be used with 'dst_end' and 'dst_start'") + elif dst_port is not None: + dst_end = dst_port + dst_start = dst_port + + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + module_object=tenant, + target_filter={'name': tenant}, + ), + subclass_1=dict( + aci_class='vzFilter', + aci_rn='flt-{0}'.format(filter_name), + module_object=filter_name, + target_filter={'name': filter_name}, + ), + subclass_2=dict( + aci_class='vzEntry', + aci_rn='e-{0}'.format(entry), + module_object=entry, + target_filter={'name': entry}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='vzEntry', + class_config=dict( + arpOpc=arp_flag, + descr=description, + dFromPort=dst_start, + dToPort=dst_end, + etherT=ether_type, + icmpv4T=icmp_msg_type, + icmpv6T=icmp6_msg_type, + name=entry, + prot=ip_protocol, + stateful=stateful, + nameAlias=name_alias, + ), + ) + + aci.get_diff(aci_class='vzEntry') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_firmware_group.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_firmware_group.py new file mode 100644 index 00000000..9c25c344 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_firmware_group.py @@ -0,0 +1,238 @@ +#!/usr/bin/python + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = { + 'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community' +} + +DOCUMENTATION = ''' +--- +module: aci_firmware_group + +short_description: This module creates a firmware group + + +description: + - This module creates a firmware group, so that you can apply firmware policy to nodes. +options: + group: + description: + - This the name of the firmware group + type: str + firmwarepol: + description: + - This is the name of the firmware policy, which was create by aci_firmware_policy. It is important that + - you use the same name as the policy created with aci_firmware_policy + type: str + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + default: present + choices: [ absent, present, query ] + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +author: + - Steven Gerhart (@sgerhart) +''' + +# FIXME: Add more, better examples +EXAMPLES = r''' + - name: firmware group + cisco.aci.aci_firmware_group: + host: "{{ inventory_hostname }}" + username: "{{ user }}" + password: "{{ pass }}" + validate_certs: no + group: testingfwgrp1 + firmwarepol: test2FrmPol + state: present +''' +RETURN = ''' +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec +from ansible.module_utils.basic import AnsibleModule + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + group=dict(type='str'), # Not required for querying all objects + firmwarepol=dict(type='str'), # Not required for querying all objects + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['group']], + ['state', 'present', ['group', 'firmwarepol']], + ], + ) + + state = module.params.get('state') + group = module.params.get('group') + firmwarepol = module.params.get('firmwarepol') + name_alias = module.params.get('name_alias') + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='firmwareFwGrp', + aci_rn='fabric/fwgrp-{0}'.format(group), + target_filter={'name': group}, + module_object=group, + ), + child_classes=['firmwareRsFwgrpp'], + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='firmwareFwGrp', + class_config=dict( + name=group, + nameAlias=name_alias, + ), + child_configs=[ + dict( + firmwareRsFwgrpp=dict( + attributes=dict( + tnFirmwareFwPName=firmwarepol, + ), + ), + ), + ], + + ) + + aci.get_diff(aci_class='firmwareFwGrp') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_firmware_group_node.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_firmware_group_node.py new file mode 100644 index 00000000..79a03fd7 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_firmware_group_node.py @@ -0,0 +1,248 @@ +#!/usr/bin/python + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +ANSIBLE_METADATA = { + 'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community' +} + +DOCUMENTATION = ''' +--- +module: aci_firmware_group_node + +short_description: This modules adds and remove nodes from the firmware group + + +description: + - This module addes/deletes a node to the firmware group. This modules assigns 1 node at a time. + +options: + group: + description: + - This is the name of the firmware group + type: str + node: + description: + - The node to be added to the firmware group - the value equals the NodeID + type: str + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + default: present + choices: [ absent, present, query ] + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + + +author: + - Steven Gerhart (@sgerhart) +''' + +EXAMPLES = r''' + - name: add firmware group node + cisco.aci.aci_firmware_group_node: + host: "{{ inventory_hostname }}" + username: "{{ user }}" + password: "{{ pass }}" + validate_certs: no + group: testingfwgrp + node: 1001 + state: present + - name: Remove firmware group node + cisco.aci.aci_firmware_group_node: + host: "{{ inventory_hostname }}" + username: "{{ user }}" + password: "{{ pass }}" + validate_certs: no + group: testingfwgrp + node: 1001 + state: absent +''' + +RETURN = ''' +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec +from ansible.module_utils.basic import AnsibleModule + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + group=dict(type='str'), # Not required for querying all objects + node=dict(type='str'), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['node', 'group']], + ['state', 'present', ['node', 'group']], + ], + ) + + state = module.params.get('state') + group = module.params.get('group') + node = module.params.get('node') + name_alias = module.params.get('name_alias') + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='firmwareFwGrp', + aci_rn='fabric/fwgrp-{0}'.format(group), + target_filter={'name': group}, + module_object=group, + ), + subclass_1=dict( + aci_class='fabricNodeBlk', + aci_rn='nodeblk-blk{0}-{0}'.format(node), + target_filter={'name': node}, + module_object=node, + ), + + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='fabricNodeBlk', + class_config=dict( + from_=node, + to_=node, + nameAlias=name_alias, + ), + + + ) + + aci.get_diff(aci_class='fabricNodeBlk') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_firmware_policy.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_firmware_policy.py new file mode 100644 index 00000000..5c466ddc --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_firmware_policy.py @@ -0,0 +1,253 @@ +#!/usr/bin/python + + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +ANSIBLE_METADATA = { + 'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community' +} + +DOCUMENTATION = ''' +--- +module: aci_firmware_policy + +short_description: This creates a firmware policy + + +description: + - This module creates a firmware policy for firmware groups. The firmware policy is create first and then + - referenced by the firmware group. You will assign the firmware and specify if you want to ignore the compatibility + - check +options: + name: + description: + - Name of the firmware policy + type: str + version: + description: + - The version of the firmware associated with this policy. This value is very import as well as constructing + - it correctly. The syntax for this field is n9000-xx.x. If you look at the firmware repository using the UI + - each version will have a "Full Version" column, this is the value you need to use. So, if the Full Version + - is 13.1(1i), the value for this field would be n9000-13.1(1i) + type: str + ignoreCompat: + description: + - Check if compatibility checks should be ignored + type: bool + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [absent, present, query] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + + +author: + - Steven Gerhart (@sgerhart) +''' + +# FIXME: Add more, better examples +EXAMPLES = r''' + - name: firmware policy + cisco.aci.aci_firmware_policy: + host: "{{ inventory_hostname }}" + username: "{{ user }}" + password: "{{ pass }}" + validate_certs: no + name: test2FrmPol + version: n9000-13.2(1m) + ignoreCompat: False + state: present + +''' + +RETURN = ''' +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + + +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec +from ansible.module_utils.basic import AnsibleModule + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + name=dict(type='str'), # Not required for querying all objects + version=dict(type='str'), + ignoreCompat=dict(type='bool'), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['name']], + ['state', 'present', ['name', 'version']], + ], + ) + + state = module.params.get('state') + name = module.params.get('name') + version = module.params.get('version') + name_alias = module.params.get('name_alias') + + if module.params.get('ignoreCompat'): + ignore = 'yes' + else: + ignore = 'no' + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='firmwareFwP', + aci_rn='fabric/fwpol-{0}'.format(name), + target_filter={'name': name}, + module_object=name, + ), + + + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='firmwareFwP', + class_config=dict( + name=name, + version=version, + ignoreCompat=ignore, + nameAlias=name_alias, + ), + + ) + + aci.get_diff(aci_class='firmwareFwP') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_firmware_source.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_firmware_source.py new file mode 100644 index 00000000..52946578 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_firmware_source.py @@ -0,0 +1,303 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2018, Dag Wieers (dagwieers) <dag@wieers.com> +# Copyright: (c) 2020, Cindy Zhao (cizhao) <cizhao@cisco.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_firmware_source +short_description: Manage firmware image sources (firmware:OSource) +description: +- Manage firmware image sources on Cisco ACI fabrics. +options: + source: + description: + - The identifying name for the outside source of images, such as an HTTP or SCP server. + type: str + aliases: [ name, source_name ] + polling_interval: + description: + - Polling interval in minutes. + type: int + url_protocol: + description: + - The Firmware download protocol. + type: str + choices: [ http, local, scp, usbkey ] + default: scp + aliases: [ url_proto ] + url: + description: + The firmware URL for the image(s) on the source. + type: str + url_password: + description: + The Firmware password or key string. + type: str + url_username: + description: + The username for the source. + type: str + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +seealso: +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(firmware:OSource). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Dag Wieers (@dagwieers) +''' + +EXAMPLES = r''' +- name: Add firmware source + cisco.aci.aci_firmware_source: + host: apic + username: admin + password: SomeSecretPassword + source: aci-msft-pkg-3.1.1i.zip + url: foo.bar.cisco.com/download/cisco/aci/aci-msft-pkg-3.1.1i.zip + url_protocol: http + state: present + delegate_to: localhost + +- name: Remove firmware source + cisco.aci.aci_firmware_source: + host: apic + username: admin + password: SomeSecretPassword + source: aci-msft-pkg-3.1.1i.zip + state: absent + delegate_to: localhost + +- name: Query a specific firmware source + cisco.aci.aci_firmware_source: + host: apic + username: admin + password: SomeSecretPassword + source: aci-msft-pkg-3.1.1i.zip + state: query + delegate_to: localhost + register: query_result + +- name: Query all firmware sources + cisco.aci.aci_firmware_source: + host: apic + username: admin + password: SomeSecretPassword + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + source=dict(type='str', aliases=['name', 'source_name']), # Not required for querying all objects + polling_interval=dict(type='int'), + url=dict(type='str'), + url_username=dict(type='str'), + url_password=dict(type='str', no_log=True), + url_protocol=dict(type='str', default='scp', choices=['http', 'local', 'scp', 'usbkey'], aliases=['url_proto']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['source']], + ['state', 'present', ['url_protocol', 'source', 'url']], + ], + ) + + polling_interval = module.params.get('polling_interval') + url_protocol = module.params.get('url_protocol') + state = module.params.get('state') + source = module.params.get('source') + url = module.params.get('url') + url_password = module.params.get('url_password') + url_username = module.params.get('url_username') + name_alias = module.params.get('name_alias') + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='fabricInst', + aci_rn='fabric', + module_object='fabric', + target_filter={'name': 'fabric'}, + ), + subclass_1=dict( + aci_class='firmwareRepoP', + aci_rn='fwrepop', + module_object='fwrepop', + target_filter={'name': 'fwrepop'}, + ), + subclass_2=dict( + aci_class='firmwareOSource', + aci_rn='osrc-{0}'.format(source), + module_object=source, + target_filter={'name': source}, + ), + config_only=False, + ) + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='firmwareOSource', + class_config=dict( + name=source, + url=url, + password=url_password, + pollingInterval=polling_interval, + proto=url_protocol, + user=url_username, + nameAlias=name_alias, + ), + ) + + aci.get_diff(aci_class='firmwareOSource') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_cdp.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_cdp.py new file mode 100644 index 00000000..635c1799 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_cdp.py @@ -0,0 +1,266 @@ +#!/usr/bin/python + +# Copyright: (c) 2019, Tim Knipper <tim.knipper@gmail.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = { + 'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community' +} + +DOCUMENTATION = r''' +--- +module: aci_interface_policy_cdp +short_description: Manage CDP interface policies (cdp:IfPol) +description: +- Manage CDP interface policies on Cisco ACI fabrics. +options: + cdp_policy: + description: + - The CDP interface policy name. + type: str + aliases: [ cdp_interface, name ] + description: + description: + - The description for the CDP interface policy name. + type: str + aliases: [ descr ] + admin_state: + description: + - Enable or Disable CDP state. + - The APIC defaults to C(yes) when unset during creation. + type: bool + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +seealso: +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(cdp:IfPol). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Tim Knipper (@tknipper11) +''' + +EXAMPLES = r''' +- name: Create CDP Interface Policy to enable CDP + cisco.aci.aci_interface_policy_cdp: + name: Ansible_CDP_Interface_Policy + host: apic.example.com + username: admin + password: adminpass + admin_state: true + state: present + +- name: Create CDP Interface Policy to disable CDP + cisco.aci.aci_interface_policy_cdp: + name: Ansible_CDP_Interface_Policy + host: apic.example.com + username: admin + password: adminpass + admin_state: false + state: present + +- name: Remove CDP Interface Policy + cisco.aci.aci_interface_policy_cdp: + name: Ansible_CDP_Interface_Policy + host: apic.example.com + username: admin + password: adminpass + output_level: debug + state: absent + +- name: Query CDP Policy + cisco.aci.aci_interface_policy_cdp: + host: apic.example.com + username: admin + password: adminpass + state: query +''' + +RETURN = r''' +current: + description: The existing configuration from the APIC after the module has finished + returned: success + type: list + sample: + [ + { + "cdpIfPol": { + "attributes": { + "adminSt": "disabled", + "annotation": "", + "descr": "Ansible Created CDP Test Policy", + "dn": "uni/infra/cdpIfP-Ansible_CDP_Test_Policy", + "name": "Ansible_CDP_Test_Policy", + "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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + +from ansible.module_utils.basic import AnsibleModule + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + cdp_policy=dict(type='str', required=False, aliases=['cdp_interface', 'name']), # Not required for querying all objects + description=dict(type='str', aliases=['descr']), + admin_state=dict(type='bool'), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['cdp_policy']], + ['state', 'present', ['cdp_policy']], + ], + ) + + aci = ACIModule(module) + + cdp_policy = module.params.get('cdp_policy') + description = module.params.get('description') + admin_state = aci.boolean(module.params.get('admin_state'), 'enabled', 'disabled') + state = module.params.get('state') + name_alias = module.params.get('name_alias') + + aci.construct_url( + root_class=dict( + aci_class='cdpIfPol', + aci_rn='infra/cdpIfP-{0}'.format(cdp_policy), + module_object=cdp_policy, + target_filter={'name': cdp_policy}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='cdpIfPol', + class_config=dict( + name=cdp_policy, + descr=description, + adminSt=admin_state, + nameAlias=name_alias, + ), + ) + + aci.get_diff(aci_class='cdpIfPol') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_fc.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_fc.py new file mode 100644 index 00000000..d2eb1595 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_fc.py @@ -0,0 +1,240 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_interface_policy_fc +short_description: Manage Fibre Channel interface policies (fc:IfPol) +description: +- Manage ACI Fiber Channel interface policies on Cisco ACI fabrics. +options: + fc_policy: + description: + - The name of the Fiber Channel interface policy. + type: str + aliases: [ name ] + description: + description: + - The description of the Fiber Channel interface policy. + type: str + aliases: [ descr ] + port_mode: + description: + - The Port Mode to use. + - The APIC defaults to C(f) when unset during creation. + type: str + choices: [ f, np ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +seealso: +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(fc:IfPol). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Dag Wieers (@dagwieers) +''' + +# FIXME: Add more, better examples +EXAMPLES = r''' +- name: Add a Fibre Channel interface policy + cisco.aci.aci_interface_policy_fc: + host: '{{ hostname }}' + username: '{{ username }}' + password: '{{ password }}' + fc_policy: '{{ fc_policy }}' + port_mode: '{{ port_mode }}' + description: '{{ description }}' + state: present + delegate_to: localhost +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + fc_policy=dict(type='str', aliases=['name']), # Not required for querying all objects + description=dict(type='str', aliases=['descr']), + port_mode=dict(type='str', choices=['f', 'np']), # No default provided on purpose + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['fc_policy']], + ['state', 'present', ['fc_policy']], + ], + ) + + fc_policy = module.params.get('fc_policy') + port_mode = module.params.get('port_mode') + description = module.params.get('description') + state = module.params.get('state') + name_alias = module.params.get('name_alias') + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='fcIfPol', + aci_rn='infra/fcIfPol-{0}'.format(fc_policy), + module_object=fc_policy, + target_filter={'name': fc_policy}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='fcIfPol', + class_config=dict( + name=fc_policy, + descr=description, + portMode=port_mode, + nameAlias=name_alias, + ), + ) + + aci.get_diff(aci_class='fcIfPol') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_l2.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_l2.py new file mode 100644 index 00000000..bd74c922 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_l2.py @@ -0,0 +1,265 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_interface_policy_l2 +short_description: Manage Layer 2 interface policies (l2:IfPol) +description: +- Manage Layer 2 interface policies on Cisco ACI fabrics. +options: + l2_policy: + description: + - The name of the Layer 2 interface policy. + type: str + aliases: [ name ] + description: + description: + - The description of the Layer 2 interface policy. + type: str + aliases: [ descr ] + qinq: + description: + - Determines if QinQ is disabled or if the port should be considered a core or edge port. + - The APIC defaults to C(disabled) when unset during creation. + type: str + choices: [ core, disabled, edge ] + vepa: + description: + - Determines if Virtual Ethernet Port Aggregator is disabled or enabled. + - The APIC defaults to C(no) when unset during creation. + type: bool + vlan_scope: + description: + - The scope of the VLAN. + - The APIC defaults to C(global) when unset during creation. + type: str + choices: [ global, portlocal ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +seealso: +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(l2:IfPol). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Dag Wieers (@dagwieers) +''' + +# FIXME: Add more, better examples +EXAMPLES = r''' +- name: Add a Layer 2 interface policy + cisco.aci.aci_interface_policy_l2: + host: '{{ hostname }}' + username: '{{ username }}' + password: '{{ password }}' + l2_policy: '{{ l2_policy }}' + vlan_scope: '{{ vlan_policy }}' + description: '{{ description }}' + delegate_to: localhost +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + +# Mapping dicts are used to normalize the proposed data to what the APIC expects, which will keep diffs accurate +QINQ_MAPPING = dict( + core='corePort', + disabled='disabled', + edge='edgePort', +) + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + l2_policy=dict(type='str', aliases=['name']), # Not required for querying all policies + description=dict(type='str', aliases=['descr']), + vlan_scope=dict(type='str', choices=['global', 'portlocal']), # No default provided on purpose + qinq=dict(type='str', choices=['core', 'disabled', 'edge']), + vepa=dict(type='bool'), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['l2_policy']], + ['state', 'present', ['l2_policy']], + ], + ) + + aci = ACIModule(module) + + l2_policy = module.params.get('l2_policy') + vlan_scope = module.params.get('vlan_scope') + qinq = module.params.get('qinq') + if qinq is not None: + qinq = QINQ_MAPPING.get(qinq) + vepa = aci.boolean(module.params.get('vepa'), 'enabled', 'disabled') + description = module.params.get('description') + state = module.params.get('state') + name_alias = module.params.get('name_alias') + + aci.construct_url( + root_class=dict( + aci_class='l2IfPol', + aci_rn='infra/l2IfP-{0}'.format(l2_policy), + module_object=l2_policy, + target_filter={'name': l2_policy}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='l2IfPol', + class_config=dict( + name=l2_policy, + descr=description, + vlanScope=vlan_scope, + qinq=qinq, vepa=vepa, + nameAlias=name_alias, + ), + ) + + aci.get_diff(aci_class='l2IfPol') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_leaf_breakout_port_group.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_leaf_breakout_port_group.py new file mode 100644 index 00000000..2646198b --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_leaf_breakout_port_group.py @@ -0,0 +1,259 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2020, Cindy Zhao <cizhao@cisco.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_interface_policy_leaf_breakout_port_group +short_description: Manage fabric interface policy leaf breakout port group (infra:BrkoutPortGrp) +description: +- Manage fabric interface policy leaf breakout port group on Cisco ACI fabrics. +options: + breakout_port_group: + description: + - Name of the leaf breakout port group to be added/deleted. + type: str + aliases: [ name ] + description: + description: + - Description for the leaf breakout port group to be created. + type: str + aliases: [ descr ] + breakout_map: + description: + - The mapping of breakout port. + type: str + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present +extends_documentation_fragment: +- cisco.aci.aci + +seealso: +- name: APIC Management Information Model reference + description: More information about the internal APIC classes B(infra:BrkoutPortGrp). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Cindy Zhao (@cizhao) +''' + +EXAMPLES = r''' +- name: Create a Leaf Breakout Port Group + cisco.aci.aci_interface_policy_leaf_breakout_port_group: + host: apic + username: admin + password: SomeSecretPassword + breakout_port_group: BreakoutPortName + breakout_map: 10g-4x + state: present + delegate_to: localhost + +- name: Query all Leaf Breakout Port Groups of type link + cisco.aci.aci_interface_policy_leaf_breakout_port_group: + host: apic + username: admin + password: SomeSecretPassword + state: query + delegate_to: localhost + register: query_result + +- name: Query a specific Leaf Breakout Port Group + cisco.aci.aci_interface_policy_leaf_breakout_port_group: + host: apic + username: admin + password: SomeSecretPassword + breakout_port_group: BreakoutPortName + state: query + delegate_to: localhost + register: query_result + +- name: Delete an Leaf Breakout Port Group + cisco.aci.aci_interface_policy_leaf_breakout_port_group: + host: apic + username: admin + password: SomeSecretPassword + breakout_port_group: BreakoutPortName + state: absent + delegate_to: localhost +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + breakout_port_group=dict(type='str', aliases=['name']), # Not required for querying all objects + description=dict(type='str', aliases=['descr']), + breakout_map=dict(type='str'), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['breakout_port_group']], + ['state', 'present', ['breakout_port_group']], + ], + ) + + breakout_port_group = module.params.get('breakout_port_group') + description = module.params.get('description') + breakout_map = module.params.get('breakout_map') + state = module.params.get('state') + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='infraBrkoutPortGrp', + aci_rn='infra/funcprof/brkoutportgrp-{0}'.format(breakout_port_group), + module_object=breakout_port_group, + target_filter={'name': breakout_port_group}, + ), + child_classes=[], + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='infraBrkoutPortGrp', + class_config=dict( + name=breakout_port_group, + descr=description, + brkoutMap=breakout_map, + ), + ) + + aci.get_diff(aci_class='infraBrkoutPortGrp') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_leaf_policy_group.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_leaf_policy_group.py new file mode 100644 index 00000000..001e6e97 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_leaf_policy_group.py @@ -0,0 +1,580 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2017, Bruno Calogero <brunocalogero@hotmail.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_interface_policy_leaf_policy_group +short_description: Manage fabric interface policy leaf policy groups (infra:AccBndlGrp, infra:AccPortGrp) +description: +- Manage fabric interface policy leaf policy groups on Cisco ACI fabrics. +options: + policy_group: + description: + - Name of the leaf policy group to be added/deleted. + type: str + aliases: [ name, policy_group_name ] + description: + description: + - Description for the leaf policy group to be created. + type: str + aliases: [ descr ] + lag_type: + description: + - Selector for the type of leaf policy group we want to create. + - C(leaf) for Leaf Access Port Policy Group + - C(link) for Port Channel (PC) + - C(node) for Virtual Port Channel (VPC) + type: str + required: yes + choices: [ leaf, link, node ] + aliases: [ lag_type_name ] + link_level_policy: + description: + - Choice of link_level_policy to be used as part of the leaf policy group to be created. + type: str + aliases: [ link_level_policy_name ] + cdp_policy: + description: + - Choice of cdp_policy to be used as part of the leaf policy group to be created. + type: str + aliases: [ cdp_policy_name ] + mcp_policy: + description: + - Choice of mcp_policy to be used as part of the leaf policy group to be created. + type: str + aliases: [ mcp_policy_name ] + lldp_policy: + description: + - Choice of lldp_policy to be used as part of the leaf policy group to be created. + type: str + aliases: [ lldp_policy_name ] + stp_interface_policy: + description: + - Choice of stp_interface_policy to be used as part of the leaf policy group to be created. + type: str + aliases: [ stp_interface_policy_name ] + egress_data_plane_policing_policy: + description: + - Choice of egress_data_plane_policing_policy to be used as part of the leaf policy group to be created. + type: str + aliases: [ egress_data_plane_policing_policy_name ] + ingress_data_plane_policing_policy: + description: + - Choice of ingress_data_plane_policing_policy to be used as part of the leaf policy group to be created. + type: str + aliases: [ ingress_data_plane_policing_policy_name ] + priority_flow_control_policy: + description: + - Choice of priority_flow_control_policy to be used as part of the leaf policy group to be created. + type: str + aliases: [ priority_flow_control_policy_name ] + fibre_channel_interface_policy: + description: + - Choice of fibre_channel_interface_policy to be used as part of the leaf policy group to be created. + type: str + aliases: [ fibre_channel_interface_policy_name ] + slow_drain_policy: + description: + - Choice of slow_drain_policy to be used as part of the leaf policy group to be created. + type: str + aliases: [ slow_drain_policy_name ] + port_channel_policy: + description: + - Choice of port_channel_policy to be used as part of the leaf policy group to be created. + type: str + aliases: [ port_channel_policy_name ] + monitoring_policy: + description: + - Choice of monitoring_policy to be used as part of the leaf policy group to be created. + type: str + aliases: [ monitoring_policy_name ] + storm_control_interface_policy: + description: + - Choice of storm_control_interface_policy to be used as part of the leaf policy group to be created. + type: str + aliases: [ storm_control_interface_policy_name ] + l2_interface_policy: + description: + - Choice of l2_interface_policy to be used as part of the leaf policy group to be created. + type: str + aliases: [ l2_interface_policy_name ] + port_security_policy: + description: + - Choice of port_security_policy to be used as part of the leaf policy group to be created. + type: str + aliases: [ port_security_policy_name ] + aep: + description: + - Choice of attached_entity_profile (AEP) to be used as part of the leaf policy group to be created. + type: str + aliases: [ aep_name ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +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. +seealso: +- name: APIC Management Information Model reference + description: More information about the internal APIC classes B(infra:AccBndlGrp) and B(infra:AccPortGrp). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Bruno Calogero (@brunocalogero) +''' + +EXAMPLES = r''' +- name: Create a Port Channel (PC) Interface Policy Group + cisco.aci.aci_interface_policy_leaf_policy_group: + host: apic + username: admin + password: SomeSecretPassword + lag_type: link + policy_group: policygroupname + description: policygroupname description + link_level_policy: whateverlinklevelpolicy + cdp_policy: whatevercdppolicy + lldp_policy: whateverlldppolicy + port_channel_policy: whateverlacppolicy + state: present + delegate_to: localhost + +- name: Create a Virtual Port Channel (VPC) Interface Policy Group + cisco.aci.aci_interface_policy_leaf_policy_group: + host: apic + username: admin + password: SomeSecretPassword + lag_type: node + policy_group: policygroupname + link_level_policy: whateverlinklevelpolicy + cdp_policy: whatevercdppolicy + lldp_policy: whateverlldppolicy + port_channel_policy: whateverlacppolicy + state: present + delegate_to: localhost + +- name: Create a Leaf Access Port Policy Group + cisco.aci.aci_interface_policy_leaf_policy_group: + host: apic + username: admin + password: SomeSecretPassword + lag_type: leaf + policy_group: policygroupname + link_level_policy: whateverlinklevelpolicy + cdp_policy: whatevercdppolicy + lldp_policy: whateverlldppolicy + state: present + delegate_to: localhost + +- name: Query all Leaf Access Port Policy Groups of type link + cisco.aci.aci_interface_policy_leaf_policy_group: + host: apic + username: admin + password: SomeSecretPassword + lag_type: link + state: query + delegate_to: localhost + register: query_result + +- name: Query a specific Lead Access Port Policy Group + cisco.aci.aci_interface_policy_leaf_policy_group: + host: apic + username: admin + password: SomeSecretPassword + lag_type: leaf + policy_group: policygroupname + state: query + delegate_to: localhost + register: query_result + +- name: Delete an Interface policy Leaf Policy Group + cisco.aci.aci_interface_policy_leaf_policy_group: + host: apic + username: admin + password: SomeSecretPassword + lag_type: leaf + policy_group: policygroupname + state: absent + delegate_to: localhost +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + # NOTE: Since this module needs to include both infra:AccBndlGrp (for PC and VPC) and infra:AccPortGrp (for leaf access port policy group): + # NOTE: I'll allow the user to make the choice here (link(PC), node(VPC), leaf(leaf-access port policy group)) + lag_type=dict(type='str', required=True, aliases=['lag_type_name'], choices=['leaf', 'link', 'node']), + policy_group=dict(type='str', aliases=['name', 'policy_group_name']), # Not required for querying all objects + description=dict(type='str', aliases=['descr']), + link_level_policy=dict(type='str', aliases=['link_level_policy_name']), + cdp_policy=dict(type='str', aliases=['cdp_policy_name']), + mcp_policy=dict(type='str', aliases=['mcp_policy_name']), + lldp_policy=dict(type='str', aliases=['lldp_policy_name']), + stp_interface_policy=dict(type='str', aliases=['stp_interface_policy_name']), + egress_data_plane_policing_policy=dict(type='str', aliases=['egress_data_plane_policing_policy_name']), + ingress_data_plane_policing_policy=dict(type='str', aliases=['ingress_data_plane_policing_policy_name']), + priority_flow_control_policy=dict(type='str', aliases=['priority_flow_control_policy_name']), + fibre_channel_interface_policy=dict(type='str', aliases=['fibre_channel_interface_policy_name']), + slow_drain_policy=dict(type='str', aliases=['slow_drain_policy_name']), + port_channel_policy=dict(type='str', aliases=['port_channel_policy_name']), + monitoring_policy=dict(type='str', aliases=['monitoring_policy_name']), + storm_control_interface_policy=dict(type='str', aliases=['storm_control_interface_policy_name']), + l2_interface_policy=dict(type='str', aliases=['l2_interface_policy_name']), + port_security_policy=dict(type='str', aliases=['port_security_policy_name']), + aep=dict(type='str', aliases=['aep_name']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['policy_group']], + ['state', 'present', ['policy_group']], + ], + ) + + policy_group = module.params.get('policy_group') + description = module.params.get('description') + lag_type = module.params.get('lag_type') + link_level_policy = module.params.get('link_level_policy') + cdp_policy = module.params.get('cdp_policy') + mcp_policy = module.params.get('mcp_policy') + lldp_policy = module.params.get('lldp_policy') + stp_interface_policy = module.params.get('stp_interface_policy') + egress_data_plane_policing_policy = module.params.get('egress_data_plane_policing_policy') + ingress_data_plane_policing_policy = module.params.get('ingress_data_plane_policing_policy') + priority_flow_control_policy = module.params.get('priority_flow_control_policy') + fibre_channel_interface_policy = module.params.get('fibre_channel_interface_policy') + slow_drain_policy = module.params.get('slow_drain_policy') + port_channel_policy = module.params.get('port_channel_policy') + monitoring_policy = module.params.get('monitoring_policy') + storm_control_interface_policy = module.params.get('storm_control_interface_policy') + l2_interface_policy = module.params.get('l2_interface_policy') + port_security_policy = module.params.get('port_security_policy') + aep = module.params.get('aep') + state = module.params.get('state') + name_alias = module.params.get('name_alias') + + aci = ACIModule(module) + if lag_type == 'leaf' and port_channel_policy is not None: + aci.fail_json('port_channel_policy is not a valid parameter for leaf\ + (leaf access port policy group), if used\ + assign null to it (port_channel_policy: null).') + + if lag_type == 'leaf': + aci_class_name = 'infraAccPortGrp' + dn_name = 'accportgrp' + class_config_dict = dict( + name=policy_group, + descr=description, + nameAlias=name_alias, + ) + # Reset for target_filter + lag_type = None + elif lag_type in ('link', 'node'): + aci_class_name = 'infraAccBndlGrp' + dn_name = 'accbundle' + class_config_dict = dict( + name=policy_group, + descr=description, + lagT=lag_type, + nameAlias=name_alias, + ) + + child_configs = [ + dict( + infraRsCdpIfPol=dict( + attributes=dict( + tnCdpIfPolName=cdp_policy, + ), + ), + ), + dict( + infraRsFcIfPol=dict( + attributes=dict( + tnFcIfPolName=fibre_channel_interface_policy, + ), + ), + ), + dict( + infraRsHIfPol=dict( + attributes=dict( + tnFabricHIfPolName=link_level_policy, + ), + ), + ), + dict( + infraRsL2IfPol=dict( + attributes=dict( + tnL2IfPolName=l2_interface_policy, + ), + ), + ), + dict( + infraRsL2PortSecurityPol=dict( + attributes=dict( + tnL2PortSecurityPolName=port_security_policy, + ), + ), + ), + dict( + infraRsLacpPol=dict( + attributes=dict( + tnLacpLagPolName=port_channel_policy, + ), + ), + ), + dict( + infraRsLldpIfPol=dict( + attributes=dict( + tnLldpIfPolName=lldp_policy, + ), + ), + ), + dict( + infraRsMcpIfPol=dict( + attributes=dict( + tnMcpIfPolName=mcp_policy, + ), + ), + ), + dict( + infraRsMonIfInfraPol=dict( + attributes=dict( + tnMonInfraPolName=monitoring_policy, + ), + ), + ), + dict( + infraRsQosEgressDppIfPol=dict( + attributes=dict( + tnQosDppPolName=egress_data_plane_policing_policy, + ), + ), + ), + dict( + infraRsQosIngressDppIfPol=dict( + attributes=dict( + tnQosDppPolName=ingress_data_plane_policing_policy, + ), + ), + ), + dict( + infraRsQosPfcIfPol=dict( + attributes=dict( + tnQosPfcIfPolName=priority_flow_control_policy, + ), + ), + ), + dict( + infraRsQosSdIfPol=dict( + attributes=dict( + tnQosSdIfPolName=slow_drain_policy, + ), + ), + ), + dict( + infraRsStormctrlIfPol=dict( + attributes=dict( + tnStormctrlIfPolName=storm_control_interface_policy, + ), + ), + ), + dict( + infraRsStpIfPol=dict( + attributes=dict( + tnStpIfPolName=stp_interface_policy, + ), + ), + ), + ] + + # Add infraRsattEntP binding only when aep was defined + if aep is not None: + child_configs.append(dict( + infraRsAttEntP=dict( + attributes=dict( + tDn='uni/infra/attentp-{0}'.format(aep), + ), + ), + )) + + aci.construct_url( + root_class=dict( + aci_class=aci_class_name, + aci_rn='infra/funcprof/{0}-{1}'.format(dn_name, policy_group), + module_object=policy_group, + target_filter={'name': policy_group, 'lagT': lag_type}, + ), + child_classes=[ + 'infraRsAttEntP', + 'infraRsCdpIfPol', + 'infraRsFcIfPol', + 'infraRsHIfPol', + 'infraRsL2IfPol', + 'infraRsL2PortSecurityPol', + 'infraRsLacpPol', + 'infraRsLldpIfPol', + 'infraRsMcpIfPol', + 'infraRsMonIfInfraPol', + 'infraRsQosEgressDppIfPol', + 'infraRsQosIngressDppIfPol', + 'infraRsQosPfcIfPol', + 'infraRsQosSdIfPol', + 'infraRsStormctrlIfPol', + 'infraRsStpIfPol', + ], + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class=aci_class_name, + class_config=class_config_dict, + child_configs=child_configs, + ) + + aci.get_diff(aci_class=aci_class_name) + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_leaf_profile.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_leaf_profile.py new file mode 100644 index 00000000..468ccbc8 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_leaf_profile.py @@ -0,0 +1,313 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2017, Bruno Calogero <brunocalogero@hotmail.com> +# Copyright: (c) 2020, Shreyas Srish <ssrish@cisco.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_interface_policy_leaf_profile +short_description: Manage fabric interface policy leaf profiles (infra:AccPortP) +description: +- Manage fabric interface policy leaf profiles on Cisco ACI fabrics. +options: + interface_profile: + description: + - The name of the Fabric access policy leaf interface profile. + type: str + aliases: [ name, leaf_interface_profile_name, leaf_interface_profile, interface_profile_name ] + description: + description: + - Description for the Fabric access policy leaf interface profile. + type: str + aliases: [ descr ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str + type: + description: + - The type of profile to be created. + type: str + choices: [ fex, leaf ] + default: leaf +extends_documentation_fragment: +- cisco.aci.aci + +seealso: +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(infra:AccPortP). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Bruno Calogero (@brunocalogero) +- Shreyas Srish (@shrsr) +''' + +EXAMPLES = r''' +- name: Add a new leaf_interface_profile + cisco.aci.aci_interface_policy_leaf_profile: + host: apic + username: admin + password: SomeSecretPassword + interface_profile: leafintprfname + description: leafintprfname description + state: present + delegate_to: localhost + +- name: Add a new leaf_interface_profile of type fex + cisco.aci.aci_interface_policy_leaf_profile: + host: apic + username: admin + password: SomeSecretPassword + interface_profile: leafintprfname_fex + type: fex + description: leafintprfname description + state: present + delegate_to: localhost + +- name: Remove a leaf_interface_profile + cisco.aci.aci_interface_policy_leaf_profile: + host: apic + username: admin + password: SomeSecretPassword + interface_profile: leafintprfname + state: absent + delegate_to: localhost + +- name: Remove a leaf_interface_profile of type fex + cisco.aci.aci_interface_policy_leaf_profile: + host: apic + username: admin + password: SomeSecretPassword + interface_profile: leafintprfname_fex + type: fex + state: absent + delegate_to: localhost + +- name: Query a leaf_interface_profile + cisco.aci.aci_interface_policy_leaf_profile: + host: apic + username: admin + password: SomeSecretPassword + interface_profile: leafintprfname + state: query + delegate_to: localhost + register: query_result + +- name: Query a leaf_interface_profile of type fex + cisco.aci.aci_interface_policy_leaf_profile: + host: apic + username: admin + password: SomeSecretPassword + interface_profile: leafintprfname_fex + type: fex + state: query + delegate_to: localhost + register: query_result + +- name: Query all leaf_interface_profiles + cisco.aci.aci_interface_policy_leaf_profile: + host: apic + username: admin + password: SomeSecretPassword + state: query + delegate_to: localhost + +- name: Query all leaf_interface_profiles of type fex + cisco.aci.aci_interface_policy_leaf_profile: + host: apic + username: admin + password: SomeSecretPassword + type: fex + state: query + delegate_to: localhost +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + interface_profile=dict(type='str', aliases=['name', 'leaf_interface_profile_name', 'leaf_interface_profile', 'interface_profile_name']), + description=dict(type='str', aliases=['descr']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + type=dict(type='str', default='leaf', choices=['fex', 'leaf']), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['interface_profile']], + ['state', 'present', ['interface_profile']], + ], + ) + + interface_profile = module.params.get('interface_profile') + description = module.params.get('description') + state = module.params.get('state') + name_alias = module.params.get('name_alias') + type_profile = module.params.get('type') + + aci = ACIModule(module) + aci_class = 'infraAccPortP' + aci_rn = 'accportprof' + if type_profile == 'fex': + aci_class = 'infraFexP' + aci_rn = 'fexprof' + aci.construct_url( + root_class=dict( + aci_class=aci_class, + aci_rn='infra/' + aci_rn + '-{0}'.format(interface_profile), + module_object=interface_profile, + target_filter={'name': interface_profile}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class=aci_class, + class_config=dict( + name=interface_profile, + descr=description, + nameAlias=name_alias, + ), + ) + + aci.get_diff(aci_class=aci_class) + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_link_level.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_link_level.py new file mode 100644 index 00000000..c6e792f7 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_link_level.py @@ -0,0 +1,292 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2019, Vasily Prokopov (@vasilyprokopov) +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_interface_policy_link_level +short_description: Manage Link Level interface policies (fabric:HIfPol) +description: +- The link level interface policy specifies the layer 1 parameters of switch interfaces. +options: + link_level_policy: + description: + - The name of the Link Level interface policy. + type: str + aliases: [ name ] + description: + description: + - The description of the Link Level interface policy. + type: str + aliases: [ descr ] + auto_negotiation: + description: + - Auto-negotiation enables devices to automatically exchange information over a link about speed and duplex abilities. + - The APIC defaults to C(on) when unset during creation. + type: bool + default: true + speed: + description: + - Determines the interface policy administrative port speed. + - The APIC defaults to C(inherit) when unset during creation. + type: str + choices: [ 100M, 1G, 10G, 25G, 40G, 50G, 100G, 200G, 400G, inherit ] + default: inherit + link_debounce_interval: + description: + - Enables the debounce timer for physical interface ports and sets it for a specified amount of time in milliseconds. + - The APIC defaults to C(100) when unset during creation. + type: int + default: 100 + forwarding_error_correction: + description: + - Determines the forwarding error correction (FEC) mode. + - The APIC defaults to C(inherit) when unset during creation. + type: str + choices: [ inherit, kp-fec, cl91-rs-fec, cl74-fc-fec, disable-fec, ieee-rs-fec, cons16-rs-fec ] + default: inherit + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present +extends_documentation_fragment: cisco.aci.aci +seealso: +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(fabric:HIfPol). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Vasily Prokopov (@vasilyprokopov) +''' + +EXAMPLES = r''' +- name: Add a Link Level Policy + aci_interface_policy_link_level: + host: apic + username: admin + password: SomeSecretPassword + link_level_policy: link_level_policy_test + description: via Ansible + auto_negotiation: on + speed: 100M + link_debounce_interval: 100 + forwarding_error_correction: cl91-rs-fec + state: present + delegate_to: localhost + +- name: Remove a Link Level Policy + aci_interface_policy_link_level: + host: apic + username: admin + password: SomeSecretPassword + link_level_policy: ansible_test + state: absent + +- name: Query a Link Level Policy + aci_interface_policy_link_level: + host: apic + username: admin + password: SomeSecretPassword + link_level_policy: link_level_policy_test + state: query + delegate_to: localhost + +- name: Query all Link Level Policies + aci_interface_policy_link_level: + host: apic + username: admin + password: SomeSecretPassword + state: query + delegate_to: localhost +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + link_level_policy=dict(type='str', aliases=['name']), + description=dict(type='str', aliases=['descr']), + auto_negotiation=dict(type='bool', default='true'), + speed=dict(type='str', default='inherit', choices=['100M', '1G', '10G', '25G', '40G', '50G', '100G', '200G', '400G', 'inherit']), + link_debounce_interval=dict(type='int', default='100'), + forwarding_error_correction=dict(type='str', default='inherit', + choices=['inherit', 'kp-fec', 'cl91-rs-fec', 'cl74-fc-fec', 'disable-fec', 'ieee-rs-fec', 'cons16-rs-fec']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['link_level_policy']], + ['state', 'present', ['link_level_policy']], + ], + ) + + aci = ACIModule(module) + + link_level_policy = module.params['link_level_policy'] + description = module.params['description'] + auto_negotiation = aci.boolean(module.params['auto_negotiation'], 'on', 'off') + speed = module.params['speed'] + link_debounce_interval = module.params['link_debounce_interval'] + if link_debounce_interval is not None and link_debounce_interval not in range(0, 5001): + module.fail_json(msg='The "link_debounce_interval" must be a value between 0 and 5000') + forwarding_error_correction = module.params['forwarding_error_correction'] + state = module.params['state'] + + aci.construct_url( + root_class=dict( + aci_class='fabricHIfPol', + aci_rn='infra/hintfpol-{0}'.format(link_level_policy), + module_object=link_level_policy, + target_filter={'name': link_level_policy}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='fabricHIfPol', + class_config=dict( + name=link_level_policy, + descr=description, + autoNeg=auto_negotiation, + speed=speed, + linkDebounce=link_debounce_interval, + fecMode=forwarding_error_correction, + ), + ) + + aci.get_diff(aci_class='fabricHIfPol') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_lldp.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_lldp.py new file mode 100644 index 00000000..a1964733 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_lldp.py @@ -0,0 +1,248 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_interface_policy_lldp +short_description: Manage LLDP interface policies (lldp:IfPol) +description: +- Manage LLDP interface policies on Cisco ACI fabrics. +options: + lldp_policy: + description: + - The LLDP interface policy name. + type: str + aliases: [ name ] + description: + description: + - The description for the LLDP interface policy name. + type: str + aliases: [ descr ] + receive_state: + description: + - Enable or disable Receive state. + - The APIC defaults to C(yes) when unset during creation. + type: bool + transmit_state: + description: + - Enable or Disable Transmit state. + - The APIC defaults to C(yes) when unset during creation. + type: bool + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +seealso: +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(lldp:IfPol). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Dag Wieers (@dagwieers) +''' + +# FIXME: Add more, better examples +EXAMPLES = r''' +- name: Add a LLDP interface policy + cisco.aci.aci_interface_policy_lldp: + host: '{{ hostname }}' + username: '{{ username }}' + password: '{{ password }}' + lldp_policy: '{{ lldp_policy }}' + description: '{{ description }}' + receive_state: '{{ receive_state }}' + transmit_state: '{{ transmit_state }}' + delegate_to: localhost +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + lldp_policy=dict(type='str', aliases=['name']), # Not required for querying all objects + description=dict(type='str', aliases=['descr']), + receive_state=dict(type='bool'), + transmit_state=dict(type='bool'), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['lldp_policy']], + ['state', 'present', ['lldp_policy']], + ], + ) + + aci = ACIModule(module) + + lldp_policy = module.params.get('lldp_policy') + description = module.params.get('description') + receive_state = aci.boolean(module.params.get('receive_state'), 'enabled', 'disabled') + transmit_state = aci.boolean(module.params.get('transmit_state'), 'enabled', 'disabled') + state = module.params.get('state') + name_alias = module.params.get('name_alias') + + aci.construct_url( + root_class=dict( + aci_class='lldpIfPol', + aci_rn='infra/lldpIfP-{0}'.format(lldp_policy), + module_object=lldp_policy, + target_filter={'name': lldp_policy}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='lldpIfPol', + class_config=dict( + name=lldp_policy, + descr=description, + adminRxSt=receive_state, + adminTxSt=transmit_state, + nameAlias=name_alias, + ), + ) + + aci.get_diff(aci_class='lldpIfPol') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_mcp.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_mcp.py new file mode 100644 index 00000000..97a1360a --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_mcp.py @@ -0,0 +1,239 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_interface_policy_mcp +short_description: Manage MCP interface policies (mcp:IfPol) +description: +- Manage MCP interface policies on Cisco ACI fabrics. +options: + mcp: + description: + - The name of the MCP interface. + type: str + aliases: [ mcp_interface, name ] + description: + description: + - The description for the MCP interface. + type: str + aliases: [ descr ] + admin_state: + description: + - Enable or disable admin state. + - The APIC defaults to C(yes) when unset during creation. + type: bool + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +seealso: +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(mcp:IfPol). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Dag Wieers (@dagwieers) +''' + +# FIXME: Add more, better examples +EXAMPLES = r''' +- name: Add a MCP interface policy + cisco.aci.aci_interface_policy_mcp: + host: '{{ hostname }}' + username: '{{ username }}' + password: '{{ password }}' + mcp: '{{ mcp }}' + description: '{{ descr }}' + admin_state: '{{ admin_state }}' + delegate_to: localhost +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + mcp=dict(type='str', aliases=['mcp_interface', 'name']), # Not required for querying all objects + description=dict(type='str', aliases=['descr']), + admin_state=dict(type='bool'), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['mcp']], + ['state', 'present', ['mcp']], + ], + ) + + aci = ACIModule(module) + + mcp = module.params.get('mcp') + description = module.params.get('description') + admin_state = aci.boolean(module.params.get('admin_state'), 'enabled', 'disabled') + state = module.params.get('state') + name_alias = module.params.get('name_alias') + + aci.construct_url( + root_class=dict( + aci_class='mcpIfPol', + aci_rn='infra/mcpIfP-{0}'.format(mcp), + module_object=mcp, + target_filter={'name': mcp}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='mcpIfPol', + class_config=dict( + name=mcp, + descr=description, + adminSt=admin_state, + nameAlias=name_alias, + ), + ) + + aci.get_diff(aci_class='mcpIfPol') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_ospf.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_ospf.py new file mode 100644 index 00000000..ff08e7a1 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_ospf.py @@ -0,0 +1,405 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2018, Dag Wieers (dagwieers) <dag@wieers.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_interface_policy_ospf +short_description: Manage OSPF interface policies (ospf:IfPol) +description: +- Manage OSPF interface policies on Cisco ACI fabrics. +options: + tenant: + description: + - The name of the Tenant the OSPF interface policy should belong to. + type: str + aliases: [ tenant_name ] + ospf: + description: + - The OSPF interface policy name. + - This name can be between 1 and 64 alphanumeric characters. + - Note that you cannot change this name after the object has been saved. + type: str + aliases: [ ospf_interface, name ] + description: + description: + - The description for the OSPF interface. + type: str + aliases: [ descr ] + network_type: + description: + - The OSPF interface policy network type. + - OSPF supports broadcast and point-to-point. + - The APIC defaults to C(unspecified) when unset during creation. + type: str + choices: [ bcast, p2p ] + cost: + description: + - The OSPF cost of the interface. + - The cost (also called metric) of an interface in OSPF is an indication of + the overhead required to send packets across a certain interface. The + cost of an interface is inversely proportional to the bandwidth of that + interface. A higher bandwidth indicates a lower cost. There is more + overhead (higher cost) and time delays involved in crossing a 56k serial + line than crossing a 10M ethernet line. The formula used to calculate the + cost is C(cost= 10000 0000/bandwith in bps) For example, it will cost + 10 EXP8/10 EXP7 = 10 to cross a 10M Ethernet line and will cost + 10 EXP8/1544000 = 64 to cross a T1 line. + - By default, the cost of an interface is calculated based on the bandwidth; + you can force the cost of an interface with the ip ospf cost value + interface subconfiguration mode command. + - Accepted values range between C(1) and C(450). + - The APIC defaults to C(0) when unset during creation. + type: int + controls: + description: + - The interface policy controls. + - 'This is a list of one or more of the following controls:' + - C(advert-subnet) -- Advertise IP subnet instead of a host mask in the router LSA. + - C(bfd) -- Bidirectional Forwarding Detection + - C(mtu-ignore) -- Disables MTU mismatch detection on an interface. + - C(passive) -- The interface does not participate in the OSPF protocol and + will not establish adjacencies or send routing updates. However the + interface is announced as part of the routing network. + type: list + elements: str + choices: [ advert-subnet, bfd, mtu-ignore, passive ] + dead_interval: + description: + - The interval between hello packets from a neighbor before the router + declares the neighbor as down. + - This value must be the same for all networking devices on a specific network. + - Specifying a smaller dead interval (seconds) will give faster detection + of a neighbor being down and improve convergence, but might cause more + routing instability. + - Accepted values range between C(1) and C(65535). + - The APIC defaults to C(40) when unset during creation. + type: int + hello_interval: + description: + - The interval between hello packets that OSPF sends on the interface. + - Note that the smaller the hello interval, the faster topological changes will be detected, but more routing traffic will ensue. + - This value must be the same for all routers and access servers on a specific network. + - Accepted values range between C(1) and C(65535). + - The APIC defaults to C(10) when unset during creation. + type: int + prefix_suppression: + description: + - Whether prefix suppressions is enabled or disabled. + - The APIC defaults to C(inherit) when unset during creation. + type: bool + priority: + description: + - The priority for the OSPF interface profile. + - Accepted values ranges between C(0) and C(255). + - The APIC defaults to C(1) when unset during creation. + type: int + retransmit_interval: + description: + - The interval between LSA retransmissions. + - The retransmit interval occurs while the router is waiting for an acknowledgement from the neighbor router that it received the LSA. + - If no acknowledgment is received at the end of the interval, then the LSA is resent. + - Accepted values range between C(1) and C(65535). + - The APIC defaults to C(5) when unset during creation. + type: int + transmit_delay: + description: + - The delay time needed to send an LSA update packet. + - OSPF increments the LSA age time by the transmit delay amount before transmitting the LSA update. + - You should take into account the transmission and propagation delays for the interface when you set this value. + - Accepted values range between C(1) and C(450). + - The APIC defaults to C(1) when unset during creation. + type: int + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +seealso: +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(ospf:IfPol). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Dag Wieers (@dagwieers) +''' + +EXAMPLES = r''' +- name: Ensure ospf interface policy exists + cisco.aci.aci_interface_policy_ospf: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + ospf: ospf1 + state: present + delegate_to: localhost + +- name: Ensure ospf interface policy does not exist + cisco.aci.aci_interface_policy_ospf: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + ospf: ospf1 + state: present + delegate_to: localhost + +- name: Query an ospf interface policy + cisco.aci.aci_interface_policy_ospf: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + ospf: ospf1 + state: query + delegate_to: localhost + register: query_result + +- name: Query all ospf interface policies in tenant production + cisco.aci.aci_interface_policy_ospf: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects + ospf=dict(type='str', aliases=['ospf_interface', 'name']), # Not required for querying all objects + description=dict(type='str', aliases=['descr']), + network_type=dict(type='str', choices=['bcast', 'p2p']), + cost=dict(type='int'), + controls=dict(type='list', elements='str', choices=['advert-subnet', 'bfd', 'mtu-ignore', 'passive']), + dead_interval=dict(type='int'), + hello_interval=dict(type='int'), + prefix_suppression=dict(type='bool'), + priority=dict(type='int'), + retransmit_interval=dict(type='int'), + transmit_delay=dict(type='int'), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['ospf', 'tenant']], + ['state', 'present', ['ospf', 'tenant']], + ], + ) + + aci = ACIModule(module) + + tenant = module.params.get('tenant') + ospf = module.params.get('ospf') + description = module.params.get('description') + name_alias = module.params.get('name_alias') + + if module.params.get('controls') is None: + controls = None + else: + controls = ','.join(module.params.get('controls')) + + cost = module.params.get('cost') + if cost is not None and cost not in range(1, 451): + module.fail_json(msg="Parameter 'cost' is only valid in range between 1 and 450.") + + dead_interval = module.params.get('dead_interval') + if dead_interval is not None and dead_interval not in range(1, 65536): + module.fail_json(msg="Parameter 'dead_interval' is only valid in range between 1 and 65536.") + + hello_interval = module.params.get('hello_interval') + if hello_interval is not None and hello_interval not in range(1, 65536): + module.fail_json(msg="Parameter 'hello_interval' is only valid in range between 1 and 65536.") + + network_type = module.params.get('network_type') + prefix_suppression = aci.boolean(module.params.get('prefix_suppression'), 'enabled', 'disabled') + priority = module.params.get('priority') + if priority is not None and priority not in range(0, 256): + module.fail_json(msg="Parameter 'priority' is only valid in range between 1 and 255.") + + retransmit_interval = module.params.get('retransmit_interval') + if retransmit_interval is not None and retransmit_interval not in range(1, 65536): + module.fail_json(msg="Parameter 'retransmit_interval' is only valid in range between 1 and 65536.") + + transmit_delay = module.params.get('transmit_delay') + if transmit_delay is not None and transmit_delay not in range(1, 451): + module.fail_json(msg="Parameter 'transmit_delay' is only valid in range between 1 and 450.") + + state = module.params.get('state') + + aci.construct_url( + root_class=dict( + aci_class='ospfIfPol', + aci_rn='tn-{0}/ospfIfPol-{1}'.format(tenant, ospf), + module_object=ospf, + target_filter={'name': ospf}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='ospfIfPol', + class_config=dict( + name=ospf, + descr=description, + cost=cost, + ctrl=controls, + deadIntvl=dead_interval, + helloIntvl=hello_interval, + nwT=network_type, + pfxSuppress=prefix_suppression, + prio=priority, + rexmitIntvl=retransmit_interval, + xmitDelay=transmit_delay, + nameAlias=name_alias, + ), + ) + + aci.get_diff(aci_class='ospfIfPol') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_port_channel.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_port_channel.py new file mode 100644 index 00000000..94e2fd74 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_port_channel.py @@ -0,0 +1,322 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_interface_policy_port_channel +short_description: Manage port channel interface policies (lacp:LagPol) +description: +- Manage port channel interface policies on Cisco ACI fabrics. +options: + port_channel: + description: + - Name of the port channel. + type: str + aliases: [ name ] + description: + description: + - The description for the port channel. + type: str + aliases: [ descr ] + max_links: + description: + - Maximum links. + - Accepted values range between 1 and 16. + - The APIC defaults to C(16) when unset during creation. + type: int + min_links: + description: + - Minimum links. + - Accepted values range between 1 and 16. + - The APIC defaults to C(1) when unset during creation. + type: int + mode: + description: + - Port channel interface policy mode. + - Determines the LACP method to use for forming port-channels. + - The APIC defaults to C(off) when unset during creation. + type: str + choices: [ active, mac-pin, mac-pin-nicload, 'off', passive ] + fast_select: + description: + - Determines if Fast Select is enabled for Hot Standby Ports. + - This makes up the LACP Policy Control Policy; if one setting is defined, then all other Control Properties + left undefined or set to false will not exist after the task is ran. + - The APIC defaults to C(yes) when unset during creation. + type: bool + graceful_convergence: + description: + - Determines if Graceful Convergence is enabled. + - This makes up the LACP Policy Control Policy; if one setting is defined, then all other Control Properties + left undefined or set to false will not exist after the task is ran. + - The APIC defaults to C(yes) when unset during creation. + type: bool + load_defer: + description: + - Determines if Load Defer is enabled. + - This makes up the LACP Policy Control Policy; if one setting is defined, then all other Control Properties + left undefined or set to false will not exist after the task is ran. + - The APIC defaults to C(no) when unset during creation. + type: bool + suspend_individual: + description: + - Determines if Suspend Individual is enabled. + - This makes up the LACP Policy Control Policy; if one setting is defined, then all other Control Properties + left undefined or set to false will not exist after the task is ran. + - The APIC defaults to C(yes) when unset during creation. + type: bool + symmetric_hash: + description: + - Determines if Symmetric Hashing is enabled. + - This makes up the LACP Policy Control Policy; if one setting is defined, then all other Control Properties + left undefined or set to false will not exist after the task is ran. + - The APIC defaults to C(no) when unset during creation. + type: bool + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +seealso: +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(lacp:LagPol). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Dag Wieers (@dagwieers) +''' + +# FIXME: Add more, better examples +EXAMPLES = r''' +- name: Add a port channel interface policy + cisco.aci.aci_interface_policy_port_channel: + host: '{{ inventory_hostname }}' + username: '{{ username }}' + password: '{{ password }}' + port_channel: '{{ port_channel }}' + description: '{{ description }}' + min_links: '{{ min_links }}' + max_links: '{{ max_links }}' + mode: '{{ mode }}' + delegate_to: localhost +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + port_channel=dict(type='str', aliases=['name']), # Not required for querying all objects + description=dict(type='str', aliases=['descr']), + min_links=dict(type='int'), + max_links=dict(type='int'), + mode=dict(type='str', choices=['active', 'mac-pin', 'mac-pin-nicload', 'off', 'passive']), + fast_select=dict(type='bool'), + graceful_convergence=dict(type='bool'), + load_defer=dict(type='bool'), + suspend_individual=dict(type='bool'), + symmetric_hash=dict(type='bool'), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['port_channel']], + ['state', 'present', ['port_channel']], + ], + ) + + port_channel = module.params.get('port_channel') + description = module.params.get('description') + min_links = module.params.get('min_links') + if min_links is not None and min_links not in range(1, 17): + module.fail_json(msg='The "min_links" must be a value between 1 and 16') + max_links = module.params.get('max_links') + if max_links is not None and max_links not in range(1, 17): + module.fail_json(msg='The "max_links" must be a value between 1 and 16') + mode = module.params.get('mode') + state = module.params.get('state') + name_alias = module.params.get('name_alias') + + # Build ctrl value for request + ctrl = [] + if module.params.get('fast_select') is True: + ctrl.append('fast-sel-hot-stdby') + if module.params.get('graceful_convergence') is True: + ctrl.append('graceful-conv') + if module.params.get('load_defer') is True: + ctrl.append('load-defer') + if module.params.get('suspend_individual') is True: + ctrl.append('susp-individual') + if module.params.get('symmetric_hash') is True: + ctrl.append('symmetric-hash') + if not ctrl: + ctrl = None + else: + ctrl = ",".join(ctrl) + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='lacpLagPol', + aci_rn='infra/lacplagp-{0}'.format(port_channel), + module_object=port_channel, + target_filter={'name': port_channel}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='lacpLagPol', + class_config=dict( + name=port_channel, + ctrl=ctrl, + descr=description, + minLinks=min_links, + maxLinks=max_links, + mode=mode, + nameAlias=name_alias, + ), + ) + + aci.get_diff(aci_class='lacpLagPol') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_port_security.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_port_security.py new file mode 100644 index 00000000..557fd2f4 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_policy_port_security.py @@ -0,0 +1,253 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_interface_policy_port_security +short_description: Manage port security (l2:PortSecurityPol) +description: +- Manage port security on Cisco ACI fabrics. +options: + port_security: + description: + - The name of the port security. + type: str + aliases: [ name ] + description: + description: + - The description for the contract. + type: str + aliases: [ descr ] + max_end_points: + description: + - Maximum number of end points. + - Accepted values range between C(0) and C(12000). + - The APIC defaults to C(0) when unset during creation. + type: int + port_security_timeout: + description: + - The delay time in seconds before MAC learning is re-enabled + - Accepted values range between C(60) and C(3600) + - The APIC defaults to C(60) when unset during creation + type: int + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +seealso: +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(l2:PortSecurityPol). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Dag Wieers (@dagwieers) +''' + +# FIXME: Add more, better examples +EXAMPLES = r''' +- name: Add a port security interface policy + cisco.aci.aci_interface_policy_port_security: + host: '{{ inventory_hostname }}' + username: '{{ username }}' + password: '{{ password }}' + port_security: '{{ port_security }}' + description: '{{ descr }}' + max_end_points: '{{ max_end_points }}' + port_security_timeout: '{{ port_security_timeout }}' + delegate_to: localhost +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + port_security=dict(type='str', aliases=['name']), # Not required for querying all objects + description=dict(type='str', aliases=['descr']), + max_end_points=dict(type='int'), + port_security_timeout=dict(type='int'), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['port_security']], + ['state', 'present', ['port_security']], + ], + ) + + port_security = module.params.get('port_security') + description = module.params.get('description') + max_end_points = module.params.get('max_end_points') + port_security_timeout = module.params.get('port_security_timeout') + name_alias = module.params.get('name_alias') + if max_end_points is not None and max_end_points not in range(12001): + module.fail_json(msg='The max_end_points must be between 0 and 12000') + if port_security_timeout is not None and port_security_timeout not in range(60, 3601): + module.fail_json(msg='The port_security_timeout must be between 60 and 3600') + state = module.params.get('state') + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='l2PortSecurityPol', + aci_rn='infra/portsecurityP-{0}'.format(port_security), + module_object=port_security, + target_filter={'name': port_security}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='l2PortSecurityPol', + class_config=dict( + name=port_security, + descr=description, + maximum=max_end_points, + nameAlias=name_alias, + timeout=port_security_timeout, + ), + ) + + aci.get_diff(aci_class='l2PortSecurityPol') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_selector_to_switch_policy_leaf_profile.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_selector_to_switch_policy_leaf_profile.py new file mode 100644 index 00000000..6921e015 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_interface_selector_to_switch_policy_leaf_profile.py @@ -0,0 +1,254 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2017, Bruno Calogero <brunocalogero@hotmail.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_interface_selector_to_switch_policy_leaf_profile +short_description: Bind interface selector profiles to switch policy leaf profiles (infra:RsAccPortP) +description: +- Bind interface selector profiles to switch policy leaf profiles on Cisco ACI fabrics. +options: + leaf_profile: + description: + - Name of the Leaf Profile to which we add a Selector. + type: str + aliases: [ leaf_profile_name ] + interface_selector: + description: + - Name of Interface Profile Selector to be added and associated with the Leaf Profile. + type: str + aliases: [ name, interface_selector_name, interface_profile_name ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- This module requires an existing leaf profile, the module M(cisco.aci.aci_switch_policy_leaf_profile) can be used for this. +seealso: +- module: cisco.aci.aci_switch_policy_leaf_profile +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(infra:RsAccPortP). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Bruno Calogero (@brunocalogero) +''' + +EXAMPLES = r''' +- name: Associating an interface selector profile to a switch policy leaf profile + cisco.aci.aci_interface_selector_to_switch_policy_leaf_profile: + host: apic + username: admin + password: SomeSecretPassword + leaf_profile: sw_name + interface_selector: interface_profile_name + state: present + delegate_to: localhost + +- name: Remove an interface selector profile associated with a switch policy leaf profile + cisco.aci.aci_interface_selector_to_switch_policy_leaf_profile: + host: apic + username: admin + password: SomeSecretPassword + leaf_profile: sw_name + interface_selector: interface_profile_name + state: absent + delegate_to: localhost + +- name: Query an interface selector profile associated with a switch policy leaf profile + cisco.aci.aci_interface_selector_to_switch_policy_leaf_profile: + host: apic + username: admin + password: SomeSecretPassword + leaf_profile: sw_name + interface_selector: interface_profile_name + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + leaf_profile=dict(type='str', aliases=['leaf_profile_name']), # Not required for querying all objects + interface_selector=dict(type='str', aliases=['interface_profile_name', 'interface_selector_name', 'name']), # Not required for querying all objects + state=dict(type='str', default='present', choices=['absent', 'present', 'query']) + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['leaf_profile', 'interface_selector']], + ['state', 'present', ['leaf_profile', 'interface_selector']] + ], + ) + + leaf_profile = module.params.get('leaf_profile') + # WARNING: interface_selector accepts non existing interface_profile names and they appear on APIC gui with a state of "missing-target" + interface_selector = module.params.get('interface_selector') + state = module.params.get('state') + + # Defining the interface profile tDn for clarity + interface_selector_tDn = 'uni/infra/accportprof-{0}'.format(interface_selector) + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='infraNodeP', + aci_rn='infra/nprof-{0}'.format(leaf_profile), + module_object=leaf_profile, + target_filter={'name': leaf_profile}, + ), + subclass_1=dict( + aci_class='infraRsAccPortP', + aci_rn='rsaccPortP-[{0}]'.format(interface_selector_tDn), + module_object=interface_selector, + target_filter={'name': interface_selector}, + ) + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='infraRsAccPortP', + class_config=dict(tDn=interface_selector_tDn), + ) + + aci.get_diff(aci_class='infraRsAccPortP') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_l2out.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_l2out.py new file mode 100644 index 00000000..5550c715 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_l2out.py @@ -0,0 +1,320 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2020, Sudhakar Shet Kudtarkar (@kudtarkar1) +# Copyright: (c) 2020, Shreyas Srish <ssrish@cisco.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + +DOCUMENTATION = r''' +--- +module: aci_l2out +short_description: Manage Layer2 Out (L2Out) objects. +description: +- Manage Layer2 Out configuration on Cisco ACI fabrics. +options: + tenant: + description: + - Name of an existing tenant. + type: str + l2out: + description: + - The name of outer layer2. + type: str + aliases: [ 'name' ] + description: + description: + - Description for the L2Out. + type: str + bd: + description: + - Name of the Bridge domain which is associted with the L2Out. + type: str + domain: + description: + - Name of the external L2 Domain that is being associated with L2Out. + type: str + vlan: + description: + - The VLAN which is being associated with the L2Out. + type: int + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- The C(tenant) must exist before using this module in your playbook. + The M(cisco.aci.aci_tenant) modules can be used for this. +seealso: +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(fvTenant). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Sudhakar Shet Kudtarkar (@kudtarkar1) +- Shreyas Srish (@shrsr) +''' + +EXAMPLES = r''' +- name: Add a new L2Out + cisco.aci.aci_l2out: + host: apic + username: admin + password: SomeSecretePassword + tenant: Auto-Demo + l2out: l2out + description: via Ansible + bd: bd1 + domain: l2Dom + vlan: 3200 + state: present + delegate_to: localhost + +- name: Remove an L2Out + cisco.aci.aci_l2out: + host: apic + username: admin + password: SomeSecretePassword + tenant: Auto-Demo + l2out: l2out + state: absent + delegate_to: localhost + +- name: Query an L2Out + cisco.aci.aci_l2out: + host: apic + username: admin + password: SomeSecretePassword + tenant: Auto-Demo + l2out: l2out + state: query + delegate_to: localhost + register: query_result + +- name: Query all L2Outs in a specific tenant + cisco.aci.aci_l2out: + host: apic + username: admin + password: SomeSecretePassword + tenant: Auto-Demo + state: query + delegate_to: localhost + register: query_result +''' + +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: str + sample: '<?xml version="1.0" encoding="UTF-8"?><imdata totalCount="1"><error code="122" text="unknown managed object class "/></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: str + sample: ?rsp-prop-include=config-only + method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST + response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json + ''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + bd=dict(type='str'), + l2out=dict(type='str', aliases=['name']), + domain=dict(type='str'), + vlan=dict(type='int'), + description=dict(type='str'), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + tenant=dict(type='str'), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['l2out', 'tenant']], + ['state', 'present', ['bd', 'l2out', 'tenant', 'domain', 'vlan']], + ], + ) + + bd = module.params.get('bd') + l2out = module.params.get('l2out') + description = module.params.get('description') + domain = module.params.get('domain') + vlan = module.params.get('vlan') + state = module.params.get('state') + tenant = module.params.get('tenant') + name_alias = module.params.get('name_alias') + child_classes = ['l2extRsEBd', 'l2extRsL2DomAtt', 'l2extLNodeP'] + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + module_object=tenant, + target_filter={'name': tenant}, + ), + subclass_1=dict( + aci_class='l2extOut', + aci_rn='l2out-{0}'.format(l2out), + module_object=l2out, + target_filter={'name': l2out}, + ), + child_classes=child_classes, + ) + + aci.get_existing() + + if state == 'present': + child_configs = [ + dict( + l2extRsL2DomAtt=dict( + attributes=dict( + tDn='uni/l2dom-{0}'.format(domain) + ) + ) + ), + dict( + l2extRsEBd=dict( + attributes=dict( + tnFvBDName=bd, encap='vlan-{0}'.format(vlan) + ) + ) + ) + ] + + aci.payload( + aci_class='l2extOut', + class_config=dict( + name=l2out, + descr=description, + dn='uni/tn-{0}/l2out-{1}'.format(tenant, l2out), + nameAlias=name_alias + ), + child_configs=child_configs, + ) + + aci.get_diff(aci_class='l2extOut') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_l2out_extepg.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_l2out_extepg.py new file mode 100644 index 00000000..8111e2b2 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_l2out_extepg.py @@ -0,0 +1,310 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2020, Sudhakar Shet Kudtarkar (@kudtarkar1) +# Copyright: (c) 2020, Shreyas Srish <ssrish@cisco.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + + +DOCUMENTATION = r''' +--- +module: aci_l2out_extepg +short_description: Manage External Network Instance (L2Out External EPG) objects (l2extInstP). +description: +- Manage External Network Instance (L2Out External EPG) objects (l2extInstP) on ACI fabrics. +options: + tenant: + description: + - Name of existing tenant. + type: str + l2out: + description: + - Name of the l2out. + type: str + extepg: + description: + - Name of the external end point group. + type: str + aliases: [ external_epg, extepg_name, name ] + description: + description: + - Description for the l2out. + type: str + preferred_group: + description: + - This depicts whether this External EPG is part of the Preferred Group and can communicate without contracts. + - This is convenient for migration scenarios, or when ACI is used for network automation but not for policy. + - The APIC defaults to C(no) when unset during creation. + type: bool + qos_class: + description: + - The bandwidth level for Quality of service. + type: str + choices: [ level1, level2, level3, level4, level5, level6, Unspecified ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- The C(tenant) and C(l2out) must exist before using this module in your playbook. + The M(cisco.aci.aci_tenant) and M(cisco.aci.aci_l2out) modules can be used for this. +seealso: +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(fvtenant) and B(l2extOut). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Sudhakar Shet Kudtarkar (@kudtarkar1) +- Shreyas Srish (@shrsr) +''' + +EXAMPLES = r''' +- name: Add a new L2 external end point group + cisco.aci.aci_l2out_extepg: + host: apic + username: admin + password: SomeSecretePassword + tenant: Auto-Demo + l2out: l2out + extepg: NewExt + description: external epg + preferred_group: False + state: present + delegate_to: localhost + +- name: Remove an L2 external end point group + cisco.aci.aci_l2out_extepg: + host: apic + username: admin + password: SomeSecretePassword + tenant: Auto-Demo + l2out: l2out + extepg: NewExt + state: absent + delegate_to: localhost + +- name: Query the L2 external end point group + cisco.aci.aci_l2out_extepg: + host: apic + username: admin + password: SomeSecretePassword + tenant: Auto-Demo + l2out: l2out + extepg: NewExt + state: query + delegate_to: localhost + register: query_result + +- name: Query all L2 external end point groups in a tenant + cisco.aci.aci_l2out_extepg: + host: apic + username: admin + password: SomeSecretePassword + tenant: Auto-Demo + state: query + delegate_to: localhost + register: query_result +''' + +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: str + sample: '<?xml version="1.0" encoding="UTF-8"?><imdata totalCount="1"><error code="122" text="unknown managed object class "/></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: str + sample: ?rsp-prop-include=config-only + method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST + response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json + ''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + l2out=dict(type='str'), + description=dict(type='str'), + extepg=dict(type='str', aliases=['external_epg', 'extepg_name', 'name']), + preferred_group=dict(type='bool'), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + tenant=dict(type='str'), + qos_class=dict(type='str', choices=['level1', 'level2', 'level3', 'level4', 'level5', 'level6', 'Unspecified']), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['l2out', 'tenant', 'extepg']], + ['state', 'present', ['l2out', 'tenant', 'extepg']], + ], + ) + + aci = ACIModule(module) + + l2out = module.params.get('l2out') + description = module.params.get('description') + preferred_group = aci.boolean(module.params.get('preferred_group'), 'include', 'exclude') + state = module.params.get('state') + tenant = module.params.get('tenant') + extepg = module.params.get('extepg') + qos_class = module.params.get('qos_class') + + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + module_object=tenant, + target_filter={'name': tenant}, + ), + subclass_1=dict( + aci_class='l2extOut', + aci_rn='l2out-{0}'.format(l2out), + module_object=l2out, + target_filter={'name': l2out}, + ), + subclass_2=dict( + aci_class='l2extInstP', + aci_rn='instP-{0}'.format(extepg), + module_object=extepg, + target_filter={'name': extepg}, + + ) + ) + + aci.get_existing() + + if state == 'present': + config = dict( + name=extepg, + descr=description, + dn='uni/tn-{0}/l2out-{1}/instP-{2}'.format(tenant, l2out, extepg), + prefGrMemb=preferred_group + ) + if qos_class: + config.update(prio=qos_class) + aci.payload( + class_config=config, + aci_class='l2extInstP', + ) + + aci.get_diff(aci_class='l2extInstP') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_l3out.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_l3out.py new file mode 100644 index 00000000..50fee411 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_l3out.py @@ -0,0 +1,367 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_l3out +short_description: Manage Layer 3 Outside (L3Out) objects (l3ext:Out) +description: +- Manage Layer 3 Outside (L3Out) on Cisco ACI fabrics. +options: + tenant: + description: + - Name of an existing tenant. + type: str + aliases: [ tenant_name ] + l3out: + description: + - Name of L3Out being created. + type: str + aliases: [ l3out_name, name ] + vrf: + description: + - Name of the VRF being associated with the L3Out. + type: str + aliases: [ vrf_name ] + domain: + description: + - Name of the external L3 domain being associated with the L3Out. + type: str + aliases: [ ext_routed_domain_name, routed_domain ] + dscp: + description: + - The target Differentiated Service (DSCP) value. + - The APIC defaults to C(unspecified) when unset during creation. + type: str + choices: [ AF11, AF12, AF13, AF21, AF22, AF23, AF31, AF32, AF33, AF41, AF42, AF43, CS0, CS1, CS2, CS3, CS4, CS5, CS6, CS7, EF, VA, unspecified ] + aliases: [ target ] + route_control: + description: + - Route Control enforcement direction. The only allowed values are export or import,export. + type: list + elements: str + choices: [ export, import ] + aliases: [ route_control_enforcement ] + l3protocol: + description: + - Routing protocol for the L3Out + type: list + elements: str + choices: [ bgp, eigrp, ospf, pim, static ] + asn: + description: + - The AS number for the L3Out. + - Only applicable when using 'eigrp' as the l3protocol + type: int + aliases: [ as_number ] + description: + description: + - Description for the L3Out. + type: str + aliases: [ descr ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- The C(tenant) and C(domain) and C(vrf) used must exist before using this module in your playbook. + The M(cisco.aci.aci_tenant) and M(cisco.aci.aci_domain) and M(cisco.aci.aci_vrf) modules can be used for this. +seealso: +- module: cisco.aci.aci_tenant +- module: cisco.aci.aci_domain +- module: cisco.aci.aci_vrf +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(l3ext:Out). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Rostyslav Davydenko (@rost-d) +''' + +EXAMPLES = r''' +- name: Add a new L3Out + cisco.aci.aci_l3out: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + name: prod_l3out + description: L3Out for Production tenant + domain: l3dom_prod + vrf: prod + l3protocol: ospf + state: present + delegate_to: localhost + +- name: Delete L3Out + cisco.aci.aci_l3out: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + name: prod_l3out + state: absent + delegate_to: localhost + +- name: Query L3Out information + cisco.aci.aci_l3out: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + name: prod_l3out + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects + l3out=dict(type='str', aliases=['l3out_name', 'name']), # Not required for querying all objects + domain=dict(type='str', aliases=['ext_routed_domain_name', 'routed_domain']), + vrf=dict(type='str', aliases=['vrf_name']), + description=dict(type='str', aliases=['descr']), + route_control=dict(type='list', elements='str', choices=['export', 'import'], aliases=['route_control_enforcement']), + dscp=dict(type='str', + choices=['AF11', 'AF12', 'AF13', 'AF21', 'AF22', 'AF23', 'AF31', 'AF32', 'AF33', 'AF41', 'AF42', + 'AF43', 'CS0', 'CS1', 'CS2', 'CS3', 'CS4', 'CS5', 'CS6', 'CS7', 'EF', 'VA', 'unspecified'], + aliases=['target']), + l3protocol=dict(type='list', elements='str', choices=['bgp', 'eigrp', 'ospf', 'pim', 'static']), + asn=dict(type='int', aliases=['as_number']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['l3out', 'tenant']], + ['state', 'present', ['l3out', 'tenant', 'domain', 'vrf']], + ], + ) + + aci = ACIModule(module) + + l3out = module.params.get('l3out') + domain = module.params.get('domain') + dscp = module.params.get('dscp') + description = module.params.get('description') + enforceRtctrl = module.params.get('route_control') + vrf = module.params.get('vrf') + l3protocol = module.params.get('l3protocol') + asn = module.params.get('asn') + state = module.params.get('state') + tenant = module.params.get('tenant') + name_alias = module.params.get('name_alias') + + if l3protocol: + if 'eigrp' in l3protocol and asn is None: + module.fail_json(msg="Parameter 'asn' is required when l3protocol is 'eigrp'") + if 'eigrp' not in l3protocol and asn is not None: + module.warn("Parameter 'asn' is only applicable when l3protocol is 'eigrp'. The ASN will be ignored") + + enforce_ctrl = '' + if enforceRtctrl is not None: + if len(enforceRtctrl) == 1 and enforceRtctrl[0] == 'import': + aci.fail_json( + "The route_control parameter is invalid: allowed options are export or import,export only") + elif len(enforceRtctrl) == 1 and enforceRtctrl[0] == 'export': + enforce_ctrl = 'export' + else: + enforce_ctrl = 'export,import' + child_classes = ['l3extRsL3DomAtt', 'l3extRsEctx', 'bgpExtP', 'ospfExtP', 'eigrpExtP', 'pimExtP'] + + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + module_object=tenant, + target_filter={'name': tenant}, + ), + subclass_1=dict( + aci_class='l3extOut', + aci_rn='out-{0}'.format(l3out), + module_object=l3out, + target_filter={'name': l3out}, + ), + child_classes=child_classes, + ) + + aci.get_existing() + + child_configs = [ + dict(l3extRsL3DomAtt=dict(attributes=dict( + tDn='uni/l3dom-{0}'.format(domain)))), + dict(l3extRsEctx=dict(attributes=dict(tnFvCtxName=vrf))), + ] + if l3protocol is not None: + for protocol in l3protocol: + if protocol == 'bgp': + child_configs.append( + dict(bgpExtP=dict(attributes=dict(descr='', nameAlias='')))) + elif protocol == 'eigrp': + child_configs.append( + dict(eigrpExtP=dict(attributes=dict(descr='', nameAlias='', asn=asn)))) + elif protocol == 'ospf': + child_configs.append( + dict(ospfExtP=dict(attributes=dict(descr='', nameAlias='')))) + elif protocol == 'pim': + child_configs.append( + dict(pimExtP=dict(attributes=dict(descr='', nameAlias='')))) + + if state == 'present': + aci.payload( + aci_class='l3extOut', + class_config=dict( + name=l3out, + descr=description, + dn='uni/tn-{0}/out-{1}'.format(tenant, l3out), + enforceRtctrl=enforce_ctrl, + targetDscp=dscp, + nameAlias=name_alias, + ), + child_configs=child_configs, + ) + + aci.get_diff(aci_class='l3extOut') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_l3out_extepg.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_l3out_extepg.py new file mode 100644 index 00000000..bbe4dfa6 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_l3out_extepg.py @@ -0,0 +1,309 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_l3out_extepg +short_description: Manage External Network Instance Profile (ExtEpg) objects (l3extInstP:instP) +description: +- Manage External Network Instance Profile (ExtEpg) objects (l3extInstP:instP) +options: + tenant: + description: + - Name of an existing tenant. + type: str + aliases: [ tenant_name ] + l3out: + description: + - Name of an existing L3Out. + type: str + aliases: [ l3out_name ] + extepg: + description: + - Name of ExtEpg being created. + type: str + aliases: [ extepg_name, name ] + description: + description: + - Description for the ExtEpg. + type: str + aliases: [ descr ] + preferred_group: + description: + - Whether ot not the EPG is part of the Preferred Group and can communicate without contracts. + - This is very convenient for migration scenarios, or when ACI is used for network automation but not for policy. + - The APIC defaults to C(no) when unset during creation. + type: bool + dscp: + description: + - The target Differentiated Service (DSCP) value. + - The APIC defaults to C(unspecified) when unset during creation. + type: str + choices: [ AF11, AF12, AF13, AF21, AF22, AF23, AF31, AF32, AF33, AF41, AF42, AF43, CS0, CS1, CS2, CS3, CS4, CS5, CS6, CS7, EF, VA, unspecified ] + aliases: [ target ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- The C(tenant) and C(domain) and C(vrf) used must exist before using this module in your playbook. + The M(cisco.aci.aci_tenant) and M(cisco.aci.aci_domain) and M(cisco.aci.aci_vrf) modules can be used for this. +seealso: +- module: cisco.aci.aci_tenant +- module: cisco.aci.aci_domain +- module: cisco.aci.aci_vrf +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(l3ext:Out). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Rostyslav Davydenko (@rost-d) +''' + +EXAMPLES = r''' +- name: Add a new ExtEpg + cisco.aci.aci_l3out_extepg: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + l3out: prod_l3out + name: prod_extepg + description: ExtEpg for Production L3Out + state: present + delegate_to: localhost + +- name: Delete ExtEpg + cisco.aci.aci_extepg: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + l3out: prod_l3out + name: prod_extepg + state: absent + delegate_to: localhost + +- name: Query ExtEpg information + cisco.aci.aci_l3out_extepg: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + l3out: prod_l3out + name: prod_extepg + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects + l3out=dict(type='str', aliases=['l3out_name']), # Not required for querying all objects + extepg=dict(type='str', aliases=['extepg_name', 'name']), # Not required for querying all objects + description=dict(type='str', aliases=['descr']), + preferred_group=dict(type='bool'), + dscp=dict(type='str', + choices=['AF11', 'AF12', 'AF13', 'AF21', 'AF22', 'AF23', 'AF31', 'AF32', 'AF33', 'AF41', 'AF42', + 'AF43', 'CS0', 'CS1', 'CS2', 'CS3', 'CS4', 'CS5', 'CS6', 'CS7', 'EF', 'VA', 'unspecified'], + aliases=['target']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'present', ['extepg', 'l3out', 'tenant']], + ['state', 'absent', ['extepg', 'l3out', 'tenant']], + ], + ) + + aci = ACIModule(module) + + tenant = module.params.get('tenant') + l3out = module.params.get('l3out') + extepg = module.params.get('extepg') + description = module.params.get('description') + preferred_group = aci.boolean(module.params.get('preferred_group'), 'include', 'exclude') + dscp = module.params.get('dscp') + state = module.params.get('state') + name_alias = module.params.get('name_alias') + + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + module_object=tenant, + target_filter={'name': tenant}, + ), + subclass_1=dict( + aci_class='l3extOut', + aci_rn='out-{0}'.format(l3out), + module_object=l3out, + target_filter={'name': l3out}, + ), + subclass_2=dict( + aci_class='l3extInstP', + aci_rn='instP-{0}'.format(extepg), + module_object=extepg, + target_filter={'name': extepg}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='l3extInstP', + class_config=dict( + name=extepg, + descr=description, + prefGrMemb=preferred_group, + targetDscp=dscp, + nameAlias=name_alias, + ), + ) + + aci.get_diff(aci_class='l3extInstP') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_l3out_extepg_to_contract.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_l3out_extepg_to_contract.py new file mode 100644 index 00000000..9bc94fe7 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_l3out_extepg_to_contract.py @@ -0,0 +1,346 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2020, Sudhakar Shet Kudtarkar (@kudtarkar1) +# Copyright: (c) 2020, Shreyas Srish <ssrish@cisco.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + +DOCUMENTATION = r''' +--- +module: aci_l3out_extepg_to_contract +short_description: Bind Contracts to External End Point Groups (EPGs) +description: +- Bind Contracts to External End Point Groups (EPGs) on ACI fabrics. +options: + tenant: + description: + - Name of existing tenant. + type: str + l3out: + description: + - Name of the l3out. + type: str + aliases: ['l3out_name'] + extepg: + description: + - Name of the external end point group. + type: str + aliases: ['extepg_name', 'external_epg'] + contract: + description: + - Name of the contract. + type: str + contract_type: + description: + - The type of contract. + type: str + required: yes + choices: ['consumer', 'provider'] + priority: + description: + - This has four levels of priority. + type: str + choices: ['level1', 'level2', 'level3', 'unspecified'] + provider_match: + description: + - This is configurable for provided contracts. + type: str + choices: ['all', 'at_least_one', 'at_most_one', 'none'] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- The C(tenant), C(l3out) and C(extepg) must exist before using this module in your playbook. + The M(cisco.aci.aci_tenant), M(cisco.aci.aci_l3out) and M(cisco.aci.aci_l3out_extepg) modules can be used for this. +seealso: +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(fvtenant), B(l3extInstP) and B(l3extOut). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Sudhakar Shet Kudtarkar (@kudtarkar1) +- Shreyas Srish (@shrsr) +''' + +EXAMPLES = r''' +- name: Bind a contract to an external EPG + cisco.aci.aci_l3out_epg_to_contract: + host: apic + username: admin + password: SomeSecretePassword + tenant: Auto-Demo + l3out: l3out + extepg : testEpg + contract: contract1 + contract_type: provider + state: present + delegate_to: localhost + +- name: Remove existing contract from an external EPG + cisco.aco.aci_l3out_epg_to_contract: + host: apic + username: admin + password: SomeSecretePassword + tenant: Auto-Demo + l3out: l3out + extepg : testEpg + contract: contract1 + contract_type: provider + state: absent + delegate_to: localhost + +- name: Query a contract bound to an external EPG + cisco.aci.aci_l3out_epg_to_contract: + host: apic + username: admin + password: SomeSecretePassword + tenant: ansible_tenant + l3out: ansible_l3out + extepg: ansible_extEpg + contract: ansible_contract + contract_type: provider + state: query + delegate_to: localhost + register: query_result + +- name: Query all contracts relationships + cisco.aci.aci_l3out_epg_to_contract: + host: apic + username: admin + password: SomeSecretePassword + contract_type: provider + state: query + delegate_to: localhost + register: query_result +''' + +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: str + sample: '<?xml version="1.0" encoding="UTF-8"?><imdata totalCount="1"><error code="122" text="unknown managed object class "/></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: str + sample: ?rsp-prop-include=config-only + method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST + response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json + ''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + +ACI_CLASS_MAPPING = dict( + consumer={ + 'class': 'fvRsCons', + 'rn': 'rscons-', + }, + provider={ + 'class': 'fvRsProv', + 'rn': 'rsprov-', + }, +) + +PROVIDER_MATCH_MAPPING = dict( + all='All', + at_least_one='AtleastOne', + at_most_one='tmostOne', + none='None', +) + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + contract_type=dict(type='str', required=True, choices=['consumer', 'provider']), + l3out=dict(type='str', aliases=['l3out_name']), + contract=dict(type='str'), + priority=dict(type='str', choices=['level1', 'level2', 'level3', 'unspecified']), + provider_match=dict(type='str', choices=['all', 'at_least_one', 'at_most_one', 'none']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + tenant=dict(type='str'), + extepg=dict(type='str', aliases=['extepg_name', 'external_epg']), + ) + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['extepg', 'contract', 'l3out', 'tenant']], + ['state', 'present', ['extepg', 'contract', 'l3out', 'tenant']], + ], + ) + + l3out = module.params.get('l3out') + contract = module.params.get('contract') + contract_type = module.params.get('contract_type') + extepg = module.params.get('extepg') + priority = module.params.get('priority') + provider_match = module.params.get('provider_match') + if provider_match is not None: + provider_match = PROVIDER_MATCH_MAPPING.get(provider_match) + state = module.params.get('state') + tenant = module.params.get('tenant') + + aci_class = ACI_CLASS_MAPPING.get(contract_type)["class"] + aci_rn = ACI_CLASS_MAPPING.get(contract_type)["rn"] + + if contract_type == "consumer" and provider_match is not None: + module.fail_json(msg="the 'provider_match' is only configurable for Provided Contracts") + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + module_object=tenant, + target_filter={'name': tenant}, + ), + subclass_1=dict( + aci_class='l3extOut', + aci_rn='out-{0}'.format(l3out), + module_object=l3out, + target_filter={'name': l3out}, + ), + subclass_2=dict( + aci_class='l3extInstP', + aci_rn='instP-{0}'.format(extepg), + module_object=extepg, + target_filter={'name': extepg}, + ), + subclass_3=dict( + aci_class=aci_class, + aci_rn='{0}{1}'.format(aci_rn, contract), + module_object=contract, + target_filter={'tnVzBrCPName': contract}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class=aci_class, + class_config=dict( + matchT=provider_match, + prio=priority, + tnVzBrCPName=contract, + ), + ) + + aci.get_diff(aci_class=aci_class) + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_l3out_extsubnet.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_l3out_extsubnet.py new file mode 100644 index 00000000..cddd76a6 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_l3out_extsubnet.py @@ -0,0 +1,332 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_l3out_extsubnet +short_description: Manage External Subnet objects (l3extSubnet:extsubnet) +description: +- Manage External Subnet objects (l3extSubnet:extsubnet) +options: + tenant: + description: + - Name of an existing tenant. + type: str + aliases: [ tenant_name ] + required: yes + l3out: + description: + - Name of an existing L3Out. + type: str + aliases: [ l3out_name ] + required: yes + extepg: + description: + - Name of an existing ExtEpg. + type: str + aliases: [ extepg_name ] + required: yes + network: + description: + - The network address for the Subnet. + type: str + aliases: [ address, ip ] + subnet_name: + description: + - Name of External Subnet being created. + type: str + aliases: [ name ] + description: + description: + - Description for the External Subnet. + type: str + aliases: [ descr ] + scope: + description: + - Determines the scope of the Subnet. + - The C(export-rtctrl) option controls which external networks are advertised out of the fabric using route-maps and IP prefix-lists. + - The C(import-security) option classifies for the external EPG. + The rules and contracts defined in this external EPG apply to networks matching this subnet. + - The C(shared-rtctrl) option controls which external prefixes are advertised to other tenants for shared services. + - The C(shared-security) option configures the classifier for the subnets in the VRF where the routes are leaked. + - The APIC defaults to C(import-security) when unset during creation. + default: [ import-security ] + type: list + elements: str + choices: [ export-rtctrl, import-security, shared-rtctrl, shared-security ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- The C(tenant) and C(domain) and C(vrf) used must exist before using this module in your playbook. + The M(cisco.aci.aci_tenant) and M(cisco.aci.aci_domain) and M(cisco.aci.aci_vrf) modules can be used for this. +seealso: +- module: cisco.aci.aci_tenant +- module: cisco.aci.aci_domain +- module: cisco.aci.aci_vrf +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(l3ext:Out). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Rostyslav Davydenko (@rost-d) +- Cindy Zhao (@cizhao) +''' + +EXAMPLES = r''' +- name: Add a new External Subnet + cisco.aci.aci_l3out_extsubnet: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + l3out: prod_l3out + extepg: prod_extepg + description: External Subnet for Production ExtEpg + network: 192.0.2.0/24 + scope: export-rtctrl + state: present + delegate_to: localhost + +- name: Delete External Subnet + cisco.aci.aci_l3out_extsubnet: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + l3out: prod_l3out + extepg: prod_extepg + network: 192.0.2.0/24 + state: absent + delegate_to: localhost + +- name: Query ExtEpg Subnet information + cisco.aci.aci_l3out_extsubnet: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + l3out: prod_l3out + extepg: prod_extepg + network: 192.0.2.0/24 + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + tenant=dict(type='str', required=True, aliases=['tenant_name']), + l3out=dict(type='str', required=True, aliases=['l3out_name']), + extepg=dict(type='str', required=True, aliases=['extepg_name', 'name']), + network=dict(type='str', aliases=['address', 'ip']), + description=dict(type='str', aliases=['descr']), + subnet_name=dict(type='str', aliases=['name']), + scope=dict(type='list', elements='str', default=['import-security'], choices=['export-rtctrl', 'import-security', 'shared-rtctrl', 'shared-security']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'present', ['network']], + ['state', 'absent', ['network']], + ], + ) + + aci = ACIModule(module) + + tenant = module.params.get('tenant') + l3out = module.params.get('l3out') + extepg = module.params.get('extepg') + network = module.params.get('network') + description = module.params.get('description') + subnet_name = module.params.get('subnet_name') + scope = ','.join(sorted(module.params.get('scope'))) + state = module.params.get('state') + name_alias = module.params.get('name_alias') + + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + module_object=tenant, + target_filter={'name': tenant}, + ), + subclass_1=dict( + aci_class='l3extOut', + aci_rn='out-{0}'.format(l3out), + module_object=l3out, + target_filter={'name': l3out}, + ), + subclass_2=dict( + aci_class='l3extInstP', + aci_rn='instP-{0}'.format(extepg), + module_object=extepg, + target_filter={'name': extepg}, + ), + subclass_3=dict( + aci_class='l3extSubnet', + aci_rn='extsubnet-[{0}]'.format(network), + module_object=network, + target_filter={'name': network}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='l3extSubnet', + class_config=dict( + ip=network, + descr=description, + name=subnet_name, + scope=scope, + nameAlias=name_alias, + ), + ) + + aci.get_diff(aci_class='l3extSubnet') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_l3out_logical_interface_vpc_member.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_l3out_logical_interface_vpc_member.py new file mode 100644 index 00000000..61110acb --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_l3out_logical_interface_vpc_member.py @@ -0,0 +1,340 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2020, Anvitha Jain(@anvitha-jain) <anvjain@cisco.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_l3out_logical_interface_vpc_member +short_description: Manage Member Node objects (l3extMember:Member) +description: +- Manage Member Node objects (l3extMember:Member) +options: + description: + description: + - The description for the logical interface VPC member. + type: str + aliases: [ descr ] + tenant: + description: + - Name of an existing tenant. + type: str + aliases: [ tenant_name ] + l3out: + description: + - Name of an existing L3Out. + type: str + aliases: [ l3out_name ] + logical_node: + description: + - Name of an existing logical node profile. + type: str + logical_interface: + description: + - Name of an existing logical interface. + type: str + path_dn: + description: + - DN of existing path endpoints for VPC policy group used to reach external L3 network. + type: str + side: + description: + - Provides the side of member. + type: str + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- The C(tenant), C(l3out), C(logical_node), C(logical_interface), C(path_dn) and C(member) used must exist before using this module in your playbook. + The M(cisco.aci.aci_tenant) and M(cisco.aci.aci_l3out) modules can be used for this. +seealso: +- module: cisco.aci.aci_tenant +- module: cisco.aci.aci_l3out +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(l3ext:Out). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Anvitha Jain(@anvitha-jain) +''' + +EXAMPLES = r''' +- name: Create a VPC member + cisco.aci.aci_l3out_logical_interface_vpc_member: + host: apic + username: admin + password: SomeSecretPassword + tenant: tenantName + l3out: l3out + logical_node: nodeName + logical_interface: interfaceName + path_dn: topology/pod-1/protpaths-101-102/pathep-[policy_group_name] + side: A + state: present + delegate_to: localhost + +- name: Delete a VPC member + cisco.aci.aci_l3out_logical_interface_vpc_member: + host: apic + username: admin + password: SomeSecretPassword + tenant: tenantName + l3out: l3out + logical_node: nodeName + logical_interface: interfaceName + path_dn: topology/pod-1/protpaths-101-102/pathep-[policy_group_name] + side: A + state: absent + delegate_to: localhost + +- name: Query all VPC members + cisco.aci.aci_l3out_logical_interface_vpc_member: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + state: query + delegate_to: localhost + register: query_result + +- name: Query a specific VPC member under l3out + cisco.aci.aci_l3out_logical_interface_vpc_member: + host: apic + username: admin + password: SomeSecretPassword + tenant: tenantName + l3out: l3out + logical_node: nodeName + logical_interface: interfaceName + path_dn: topology/pod-1/protpaths-101-102/pathep-[policy_group_name] + side: A + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects + l3out=dict(type='str', aliases=['l3out_name']), # Not required for querying all objects + logical_node=dict(type='str'), # Not required for querying all objects + logical_interface=dict(type='str'), + path_dn=dict(type='str'), + side=dict(type='str'), + description=dict(type='str', aliases=['descr']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'present', ['side', 'path_dn', 'logical_interface', 'logical_node', 'l3out', 'tenant']], + ['state', 'absent', ['side', 'path_dn', 'logical_interface', 'logical_node', 'l3out', 'tenant']], + ], + ) + + aci = ACIModule(module) + + tenant = module.params.get('tenant') + l3out = module.params.get('l3out') + logical_node = module.params.get('logical_node') + logical_interface = module.params.get('logical_interface') + path_dn = module.params.get('path_dn') + side = module.params.get('side') + description = module.params.get('description') + state = module.params.get('state') + name_alias = module.params.get('name_alias') + + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + module_object=tenant, + target_filter={'name': tenant}, + ), + subclass_1=dict( + aci_class='l3extOut', + aci_rn='out-{0}'.format(l3out), + module_object=l3out, + target_filter={'name': l3out}, + ), + subclass_2=dict( + aci_class='l3extLNodeP', + aci_rn='lnodep-{0}'.format(logical_node), + module_object=logical_node, + target_filter={'name': logical_node}, + ), + subclass_3=dict( + aci_class='l3extLIfP', + aci_rn='/lifp-{0}'.format(logical_interface), + module_object=logical_interface, + target_filter={'name': logical_interface}, + ), + subclass_4=dict( + aci_class='l3extRsPathL3OutAtt', + aci_rn='/rspathL3OutAtt-[{0}]'.format(path_dn), + module_object=path_dn, + target_filter={'name': path_dn}, + ), + subclass_5=dict( + aci_class='l3extMember', + aci_rn='/mem-{0}'.format(side), + module_object=side, + target_filter={'name': side}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='l3extMember', + class_config=dict( + name=side, + descr=description, + nameAlias=name_alias, + ), + ) + + aci.get_diff(aci_class='l3extMember') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_l3out_route_tag_policy.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_l3out_route_tag_policy.py new file mode 100644 index 00000000..412a492d --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_l3out_route_tag_policy.py @@ -0,0 +1,255 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_l3out_route_tag_policy +short_description: Manage route tag policies (l3ext:RouteTagPol) +description: +- Manage route tag policies on Cisco ACI fabrics. +options: + rtp: + description: + - The name of the route tag policy. + type: str + aliases: [ name, rtp_name ] + description: + description: + - The description for the route tag policy. + type: str + aliases: [ descr ] + tenant: + description: + - The name of the tenant. + type: str + aliases: [ tenant_name ] + tag: + description: + - The value of the route tag. + - Accepted values range between C(0) and C(4294967295). + - The APIC defaults to C(4294967295) when unset during creation. + type: int + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- The C(tenant) used must exist before using this module in your playbook. + The M(cisco.aci.aci_tenant) module can be used for this. +seealso: +- module: cisco.aci.aci_tenant +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(l3ext:RouteTagPol). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Dag Wieers (@dagwieers) +''' + +# FIXME: Add more, better examples +EXAMPLES = r''' +- cisco.aci.aci_l3out_route_tag_policy: + host: apic + username: admin + password: SomeSecretPassword + rtp: '{{ rtp_name }}' + tenant: production + tag: '{{ tag }}' + description: '{{ description }}' + delegate_to: localhost +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects + rtp=dict(type='str', aliases=['name', 'rtp_name']), # Not required for querying all objects + description=dict(type='str', aliases=['descr']), + tag=dict(type='int'), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['rtp', 'tenant']], + ['state', 'present', ['rtp', 'tenant']], + ], + ) + + rtp = module.params.get('rtp') + description = module.params.get('description') + tag = module.params.get('tag') + state = module.params.get('state') + tenant = module.params.get('tenant') + name_alias = module.params.get('name_alias') + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + module_object=tenant, + target_filter={'name': tenant}, + ), + subclass_1=dict( + aci_class='l3extRouteTagPol', + aci_rn='rttag-{0}'.format(rtp), + module_object=rtp, + target_filter={'name': rtp}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='l3extRouteTagPol', + class_config=dict( + name=rtp, + descr=description, tag=tag, + nameAlias=name_alias, + ), + ) + + aci.get_diff(aci_class='l3extRouteTagPol') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_l3out_static_routes.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_l3out_static_routes.py new file mode 100644 index 00000000..2faf6e3b --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_l3out_static_routes.py @@ -0,0 +1,368 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2020, Anvitha Jain(@anvitha-jain) <anvjain@cisco.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_l3out_static_routes +short_description: Manage Static routes object (l3ext:ipRouteP) +description: +- Manage External Subnet objects (l3ext:ipRouteP) +options: + description: + description: + - The description for the static routes. + type: str + aliases: [ descr ] + tenant: + description: + - Name of an existing tenant. + type: str + aliases: [ tenant_name ] + l3out: + description: + - Name of an existing L3Out. + type: str + aliases: [ l3out_name ] + logical_node: + description: + - Name of an existing logical node profile. + type: str + pod_id: + description: + - Existing podId. + type: int + node_id: + description: + - Existing nodeId. + type: int + prefix: + description: + - Configure IP and next hop IP for the routed outside network. + type: str + aliases: [ route ] + track_policy: + description: + - Relation definition for static route to TrackList. + type: str + preference: + description: + - Administrative preference value for the route. + type: int + bfd: + description: + - Determines if bfd is required for route control. + - The APIC defaults to C(null) when unset during creation. + type: str + choices: [ bfd, null ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- The C(tenant), C(l3out), C(logical_node), C(fabric_node) and C(prefix) used must exist before using this module in your playbook. + The M(cisco.aci.aci_tenant) and M(cisco.aci.aci_l3out) modules can be used for this. +seealso: +- module: cisco.aci.aci_tenant +- module: cisco.aci.aci_l3out +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(l3ext:Out). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Anvitha Jain(@anvitha-jain) +''' + +EXAMPLES = r''' +- name: Create static routes + cisco.aci.aci_l3out_static_routes: + host: apic + username: admin + password: SomeSecretPassword + tenant: tenantName + l3out: l3out + logical_node: nodeName + node_id: 101 + pod_id: 1 + prefix: 10.10.0.0/16 + delegate_to: localhost + +- name: Delete static routes + cisco.aci.aci_l3out_static_routes: + host: apic + username: admin + password: SomeSecretPassword + tenant: tenantName + l3out: l3out + logical_node: nodeName + node_id: 101 + pod_id: 1 + prefix: 10.10.0.0/16 + delegate_to: localhost + +- name: Query for a specific MO under l3out + cisco.aci.aci_l3out_static_routes: + host: apic + username: admin + password: SomeSecretPassword + tenant: tenantName + l3out: l3out + logical_node: nodeName + node_id: 101 + pod_id: 1 + prefix: 10.10.0.0/16 + delegate_to: localhost + +- name: Query for all static routes + cisco.aci.aci_l3out_static_routes: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects + l3out=dict(type='str', aliases=['l3out_name']), # Not required for querying all objects + logical_node=dict(type='str'), # Not required for querying all objects + pod_id=dict(type='int'), + node_id=dict(type='int'), + prefix=dict(type='str', aliases=['route']), + track_policy=dict(type='str'), + preference=dict(type='int'), + bfd=dict(type='str', choices=['bfd', None]), + description=dict(type='str', aliases=['descr']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'present', ['prefix', 'node_id', 'pod_id', 'logical_node', 'l3out', 'tenant']], + ['state', 'absent', ['prefix', 'node_id', 'pod_id', 'logical_node', 'l3out', 'tenant']], + ], + ) + + aci = ACIModule(module) + + tenant = module.params.get('tenant') + l3out = module.params.get('l3out') + logical_node = module.params.get('logical_node') + node_id = module.params.get('node_id') + pod_id = module.params.get('pod_id') + prefix = module.params.get('prefix') + track_policy = module.params.get('track_policy') + preference = module.params.get('preference') + bfd = module.params.get('bfd') + description = module.params.get('description') + state = module.params.get('state') + name_alias = module.params.get('name_alias') + + fabric_node = 'topology/pod-{0}/node-{1}'.format(pod_id, node_id) + child_classes = ['ipNexthopP'] + if track_policy is not None: + child_classes.append('ipRsRouteTrack') + + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + module_object=tenant, + target_filter={'name': tenant}, + ), + subclass_1=dict( + aci_class='l3extOut', + aci_rn='out-{0}'.format(l3out), + module_object=l3out, + target_filter={'name': l3out}, + ), + subclass_2=dict( + aci_class='l3extLNodeP', + aci_rn='lnodep-{0}'.format(logical_node), + module_object=logical_node, + target_filter={'name': logical_node}, + ), + subclass_3=dict( + aci_class='l3extRsNodeL3OutAtt', + aci_rn='/rsnodeL3OutAtt-[{0}]'.format(fabric_node), + module_object=fabric_node, + target_filter={'name': fabric_node}, + ), + subclass_4=dict( + aci_class='ipRouteP', + aci_rn='/rt-[{0}]'.format(prefix), + module_object=prefix, + target_filter={'name': prefix}, + ), + child_classes=child_classes + ) + + aci.get_existing() + + if state == 'present': + child_configs = [] + class_config = dict( + descr=description, + ip=prefix, + pref=preference, + nameAlias=name_alias, + ) + if bfd is not None: + class_config['rtCtrl'] = bfd + + if track_policy is not None: + tDn = 'uni/tn-{0}/tracklist-{1}'.format(tenant, track_policy) + child_configs.append({'ipRsRouteTrack': {'attributes': {'tDn': tDn}}}) + + aci.payload( + aci_class='ipRouteP', + class_config=class_config, + child_configs=child_configs + ), + + aci.get_diff(aci_class='ipRouteP') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_maintenance_group.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_maintenance_group.py new file mode 100644 index 00000000..2df19b7d --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_maintenance_group.py @@ -0,0 +1,236 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = { + 'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community' +} + +DOCUMENTATION = ''' +module: aci_maintenance_group +short_description: This creates an ACI maintenance group +notes: + - a maintenance policy (aci_maintenance_policy must be created prior to creating an aci maintenance group +description: + - This modules creates an ACI maintenance group +options: + group: + description: + - This is the name of the group + type: str + policy: + description: + - This is the name of the policy that was created using aci_maintenance_policy + type: str + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [absent, present, query] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +author: + - Steven Gerhart (@sgerhart) +''' + +# FIXME: Add more, better examples +EXAMPLES = r''' +- name: maintenance group + cisco.aci.aci_maintenance_group: + host: "{{ inventory_hostname }}" + username: "{{ user }}" + password: "{{ pass }}" + validate_certs: no + group: maintenancegrp1 + policy: maintenancePol1 + state: present +''' + +RETURN = ''' +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec +from ansible.module_utils.basic import AnsibleModule + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + group=dict(type='str'), # Not required for querying all objects + policy=dict(type='str'), # Not required for querying all objects + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['group']], + ['state', 'present', ['group']], + ], + ) + + state = module.params.get('state') + group = module.params.get('group') + policy = module.params.get('policy') + name_alias = module.params.get('name_alias') + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='maintMaintGrp', + aci_rn='fabric/maintgrp-{0}'.format(group), + target_filter={'name': group}, + module_object=group, + ), + child_classes=['maintRsMgrpp'], + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='maintMaintGrp', + class_config=dict( + name=group, + nameAlias=name_alias, + ), + child_configs=[ + dict( + maintRsMgrpp=dict( + attributes=dict( + tnMaintMaintPName=policy, + ), + ), + ), + ], + + ) + + aci.get_diff(aci_class='maintMaintGrp') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_maintenance_group_node.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_maintenance_group_node.py new file mode 100644 index 00000000..3043c466 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_maintenance_group_node.py @@ -0,0 +1,242 @@ +#!/usr/bin/python + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = { + 'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community' +} + +DOCUMENTATION = r''' +--- +module: aci_maintenance_group_node +short_description: Manage maintenance group nodes +description: +- Manage maintenance group nodes +options: + group: + description: + - The maintenance group name that you want to add the node to. + type: str + node: + description: + - The node to be added to the maintenance group. + - The value equals the nodeid. + type: str + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +author: +- Steven Gerhart (@sgerhart) +''' + +EXAMPLES = r''' +- name: maintenance group + cisco.aci.aci_maintenance_group_node: + host: "{{ inventory_hostname }}" + username: "{{ user }}" + password: "{{ pass }}" + validate_certs: no + group: maintenancegrp1 + node: 1001 + state: present + +- name: maintenance group + cisco.aci.aci_maintenance_group_node: + host: "{{ inventory_hostname }}" + username: "{{ user }}" + password: "{{ pass }}" + validate_certs: no + group: maintenancegrp1 + node: 1002 + state: absent +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json + +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + group=dict(type='str'), # Not required for querying all objects + node=dict(type='str'), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['node', 'group']], + ['state', 'present', ['node', 'group']], + ], + ) + + state = module.params.get('state') + group = module.params.get('group') + node = module.params.get('node') + name_alias = module.params.get('name_alias') + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='maintMaintGrp', + aci_rn='fabric/maintgrp-{0}'.format(group), + target_filter={'name': group}, + module_object=group, + ), + subclass_1=dict( + aci_class='fabricNodeBlk', + aci_rn='nodeblk-blk{0}-{0}'.format(node), + target_filter={'name': 'blk{0}-{0}'.format(node)}, + module_object=node, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='fabricNodeBlk', + class_config=dict( + from_=node, + to_=node, + nameAlias=name_alias, + ), + ) + + aci.get_diff(aci_class='fabricNodeBlk') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_maintenance_policy.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_maintenance_policy.py new file mode 100644 index 00000000..b067e1d5 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_maintenance_policy.py @@ -0,0 +1,277 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = { + 'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community' +} + +DOCUMENTATION = r''' +--- +module: aci_maintenance_policy +short_description: Manage firmware maintenance policies +description: +- Manage maintenance policies that defines behavior during an ACI upgrade. +options: + name: + description: + - The name for the maintenance policy. + type: str + aliases: [ maintenance_policy ] + runmode: + description: + - Whether the system pauses on error or just continues through it. + type: str + choices: [ pauseOnlyOnFailures, pauseNever ] + default: pauseOnlyOnFailures + graceful: + description: + - Whether the system will bring down the nodes gracefully during an upgrade, which reduces traffic lost. + - The APIC defaults to C(no) when unset during creation. + type: bool + scheduler: + description: + - The name of scheduler that is applied to the policy. + type: str + adminst: + description: + - Will trigger an immediate upgrade for nodes if adminst is set to triggered. + type: str + choices: [ triggered, untriggered ] + default: untriggered + ignoreCompat: + description: + - To check whether compatibility checks should be ignored + - The APIC defaults to C(no) when unset during creation. + type: bool + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- A scheduler is required for this module, which could have been created using the M(cisco.aci.aci_fabric_scheduler) module or via the UI. +author: +- Steven Gerhart (@sgerhart) +''' + +# FIXME: Add more, better examples +EXAMPLES = r''' +- name: Ensure maintenance policy is present + cisco.aci.aci_maintenance_policy: + host: '{{ inventory_hostname }}' + username: '{{ user }}' + password: '{{ pass }}' + validate_certs: no + name: maintenancePol1 + scheduler: simpleScheduler + runmode: False + state: present +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + + +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec +from ansible.module_utils.basic import AnsibleModule + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + name=dict(type='str', aliases=['maintenance_policy']), # Not required for querying all objects + runmode=dict(type='str', default='pauseOnlyOnFailures', choices=['pauseOnlyOnFailures', 'pauseNever']), + graceful=dict(type='bool'), + scheduler=dict(type='str'), + ignoreCompat=dict(type='bool'), + adminst=dict(type='str', default='untriggered', choices=['triggered', 'untriggered']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['name']], + ['state', 'present', ['name', 'scheduler']], + ], + ) + + aci = ACIModule(module) + + state = module.params.get('state') + name = module.params.get('name') + runmode = module.params.get('runmode') + scheduler = module.params.get('scheduler') + adminst = module.params.get('adminst') + graceful = aci.boolean(module.params.get('graceful')) + ignoreCompat = aci.boolean(module.params.get('ignoreCompat')) + name_alias = module.params.get('name_alias') + + aci.construct_url( + root_class=dict( + aci_class='maintMaintP', + aci_rn='fabric/maintpol-{0}'.format(name), + target_filter={'name': name}, + module_object=name, + ), + child_classes=['maintRsPolScheduler'] + + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='maintMaintP', + class_config=dict( + name=name, + runMode=runmode, + graceful=graceful, + adminSt=adminst, + ignoreCompat=ignoreCompat, + nameAlias=name_alias, + ), + child_configs=[ + dict( + maintRsPolScheduler=dict( + attributes=dict( + tnTrigSchedPName=scheduler, + ), + ), + ), + ], + + ) + + aci.get_diff(aci_class='maintMaintP') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_rest.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_rest.py new file mode 100644 index 00000000..2e18c548 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_rest.py @@ -0,0 +1,451 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2017, Dag Wieers (@dagwieers) <dag@wieers.com> +# Copyright: (c) 2020, Cindy Zhao (@cizhao) <cizhao@cisco.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +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. +requirements: +- lxml (when using XML payload) +- xmljson >= 0.1.8 (when using XML payload) +- python 2.7+ (when using xmljson) +options: + method: + description: + - The HTTP method of the request. + - Using C(delete) is typically used for deleting objects. + - Using C(get) is typically used for querying objects. + - Using C(post) is typically used for modifying objects. + type: str + choices: [ delete, get, post ] + default: get + aliases: [ action ] + path: + description: + - URI being used to execute API calls. + - Must end in C(.xml) or C(.json). + type: str + required: yes + aliases: [ uri ] + content: + description: + - When used instead of C(src), sets the payload of the API request directly. + - This may be convenient to template simple requests. + - For anything complex use the C(template) lookup plugin (see examples) + or the M(template) module with parameter C(src). + type: raw + src: + description: + - Name of the absolute path of the filename that includes the body + of the HTTP request being sent to the ACI fabric. + - If you require a templated payload, use the C(content) parameter + together with the C(template) lookup plugin, or use M(template). + type: path + aliases: [ config_file ] +extends_documentation_fragment: +- cisco.aci.aci + +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. +- If you do not have any attributes, it may be necessary to add the "attributes" key with an empty dictionnary "{}" for value + as the APIC does expect the entry to precede any children. +seealso: +- module: cisco.aci.aci_tenant +- name: Cisco APIC REST API Configuration Guide + description: More information about the APIC REST API. + link: 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: +- Dag Wieers (@dagwieers) +- Cindy Zhao (@cizhao) +''' + +EXAMPLES = r''' +- name: Add a tenant using certificate authentication + cisco.aci.aci_rest: + host: apic + username: admin + private_key: pki/admin.key + method: post + path: /api/mo/uni.xml + src: /home/cisco/ansible/aci/configs/aci_config.xml + delegate_to: localhost + +- name: Add a tenant from a templated payload file from templates/ + cisco.aci.aci_rest: + host: apic + username: admin + private_key: pki/admin.key + method: post + path: /api/mo/uni.xml + content: "{{ lookup('template', 'aci/tenant.xml.j2') }}" + delegate_to: localhost + +- name: Add a tenant using inline YAML + cisco.aci.aci_rest: + host: apic + username: admin + private_key: pki/admin.key + validate_certs: no + path: /api/mo/uni.json + method: post + content: + fvTenant: + attributes: + name: Sales + descr: Sales department + delegate_to: localhost + +- name: Add a tenant using a JSON string + cisco.aci.aci_rest: + host: apic + username: admin + private_key: pki/admin.key + validate_certs: no + path: /api/mo/uni.json + method: post + content: + { + "fvTenant": { + "attributes": { + "name": "Sales", + "descr": "Sales department" + } + } + } + delegate_to: localhost + +- name: Add a tenant using an XML string + cisco.aci.aci_rest: + host: apic + username: admin + private_key: pki/{{ aci_username }}.key + validate_certs: no + path: /api/mo/uni.xml + method: post + content: '<fvTenant name="Sales" descr="Sales departement"/>' + delegate_to: localhost + +- name: Get tenants using password authentication + cisco.aci.aci_rest: + host: apic + username: admin + password: SomeSecretPassword + method: get + path: /api/node/class/fvTenant.json + delegate_to: localhost + register: query_result + +- name: Configure contracts + cisco.aci.aci_rest: + host: apic + username: admin + private_key: pki/admin.key + method: post + path: /api/mo/uni.xml + src: /home/cisco/ansible/aci/configs/contract_config.xml + delegate_to: localhost + +- name: Register leaves and spines + cisco.aci.aci_rest: + host: apic + username: admin + private_key: pki/admin.key + validate_certs: no + method: post + path: /api/mo/uni/controller/nodeidentpol.xml + content: + <fabricNodeIdentPol> + <fabricNodeIdentP name="{{ item.name }}" nodeId="{{ item.nodeid }}" status="{{ item.status }}" serial="{{ item.serial }}"/> + </fabricNodeIdentPol> + with_items: + - '{{ apic_leavesspines }}' + delegate_to: localhost + +- name: Wait for all controllers to become ready + cisco.aci.aci_rest: + host: apic + username: admin + private_key: pki/admin.key + validate_certs: no + path: /api/node/class/topSystem.json?query-target-filter=eq(topSystem.role,"controller") + register: apics + until: "'totalCount' in apics and apics.totalCount|int >= groups['apic']|count" + retries: 120 + delay: 30 + delegate_to: localhost + run_once: yes +''' + +RETURN = r''' +error_code: + description: The REST ACI return code, useful for troubleshooting on failure + returned: always + type: int + sample: 122 +error_text: + description: The REST ACI descriptive text, useful for troubleshooting on failure + returned: always + type: str + sample: unknown managed object class foo +imdata: + description: Converted output returned by the APIC REST (register this for post-processing) + returned: always + type: str + sample: [{"error": {"attributes": {"code": "122", "text": "unknown managed object class foo"}}}] +payload: + description: The (templated) payload send to the APIC REST API (xml or json) + returned: always + type: str + sample: '<foo bar="boo"/>' +raw: + description: The raw output returned by the APIC REST API (xml or json) + returned: parse error + type: str + sample: '<?xml version="1.0" encoding="UTF-8"?><imdata totalCount="1"><error code="122" text="unknown managed object class foo"/></imdata>' +response: + description: HTTP response string + returned: always + type: str + sample: 'HTTP Error 400: Bad Request' +status: + description: HTTP status code + returned: always + type: int + sample: 400 +totalCount: + description: Number of items in the imdata array + returned: always + type: str + sample: '0' +url: + description: URL used for APIC REST call + returned: success + type: str + sample: https://1.2.3.4/api/mo/uni/tn-[Dag].json?rsp-subtree=modified +''' + +import json +import os + +try: + from ansible.module_utils.six.moves.urllib.parse import parse_qsl, urlencode, urlparse, urlunparse + HAS_URLPARSE = True +except Exception: + HAS_URLPARSE = False + +# Optional, only used for XML payload +try: + from lxml import etree # noqa + HAS_LXML_ETREE = True +except ImportError: + HAS_LXML_ETREE = False + +# Optional, only used for XML payload +try: + from xmljson import cobra # noqa + HAS_XMLJSON_COBRA = True +except ImportError: + HAS_XMLJSON_COBRA = False + +# Optional, only used for YAML validation +try: + import yaml + HAS_YAML = True +except Exception: + HAS_YAML = False + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec +from ansible.module_utils.urls import fetch_url +from ansible.module_utils._text import to_text + + +def update_qsl(url, params): + ''' Add or update a URL query string ''' + + if HAS_URLPARSE: + url_parts = list(urlparse(url)) + query = dict(parse_qsl(url_parts[4])) + query.update(params) + url_parts[4] = urlencode(query) + return urlunparse(url_parts) + elif '?' in url: + return url + '&' + '&'.join(['%s=%s' % (k, v) for k, v in params.items()]) + else: + return url + '?' + '&'.join(['%s=%s' % (k, v) for k, v in params.items()]) + + +class ACIRESTModule(ACIModule): + + def changed(self, d): + ''' Check ACI response for changes ''' + + if isinstance(d, dict): + for k, v in d.items(): + if k == 'status' and v in ('created', 'modified', 'deleted'): + return True + elif self.changed(v) is True: + return True + elif isinstance(d, list): + for i in d: + if self.changed(i) is True: + return True + + return False + + def response_type(self, rawoutput, rest_type='xml'): + ''' Handle APIC response output ''' + + if rest_type == 'json': + self.response_json(rawoutput) + else: + self.response_xml(rawoutput) + + # Use APICs built-in idempotency + if HAS_URLPARSE: + self.result['changed'] = self.changed(self.imdata) + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + path=dict(type='str', required=True, aliases=['uri']), + method=dict(type='str', default='get', choices=['delete', 'get', 'post'], aliases=['action']), + src=dict(type='path', aliases=['config_file']), + content=dict(type='raw'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + mutually_exclusive=[['content', 'src']], + ) + + content = module.params.get('content') + path = module.params.get('path') + src = module.params.get('src') + + # Report missing file + file_exists = False + if src: + if os.path.isfile(src): + file_exists = True + else: + module.fail_json(msg="Cannot find/access src '%s'" % src) + + # Find request type + if path.find('.xml') != -1: + rest_type = 'xml' + if not HAS_LXML_ETREE: + module.fail_json(msg='The lxml python library is missing, or lacks etree support.') + if not HAS_XMLJSON_COBRA: + module.fail_json(msg='The xmljson python library is missing, or lacks cobra support.') + elif path.find('.json') != -1: + rest_type = 'json' + else: + module.fail_json(msg='Failed to find REST API payload type (neither .xml nor .json).') + + aci = ACIRESTModule(module) + aci.result['status'] = -1 # Ensure we always return a status + + # We include the payload as it may be templated + payload = content + if file_exists: + with open(src, 'r') as config_object: + # TODO: Would be nice to template this, requires action-plugin + payload = config_object.read() + payload_output_file = json.loads(payload) + + # Validate payload + if rest_type == 'json': + if content and isinstance(content, dict): + # Validate inline YAML/JSON + payload = json.dumps(payload) + elif payload and isinstance(payload, str) and HAS_YAML: + try: + # Validate YAML/JSON string + payload = json.dumps(yaml.safe_load(payload)) + except Exception as e: + module.fail_json(msg='Failed to parse provided JSON/YAML payload: %s' % to_text(e), exception=to_text(e), payload=payload) + elif rest_type == 'xml' and HAS_LXML_ETREE: + if content and isinstance(content, dict) and HAS_XMLJSON_COBRA: + # Validate inline YAML/JSON + payload = etree.tostring(cobra.etree(payload)[0]) + elif payload and isinstance(payload, str): + try: + # Validate XML string + payload = etree.tostring(etree.fromstring(payload)) + except Exception as e: + module.fail_json(msg='Failed to parse provided XML payload: %s' % to_text(e), payload=payload) + + # Perform actual request using auth cookie (Same as aci.request(), but also supports XML) + if 'port' in aci.params and aci.params.get('port') is not None: + aci.url = '%(protocol)s://%(host)s:%(port)s/' % aci.params + path.lstrip('/') + else: + aci.url = '%(protocol)s://%(host)s/' % aci.params + path.lstrip('/') + if aci.params.get('method') != 'get': + path += '?rsp-subtree=modified' + aci.url = update_qsl(aci.url, {'rsp-subtree': 'modified'}) + + # Sign and encode request as to APIC's wishes + if aci.params.get('private_key') is not None: + aci.cert_auth(path=path, payload=payload) + + aci.method = aci.params.get('method').upper() + + # Perform request + resp, info = fetch_url(module, aci.url, + data=payload, + headers=aci.headers, + method=aci.method, + timeout=aci.params.get('timeout'), + use_proxy=aci.params.get('use_proxy')) + + aci.response = info.get('msg') + aci.status = info.get('status') + + # Report failure + if info.get('status') != 200: + try: + # APIC error + aci.response_type(info.get('body'), rest_type) + aci.fail_json(msg='APIC Error %(code)s: %(text)s' % aci.error) + except KeyError: + # Connection error + aci.fail_json(msg='Connection failed for %(url)s. %(msg)s' % info) + + aci.response_type(resp.read(), rest_type) + + aci.result['imdata'] = aci.imdata + aci.result['totalCount'] = aci.totalCount + + output_path = aci.params.get('output_path') + if(output_path is not None): + with open(output_path, "a") as output_file: + json.dump([payload_output_file], output_file) + + # Report success + aci.exit_json(**aci.result) + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_static_binding_to_epg.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_static_binding_to_epg.py new file mode 100644 index 00000000..15677831 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_static_binding_to_epg.py @@ -0,0 +1,441 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2017, Bruno Calogero <brunocalogero@hotmail.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_static_binding_to_epg +short_description: Bind static paths to EPGs (fv:RsPathAtt) +description: +- Bind static paths to EPGs on Cisco ACI fabrics. +options: + tenant: + description: + - Name of an existing tenant. + type: str + aliases: [ tenant_name ] + ap: + description: + - Name of an existing application network profile, that will contain the EPGs. + type: str + aliases: [ app_profile, app_profile_name ] + epg: + description: + - The name of the end point group. + type: str + aliases: [ epg_name ] + description: + description: + - Description for the static path to EPG binding. + type: str + aliases: [ descr ] + encap_id: + description: + - The encapsulation ID associating the C(epg) with the interface path. + - This acts as the secondary C(encap_id) when using micro-segmentation. + - Accepted values are any valid encap ID for specified encap, currently ranges between C(1) and C(4096). + type: int + aliases: [ vlan, vlan_id ] + primary_encap_id: + description: + - Determines the primary encapsulation ID associating the C(epg) + with the interface path when using micro-segmentation. + - Accepted values are any valid encap ID for specified encap, currently ranges between C(1) and C(4096). + type: int + aliases: [ primary_vlan, primary_vlan_id ] + deploy_immediacy: + description: + - The Deployment Immediacy of Static EPG on PC, VPC or Interface. + - The APIC defaults to C(lazy) when unset during creation. + type: str + choices: [ immediate, lazy ] + 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 to C(trunk) when unset during creation. + type: str + choices: [ 802.1p, access, native, regular, tagged, trunk, untagged ] + aliases: [ interface_mode_name, mode ] + interface_type: + description: + - The type of interface for the static EPG deployment. + type: str + choices: [ fex, port_channel, switch_port, vpc ] + default: switch_port + pod_id: + description: + - The pod number part of the tDn. + - C(pod_id) is usually an integer below C(10). + type: int + 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. + - The C(leafs) value is usually something like '101' or '101-102' depending on C(connection_type). + type: list + elements: str + aliases: [ leaves, nodes, paths, switches ] + interface: + description: + - The C(interface) string value part of the tDn. + - Usually a policy group like C(test-IntPolGrp) or an interface of the following format C(1/7) depending on C(interface_type). + type: str + extpaths: + description: + - The C(extpaths) integer value part of the tDn. + - C(extpaths) is only used if C(interface_type) is C(fex). + - Usually something like C(1011). + type: int + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- The C(tenant), C(ap), C(epg) used must exist before using this module in your playbook. + The M(cisco.aci.aci_tenant), M(cisco.aci.aci_ap), M(cisco.aci.aci_epg) modules can be used for this. +seealso: +- module: cisco.aci.aci_tenant +- module: cisco.aci.aci_ap +- module: cisco.aci.aci_epg +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(fv:RsPathAtt). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Bruno Calogero (@brunocalogero) +''' + +EXAMPLES = r''' +- name: Deploy Static Path binding for given EPG + cisco.aci.aci_static_binding_to_epg: + host: apic + username: admin + password: SomeSecretPassword + tenant: accessport-code-cert + ap: accessport_code_app + epg: accessport_epg1 + encap_id: 222 + deploy_immediacy: lazy + interface_mode: untagged + interface_type: switch_port + pod_id: 1 + leafs: 101 + interface: '1/7' + state: present + delegate_to: localhost + +- name: Remove Static Path binding for given EPG + cisco.aci.aci_static_binding_to_epg: + host: apic + username: admin + password: SomeSecretPassword + tenant: accessport-code-cert + ap: accessport_code_app + epg: accessport_epg1 + interface_type: switch_port + pod: 1 + leafs: 101 + interface: '1/7' + state: absent + delegate_to: localhost + +- name: Get specific Static Path binding for given EPG + cisco.aci.aci_static_binding_to_epg: + host: apic + username: admin + password: SomeSecretPassword + tenant: accessport-code-cert + ap: accessport_code_app + epg: accessport_epg1 + interface_type: switch_port + pod: 1 + leafs: 101 + interface: '1/7' + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + +INTERFACE_MODE_MAPPING = { + '802.1p': 'native', + 'access': 'untagged', + 'native': 'native', + 'regular': 'regular', + 'tagged': 'regular', + 'trunk': 'regular', + 'untagged': 'untagged', +} + +INTERFACE_TYPE_MAPPING = dict( + fex='topology/pod-{pod_id}/paths-{leafs}/extpaths-{extpaths}/pathep-[eth{interface}]', + port_channel='topology/pod-{pod_id}/paths-{leafs}/pathep-[{interface}]', + switch_port='topology/pod-{pod_id}/paths-{leafs}/pathep-[eth{interface}]', + vpc='topology/pod-{pod_id}/protpaths-{leafs}/pathep-[{interface}]', +) + +# TODO: change 'deploy_immediacy' to 'resolution_immediacy' (as seen in aci_epg_to_domain)? + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects + ap=dict(type='str', aliases=['app_profile', 'app_profile_name']), # Not required for querying all objects + epg=dict(type='str', aliases=['epg_name']), # Not required for querying all objects + description=dict(type='str', aliases=['descr']), + encap_id=dict(type='int', aliases=['vlan', 'vlan_id']), + primary_encap_id=dict(type='int', aliases=['primary_vlan', 'primary_vlan_id']), + deploy_immediacy=dict(type='str', choices=['immediate', 'lazy']), + interface_mode=dict(type='str', choices=['802.1p', 'access', 'native', 'regular', 'tagged', 'trunk', 'untagged'], + aliases=['interface_mode_name', 'mode']), + interface_type=dict(type='str', default='switch_port', choices=['fex', 'port_channel', 'switch_port', 'vpc']), + pod_id=dict(type='int', aliases=['pod', 'pod_number']), # Not required for querying all objects + leafs=dict(type='list', elements='str', aliases=['leaves', 'nodes', 'paths', 'switches']), # Not required for querying all objects + interface=dict(type='str'), # Not required for querying all objects + extpaths=dict(type='int'), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['interface_type', 'fex', ['extpaths']], + ['state', 'absent', ['ap', 'epg', 'interface', 'leafs', 'pod_id', 'tenant']], + ['state', 'present', ['ap', 'encap_id', 'epg', 'interface', 'leafs', 'pod_id', 'tenant']], + ], + ) + + tenant = module.params.get('tenant') + ap = module.params.get('ap') + epg = module.params.get('epg') + description = module.params.get('description') + encap_id = module.params.get('encap_id') + primary_encap_id = module.params.get('primary_encap_id') + deploy_immediacy = module.params.get('deploy_immediacy') + interface_mode = module.params.get('interface_mode') + interface_type = module.params.get('interface_type') + pod_id = module.params.get('pod_id') + leafs = module.params.get('leafs') + if leafs is not None: + # Process leafs, and support dash-delimited leafs + leafs = [] + for leaf in module.params.get('leafs'): + # Users are likely to use integers for leaf IDs, which would raise an exception when using the join method + leafs.extend(str(leaf).split('-')) + if len(leafs) == 1: + if interface_type == 'vpc': + module.fail_json(msg='A interface_type of "vpc" requires 2 leafs') + leafs = leafs[0] + elif len(leafs) == 2: + if interface_type != 'vpc': + module.fail_json(msg='The interface_types "switch_port", "port_channel", and "fex" \ + do not support using multiple leafs for a single binding') + leafs = "-".join(leafs) + else: + module.fail_json(msg='The "leafs" parameter must not have more than 2 entries') + interface = module.params.get('interface') + extpaths = module.params.get('extpaths') + state = module.params.get('state') + + if encap_id is not None: + if encap_id not in range(1, 4097): + module.fail_json(msg='Valid VLAN assigments are from 1 to 4096') + encap_id = 'vlan-{0}'.format(encap_id) + + if primary_encap_id is not None: + if primary_encap_id not in range(1, 4097): + module.fail_json(msg='Valid VLAN assigments are from 1 to 4096') + primary_encap_id = 'vlan-{0}'.format(primary_encap_id) + + static_path = INTERFACE_TYPE_MAPPING[interface_type].format(pod_id=pod_id, leafs=leafs, extpaths=extpaths, interface=interface) + + path_target_filter = {} + if pod_id is not None and leafs is not None and interface is not None and (interface_type != 'fex' or extpaths is not None): + path_target_filter = {'tDn': static_path} + + if interface_mode is not None: + interface_mode = INTERFACE_MODE_MAPPING[interface_mode] + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + module_object=tenant, + target_filter={'name': tenant}, + ), + subclass_1=dict( + aci_class='fvAp', + aci_rn='ap-{0}'.format(ap), + module_object=ap, + target_filter={'name': ap}, + ), + subclass_2=dict( + aci_class='fvAEPg', + aci_rn='epg-{0}'.format(epg), + module_object=epg, + target_filter={'name': epg}, + ), + subclass_3=dict( + aci_class='fvRsPathAtt', + aci_rn='rspathAtt-[{0}]'.format(static_path), + module_object=static_path, + target_filter=path_target_filter, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='fvRsPathAtt', + class_config=dict( + descr=description, + encap=encap_id, + primaryEncap=primary_encap_id, + instrImedcy=deploy_immediacy, + mode=interface_mode, + tDn=static_path, + ), + ) + + aci.get_diff(aci_class='fvRsPathAtt') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_switch_leaf_selector.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_switch_leaf_selector.py new file mode 100644 index 00000000..0334fd84 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_switch_leaf_selector.py @@ -0,0 +1,349 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2017, Bruno Calogero <brunocalogero@hotmail.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_switch_leaf_selector +short_description: Bind leaf selectors to switch policy leaf profiles (infra:LeafS, infra:NodeBlk, infra:RsAccNodePGrep) +description: +- Bind leaf selectors (with node block range and policy group) to switch policy leaf profiles on Cisco ACI fabrics. +options: + description: + description: + - The description to assign to the C(leaf). + type: str + leaf_profile: + description: + - Name of the Leaf Profile to which we add a Selector. + type: str + aliases: [ leaf_profile_name ] + leaf: + description: + - Name of Leaf Selector. + type: str + aliases: [ name, leaf_name, leaf_profile_leaf_name, leaf_selector_name ] + leaf_node_blk: + description: + - Name of Node Block range to be added to Leaf Selector of given Leaf Profile. + type: str + aliases: [ leaf_node_blk_name, node_blk_name ] + leaf_node_blk_description: + description: + - The description to assign to the C(leaf_node_blk) + type: str + from: + description: + - Start of Node Block range. + type: int + aliases: [ node_blk_range_from, from_range, range_from ] + to: + description: + - Start of Node Block range. + type: int + aliases: [ node_blk_range_to, to_range, range_to ] + policy_group: + description: + - Name of the Policy Group to be added to Leaf Selector of given Leaf Profile. + type: str + aliases: [ name, policy_group_name ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- This module is to be used with M(cisco.aci.aci_switch_policy_leaf_profile). + One first creates a leaf profile (infra:NodeP) and then creates an associated selector (infra:LeafS), +seealso: +- module: cisco.aci.aci_switch_policy_leaf_profile +- name: APIC Management Information Model reference + description: More information about the internal APIC classes B(infra:LeafS), + B(infra:NodeBlk) and B(infra:RsAccNodePGrp). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Bruno Calogero (@brunocalogero) +''' + +EXAMPLES = r''' +- name: adding a switch policy leaf profile selector associated Node Block range (w/ policy group) + cisco.aci.aci_switch_leaf_selector: + host: apic + username: admin + password: SomeSecretPassword + leaf_profile: sw_name + leaf: leaf_selector_name + leaf_node_blk: node_blk_name + from: 1011 + to: 1011 + policy_group: somepolicygroupname + state: present + delegate_to: localhost + +- name: adding a switch policy leaf profile selector associated Node Block range (w/o policy group) + cisco.aci.aci_switch_leaf_selector: + host: apic + username: admin + password: SomeSecretPassword + leaf_profile: sw_name + leaf: leaf_selector_name + leaf_node_blk: node_blk_name + from: 1011 + to: 1011 + state: present + delegate_to: localhost + +- name: Removing a switch policy leaf profile selector + cisco.aci.aci_switch_leaf_selector: + host: apic + username: admin + password: SomeSecretPassword + leaf_profile: sw_name + leaf: leaf_selector_name + state: absent + delegate_to: localhost + +- name: Querying a switch policy leaf profile selector + cisco.aci.aci_switch_leaf_selector: + host: apic + username: admin + password: SomeSecretPassword + leaf_profile: sw_name + leaf: leaf_selector_name + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update({ + 'description': dict(type='str'), + 'leaf_profile': dict(type='str', aliases=['leaf_profile_name']), # Not required for querying all objects + 'leaf': dict(type='str', aliases=['name', 'leaf_name', 'leaf_profile_leaf_name', 'leaf_selector_name']), # Not required for querying all objects + 'leaf_node_blk': dict(type='str', aliases=['leaf_node_blk_name', 'node_blk_name']), + 'leaf_node_blk_description': dict(type='str'), + # NOTE: Keyword 'from' is a reserved word in python, so we need it as a string + 'from': dict(type='int', aliases=['node_blk_range_from', 'from_range', 'range_from']), + 'to': dict(type='int', aliases=['node_blk_range_to', 'to_range', 'range_to']), + 'policy_group': dict(type='str', aliases=['policy_group_name']), + 'state': dict(type='str', default='present', choices=['absent', 'present', 'query']), + 'name_alias': dict(type='str'), + }) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['leaf_profile', 'leaf']], + ['state', 'present', ['leaf_profile', 'leaf', 'leaf_node_blk', 'from', 'to']] + ] + ) + + description = module.params.get('description') + leaf_profile = module.params.get('leaf_profile') + leaf = module.params.get('leaf') + leaf_node_blk = module.params.get('leaf_node_blk') + leaf_node_blk_description = module.params.get('leaf_node_blk_description') + from_ = module.params.get('from') + to_ = module.params.get('to') + policy_group = module.params.get('policy_group') + state = module.params.get('state') + name_alias = module.params.get('name_alias') + + # Build child_configs dynamically + child_configs = [ + dict( + infraNodeBlk=dict( + attributes=dict( + descr=leaf_node_blk_description, + name=leaf_node_blk, + from_=from_, + to_=to_, + ), + ), + ), + ] + + # Add infraRsAccNodePGrp only when policy_group was defined + if policy_group is not None: + child_configs.append(dict( + infraRsAccNodePGrp=dict( + attributes=dict( + tDn='uni/infra/funcprof/accnodepgrp-{0}'.format(policy_group), + ), + ), + )) + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='infraNodeP', + aci_rn='infra/nprof-{0}'.format(leaf_profile), + module_object=leaf_profile, + target_filter={'name': leaf_profile}, + ), + subclass_1=dict( + aci_class='infraLeafS', + # NOTE: normal rn: leaves-{name}-typ-{type}, hence here hardcoded to range for purposes of module + aci_rn='leaves-{0}-typ-range'.format(leaf), + module_object=leaf, + target_filter={'name': leaf}, + ), + # NOTE: infraNodeBlk is not made into a subclass because there is a 1-1 mapping between node block and leaf selector name + child_classes=['infraNodeBlk', 'infraRsAccNodePGrp'], + + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='infraLeafS', + class_config=dict( + descr=description, + name=leaf, + nameAlias=name_alias, + ), + child_configs=child_configs, + ) + + aci.get_diff(aci_class='infraLeafS') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_switch_policy_leaf_profile.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_switch_policy_leaf_profile.py new file mode 100644 index 00000000..932a0d8b --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_switch_policy_leaf_profile.py @@ -0,0 +1,250 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2017, Bruno Calogero <brunocalogero@hotmail.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_switch_policy_leaf_profile +short_description: Manage switch policy leaf profiles (infra:NodeP) +description: +- Manage switch policy leaf profiles on Cisco ACI fabrics. +options: + leaf_profile: + description: + - The name of the Leaf Profile. + type: str + aliases: [ leaf_profile_name, name ] + description: + description: + - Description for the Leaf Profile. + type: str + aliases: [ descr ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +seealso: +- module: cisco.aci.aci_switch_policy_leaf_profile +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(infra:NodeP). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Bruno Calogero (@brunocalogero) +''' + +EXAMPLES = r''' +- name: creating a Leaf Profile with description + cisco.aci.aci_switch_policy_leaf_profile: + host: apic + username: admin + password: SomeSecretPassword + leaf_profile: sw_name + description: sw_description + state: present + delegate_to: localhost + +- name: Deleting a Leaf Profile + cisco.aci.aci_switch_policy_leaf_profile: + host: apic + username: admin + password: SomeSecretPassword + leaf_profile: sw_name + state: absent + delegate_to: localhost + +- name: Query a Leaf Profile + cisco.aci.aci_switch_policy_leaf_profile: + host: apic + username: admin + password: SomeSecretPassword + leaf_profile: sw_name + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + leaf_profile=dict(type='str', aliases=['name', 'leaf_profile_name']), # Not required for querying all objects + description=dict(type='str', aliases=['descr']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['leaf_profile']], + ['state', 'present', ['leaf_profile']], + ], + ) + + leaf_profile = module.params.get('leaf_profile') + description = module.params.get('description') + state = module.params.get('state') + name_alias = module.params.get('name_alias') + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='infraNodeP', + aci_rn='infra/nprof-{0}'.format(leaf_profile), + module_object=leaf_profile, + target_filter={'name': leaf_profile}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='infraNodeP', + class_config=dict( + name=leaf_profile, + descr=description, + nameAlias=name_alias, + ), + ) + + aci.get_diff(aci_class='infraNodeP') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_switch_policy_vpc_protection_group.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_switch_policy_vpc_protection_group.py new file mode 100644 index 00000000..184f20dd --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_switch_policy_vpc_protection_group.py @@ -0,0 +1,304 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2017, Bruno Calogero <brunocalogero@hotmail.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_switch_policy_vpc_protection_group +short_description: Manage switch policy explicit vPC protection groups (fabric:ExplicitGEp, fabric:NodePEp). +description: +- Manage switch policy explicit vPC protection groups on Cisco ACI fabrics. +options: + protection_group: + description: + - The name of the Explicit vPC Protection Group. + type: str + aliases: [ name, protection_group_name ] + protection_group_id: + description: + - The Explicit vPC Protection Group ID. + type: int + aliases: [ id ] + vpc_domain_policy: + description: + - The vPC domain policy to be associated with the Explicit vPC Protection Group. + type: str + aliases: [ vpc_domain_policy_name ] + switch_1_id: + description: + - The ID of the first Leaf Switch for the Explicit vPC Protection Group. + type: int + switch_2_id: + description: + - The ID of the Second Leaf Switch for the Explicit vPC Protection Group. + type: int + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +seealso: +- module: cisco.aci.aci_switch_policy_leaf_profile +- name: APIC Management Information Model reference + description: More information about the internal APIC classes B(fabric:ExplicitGEp) and B(fabric:NodePEp). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Bruno Calogero (@brunocalogero) +''' + +EXAMPLES = r''' +- name: Add vPC Protection Group + cisco.aci.aci_switch_policy_vpc_protection_group: + host: apic + username: admin + password: SomeSecretPassword + protection_group: leafPair101-vpcGrp + protection_group_id: 6 + switch_1_id: 1011 + switch_2_id: 1012 + state: present + delegate_to: localhost + +- name: Remove Explicit vPC Protection Group + cisco.aci.aci_switch_policy_vpc_protection_group: + host: apic + username: admin + password: SomeSecretPassword + protection_group: leafPair101-vpcGrp + state: absent + delegate_to: localhost + +- name: Query vPC Protection Groups + cisco.aci.aci_switch_policy_vpc_protection_group: + host: apic + username: admin + password: SomeSecretPassword + state: query + delegate_to: localhost + register: query_result + +- name: Query our vPC Protection Group + cisco.aci.aci_switch_policy_vpc_protection_group: + host: apic + username: admin + password: SomeSecretPassword + protection_group: leafPair101-vpcGrp + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + protection_group=dict(type='str', aliases=['name', 'protection_group_name']), # Not required for querying all objects + protection_group_id=dict(type='int', aliases=['id']), + vpc_domain_policy=dict(type='str', aliases=['vpc_domain_policy_name']), + switch_1_id=dict(type='int'), + switch_2_id=dict(type='int'), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['protection_group']], + ['state', 'present', ['protection_group', 'protection_group_id', 'switch_1_id', 'switch_2_id']], + ], + ) + + protection_group = module.params.get('protection_group') + protection_group_id = module.params.get('protection_group_id') + vpc_domain_policy = module.params.get('vpc_domain_policy') + switch_1_id = module.params.get('switch_1_id') + switch_2_id = module.params.get('switch_2_id') + state = module.params.get('state') + name_alias = module.params.get('name_alias') + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='fabricExplicitGEp', + aci_rn='fabric/protpol/expgep-{0}'.format(protection_group), + module_object=protection_group, + target_filter={'name': protection_group}, + ), + child_classes=['fabricNodePEp', 'fabricNodePEp', 'fabricRsVpcInstPol'], + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='fabricExplicitGEp', + class_config=dict( + name=protection_group, + id=protection_group_id, + nameAlias=name_alias, + ), + child_configs=[ + dict( + fabricNodePEp=dict( + attributes=dict( + id='{0}'.format(switch_1_id), + ), + ), + ), + dict( + fabricNodePEp=dict( + attributes=dict( + id='{0}'.format(switch_2_id), + ), + ), + ), + dict( + fabricRsVpcInstPol=dict( + attributes=dict( + tnVpcInstPolName=vpc_domain_policy, + ), + ), + ), + ], + ) + + aci.get_diff(aci_class='fabricExplicitGEp') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_system.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_system.py new file mode 100644 index 00000000..b4789adc --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_system.py @@ -0,0 +1,197 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2020, Lionel Hercot (@lhercot) <lhercot@cisco.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = r''' +--- +module: aci_system +short_description: Query the ACI system information (top:System) +description: +- Query the ACI system information (top:System) on Cisco ACI. +author: +- Lionel Hercot (@lhercot) +options: + id: + description: + - The controller node ID + aliases: [ controller, node ] + type: int + state: + description: + - Use C(query) for listing an object or multiple objects. + choices: [ query ] + default: query + type: str +notes: +- More information about the internal APIC class B(top:System) from + L(the APIC Management Information Model reference,https://developer.cisco.com/docs/apic-mim-ref/). +- This module is used to query system information for both cloud and on-premises controllers. + +extends_documentation_fragment: +- cisco.aci.aci +''' + +EXAMPLES = r''' +- name: Query all controllers system information + cisco.aci.aci_system: + host: apic + username: userName + password: somePassword + validate_certs: no + state: query + delegate_to: localhost + +- name: Query controller 1 specific system information + cisco.aci.aci_system: + host: apic + username: userName + password: somePassword + validate_certs: no + id: 1 + state: query + delegate_to: localhost +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec +from ansible.module_utils.basic import AnsibleModule + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + id=dict(type='int', aliases=['controller', 'node']), + state=dict(type='str', default='query', choices=['query']), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + ) + + id = module.params.get('id') + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='topSystem', + target_filter={'id': id} + ) + ) + + aci.get_existing() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_taboo_contract.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_taboo_contract.py new file mode 100644 index 00000000..b730328c --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_taboo_contract.py @@ -0,0 +1,286 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2018, Dag Wieers (dagwieers) <dag@wieers.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_taboo_contract +short_description: Manage taboo contracts (vz:BrCP) +description: +- Manage taboo contracts on Cisco ACI fabrics. +options: + taboo_contract: + description: + - The name of the Taboo Contract. + type: str + aliases: [ name ] + description: + description: + - The description for the Taboo Contract. + type: str + aliases: [ descr ] + tenant: + description: + - The name of the tenant. + type: str + aliases: [ tenant_name ] + scope: + description: + - The scope of a service contract. + - The APIC defaults to C(context) when unset during creation. + type: str + choices: [ application-profile, context, global, tenant ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- The C(tenant) used must exist before using this module in your playbook. + The M(cisco.aci.aci_tenant) module can be used for this. +seealso: +- module: cisco.aci.aci_tenant +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(vz:BrCP). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Dag Wieers (@dagwieers) +''' + +EXAMPLES = r''' +- name: Add taboo contract + cisco.aci.aci_taboo_contract: + host: apic + username: admin + password: SomeSecretPassword + tenant: ansible_test + taboo_contract: taboo_contract_test + state: present + delegate_to: localhost + +- name: Remove taboo contract + cisco.aci.aci_taboo_contract: + host: apic + username: admin + password: SomeSecretPassword + tenant: ansible_test + taboo_contract: taboo_contract_test + state: absent + delegate_to: localhost + +- name: Query all taboo contracts + cisco.aci.aci_taboo_contract: + host: apic + username: admin + password: SomeSecretPassword + state: query + delegate_to: localhost + register: query_result + +- name: Query a specific taboo contract + cisco.aci.aci_taboo_contract: + host: apic + username: admin + password: SomeSecretPassword + tenant: ansible_test + taboo_contract: taboo_contract_test + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + taboo_contract=dict(type='str', aliases=['name']), # Not required for querying all contracts + tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all contracts + scope=dict(type='str', choices=['application-profile', 'context', 'global', 'tenant']), + description=dict(type='str', aliases=['descr']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['tenant', 'taboo_contract']], + ['state', 'present', ['tenant', 'taboo_contract']], + ], + ) + + taboo_contract = module.params.get('taboo_contract') + description = module.params.get('description') + scope = module.params.get('scope') + state = module.params.get('state') + tenant = module.params.get('tenant') + name_alias = module.params.get('name_alias') + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + module_object=tenant, + target_filter={'name': tenant}, + ), + subclass_1=dict( + aci_class='vzTaboo', + aci_rn='taboo-{0}'.format(taboo_contract), + module_object=taboo_contract, + target_filter={'name': taboo_contract}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='vzTaboo', + class_config=dict( + name=taboo_contract, + descr=description, + scope=scope, + nameAlias=name_alias, + ), + ) + + aci.get_diff(aci_class='vzTaboo') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_tenant.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_tenant.py new file mode 100644 index 00000000..26ee14cf --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_tenant.py @@ -0,0 +1,261 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_tenant +short_description: Manage tenants (fv:Tenant) +description: +- Manage tenants on Cisco ACI fabrics. +options: + tenant: + description: + - The name of the tenant. + type: str + aliases: [ name, tenant_name ] + description: + description: + - Description for the tenant. + type: str + aliases: [ descr ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +seealso: +- module: cisco.aci.aci_ap +- module: cisco.aci.aci_bd +- module: cisco.aci.aci_contract +- module: cisco.aci.aci_filter +- module: cisco.aci.aci_vrf +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(fv:Tenant). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Jacob McGill (@jmcgill298) +''' + +EXAMPLES = r''' +- name: Add a new tenant + cisco.aci.aci_tenant: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + description: Production tenant + state: present + delegate_to: localhost + +- name: Remove a tenant + cisco.aci.aci_tenant: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + state: absent + delegate_to: localhost + +- name: Query a tenant + cisco.aci.aci_tenant: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + state: query + delegate_to: localhost + register: query_result + +- name: Query all tenants + cisco.aci.aci_tenant: + host: apic + username: admin + password: SomeSecretPassword + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + tenant=dict(type='str', aliases=['name', 'tenant_name']), # Not required for querying all objects + description=dict(type='str', aliases=['descr']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['tenant']], + ['state', 'present', ['tenant']], + ], + ) + + description = module.params.get('description') + state = module.params.get('state') + tenant = module.params.get('tenant') + name_alias = module.params.get('name_alias') + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + module_object=tenant, + target_filter={'name': tenant}, + ), + ) + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='fvTenant', + class_config=dict( + name=tenant, + descr=description, + nameAlias=name_alias, + ), + ) + + aci.get_diff(aci_class='fvTenant') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_tenant_action_rule_profile.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_tenant_action_rule_profile.py new file mode 100644 index 00000000..ca8393d2 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_tenant_action_rule_profile.py @@ -0,0 +1,246 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_tenant_action_rule_profile +short_description: Manage action rule profiles (rtctrl:AttrP) +description: +- Manage action rule profiles on Cisco ACI fabrics. +options: + action_rule: + description: + - The name of the action rule profile. + type: str + aliases: [ action_rule_name, name ] + description: + description: + - The description for the action rule profile. + type: str + aliases: [ descr ] + tenant: + description: + - The name of the tenant. + type: str + aliases: [ tenant_name ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- The C(tenant) used must exist before using this module in your playbook. + The M(cisco.aci.aci_tenant) module can be used for this. +seealso: +- module: cisco.aci.aci_tenant +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(rtctrl:AttrP). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Dag Wieers (@dagwieers) +''' + +# FIXME: Add more, better examples +EXAMPLES = r''' +- cisco.aci.aci_tenant_action_rule_profile: + host: apic + username: admin + password: SomeSecretPassword + action_rule: '{{ action_rule }}' + description: '{{ descr }}' + tenant: '{{ tenant }}' + delegate_to: localhost +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + action_rule=dict(type='str', aliases=['action_rule_name', 'name']), # Not required for querying all objects + tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects + description=dict(type='str', aliases=['descr']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['action_rule', 'tenant']], + ['state', 'present', ['action_rule', 'tenant']], + ], + ) + + action_rule = module.params.get('action_rule') + description = module.params.get('description') + state = module.params.get('state') + tenant = module.params.get('tenant') + name_alias = module.params.get('name_alias') + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + module_object=tenant, + target_filter={'name': tenant}, + ), + subclass_1=dict( + aci_class='rtctrlAttrP', + aci_rn='attr-{0}'.format(action_rule), + module_object=action_rule, + target_filter={'name': action_rule}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='rtctrlAttrP', + class_config=dict( + name=action_rule, + descr=description, + nameAlias=name_alias, + ), + ) + + aci.get_diff(aci_class='rtctrlAttrP') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_tenant_ep_retention_policy.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_tenant_ep_retention_policy.py new file mode 100644 index 00000000..5b0e0e70 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_tenant_ep_retention_policy.py @@ -0,0 +1,361 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_tenant_ep_retention_policy +short_description: Manage End Point (EP) retention protocol policies (fv:EpRetPol) +description: +- Manage End Point (EP) retention protocol policies on Cisco ACI fabrics. +options: + tenant: + description: + - The name of an existing tenant. + type: str + aliases: [ tenant_name ] + epr_policy: + description: + - The name of the end point retention policy. + type: str + aliases: [ epr_name, name ] + bounce_age: + description: + - Bounce entry aging interval in seconds. + - Accepted values range between C(150) and C(65535); 0 is used for infinite. + - The APIC defaults to C(630) when unset during creation. + type: int + bounce_trigger: + description: + - Determines if the bounce entries are installed by RARP Flood or COOP Protocol. + - The APIC defaults to C(coop) when unset during creation. + type: str + choices: [ coop, flood ] + hold_interval: + description: + - Hold interval in seconds. + - Accepted values range between C(5) and C(65535). + - The APIC defaults to C(300) when unset during creation. + type: int + local_ep_interval: + description: + - Local end point aging interval in seconds. + - Accepted values range between C(120) and C(65535); 0 is used for infinite. + - The APIC defaults to C(900) when unset during creation. + type: int + remote_ep_interval: + description: + - Remote end point aging interval in seconds. + - Accepted values range between C(120) and C(65535); 0 is used for infinite. + - The APIC defaults to C(300) when unset during creation. + type: int + move_frequency: + description: + - Move frequency per second. + - Accepted values range between C(0) and C(65535); 0 is used for none. + - The APIC defaults to C(256) when unset during creation. + type: int + description: + description: + - Description for the End point retention policy. + type: str + aliases: [ descr ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- The C(tenant) used must exist before using this module in your playbook. + The M(cisco.aci.aci_tenant) module can be used for this. +seealso: +- module: cisco.aci.aci_tenant +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(fv:EpRetPol). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Swetha Chunduri (@schunduri) +''' + +EXAMPLES = r''' +- name: Add a new EPR policy + cisco.aci.aci_tenant_ep_retention_policy: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + epr_policy: EPRPol1 + bounce_age: 630 + hold_interval: 300 + local_ep_interval: 900 + remote_ep_interval: 300 + move_frequency: 256 + description: test + state: present + delegate_to: localhost + +- name: Remove an EPR policy + cisco.aci.aci_tenant_ep_retention_policy: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + epr_policy: EPRPol1 + state: absent + delegate_to: localhost + +- name: Query an EPR policy + cisco.aci.aci_tenant_ep_retention_policy: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + epr_policy: EPRPol1 + state: query + delegate_to: localhost + register: query_result + +- name: Query all EPR policies + cisco.aci.aci_tenant_ep_retention_policy: + host: apic + username: admin + password: SomeSecretPassword + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + +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 objects + epr_policy=dict(type='str', aliases=['epr_name', 'name']), # Not required for querying all objects + bounce_age=dict(type='int'), + bounce_trigger=dict(type='str', choices=['coop', 'flood']), + hold_interval=dict(type='int'), + local_ep_interval=dict(type='int'), + remote_ep_interval=dict(type='int'), + description=dict(type='str', aliases=['descr']), + move_frequency=dict(type='int'), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['epr_policy', 'tenant']], + ['state', 'present', ['epr_policy', 'tenant']], + ], + ) + + epr_policy = module.params.get('epr_policy') + bounce_age = module.params.get('bounce_age') + if bounce_age is not None and bounce_age != 0 and bounce_age not in range(150, 65536): + module.fail_json(msg="The bounce_age must be a value of 0 or between 150 and 65535") + if bounce_age == 0: + bounce_age = 'infinite' + bounce_trigger = module.params.get('bounce_trigger') + if bounce_trigger is not None: + bounce_trigger = BOUNCE_TRIG_MAPPING[bounce_trigger] + description = module.params.get('description') + hold_interval = module.params.get('hold_interval') + if hold_interval is not None and hold_interval not in range(5, 65536): + module.fail_json(msg="The hold_interval must be a value between 5 and 65535") + local_ep_interval = module.params.get('local_ep_interval') + if local_ep_interval is not None and local_ep_interval != 0 and local_ep_interval not in range(120, 65536): + module.fail_json(msg="The local_ep_interval must be a value of 0 or between 120 and 65535") + if local_ep_interval == 0: + local_ep_interval = "infinite" + move_frequency = module.params.get('move_frequency') + if move_frequency is not None and move_frequency not in range(65536): + module.fail_json(msg="The move_frequency must be a value between 0 and 65535") + if move_frequency == 0: + move_frequency = "none" + remote_ep_interval = module.params.get('remote_ep_interval') + if remote_ep_interval is not None and remote_ep_interval not in range(120, 65536): + module.fail_json(msg="The remote_ep_interval must be a value of 0 or between 120 and 65535") + if remote_ep_interval == 0: + remote_ep_interval = "infinite" + state = module.params.get('state') + tenant = module.params.get('tenant') + name_alias = module.params.get('name_alias') + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + module_object=tenant, + target_filter={'name': tenant}, + ), + subclass_1=dict( + aci_class='fvEpRetPol', + aci_rn='epRPol-{0}'.format(epr_policy), + module_object=epr_policy, + target_filter={'name': epr_policy}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='fvEpRetPol', + class_config=dict( + name=epr_policy, + descr=description, + bounceAgeIntvl=bounce_age, + bounceTrig=bounce_trigger, + holdIntvl=hold_interval, + localEpAgeIntvl=local_ep_interval, + remoteEpAgeIntvl=remote_ep_interval, + moveFreq=move_frequency, + nameAlias=name_alias, + ), + ) + + aci.get_diff(aci_class='fvEpRetPol') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_tenant_span_dst_group.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_tenant_span_dst_group.py new file mode 100644 index 00000000..9c6c2664 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_tenant_span_dst_group.py @@ -0,0 +1,246 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_tenant_span_dst_group +short_description: Manage SPAN destination groups (span:DestGrp) +description: +- Manage SPAN destination groups on Cisco ACI fabrics. +options: + dst_group: + description: + - The name of the SPAN destination group. + type: str + aliases: [ name ] + description: + description: + - The description of the SPAN destination group. + type: str + aliases: [ descr ] + tenant: + description: + - The name of the tenant. + type: str + aliases: [ tenant_name ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- The C(tenant) used must exist before using this module in your playbook. + The M(cisco.aci.aci_tenant) module can be used for this. +seealso: +- module: cisco.aci.aci_tenant +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(span:DestGrp). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Dag Wieers (@dagwieers) +''' + +# FIXME: Add more, better examples +EXAMPLES = r''' +- cisco.aci.aci_tenant_span_dst_group: + host: apic + username: admin + password: SomeSecretPassword + dst_group: '{{ dst_group }}' + description: '{{ descr }}' + tenant: '{{ tenant }}' + delegate_to: localhost +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects + dst_group=dict(type='str', aliases=['name']), # Not required for querying all objects + description=dict(type='str', aliases=['descr']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['dst_group', 'tenant']], + ['state', 'present', ['dst_group', 'tenant']], + ], + ) + + dst_group = module.params.get('dst_group') + description = module.params.get('description') + state = module.params.get('state') + tenant = module.params.get('tenant') + name_alias = module.params.get('name_alias') + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + module_object=tenant, + target_filter={'name': tenant}, + ), + subclass_1=dict( + aci_class='spanDestGrp', + aci_rn='destgrp-{0}'.format(dst_group), + module_object=dst_group, + target_filter={'name': dst_group}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='spanDestGrp', + class_config=dict( + name=dst_group, + descr=description, + nameAlias=name_alias, + ), + ) + + aci.get_diff(aci_class='spanDestGrp') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_tenant_span_src_group.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_tenant_span_src_group.py new file mode 100644 index 00000000..0e8cbb1e --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_tenant_span_src_group.py @@ -0,0 +1,265 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_tenant_span_src_group +short_description: Manage SPAN source groups (span:SrcGrp) +description: +- Manage SPAN source groups on Cisco ACI fabrics. +options: + admin_state: + description: + - Enable or disable the span sources. + - The APIC defaults to C(yes) when unset during creation. + type: bool + description: + description: + - The description for Span source group. + type: str + aliases: [ descr ] + dst_group: + description: + - The Span destination group to associate with the source group. + type: str + src_group: + description: + - The name of the Span source group. + type: str + aliases: [ name ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str + tenant: + description: + - The name of the Tenant. + type: str + aliases: [ tenant_name ] +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- The C(tenant) used must exist before using this module in your playbook. + The M(cisco.aci.aci_tenant) module can be used for this. +seealso: +- module: cisco.aci.aci_tenant +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(span:SrcGrp). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Jacob McGill (@jmcgill298) +''' + +# FIXME: Add more, better examples +EXAMPLES = r''' +- cisco.aci.aci_tenant_span_src_group: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + src_group: "{{ src_group }}" + dst_group: "{{ dst_group }}" + admin_state: "{{ admin_state }}" + description: "{{ description }}" + delegate_to: localhost +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects + src_group=dict(type='str', aliases=['name']), # Not required for querying all objects + admin_state=dict(type='bool'), + description=dict(type='str', aliases=['descr']), + dst_group=dict(type='str'), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['src_group', 'tenant']], + ['state', 'present', ['src_group', 'tenant']], + ], + ) + + aci = ACIModule(module) + + admin_state = aci.boolean(module.params.get('admin_state'), 'enabled', 'disabled') + description = module.params.get('description') + dst_group = module.params.get('dst_group') + src_group = module.params.get('src_group') + state = module.params.get('state') + tenant = module.params.get('tenant') + name_alias = module.params.get('name_alias') + + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + module_object=tenant, + target_filter={'name': tenant}, + ), + subclass_1=dict( + aci_class='spanSrcGrp', + aci_rn='srcgrp-{0}'.format(src_group), + module_object=src_group, + target_filter={'name': src_group}, + ), + child_classes=['spanSpanLbl'], + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='spanSrcGrp', + class_config=dict( + adminSt=admin_state, + descr=description, + name=src_group, + nameAlias=name_alias, + ), + child_configs=[{'spanSpanLbl': {'attributes': {'name': dst_group}}}], + ) + + aci.get_diff(aci_class='spanSrcGrp') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_tenant_span_src_group_to_dst_group.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_tenant_span_src_group_to_dst_group.py new file mode 100644 index 00000000..c547320f --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_tenant_span_src_group_to_dst_group.py @@ -0,0 +1,260 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_tenant_span_src_group_to_dst_group +short_description: Bind SPAN source groups to destination groups (span:SpanLbl) +description: +- Bind SPAN source groups to associated destination groups on Cisco ACI fabrics. +options: + description: + description: + - The description for Span source group to destination group binding. + type: str + aliases: [ descr ] + dst_group: + description: + - The Span destination group to associate with the source group. + type: str + src_group: + description: + - The name of the Span source group. + type: str + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str + tenant: + description: + - The name of the Tenant. + type: str + aliases: [ tenant_name ] +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- The C(tenant), C(src_group), and C(dst_group) must exist before using this module in your playbook. + The M(cisco.aci.aci_tenant), M(cisco.aci.aci_tenant_span_src_group), and M(cisco.aci.aci_tenant_span_dst_group) modules can be used for this. +seealso: +- module: cisco.aci.aci_tenant +- module: cisco.aci.aci_tenant_span_src_group +- module: cisco.aci.aci_tenant_span_dst_group +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(span:SrcGrp). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Jacob McGill (@jmcgill298) +''' + +# FIXME: Add more, better examples +EXAMPLES = r''' +- cisco.aci.aci_tenant_span_src_group_to_dst_group: + host: apic + username: admin + password: SomeSecretPassword + tenant: production + src_group: "{{ src_group }}" + dst_group: "{{ dst_group }}" + description: "{{ description }}" + delegate_to: localhost +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects + dst_group=dict(type='str'), # Not required for querying all objects + src_group=dict(type='str'), # Not required for querying all objects + description=dict(type='str', aliases=['descr']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['dst_group', 'src_group', 'tenant']], + ['state', 'present', ['dst_group', 'src_group', 'tenant']], + ], + ) + + description = module.params.get('description') + dst_group = module.params.get('dst_group') + src_group = module.params.get('src_group') + state = module.params.get('state') + tenant = module.params.get('tenant') + name_alias = module.params.get('name_alias') + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + module_object=tenant, + target_filter={'name': tenant}, + ), + subclass_1=dict( + aci_class='spanSrcGrp', + aci_rn='srcgrp-{0}'.format(src_group), + module_object=src_group, + target_filter={'name': src_group}, + ), + subclass_2=dict( + aci_class='spanSpanLbl', + aci_rn='spanlbl-{0}'.format(dst_group), + module_object=dst_group, + target_filter={'name': dst_group}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='spanSpanLbl', + class_config=dict( + descr=description, + name=dst_group, + nameAlias=name_alias, + ), + ) + + aci.get_diff(aci_class='spanSpanLbl') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_vlan_pool.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_vlan_pool.py new file mode 100644 index 00000000..542d63c6 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_vlan_pool.py @@ -0,0 +1,283 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2017, Jacob McGill (@jmcgill298) +# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_vlan_pool +short_description: Manage VLAN pools (fvns:VlanInstP) +description: +- Manage VLAN pools on Cisco ACI fabrics. +options: + pool_allocation_mode: + description: + - The method used for allocating VLANs to resources. + type: str + choices: [ dynamic, static] + aliases: [ allocation_mode, mode ] + description: + description: + - Description for the C(pool). + type: str + aliases: [ descr ] + pool: + description: + - The name of the pool. + type: str + aliases: [ name, pool_name ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +seealso: +- module: cisco.aci.aci_encap_pool +- module: cisco.aci.aci_vlan_pool_encap_block +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(fvns:VlanInstP). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Jacob McGill (@jmcgill298) +- Dag Wieers (@dagwieers) +''' + +EXAMPLES = r''' +- name: Add a new VLAN pool + cisco.aci.aci_vlan_pool: + host: apic + username: admin + password: SomeSecretPassword + pool: production + pool_allocation_mode: dynamic + description: Production VLANs + state: present + delegate_to: localhost + +- name: Remove a VLAN pool + cisco.aci.aci_vlan_pool: + host: apic + username: admin + password: SomeSecretPassword + pool: production + pool_allocation_mode: dynamic + state: absent + delegate_to: localhost + +- name: Query a VLAN pool + cisco.aci.aci_vlan_pool: + host: apic + username: admin + password: SomeSecretPassword + pool: production + pool_allocation_mode: dynamic + state: query + delegate_to: localhost + register: query_result + +- name: Query all VLAN pools + cisco.aci.aci_vlan_pool: + host: apic + username: admin + password: SomeSecretPassword + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + pool=dict(type='str', aliases=['name', 'pool_name']), # Not required for querying all objects + description=dict(type='str', aliases=['descr']), + pool_allocation_mode=dict(type='str', aliases=['allocation_mode', 'mode'], choices=['dynamic', 'static']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['pool']], + ['state', 'present', ['pool']], + ], + ) + + description = module.params.get('description') + pool = module.params.get('pool') + pool_allocation_mode = module.params.get('pool_allocation_mode') + state = module.params.get('state') + name_alias = module.params.get('name_alias') + + pool_name = pool + + # ACI Pool URL requires the allocation mode for vlan and vsan pools (ex: uni/infra/vlanns-[poolname]-static) + if pool is not None: + if pool_allocation_mode is not None: + pool_name = '[{0}]-{1}'.format(pool, pool_allocation_mode) + else: + module.fail_json(msg="ACI requires the 'pool_allocation_mode' when 'pool' is provided") + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='fvnsVlanInstP', + aci_rn='infra/vlanns-{0}'.format(pool_name), + module_object=pool, + target_filter={'name': pool}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='fvnsVlanInstP', + class_config=dict( + allocMode=pool_allocation_mode, + descr=description, + name=pool, + nameAlias=name_alias, + ), + ) + + aci.get_diff(aci_class='fvnsVlanInstP') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_vlan_pool_encap_block.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_vlan_pool_encap_block.py new file mode 100644 index 00000000..e7204c63 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_vlan_pool_encap_block.py @@ -0,0 +1,362 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2017, Jacob McGill (jmcgill298) +# Copyright: (c) 2018, Dag Wieers (dagwieers) <dag@wieers.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_vlan_pool_encap_block +short_description: Manage encap blocks assigned to VLAN pools (fvns:EncapBlk) +description: +- Manage VLAN encap blocks that are assigned to VLAN pools on Cisco ACI fabrics. +options: + allocation_mode: + description: + - The method used for allocating encaps to resources. + type: str + choices: [ dynamic, inherit, static] + aliases: [ mode ] + description: + description: + - Description for the pool encap block. + type: str + aliases: [ descr ] + pool: + description: + - The name of the pool that the encap block should be assigned to. + type: str + aliases: [ pool_name ] + pool_allocation_mode: + description: + - The method used for allocating encaps to resources. + type: str + choices: [ dynamic, static] + aliases: [ pool_mode ] + block_end: + description: + - The end of encap block. + type: int + aliases: [ end ] + block_name: + description: + - The name to give to the encap block. + type: str + aliases: [ name ] + block_start: + description: + - The start of the encap block. + type: int + aliases: [ start ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str +extends_documentation_fragment: +- cisco.aci.aci + +notes: +- The C(pool) must exist in order to add or delete a encap block. +seealso: +- module: cisco.aci.aci_encap_pool_range +- module: cisco.aci.aci_vlan_pool +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(fvns:EncapBlk). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Jacob McGill (@jmcgill298) +- Dag Wieers (@dagwieers) +''' + +EXAMPLES = r''' +- name: Add a new VLAN encap block + cisco.aci.aci_vlan_pool_encap_block: + host: apic + username: admin + password: SomeSecretPassword + pool: production + block_start: 20 + block_end: 50 + state: present + delegate_to: localhost + +- name: Remove a VLAN encap block + cisco.aci.aci_vlan_pool_encap_block: + host: apic + username: admin + password: SomeSecretPassword + pool: production + block_start: 20 + block_end: 50 + state: absent + delegate_to: localhost + +- name: Query a VLAN encap block + cisco.aci.aci_vlan_pool_encap_block: + host: apic + username: admin + password: SomeSecretPassword + pool: production + block_start: 20 + block_end: 50 + state: query + delegate_to: localhost + register: query_result + +- name: Query a VLAN pool for encap blocks + cisco.aci.aci_vlan_pool_encap_block: + host: apic + username: admin + password: SomeSecretPassword + pool: production + state: query + delegate_to: localhost + register: query_result + +- name: Query all VLAN encap blocks + cisco.aci.aci_vlan_pool_encap_block: + host: apic + username: admin + password: SomeSecretPassword + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + pool=dict(type='str', aliases=['pool_name']), # Not required for querying all objects + 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 + allocation_mode=dict(type='str', aliases=['mode'], choices=['dynamic', 'inherit', 'static']), + description=dict(type='str', aliases=['descr']), + pool_allocation_mode=dict(type='str', aliases=['pool_mode'], choices=['dynamic', 'static']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['pool', 'block_end', 'block_name', 'block_start']], + ['state', 'present', ['pool', 'block_end', 'block_name', 'block_start']], + ], + ) + + allocation_mode = module.params.get('allocation_mode') + description = module.params.get('description') + pool = module.params.get('pool') + pool_allocation_mode = module.params.get('pool_allocation_mode') + block_end = module.params.get('block_end') + block_name = module.params.get('block_name') + block_start = module.params.get('block_start') + state = module.params.get('state') + name_alias = module.params.get('name_alias') + + if block_end is not None: + encap_end = 'vlan-{0}'.format(block_end) + else: + encap_end = None + + if block_start is not None: + encap_start = 'vlan-{0}'.format(block_start) + else: + encap_start = None + + # Collect proper mo information + aci_block_mo = 'from-[{0}]-to-[{1}]'.format(encap_start, encap_end) + pool_name = pool + + # Validate block_end and block_start are valid for its respective encap type + for encap_id in block_end, block_start: + if encap_id is not None: + if not 1 <= encap_id <= 4094: + module.fail_json(msg="vlan pools must have 'block_start' and 'block_end' values between 1 and 4094") + + if block_end is not None and block_start is not None: + # Validate block_start is less than block_end + if block_start > block_end: + module.fail_json(msg="The 'block_start' must be less than or equal to the 'block_end'") + + elif block_end is None and block_start is None: + if block_name is None: + # Reset range managed object to None for aci util to properly handle query + aci_block_mo = None + + # ACI Pool URL requires the allocation mode (ex: uni/infra/vlanns-[poolname]-static) + if pool is not None: + if pool_allocation_mode is not None: + pool_name = '[{0}]-{1}'.format(pool, pool_allocation_mode) + else: + module.fail_json(msg="ACI requires the 'pool_allocation_mode' when 'pool' is provided") + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='fvnsVlanInstP', + aci_rn='infra/vlanns-{0}'.format(pool_name), + module_object=pool, + target_filter={'name': pool}, + ), + subclass_1=dict( + aci_class='fvnsEncapBlk', + aci_rn=aci_block_mo, + module_object=aci_block_mo, + target_filter={'from': encap_start, 'to': encap_end, 'name': block_name}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='fvnsEncapBlk', + class_config={ + "allocMode": allocation_mode, + "descr": description, + "from": encap_start, + "name": block_name, + "to": encap_end, + "nameAlias": name_alias, + }, + ) + + aci.get_diff(aci_class='fvnsEncapBlk') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_vmm_credential.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_vmm_credential.py new file mode 100644 index 00000000..b9a8a8c7 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_vmm_credential.py @@ -0,0 +1,316 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + +DOCUMENTATION = r''' +--- +module: aci_vmm_credential +short_description: Manage virtual domain credential profiles (vmm:UsrAccP) +description: +- Manage virtual domain credential profiles on Cisco ACI fabrics. +options: + name: + description: + - Name of the credential profile. + type: str + aliases: [ credential_name, credential_profile ] + credential_password: + description: + - VMM controller password. + type: str + aliases: [] + credential_username: + description: + - VMM controller username. + type: str + aliases: [] + description: + description: + - Description for the tenant. + type: str + aliases: [ descr ] + domain: + description: + - Name of the virtual domain profile. + type: str + aliases: [ domain_name, domain_profile, name ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str + vm_provider: + description: + - The VM platform for VMM Domains. + - Support for Kubernetes was added in ACI v3.0. + - Support for CloudFoundry, OpenShift and Red Hat was added in ACI v3.1. + type: str + choices: [ cloudfoundry, kubernetes, microsoft, openshift, openstack, redhat, vmware ] +extends_documentation_fragment: +- cisco.aci.aci + +seealso: +- module: cisco.aci.aci_domain +- name: APIC Management Information Model reference + description: More information about the internal APIC classes B(vmm:DomP) + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Jason Juenger (@jasonjuenger) +''' + +EXAMPLES = r''' +- name: Add credential to VMware VMM domain + cisco.aci.aci_vmm_credential: + host: apic + username: admin + password: SomeSecretPassword + domain: vmware_dom + description: secure credential + name: vCenterCredential + credential_username: vCenterUsername + credential_password: vCenterPassword + vm_provider: vmware + state: present + +- name: Remove credential from VMware VMM domain + cisco.aci.aci_vmm_credential: + host: apic + username: admin + password: SomeSecretPassword + domain: vmware_dom + name: myCredential + vm_provider: vmware + state: absent + +- name: Query a specific VMware VMM credential + cisco.aci.aci_vmm_credential: + host: apic + username: admin + password: SomeSecretPassword + domain: vmware_dom + name: vCenterCredential + vm_provider: vmware + state: query + delegate_to: localhost + register: query_result + +- name: Query all VMware VMM credentials + cisco.aci.aci_vmm_credential: + host: apic + username: admin + password: SomeSecretPassword + domain: vmware_dom + vm_provider: vmware + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + +VM_PROVIDER_MAPPING = dict( + cloudfoundry='CloudFoundry', + kubernetes='Kubernetes', + microsoft='Microsoft', + openshift='OpenShift', + openstack='OpenStack', + redhat='Redhat', + vmware='VMware', +) + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + name=dict(type='str', aliases=['credential_name', 'credential_profile']), + credential_password=dict(type='str', no_log=True), + credential_username=dict(type='str'), + description=dict(type='str', aliases=['descr']), + domain=dict(type='str', aliases=['domain_name', 'domain_profile']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + vm_provider=dict(type='str', choices=list(VM_PROVIDER_MAPPING.keys())), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['domain']], + ['state', 'present', ['domain']], + ], + ) + + name = module.params.get('name') + credential_password = module.params.get('credential_password') + credential_username = module.params.get('credential_username') + description = module.params.get('description') + domain = module.params.get('domain') + state = module.params.get('state') + vm_provider = module.params.get('vm_provider') + name_alias = module.params.get('name_alias') + + credential_class = 'vmmUsrAccP' + usracc_mo = 'uni/vmmp-{0}/dom-{1}/usracc-{2}'.format(VM_PROVIDER_MAPPING.get(vm_provider), domain, name) + usracc_rn = 'vmmp-{0}/dom-{1}/usracc-{2}'.format(VM_PROVIDER_MAPPING.get(vm_provider), domain, name) + + # Ensure that querying all objects works when only domain is provided + if name is None: + usracc_mo = None + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class=credential_class, + aci_rn=usracc_rn, + module_object=usracc_mo, + target_filter={'name': domain, 'usracc': name}, + ), + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class=credential_class, + class_config=dict( + descr=description, + name=name, + pwd=credential_password, + usr=credential_username, + nameAlias=name_alias, + ), + ) + + aci.get_diff(aci_class=credential_class) + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_vrf.py b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_vrf.py new file mode 100644 index 00000000..6bb230c2 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/aci/plugins/modules/aci_vrf.py @@ -0,0 +1,324 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + +DOCUMENTATION = r''' +--- +module: aci_vrf +short_description: Manage contexts or VRFs (fv:Ctx) +description: +- Manage contexts or VRFs on Cisco ACI fabrics. +- Each context is a private network associated to a tenant, i.e. VRF. +- Enable Preferred Groups for VRF +options: + tenant: + description: + - The name of the Tenant the VRF should belong to. + type: str + aliases: [ tenant_name ] + vrf: + description: + - The name of the VRF. + type: str + aliases: [ context, name, vrf_name ] + policy_control_direction: + description: + - Determines if the policy should be enforced by the fabric on ingress or egress. + type: str + choices: [ egress, ingress ] + policy_control_preference: + description: + - Determines if the fabric should enforce contract policies to allow routing and packet forwarding. + type: str + choices: [ enforced, unenforced ] + description: + description: + - The description for the VRF. + type: str + aliases: [ descr ] + state: + description: + - Use C(present) or C(absent) for adding or removing. + - Use C(query) for listing an object or multiple objects. + type: str + choices: [ absent, present, query ] + default: present + name_alias: + description: + - The alias for the current object. This relates to the nameAlias field in ACI. + type: str + preferred_group: + description: + - Enables preferred groups for the VRF under vzAny + type: str + choices: [enabled, disabled] + match_type: + description: + - Configures match type for contracts under vzAny + type: str + choices: [ all, at_least_one, at_most_one, none] +extends_documentation_fragment: +- cisco.aci.aci +notes: +- The C(tenant) used must exist before using this module in your playbook. + The M(cisco.aci.aci_tenant) module can be used for this. +seealso: +- module: cisco.aci.aci_tenant +- name: APIC Management Information Model reference + description: More information about the internal APIC class B(fv:Ctx). + link: https://developer.cisco.com/docs/apic-mim-ref/ +author: +- Jacob McGill (@jmcgill298) +''' + +EXAMPLES = r''' +- name: Add a new VRF to a tenant + cisco.aci.aci_vrf: + host: apic + username: admin + password: SomeSecretPassword + vrf: vrf_lab + tenant: lab_tenant + descr: Lab VRF + policy_control_preference: enforced + policy_control_direction: ingress + state: present + delegate_to: localhost + +- name: Remove a VRF for a tenant + cisco.aci.aci_vrf: + host: apic + username: admin + password: SomeSecretPassword + vrf: vrf_lab + tenant: lab_tenant + state: absent + delegate_to: localhost + +- name: Query a VRF of a tenant + cisco.aci.aci_vrf: + host: apic + username: admin + password: SomeSecretPassword + vrf: vrf_lab + tenant: lab_tenant + state: query + delegate_to: localhost + register: query_result + +- name: Query all VRFs + cisco.aci.aci_vrf: + host: apic + username: admin + password: SomeSecretPassword + state: query + delegate_to: localhost + register: query_result +''' + +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: str + 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: str + sample: ?rsp-prop-include=config-only +method: + description: The HTTP method used for the request to the APIC + returned: failure or debug + type: str + sample: POST +response: + description: The HTTP response from the APIC + returned: failure or debug + type: str + 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: str + sample: https://10.11.12.13/api/mo/uni/tn-production.json +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec + +MATCH_TYPE_MAPPING = dict( + all='All', + at_least_one='AtleastOne', + at_most_one='AtmostOne', + none='None', +) + + +def main(): + argument_spec = aci_argument_spec() + argument_spec.update( + tenant=dict(type='str', aliases=['tenant_name']), # Not required for querying all objects + vrf=dict(type='str', aliases=['context', 'name', 'vrf_name']), # Not required for querying all objects + description=dict(type='str', aliases=['descr']), + policy_control_direction=dict(type='str', choices=['egress', 'ingress']), + policy_control_preference=dict(type='str', choices=['enforced', 'unenforced']), + state=dict(type='str', default='present', choices=['absent', 'present', 'query']), + preferred_group=dict(type='str', choices=['enabled', 'disabled']), + match_type=dict(type='str', choices=['all', 'at_least_one', 'at_most_one', 'none']), + name_alias=dict(type='str'), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_if=[ + ['state', 'absent', ['tenant', 'vrf']], + ['state', 'present', ['tenant', 'vrf']], + ], + ) + + description = module.params.get('description') + policy_control_direction = module.params.get('policy_control_direction') + policy_control_preference = module.params.get('policy_control_preference') + state = module.params.get('state') + tenant = module.params.get('tenant') + vrf = module.params.get('vrf') + name_alias = module.params.get('name_alias') + preferred_group = module.params.get('preferred_group') + match_type = module.params.get('match_type') + + if match_type is not None: + match_type = MATCH_TYPE_MAPPING[match_type] + + aci = ACIModule(module) + aci.construct_url( + root_class=dict( + aci_class='fvTenant', + aci_rn='tn-{0}'.format(tenant), + module_object=tenant, + target_filter={'name': tenant}, + ), + subclass_1=dict( + aci_class='fvCtx', + aci_rn='ctx-{0}'.format(vrf), + module_object=vrf, + target_filter={'name': vrf}, + ), + child_classes=['vzAny'] + ) + + aci.get_existing() + + if state == 'present': + aci.payload( + aci_class='fvCtx', + class_config=dict( + descr=description, + pcEnfDir=policy_control_direction, + pcEnfPref=policy_control_preference, + name=vrf, + nameAlias=name_alias, + ), + child_configs=[ + dict(vzAny=dict(attributes=dict(prefGrMemb=preferred_group, matchT=match_type))), + ], + ) + + aci.get_diff(aci_class='fvCtx') + + aci.post_config() + + elif state == 'absent': + aci.delete_config() + + aci.exit_json() + + +if __name__ == "__main__": + main() |