diff options
author | Ansible Core Team <info@ansible.com> | 2020-03-09 09:40:34 +0000 |
---|---|---|
committer | Ansible Core Team <info@ansible.com> | 2020-03-09 09:40:34 +0000 |
commit | ad5be6f8fd604ad53c784af148965b20459884af (patch) | |
tree | ba0ee59f1423a6c0e65ae99ccce5e47f2725b007 | |
parent | aee8e4f5ff0cf2dcc25a2a72f446add6367bf539 (diff) | |
download | ansible-ad5be6f8fd604ad53c784af148965b20459884af.tar.gz |
Migrated to cisco.aci
177 files changed, 0 insertions, 34283 deletions
diff --git a/lib/ansible/module_utils/network/aci/aci.py b/lib/ansible/module_utils/network/aci/aci.py deleted file mode 100644 index 313d71de97..0000000000 --- a/lib/ansible/module_utils/network/aci/aci.py +++ /dev/null @@ -1,1164 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Ansible, but is an independent component - -# This particular file snippet, and this file snippet only, is BSD licensed. -# Modules you write using this snippet, which is embedded dynamically by Ansible -# still belong to the author of the module, and may assign their own license -# to the complete work. - -# Copyright: (c) 2017, Dag Wieers <dag@wieers.com> -# Copyright: (c) 2017, Jacob McGill (@jmcgill298) -# Copyright: (c) 2017, Swetha Chunduri (@schunduri) -# Copyright: (c) 2019, Rob Huelga (@RobW3LGA) -# All rights reserved. - -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -import base64 -import json -import os -from copy import deepcopy - -from ansible.module_utils.parsing.convert_bool import boolean -from ansible.module_utils.urls import fetch_url -from ansible.module_utils._text import to_bytes, to_native - -# Optional, only used for APIC signature-based authentication -try: - from OpenSSL.crypto import FILETYPE_PEM, load_privatekey, sign - HAS_OPENSSL = True -except ImportError: - HAS_OPENSSL = False - -# Optional, only used for XML payload -try: - import lxml.etree - HAS_LXML_ETREE = True -except ImportError: - HAS_LXML_ETREE = False - -# Optional, only used for XML payload -try: - from xmljson import cobra - HAS_XMLJSON_COBRA = True -except ImportError: - HAS_XMLJSON_COBRA = False - - -def aci_argument_spec(): - return dict( - host=dict(type='str', required=True, aliases=['hostname']), - port=dict(type='int', required=False), - username=dict(type='str', default='admin', aliases=['user']), - password=dict(type='str', no_log=True), - private_key=dict(type='str', aliases=['cert_key'], no_log=True), # Beware, this is not the same as client_key ! - certificate_name=dict(type='str', aliases=['cert_name']), # Beware, this is not the same as client_cert ! - output_level=dict(type='str', default='normal', choices=['debug', 'info', 'normal']), - timeout=dict(type='int', default=30), - use_proxy=dict(type='bool', default=True), - use_ssl=dict(type='bool', default=True), - validate_certs=dict(type='bool', default=True), - ) - - -class ACIModule(object): - - def __init__(self, module): - self.module = module - self.params = module.params - self.result = dict(changed=False) - self.headers = dict() - self.child_classes = set() - - # error output - self.error = dict(code=None, text=None) - - # normal output - self.existing = None - - # info output - self.config = dict() - self.original = None - self.proposed = dict() - - # debug output - self.filter_string = '' - self.method = None - self.path = None - self.response = None - self.status = None - self.url = None - - # aci_rest output - self.imdata = None - self.totalCount = None - - # Ensure protocol is set - self.define_protocol() - - if self.module._debug: - self.module.warn('Enable debug output because ANSIBLE_DEBUG was set.') - self.params['output_level'] = 'debug' - - if self.params.get('private_key'): - # Perform signature-based authentication, no need to log on separately - if not HAS_OPENSSL: - self.module.fail_json(msg='Cannot use signature-based authentication because pyopenssl is not available') - elif self.params.get('password') is not None: - self.module.warn("When doing ACI signatured-based authentication, providing parameter 'password' is not required") - elif self.params.get('password'): - # Perform password-based authentication, log on using password - self.login() - else: - self.module.fail_json(msg="Either parameter 'password' or 'private_key' is required for authentication") - - def boolean(self, value, true='yes', false='no'): - ''' Return an acceptable value back ''' - - # When we expect value is of type=bool - if value is None: - return None - elif value is True: - return true - elif value is False: - return false - - # If all else fails, escalate back to user - self.module.fail_json(msg="Boolean value '%s' is an invalid ACI boolean value.") - - def iso8601_format(self, dt): - ''' Return an ACI-compatible ISO8601 formatted time: 2123-12-12T00:00:00.000+00:00 ''' - try: - return dt.isoformat(timespec='milliseconds') - except Exception: - tz = dt.strftime('%z') - return '%s.%03d%s:%s' % (dt.strftime('%Y-%m-%dT%H:%M:%S'), dt.microsecond / 1000, tz[:3], tz[3:]) - - def define_protocol(self): - ''' Set protocol based on use_ssl parameter ''' - - # Set protocol for further use - self.params['protocol'] = 'https' if self.params.get('use_ssl', True) else 'http' - - def define_method(self): - ''' Set method based on state parameter ''' - - # Set method for further use - state_map = dict(absent='delete', present='post', query='get') - self.params['method'] = state_map.get(self.params.get('state')) - - def login(self): - ''' Log in to APIC ''' - - # Perform login request - if self.params.get('port') is not None: - url = '%(protocol)s://%(host)s:%(port)s/api/aaaLogin.json' % self.params - else: - url = '%(protocol)s://%(host)s/api/aaaLogin.json' % self.params - payload = {'aaaUser': {'attributes': {'name': self.params.get('username'), 'pwd': self.params.get('password')}}} - resp, auth = fetch_url(self.module, url, - data=json.dumps(payload), - method='POST', - timeout=self.params.get('timeout'), - use_proxy=self.params.get('use_proxy')) - - # Handle APIC response - if auth.get('status') != 200: - self.response = auth.get('msg') - self.status = auth.get('status') - try: - # APIC error - self.response_json(auth['body']) - self.fail_json(msg='Authentication failed: %(code)s %(text)s' % self.error) - except KeyError: - # Connection error - self.fail_json(msg='Connection failed for %(url)s. %(msg)s' % auth) - - # Retain cookie for later use - self.headers['Cookie'] = resp.headers.get('Set-Cookie') - - def cert_auth(self, path=None, payload='', method=None): - ''' Perform APIC signature-based authentication, not the expected SSL client certificate authentication. ''' - - if method is None: - method = self.params.get('method').upper() - - # NOTE: ACI documentation incorrectly uses complete URL - if path is None: - path = self.path - path = '/' + path.lstrip('/') - - if payload is None: - payload = '' - - # Check if we got a private key. This allows the use of vaulting the private key. - if self.params.get('private_key').startswith('-----BEGIN PRIVATE KEY-----'): - try: - sig_key = load_privatekey(FILETYPE_PEM, self.params.get('private_key')) - except Exception: - self.module.fail_json(msg="Cannot load provided 'private_key' parameter.") - # Use the username as the certificate_name value - if self.params.get('certificate_name') is None: - self.params['certificate_name'] = self.params.get('username') - elif self.params.get('private_key').startswith('-----BEGIN CERTIFICATE-----'): - self.module.fail_json(msg="Provided 'private_key' parameter value appears to be a certificate.") - else: - # If we got a private key file, read from this file. - # NOTE: Avoid exposing any other credential as a filename in output... - if not os.path.exists(self.params.get('private_key')): - self.module.fail_json(msg="The provided private key file does not appear to exist. Is it a filename?") - try: - with open(self.params.get('private_key'), 'r') as fh: - private_key_content = fh.read() - except Exception: - self.module.fail_json(msg="Cannot open private key file '%(private_key)s'." % self.params) - if private_key_content.startswith('-----BEGIN PRIVATE KEY-----'): - try: - sig_key = load_privatekey(FILETYPE_PEM, private_key_content) - except Exception: - self.module.fail_json(msg="Cannot load private key file '%(private_key)s'." % self.params) - # Use the private key basename (without extension) as certificate_name - if self.params.get('certificate_name') is None: - self.params['certificate_name'] = os.path.basename(os.path.splitext(self.params.get('private_key'))[0]) - elif private_key_content.startswith('-----BEGIN CERTIFICATE-----'): - self.module.fail_json(msg="Provided private key file '%(private_key)s' appears to be a certificate." % self.params) - else: - self.module.fail_json(msg="Provided private key file '%(private_key)s' does not appear to be a private key." % self.params) - - # NOTE: ACI documentation incorrectly adds a space between method and path - sig_request = method + path + payload - sig_signature = base64.b64encode(sign(sig_key, sig_request, 'sha256')) - sig_dn = 'uni/userext/user-%(username)s/usercert-%(certificate_name)s' % self.params - self.headers['Cookie'] = 'APIC-Certificate-Algorithm=v1.0; ' +\ - 'APIC-Certificate-DN=%s; ' % sig_dn +\ - 'APIC-Certificate-Fingerprint=fingerprint; ' +\ - 'APIC-Request-Signature=%s' % to_native(sig_signature) - - def response_json(self, rawoutput): - ''' Handle APIC JSON response output ''' - try: - jsondata = json.loads(rawoutput) - except Exception as e: - # Expose RAW output for troubleshooting - self.error = dict(code=-1, text="Unable to parse output as JSON, see 'raw' output. %s" % e) - self.result['raw'] = rawoutput - return - - # Extract JSON API output - self.imdata = jsondata.get('imdata') - if self.imdata is None: - self.imdata = dict() - self.totalCount = int(jsondata.get('totalCount')) - - # Handle possible APIC error information - self.response_error() - - def response_xml(self, rawoutput): - ''' Handle APIC XML response output ''' - - # NOTE: The XML-to-JSON conversion is using the "Cobra" convention - try: - xml = lxml.etree.fromstring(to_bytes(rawoutput)) - xmldata = cobra.data(xml) - except Exception as e: - # Expose RAW output for troubleshooting - self.error = dict(code=-1, text="Unable to parse output as XML, see 'raw' output. %s" % e) - self.result['raw'] = rawoutput - return - - # Reformat as ACI does for JSON API output - self.imdata = xmldata.get('imdata', {}).get('children') - if self.imdata is None: - self.imdata = dict() - self.totalCount = int(xmldata.get('imdata', {}).get('attributes', {}).get('totalCount')) - - # Handle possible APIC error information - self.response_error() - - def response_error(self): - ''' Set error information when found ''' - - # Handle possible APIC error information - if self.totalCount != '0': - try: - self.error = self.imdata[0].get('error').get('attributes') - except (AttributeError, IndexError, KeyError): - pass - - def request(self, path, payload=None): - ''' Perform a REST request ''' - - # Ensure method is set (only do this once) - self.define_method() - self.path = path - - if self.params.get('port') is not None: - self.url = '%(protocol)s://%(host)s:%(port)s/' % self.params + path.lstrip('/') - else: - self.url = '%(protocol)s://%(host)s/' % self.params + path.lstrip('/') - - # Sign and encode request as to APIC's wishes - if self.params.get('private_key'): - self.cert_auth(path=path, payload=payload) - - # Perform request - resp, info = fetch_url(self.module, self.url, - data=payload, - headers=self.headers, - method=self.params.get('method').upper(), - timeout=self.params.get('timeout'), - use_proxy=self.params.get('use_proxy')) - - self.response = info.get('msg') - self.status = info.get('status') - - # Handle APIC response - if info.get('status') != 200: - try: - # APIC error - self.response_json(info['body']) - self.fail_json(msg='APIC Error %(code)s: %(text)s' % self.error) - except KeyError: - # Connection error - self.fail_json(msg='Connection failed for %(url)s. %(msg)s' % info) - - self.response_json(resp.read()) - - def query(self, path): - ''' Perform a query with no payload ''' - - self.path = path - - if self.params.get('port') is not None: - self.url = '%(protocol)s://%(host)s:%(port)s/' % self.params + path.lstrip('/') - else: - self.url = '%(protocol)s://%(host)s/' % self.params + path.lstrip('/') - - # Sign and encode request as to APIC's wishes - if self.params.get('private_key'): - self.cert_auth(path=path, method='GET') - - # Perform request - resp, query = fetch_url(self.module, self.url, - data=None, - headers=self.headers, - method='GET', - timeout=self.params.get('timeout'), - use_proxy=self.params.get('use_proxy')) - - # Handle APIC response - if query.get('status') != 200: - self.response = query.get('msg') - self.status = query.get('status') - try: - # APIC error - self.response_json(query['body']) - self.fail_json(msg='APIC Error %(code)s: %(text)s' % self.error) - except KeyError: - # Connection error - self.fail_json(msg='Connection failed for %(url)s. %(msg)s' % query) - - query = json.loads(resp.read()) - - return json.dumps(query.get('imdata'), sort_keys=True, indent=2) + '\n' - - def request_diff(self, path, payload=None): - ''' Perform a request, including a proper diff output ''' - self.result['diff'] = dict() - self.result['diff']['before'] = self.query(path) - self.request(path, payload=payload) - # TODO: Check if we can use the request output for the 'after' diff - self.result['diff']['after'] = self.query(path) - - if self.result.get('diff', {}).get('before') != self.result.get('diff', {}).get('after'): - self.result['changed'] = True - - # TODO: This could be designed to update existing keys - def update_qs(self, params): - ''' Append key-value pairs to self.filter_string ''' - accepted_params = dict((k, v) for (k, v) in params.items() if v is not None) - if accepted_params: - if self.filter_string: - self.filter_string += '&' - else: - self.filter_string = '?' - self.filter_string += '&'.join(['%s=%s' % (k, v) for (k, v) in accepted_params.items()]) - - # TODO: This could be designed to accept multiple obj_classes and keys - def build_filter(self, obj_class, params): - ''' Build an APIC filter based on obj_class and key-value pairs ''' - accepted_params = dict((k, v) for (k, v) in params.items() if v is not None) - if len(accepted_params) == 1: - return ','.join('eq({0}.{1},"{2}")'.format(obj_class, k, v) for (k, v) in accepted_params.items()) - elif len(accepted_params) > 1: - return 'and(' + ','.join(['eq({0}.{1},"{2}")'.format(obj_class, k, v) for (k, v) in accepted_params.items()]) + ')' - - def _deep_url_path_builder(self, obj): - target_class = obj.get('target_class') - target_filter = obj.get('target_filter') - subtree_class = obj.get('subtree_class') - subtree_filter = obj.get('subtree_filter') - object_rn = obj.get('object_rn') - mo = obj.get('module_object') - add_subtree_filter = obj.get('add_subtree_filter') - add_target_filter = obj.get('add_target_filter') - - if self.module.params.get('state') in ('absent', 'present') and mo is not None: - self.path = 'api/mo/uni/{0}.json'.format(object_rn) - self.update_qs({'rsp-prop-include': 'config-only'}) - - else: - # State is 'query' - if object_rn is not None: - # Query for a specific object in the module's class - self.path = 'api/mo/uni/{0}.json'.format(object_rn) - else: - self.path = 'api/class/{0}.json'.format(target_class) - - if add_target_filter: - self.update_qs( - {'query-target-filter': self.build_filter(target_class, target_filter)}) - - if add_subtree_filter: - self.update_qs( - {'rsp-subtree-filter': self.build_filter(subtree_class, subtree_filter)}) - - if self.params.get('port') is not None: - self.url = '{protocol}://{host}:{port}/{path}'.format( - path=self.path, **self.module.params) - - else: - self.url = '{protocol}://{host}/{path}'.format( - path=self.path, **self.module.params) - - if self.child_classes: - self.update_qs( - {'rsp-subtree': 'full', 'rsp-subtree-class': ','.join(sorted(self.child_classes))}) - - def _deep_url_parent_object(self, parent_objects, parent_class): - - for parent_object in parent_objects: - if parent_object.get('aci_class') is parent_class: - return parent_object - - return None - - def construct_deep_url(self, target_object, parent_objects=None, child_classes=None): - """ - This method is used to retrieve the appropriate URL path and filter_string to make the request to the APIC. - - :param target_object: The target class dictionary containing parent_class, aci_class, aci_rn, target_filter, and module_object keys. - :param parent_objects: The parent class list of dictionaries containing parent_class, aci_class, aci_rn, target_filter, and module_object keys. - :param child_classes: The list of child classes that the module supports along with the object. - :type target_object: dict - :type parent_objects: list[dict] - :type child_classes: list[string] - :return: The path and filter_string needed to build the full URL. - """ - - self.filter_string = '' - rn_builder = None - subtree_classes = None - add_subtree_filter = False - add_target_filter = False - has_target_query = False - has_target_query_compare = False - has_target_query_difference = False - has_target_query_called = False - - if child_classes is None: - self.child_classes = set() - else: - self.child_classes = set(child_classes) - - target_parent_class = target_object.get('parent_class') - target_class = target_object.get('aci_class') - target_rn = target_object.get('aci_rn') - target_filter = target_object.get('target_filter') - target_module_object = target_object.get('module_object') - - url_path_object = dict( - target_class=target_class, - target_filter=target_filter, - subtree_class=target_class, - subtree_filter=target_filter, - module_object=target_module_object - ) - - if target_module_object is not None: - rn_builder = target_rn - else: - has_target_query = True - has_target_query_compare = True - - if parent_objects is not None: - current_parent_class = target_parent_class - has_parent_query_compare = False - has_parent_query_difference = False - is_first_parent = True - is_single_parent = None - search_classes = set() - - while current_parent_class != 'uni': - parent_object = self._deep_url_parent_object( - parent_objects=parent_objects, parent_class=current_parent_class) - - if parent_object is not None: - parent_parent_class = parent_object.get('parent_class') - parent_class = parent_object.get('aci_class') - parent_rn = parent_object.get('aci_rn') - parent_filter = parent_object.get('target_filter') - parent_module_object = parent_object.get('module_object') - - if is_first_parent: - is_single_parent = True - else: - is_single_parent = False - is_first_parent = False - - if parent_parent_class != 'uni': - search_classes.add(parent_class) - - if parent_module_object is not None: - if rn_builder is not None: - rn_builder = '{0}/{1}'.format(parent_rn, rn_builder) - else: - rn_builder = parent_rn - - url_path_object['target_class'] = parent_class - url_path_object['target_filter'] = parent_filter - - has_target_query = False - else: - rn_builder = None - subtree_classes = search_classes - - has_target_query = True - if is_single_parent: - has_parent_query_compare = True - - current_parent_class = parent_parent_class - else: - raise ValueError("Reference error for parent_class '{0}'. Each parent_class must reference a valid object".format(current_parent_class)) - - if not has_target_query_difference and not has_target_query_called: - if has_target_query is not has_target_query_compare: - has_target_query_difference = True - else: - if not has_parent_query_difference and has_target_query is not has_parent_query_compare: - has_parent_query_difference = True - has_target_query_called = True - - if not has_parent_query_difference and has_parent_query_compare and target_module_object is not None: - add_target_filter = True - - elif has_parent_query_difference and target_module_object is not None: - add_subtree_filter = True - self.child_classes.add(target_class) - - if has_target_query: - add_target_filter = True - - elif has_parent_query_difference and not has_target_query and target_module_object is None: - self.child_classes.add(target_class) - self.child_classes.update(subtree_classes) - - elif not has_parent_query_difference and not has_target_query and target_module_object is None: - self.child_classes.add(target_class) - - elif not has_target_query and is_single_parent and target_module_object is None: - self.child_classes.add(target_class) - - url_path_object['object_rn'] = rn_builder - url_path_object['add_subtree_filter'] = add_subtree_filter - url_path_object['add_target_filter'] = add_target_filter - - self._deep_url_path_builder(url_path_object) - - def construct_url(self, root_class, subclass_1=None, subclass_2=None, subclass_3=None, child_classes=None): - """ - This method is used to retrieve the appropriate URL path and filter_string to make the request to the APIC. - - :param root_class: The top-level class dictionary containing aci_class, aci_rn, target_filter, and module_object keys. - :param sublass_1: The second-level class dictionary containing aci_class, aci_rn, target_filter, and module_object keys. - :param sublass_2: The third-level class dictionary containing aci_class, aci_rn, target_filter, and module_object keys. - :param sublass_3: The fourth-level class dictionary containing aci_class, aci_rn, target_filter, and module_object keys. - :param child_classes: The list of child classes that the module supports along with the object. - :type root_class: dict - :type subclass_1: dict - :type subclass_2: dict - :type subclass_3: dict - :type child_classes: list - :return: The path and filter_string needed to build the full URL. - """ - self.filter_string = '' - - if child_classes is None: - self.child_classes = set() - else: - self.child_classes = set(child_classes) - - if subclass_3 is not None: - self._construct_url_4(root_class, subclass_1, subclass_2, subclass_3) - elif subclass_2 is not None: - self._construct_url_3(root_class, subclass_1, subclass_2) - elif subclass_1 is not None: - self._construct_url_2(root_class, subclass_1) - else: - self._construct_url_1(root_class) - - if self.params.get('port') is not None: - self.url = '{protocol}://{host}:{port}/{path}'.format(path=self.path, **self.module.params) - else: - self.url = '{protocol}://{host}/{path}'.format(path=self.path, **self.module.params) - - if self.child_classes: - # Append child_classes to filter_string if filter string is empty - self.update_qs({'rsp-subtree': 'full', 'rsp-subtree-class': ','.join(sorted(self.child_classes))}) - - def _construct_url_1(self, obj): - """ - This method is used by construct_url when the object is the top-level class. - """ - obj_class = obj.get('aci_class') - obj_rn = obj.get('aci_rn') - obj_filter = obj.get('target_filter') - mo = obj.get('module_object') - - if self.module.params.get('state') in ('absent', 'present'): - # State is absent or present - self.path = 'api/mo/uni/{0}.json'.format(obj_rn) - self.update_qs({'rsp-prop-include': 'config-only'}) - elif mo is None: - # Query for all objects of the module's class (filter by properties) - self.path = 'api/class/{0}.json'.format(obj_class) - self.update_qs({'query-target-filter': self.build_filter(obj_class, obj_filter)}) - else: - # Query for a specific object in the module's class - self.path = 'api/mo/uni/{0}.json'.format(obj_rn) - - def _construct_url_2(self, parent, obj): - """ - This method is used by construct_url when the object is the second-level class. - """ - parent_class = parent.get('aci_class') - parent_rn = parent.get('aci_rn') - parent_filter = parent.get('target_filter') - parent_obj = parent.get('module_object') - obj_class = obj.get('aci_class') - obj_rn = obj.get('aci_rn') - obj_filter = obj.get('target_filter') - mo = obj.get('module_object') - - if self.module.params.get('state') in ('absent', 'present'): - # State is absent or present - self.path = 'api/mo/uni/{0}/{1}.json'.format(parent_rn, obj_rn) - self.update_qs({'rsp-prop-include': 'config-only'}) - elif parent_obj is None and mo is None: - # Query for all objects of the module's class - self.path = 'api/class/{0}.json'.format(obj_class) - self.update_qs({'query-target-filter': self.build_filter(obj_class, obj_filter)}) - elif parent_obj is None: # mo is known - # Query for all objects of the module's class that match the provided ID value - self.path = 'api/class/{0}.json'.format(obj_class) - self.update_qs({'query-target-filter': self.build_filter(obj_class, obj_filter)}) - elif mo is None: # parent_obj is known - # Query for all object's of the module's class that belong to a specific parent object - self.child_classes.add(obj_class) - self.path = 'api/mo/uni/{0}.json'.format(parent_rn) - else: - # Query for specific object in the module's class - self.path = 'api/mo/uni/{0}/{1}.json'.format(parent_rn, obj_rn) - - def _construct_url_3(self, root, parent, obj): - """ - This method is used by construct_url when the object is the third-level class. - """ - root_class = root.get('aci_class') - root_rn = root.get('aci_rn') - root_filter = root.get('target_filter') - root_obj = root.get('module_object') - parent_class = parent.get('aci_class') - parent_rn = parent.get('aci_rn') - parent_filter = parent.get('target_filter') - parent_obj = parent.get('module_object') - obj_class = obj.get('aci_class') - obj_rn = obj.get('aci_rn') - obj_filter = obj.get('target_filter') - mo = obj.get('module_object') - - if self.module.params.get('state') in ('absent', 'present'): - # State is absent or present - self.path = 'api/mo/uni/{0}/{1}/{2}.json'.format(root_rn, parent_rn, obj_rn) - self.update_qs({'rsp-prop-include': 'config-only'}) - elif root_obj is None and parent_obj is None and mo is None: - # Query for all objects of the module's class - self.path = 'api/class/{0}.json'.format(obj_class) - self.update_qs({'query-target-filter': self.build_filter(obj_class, obj_filter)}) - elif root_obj is None and parent_obj is None: # mo is known - # Query for all objects of the module's class matching the provided ID value of the object - self.path = 'api/class/{0}.json'.format(obj_class) - self.update_qs({'query-target-filter': self.build_filter(obj_class, obj_filter)}) - elif root_obj is None and mo is None: # parent_obj is known - # Query for all objects of the module's class that belong to any parent class - # matching the provided ID value for the parent object - self.child_classes.add(obj_class) - self.path = 'api/class/{0}.json'.format(parent_class) - self.update_qs({'query-target-filter': self.build_filter(parent_class, parent_filter)}) - elif parent_obj is None and mo is None: # root_obj is known - # Query for all objects of the module's class that belong to a specific root object - self.child_classes.update([parent_class, obj_class]) - self.path = 'api/mo/uni/{0}.json'.format(root_rn) - # NOTE: No need to select by root_filter - # self.update_qs({'query-target-filter': self.build_filter(root_class, root_filter)}) - elif root_obj is None: # mo and parent_obj are known - # Query for all objects of the module's class that belong to any parent class - # matching the provided ID values for both object and parent object - self.child_classes.add(obj_class) - self.path = 'api/class/{0}.json'.format(parent_class) - self.update_qs({'query-target-filter': self.build_filter(parent_class, parent_filter)}) - self.update_qs({'rsp-subtree-filter': self.build_filter(obj_class, obj_filter)}) - elif parent_obj is None: # mo and root_obj are known - # Query for all objects of the module's class that match the provided ID value and belong to a specific root object - self.child_classes.add(obj_class) - self.path = 'api/mo/uni/{0}.json'.format(root_rn) - # NOTE: No need to select by root_filter - # self.update_qs({'query-target-filter': self.build_filter(root_class, root_filter)}) - # TODO: Filter by parent_filter and obj_filter - self.update_qs({'rsp-subtree-filter': self.build_filter(obj_class, obj_filter)}) - elif mo is None: # root_obj and parent_obj are known - # Query for all objects of the module's class that belong to a specific parent object - self.child_classes.add(obj_class) - self.path = 'api/mo/uni/{0}/{1}.json'.format(root_rn, parent_rn) - # NOTE: No need to select by parent_filter - # self.update_qs({'query-target-filter': self.build_filter(parent_class, parent_filter)}) - else: - # Query for a specific object of the module's class - self.path = 'api/mo/uni/{0}/{1}/{2}.json'.format(root_rn, parent_rn, obj_rn) - - def _construct_url_4(self, root, sec, parent, obj): - """ - This method is used by construct_url when the object is the fourth-level class. - """ - root_class = root.get('aci_class') - root_rn = root.get('aci_rn') - root_filter = root.get('target_filter') - root_obj = root.get('module_object') - sec_class = sec.get('aci_class') - sec_rn = sec.get('aci_rn') - sec_filter = sec.get('target_filter') - sec_obj = sec.get('module_object') - parent_class = parent.get('aci_class') - parent_rn = parent.get('aci_rn') - parent_filter = parent.get('target_filter') - parent_obj = parent.get('module_object') - obj_class = obj.get('aci_class') - obj_rn = obj.get('aci_rn') - obj_filter = obj.get('target_filter') - mo = obj.get('module_object') - - if self.child_classes is None: - self.child_classes = [obj_class] - - if self.module.params.get('state') in ('absent', 'present'): - # State is absent or present - self.path = 'api/mo/uni/{0}/{1}/{2}/{3}.json'.format(root_rn, sec_rn, parent_rn, obj_rn) - self.update_qs({'rsp-prop-include': 'config-only'}) - # TODO: Add all missing cases - elif root_obj is None: - self.child_classes.add(obj_class) - self.path = 'api/class/{0}.json'.format(obj_class) - self.update_qs({'query-target-filter': self.build_filter(obj_class, obj_filter)}) - elif sec_obj is None: - self.child_classes.add(obj_class) - self.path = 'api/mo/uni/{0}.json'.format(root_rn) - # NOTE: No need to select by root_filter - # self.update_qs({'query-target-filter': self.build_filter(root_class, root_filter)}) - # TODO: Filter by sec_filter, parent and obj_filter - self.update_qs({'rsp-subtree-filter': self.build_filter(obj_class, obj_filter)}) - elif parent_obj is None: - self.child_classes.add(obj_class) - self.path = 'api/mo/uni/{0}/{1}.json'.format(root_rn, sec_rn) - # NOTE: No need to select by sec_filter - # self.update_qs({'query-target-filter': self.build_filter(sec_class, sec_filter)}) - # TODO: Filter by parent_filter and obj_filter - self.update_qs({'rsp-subtree-filter': self.build_filter(obj_class, obj_filter)}) - elif mo is None: - self.child_classes.add(obj_class) - self.path = 'api/mo/uni/{0}/{1}/{2}.json'.format(root_rn, sec_rn, parent_rn) - # NOTE: No need to select by parent_filter - # self.update_qs({'query-target-filter': self.build_filter(parent_class, parent_filter)}) - else: - # Query for a specific object of the module's class - self.path = 'api/mo/uni/{0}/{1}/{2}/{3}.json'.format(root_rn, sec_rn, parent_rn, obj_rn) - - def delete_config(self): - """ - This method is used to handle the logic when the modules state is equal to absent. The method only pushes a change if - the object exists, and if check_mode is False. A successful change will mark the module as changed. - """ - self.proposed = dict() - - if not self.existing: - return - - elif not self.module.check_mode: - # Sign and encode request as to APIC's wishes - if self.params['private_key']: - self.cert_auth(method='DELETE') - - resp, info = fetch_url(self.module, self.url, - headers=self.headers, - method='DELETE', - timeout=self.params.get('timeout'), - use_proxy=self.params.get('use_proxy')) - - self.response = info.get('msg') - self.status = info.get('status') - self.method = 'DELETE' - - # Handle APIC response - if info.get('status') == 200: - self.result['changed'] = True - self.response_json(resp.read()) - else: - try: - # APIC error - self.response_json(info['body']) - self.fail_json(msg='APIC Error %(code)s: %(text)s' % self.error) - except KeyError: - # Connection error - self.fail_json(msg='Connection failed for %(url)s. %(msg)s' % info) - else: - self.result['changed'] = True - self.method = 'DELETE' - - def get_diff(self, aci_class): - """ - This method is used to get the difference between the proposed and existing configurations. Each module - should call the get_existing method before this method, and add the proposed config to the module results - using the module's config parameters. The new config will added to the self.result dictionary. - - :param aci_class: Type str. - This is the root dictionary key for the MO's configuration body, or the ACI class of the MO. - """ - proposed_config = self.proposed[aci_class]['attributes'] - if self.existing: - existing_config = self.existing[0][aci_class]['attributes'] - config = {} - - # values are strings, so any diff between proposed and existing can be a straight replace - for key, value in proposed_config.items(): - existing_field = existing_config.get(key) - if value != existing_field: - config[key] = value - - # add name back to config only if the configs do not match - if config: - # TODO: If URLs are built with the object's name, then we should be able to leave off adding the name back - # config['name'] = proposed_config.get('name') - config = {aci_class: {'attributes': config}} - - # check for updates to child configs and update new config dictionary - children = self.get_diff_children(aci_class) - if children and config: - config[aci_class].update({'children': children}) - elif children: - config = {aci_class: {'attributes': {}, 'children': children}} - - else: - config = self.proposed - - self.config = config - - @staticmethod - def get_diff_child(child_class, proposed_child, existing_child): - """ - This method is used to get the difference between a proposed and existing child configs. The get_nested_config() - method should be used to return the proposed and existing config portions of child. - - :param child_class: Type str. - The root class (dict key) for the child dictionary. - :param proposed_child: Type dict. - The config portion of the proposed child dictionary. - :param existing_child: Type dict. - The config portion of the existing child dictionary. - :return: The child config with only values that are updated. If the proposed dictionary has no updates to make - to what exists on the APIC, then None is returned. - """ - update_config = {child_class: {'attributes': {}}} - for key, value in proposed_child.items(): - existing_field = existing_child.get(key) - if value != existing_field: - update_config[child_class]['attributes'][key] = value - - if not update_config[child_class]['attributes']: - return None - - return update_config - - def get_diff_children(self, aci_class): - """ - This method is used to retrieve the updated child configs by comparing the proposed children configs - agains the objects existing children configs. - - :param aci_class: Type str. - This is the root dictionary key for the MO's configuration body, or the ACI class of the MO. - :return: The list of updated child config dictionaries. None is returned if there are no changes to the child - configurations. - """ - proposed_children = self.proposed[aci_class].get('children') - if proposed_children: - child_updates = [] - existing_children = self.existing[0][aci_class].get('children', []) - - # Loop through proposed child configs and compare against existing child configuration - for child in proposed_children: - child_class, proposed_child, existing_child = self.get_nested_config(child, existing_children) - - if existing_child is None: - child_update = child - else: - child_update = self.get_diff_child(child_class, proposed_child, existing_child) - - # Update list of updated child configs only if the child config is different than what exists - if child_update: - child_updates.append(child_update) - else: - return None - - return child_updates - - def get_existing(self): - """ - This method is used to get the existing object(s) based on the path specified in the module. Each module should - build the URL so that if the object's name is supplied, then it will retrieve the configuration for that particular - object, but if no name is supplied, then it will retrieve all MOs for the class. Following this method will ensure - that this method can be used to supply the existing configuration when using the get_diff method. The response, status, - and existing configuration will be added to the self.result dictionary. - """ - uri = self.url + self.filter_string - - # Sign and encode request as to APIC's wishes - if self.params.get('private_key'): - self.cert_auth(path=self.path + self.filter_string, method='GET') - - resp, info = fetch_url(self.module, uri, - headers=self.headers, - method='GET', - timeout=self.params.get('timeout'), - use_proxy=self.params.get('use_proxy')) - self.response = info.get('msg') - self.status = info.get('status') - self.method = 'GET' - - # Handle APIC response - if info.get('status') == 200: - self.existing = json.loads(resp.read())['imdata'] - else: - try: - # APIC error - self.response_json(info['body']) - self.fail_json(msg='APIC Error %(code)s: %(text)s' % self.error) - except KeyError: - # Connection error - self.fail_json(msg='Connection failed for %(url)s. %(msg)s' % info) - - @staticmethod - def get_nested_config(proposed_child, existing_children): - """ - This method is used for stiping off the outer layers of the child dictionaries so only the configuration - key, value pairs are returned. - - :param proposed_child: Type dict. - The dictionary that represents the child config. - :param existing_children: Type list. - The list of existing child config dictionaries. - :return: The child's class as str (root config dict key), the child's proposed config dict, and the child's - existing configuration dict. - """ - for key in proposed_child.keys(): - child_class = key - proposed_config = proposed_child[key]['attributes'] - existing_config = None - - # FIXME: Design causes issues for repeated child_classes - # get existing dictionary from the list of existing to use for comparison - for child in existing_children: - if child.get(child_class): - existing_config = child[key]['attributes'] - # NOTE: This is an ugly fix - # Return the one that is a subset match - if set(proposed_config.items()).issubset(set(existing_config.items())): - break - - return child_class, proposed_config, existing_config - - def payload(self, aci_class, class_config, child_configs=None): - """ - This method is used to dynamically build the proposed configuration dictionary from the config related parameters - passed into the module. All values that were not passed values from the playbook task will be removed so as to not - inadvertently change configurations. - - :param aci_class: Type str - This is the root dictionary key for the MO's configuration body, or the ACI class of the MO. - :param class_config: Type dict - This is the configuration of the MO using the dictionary keys expected by the API - :param child_configs: Type list - This is a list of child dictionaries associated with the MOs config. The list should only - include child objects that are used to associate two MOs together. Children that represent - MOs should have their own module. - """ - proposed = dict((k, str(v)) for k, v in class_config.items() if v is not None) - self.proposed = {aci_class: {'attributes': proposed}} - - # add child objects to proposed - if child_configs: - children = [] - for child in child_configs: - child_copy = deepcopy(child) - has_value = False - for root_key in child_copy.keys(): - for final_keys, values in child_copy[root_key]['attributes'].items(): - if values is None: - child[root_key]['attributes'].pop(final_keys) - else: - child[root_key]['attributes'][final_keys] = str(values) - has_value = True - if has_value: - children.append(child) - - if children: - self.proposed[aci_class].update(dict(children=children)) - - def post_config(self): - """ - This method is used to handle the logic when the modules state is equal to present. The method only pushes a change if - the object has differences than what exists on the APIC, and if check_mode is False. A successful change will mark the - module as changed. - """ - if not self.config: - return - elif not self.module.check_mode: - # Sign and encode request as to APIC's wishes - if self.params.get('private_key'): - self.cert_auth(method='POST', payload=json.dumps(self.config)) - - resp, info = fetch_url(self.module, self.url, - data=json.dumps(self.config), - headers=self.headers, - method='POST', - timeout=self.params.get('timeout'), - use_proxy=self.params.get('use_proxy')) - - self.response = info.get('msg') - self.status = info.get('status') - self.method = 'POST' - - # Handle APIC response - if info.get('status') == 200: - self.result['changed'] = True - self.response_json(resp.read()) - else: - try: - # APIC error - self.response_json(info['body']) - self.fail_json(msg='APIC Error %(code)s: %(text)s' % self.error) - except KeyError: - # Connection error - self.fail_json(msg='Connection failed for %(url)s. %(msg)s' % info) - else: - self.result['changed'] = True - self.method = 'POST' - - def exit_json(self, **kwargs): - - if 'state' in self.params: - if self.params.get('state') in ('absent', 'present'): - if self.params.get('output_level') in ('debug', 'info'): - self.result['previous'] = self.existing - - # Return the gory details when we need it - if self.params.get('output_level') == 'debug': - if 'state' in self.params: - self.result['filter_string'] = self.filter_string - self.result['method'] = self.method - # self.result['path'] = self.path # Adding 'path' in result causes state: absent in output - self.result['response'] = self.response - self.result['status'] = self.status - self.result['url'] = self.url - - if 'state' in self.params: - self.original = self.existing - if self.params.get('state') in ('absent', 'present'): - self.get_existing() - - # if self.module._diff and self.original != self.existing: - # self.result['diff'] = dict( - # before=json.dumps(self.original, sort_keys=True, indent=4), - # after=json.dumps(self.existing, sort_keys=True, indent=4), - # ) - self.result['current'] = self.existing - - if self.params.get('output_level') in ('debug', 'info'): - self.result['sent'] = self.config - self.result['proposed'] = self.proposed - - self.result.update(**kwargs) - self.module.exit_json(**self.result) - - def fail_json(self, msg, **kwargs): - - # Return error information, if we have it - if self.error.get('code') is not None and self.error.get('text') is not None: - self.result['error'] = self.error - - if 'state' in self.params: - if self.params.get('state') in ('absent', 'present'): - if self.params.get('output_level') in ('debug', 'info'): - self.result['previous'] = self.existing - - # Return the gory details when we need it - if self.params.get('output_level') == 'debug': - if self.imdata is not None: - self.result['imdata'] = self.imdata - self.result['totalCount'] = self.totalCount - - if self.params.get('output_level') == 'debug': - if self.url is not None: - if 'state' in self.params: - self.result['filter_string'] = self.filter_string - self.result['method'] = self.method - # self.result['path'] = self.path # Adding 'path' in result causes state: absent in output - self.result['response'] = self.response - self.result['status'] = self.status - self.result['url'] = self.url - - if 'state' in self.params: - if self.params.get('output_level') in ('debug', 'info'): - self.result['sent'] = self.config - self.result['proposed'] = self.proposed - - self.result.update(**kwargs) - self.module.fail_json(msg=msg, **self.result) diff --git a/lib/ansible/modules/network/aci/aci_aaa_user.py b/lib/ansible/modules/network/aci/aci_aaa_user.py deleted file mode 100644 index d5dbde6cd2..0000000000 --- a/lib/ansible/modules/network/aci/aci_aaa_user.py +++ /dev/null @@ -1,367 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2018, Dag Wieers (dagwieers) <dag@wieers.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -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 -version_added: '2.5' -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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: 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: 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 - 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 - aci_aaa_user: - host: apic - username: admin - password: SomeSecretPassword - aaa_user: dag - state: absent - delegate_to: localhost - -- name: Query a user - aci_aaa_user: - host: apic - username: admin - password: SomeSecretPassword - aaa_user: dag - state: query - delegate_to: localhost - register: query_result - -- name: Query all users - 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_aaa_user_certificate.py b/lib/ansible/modules/network/aci/aci_aaa_user_certificate.py deleted file mode 100644 index 2cfbe8a383..0000000000 --- a/lib/ansible/modules/network/aci/aci_aaa_user_certificate.py +++ /dev/null @@ -1,298 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2018, Dag Wieers (dagwieers) <dag@wieers.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -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. -version_added: '2.5' -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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: aci -notes: -- The C(aaa_user) must exist before using this module in your playbook. - The M(aci_aaa_user) module can be used for this. -seealso: -- module: 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 - 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 - 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 - 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 - 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_access_port_block_to_access_port.py b/lib/ansible/modules/network/aci/aci_access_port_block_to_access_port.py deleted file mode 100644 index 67e2241caa..0000000000 --- a/lib/ansible/modules/network/aci/aci_access_port_block_to_access_port.py +++ /dev/null @@ -1,346 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2018, Simon Metzger <smnmtzgr@gmail.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function -__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. -version_added: '2.8' -options: - leaf_interface_profile: - description: - - The name of the Fabric access policy leaf interface profile. - type: str - required: yes - aliases: [ leaf_interface_profile_name ] - access_port_selector: - description: - - The name of the Fabric access policy leaf interface profile access port selector. - type: str - required: yes - 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 - required: yes - 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 - required: yes - 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 - required: yes - 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 ] - 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: aci -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 - aci_access_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 - state: present - delegate_to: localhost - -- name: Associate an access port block (port range) to an interface selector - aci_access_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: 16 - state: present - delegate_to: localhost - -- name: Remove an access port block from an interface selector - aci_access_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 - state: absent - delegate_to: localhost - -- name: Query Specific access port block under given access port selector - aci_access_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 port blocks under given leaf interface profile - aci_access_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 port blocks in the fabric - aci_access_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.module_utils.basic import AnsibleModule -from ansible.module_utils.network.aci.aci import ACIModule, aci_argument_spec - - -def main(): - argument_spec = aci_argument_spec() - argument_spec.update( - leaf_interface_profile=dict(type='str', aliases=['leaf_interface_profile_name']), # Not required for querying all objects - access_port_selector=dict(type='str', aliases=['name', 'access_port_selector_name']), # Not required for querying all objects - leaf_port_blk=dict(type='str', aliases=['leaf_port_blk_name']), # Not required for querying all objects - leaf_port_blk_description=dict(type='str'), - from_port=dict(type='str', aliases=['from', 'fromPort', 'from_port_range']), - to_port=dict(type='str', aliases=['to', 'toPort', 'to_port_range']), - from_card=dict(type='str', aliases=['from_card_range']), - to_card=dict(type='str', aliases=['to_card_range']), - state=dict(type='str', default='present', choices=['absent', 'present', 'query']), - ) - - module = AnsibleModule( - argument_spec=argument_spec, - supports_check_mode=True, - required_if=[ - ['state', 'absent', ['access_port_selector', 'leaf_port_blk', 'leaf_interface_profile']], - ['state', 'present', ['access_port_selector', 'leaf_port_blk', 'from_port', 'to_port', 'leaf_interface_profile']], - ], - ) - - leaf_interface_profile = module.params.get('leaf_interface_profile') - access_port_selector = module.params.get('access_port_selector') - leaf_port_blk = module.params.get('leaf_port_blk') - leaf_port_blk_description = module.params.get('leaf_port_blk_description') - from_port = module.params.get('from_port') - to_port = module.params.get('to_port') - from_card = module.params.get('from_card') - to_card = module.params.get('to_card') - state = module.params.get('state') - - aci = ACIModule(module) - aci.construct_url( - root_class=dict( - aci_class='infraAccPortP', - aci_rn='infra/accportprof-{0}'.format(leaf_interface_profile), - module_object=leaf_interface_profile, - target_filter={'name': leaf_interface_profile}, - ), - subclass_1=dict( - aci_class='infraHPortS', - # NOTE: normal rn: hports-{name}-typ-{type}, hence here hardcoded to range for purposes of module - aci_rn='hports-{0}-typ-range'.format(access_port_selector), - module_object=access_port_selector, - target_filter={'name': access_port_selector}, - ), - subclass_2=dict( - aci_class='infraPortBlk', - aci_rn='portblk-{0}'.format(leaf_port_blk), - module_object=leaf_port_blk, - target_filter={'name': leaf_port_blk}, - ), - ) - - aci.get_existing() - - if state == 'present': - aci.payload( - aci_class='infraPortBlk', - class_config=dict( - descr=leaf_port_blk_description, - name=leaf_port_blk, - fromPort=from_port, - toPort=to_port, - fromCard=from_card, - toCard=to_card, - # type='range', - ), - ) - - aci.get_diff(aci_class='infraPortBlk') - - aci.post_config() - - elif state == 'absent': - aci.delete_config() - - aci.exit_json() - - -if __name__ == "__main__": - main() diff --git a/lib/ansible/modules/network/aci/aci_access_port_to_interface_policy_leaf_profile.py b/lib/ansible/modules/network/aci/aci_access_port_to_interface_policy_leaf_profile.py deleted file mode 100644 index 38892f8c69..0000000000 --- a/lib/ansible/modules/network/aci/aci_access_port_to_interface_policy_leaf_profile.py +++ /dev/null @@ -1,397 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Bruno Calogero <brunocalogero@hotmail.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -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. -version_added: '2.5' -options: - leaf_interface_profile: - description: - - The name of the Fabric access policy leaf interface profile. - type: str - required: yes - aliases: [ leaf_interface_profile_name ] - access_port_selector: - description: - - The name of the Fabric access policy leaf interface profile access port selector. - type: str - required: yes - aliases: [ name, access_port_selector_name ] - description: - description: - - The description to assign to the C(access_port_selector) - type: str - leaf_port_blk: - description: - - B(Deprecated) - - Starting with Ansible 2.8 we recommend using M(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 - required: yes - aliases: [ leaf_port_blk_name ] - leaf_port_blk_description: - description: - - B(Deprecated) - - Starting with Ansible 2.8 we recommend using M(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(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 - required: yes - aliases: [ from, fromPort, from_port_range ] - to_port: - description: - - B(Deprecated) - - Starting with Ansible 2.8 we recommend using M(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 - required: yes - aliases: [ to, toPort, to_port_range ] - from_card: - description: - - B(Deprecated) - - Starting with Ansible 2.8 we recommend using M(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 ] - version_added: '2.6' - to_card: - description: - - B(Deprecated) - - Starting with Ansible 2.8 we recommend using M(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 ] - version_added: '2.6' - 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 - version_added: '2.6' - 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: aci -seealso: -- module: 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) -''' - -EXAMPLES = r''' -- name: Associate an Interface Access Port Selector to an Interface Policy Leaf Profile with a Policy Group - aci_access_port_to_interface_policy_leaf_profile: - host: apic - username: admin - password: SomeSecretPassword - leaf_interface_profile: leafintprfname - access_port_selector: accessportselectorname - leaf_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) - aci_access_port_to_interface_policy_leaf_profile: - host: apic - username: admin - password: SomeSecretPassword - leaf_interface_profile: leafintprfname - access_port_selector: accessportselectorname - leaf_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 - aci_access_port_to_interface_policy_leaf_profile: - host: apic - username: admin - password: SomeSecretPassword - leaf_interface_profile: leafintprfname - access_port_selector: accessportselectorname - state: absent - delegate_to: localhost - -- name: Query Specific access_port_selector under given leaf_interface_profile - aci_access_port_to_interface_policy_leaf_profile: - host: apic - username: admin - password: SomeSecretPassword - leaf_interface_profile: leafintprfname - 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.module_utils.network.aci.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( - leaf_interface_profile=dict(type='str', aliases=['leaf_interface_profile_name']), # Not required for querying all objects - access_port_selector=dict(type='str', aliases=['name', 'access_port_selector_name']), # Not required for querying all objects - description=dict(type='str'), - leaf_port_blk=dict(type='str', aliases=['leaf_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']), - 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_interface_profile', 'access_port_selector']], - ['state', 'present', ['leaf_interface_profile', 'access_port_selector']], - ], - ) - - leaf_interface_profile = module.params.get('leaf_interface_profile') - access_port_selector = module.params.get('access_port_selector') - description = module.params.get('description') - leaf_port_blk = module.params.get('leaf_port_blk') - leaf_port_blk_description = module.params.get('leaf_port_blk_description') - from_port = module.params.get('from_port') - to_port = module.params.get('to_port') - from_card = module.params.get('from_card') - to_card = module.params.get('to_card') - policy_group = module.params.get('policy_group') - interface_type = module.params.get('interface_type') - state = module.params.get('state') - - # Build child_configs dynamically - child_configs = [dict( - infraPortBlk=dict( - attributes=dict( - descr=leaf_port_blk_description, - name=leaf_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.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}, - ), - 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/lib/ansible/modules/network/aci/aci_access_sub_port_block_to_access_port.py b/lib/ansible/modules/network/aci/aci_access_sub_port_block_to_access_port.py deleted file mode 100644 index 6589cfca71..0000000000 --- a/lib/ansible/modules/network/aci/aci_access_sub_port_block_to_access_port.py +++ /dev/null @@ -1,370 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2019, Simon Metzger <smnmtzgr@gmail.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function -__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) -version_added: '2.8' -options: - leaf_interface_profile: - description: - - The name of the Fabric access policy leaf interface profile. - type: str - required: yes - aliases: [ leaf_interface_profile_name ] - access_port_selector: - description: - - The name of the Fabric access policy leaf interface profile access port selector. - type: str - required: yes - 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 - required: yes - 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 - required: yes - 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 - required: yes - 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 - required: yes - 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 - required: yes - 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: aci -''' - -EXAMPLES = r''' -- name: Associate an access sub port block (single port) to an interface selector - 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 - 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 - 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 - 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 - 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 - 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_aep.py b/lib/ansible/modules/network/aci/aci_aep.py deleted file mode 100644 index aa737ce699..0000000000 --- a/lib/ansible/modules/network/aci/aci_aep.py +++ /dev/null @@ -1,276 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': '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. -version_added: '2.4' -options: - aep: - description: - - The name of the Attachable Access Entity Profile. - type: str - required: yes - 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 ] - version_added: '2.5' - 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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: aci -seealso: -- module: 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) -''' - -EXAMPLES = r''' -- name: Add a new AEP - aci_aep: - host: apic - username: admin - password: SomeSecretPassword - aep: ACI-AEP - description: default - state: present - delegate_to: localhost - -- name: Remove an existing AEP - aci_aep: - host: apic - username: admin - password: SomeSecretPassword - aep: ACI-AEP - state: absent - delegate_to: localhost - -- name: Query all AEPs - aci_aep: - host: apic - username: admin - password: SomeSecretPassword - state: query - delegate_to: localhost - register: query_result - -- name: Query a specific AEP - 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.module_utils.network.aci.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}, - ), - ) - aci.get_existing() - - 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/lib/ansible/modules/network/aci/aci_aep_to_domain.py b/lib/ansible/modules/network/aci/aci_aep_to_domain.py deleted file mode 100644 index 8a1437d77e..0000000000 --- a/lib/ansible/modules/network/aci/aci_aep_to_domain.py +++ /dev/null @@ -1,312 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Dag Wieers <dag@wieers.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function -__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. -version_added: '2.5' -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: aci -notes: -- The C(aep) and C(domain) parameters should exist before using this module. - The M(aci_aep) and M(aci_domain) can be used for these. -seealso: -- module: aci_aep -- module: 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 - 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 - 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 - 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 - 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_ap.py b/lib/ansible/modules/network/aci/aci_ap.py deleted file mode 100644 index 94ce0f7a93..0000000000 --- a/lib/ansible/modules/network/aci/aci_ap.py +++ /dev/null @@ -1,280 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': '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 -version_added: '2.4' -options: - tenant: - description: - - The name of an existing tenant. - type: str - required: yes - aliases: [ tenant_name ] - ap: - description: - - The name of the application network profile. - type: str - required: yes - aliases: [ app_profile, app_profile_name, name ] - description: - description: - - Description for the AP. - 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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: aci -notes: -- This module does not manage EPGs, see M(aci_epg) to do this. -- The used C(tenant) must exist before using this module in your playbook. - The M(aci_tenant) module can be used for this. -seealso: -- module: 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) -''' - -EXAMPLES = r''' -- name: Add a new AP - aci_ap: - host: apic - username: admin - password: SomeSecretPassword - tenant: production - ap: default - description: default ap - state: present - delegate_to: localhost - -- name: Remove an AP - aci_ap: - host: apic - username: admin - password: SomeSecretPassword - tenant: production - ap: default - state: absent - delegate_to: localhost - -- name: Query an AP - aci_ap: - host: apic - username: admin - password: SomeSecretPassword - tenant: production - ap: default - state: query - delegate_to: localhost - register: query_result - -- name: Query all APs - 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.module_utils.network.aci.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'), - ) - - 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') - - 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}, - ), - ) - - aci.get_existing() - - if state == 'present': - aci.payload( - aci_class='fvAp', - class_config=dict( - name=ap, - descr=description, - nameAlias=name_alias, - ), - ) - - 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/lib/ansible/modules/network/aci/aci_bd.py b/lib/ansible/modules/network/aci/aci_bd.py deleted file mode 100644 index 9804e2e229..0000000000 --- a/lib/ansible/modules/network/aci/aci_bd.py +++ /dev/null @@ -1,462 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': 'certified'} - -DOCUMENTATION = r''' ---- -module: aci_bd -short_description: Manage Bridge Domains (BD) objects (fv:BD) -description: -- Manages Bridge Domains (BD) on Cisco ACI fabrics. -version_added: '2.4' -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 ] - version_added: '2.5' - 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: - version_added: '2.10' - 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: aci -notes: -- The C(tenant) used must exist before using this module in your playbook. - The M(aci_tenant) module can be used for this. -seealso: -- module: 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 - 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 - 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 - 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 - 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 - 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 - 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_bd_subnet.py b/lib/ansible/modules/network/aci/aci_bd_subnet.py deleted file mode 100644 index ee2b78c9bd..0000000000 --- a/lib/ansible/modules/network/aci/aci_bd_subnet.py +++ /dev/null @@ -1,466 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': 'certified'} - -DOCUMENTATION = r''' ---- -module: aci_bd_subnet -short_description: Manage Subnets (fv:Subnet) -description: -- Manage Subnets on Cisco ACI fabrics. -version_added: '2.4' -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 - 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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: 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(aci_tenant) module and M(aci_bd) can be used for these. -seealso: -- module: aci_bd -- module: 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 - aci_tenant: - host: apic - username: admin - password: SomeSecretPassword - tenant: production - state: present - delegate_to: localhost - -- name: Create a bridge domain - aci_bd: - host: apic - username: admin - password: SomeSecretPassword - tenant: production - bd: database - state: present - delegate_to: localhost - -- name: Create a subnet - 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 - 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 - 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 - aci_bd_subnet: - host: apic - username: admin - password: SomeSecretPassword - state: query - delegate_to: localhost - -- name: Get all subnets of specific gateway in specified tenant - 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 - 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 - 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.module_utils.network.aci.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', 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/lib/ansible/modules/network/aci/aci_bd_to_l3out.py b/lib/ansible/modules/network/aci/aci_bd_to_l3out.py deleted file mode 100644 index a96a5ae94b..0000000000 --- a/lib/ansible/modules/network/aci/aci_bd_to_l3out.py +++ /dev/null @@ -1,239 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': '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. -version_added: '2.4' -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: aci -notes: -- The C(bd) and C(l3out) parameters should exist before using this module. - The M(aci_bd) and C(aci_l3out) can be used for these. -seealso: -- module: aci_bd -- module: 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) -''' - -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.module_utils.network.aci.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_together=[['gateway', 'mask']], - 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/lib/ansible/modules/network/aci/aci_config_rollback.py b/lib/ansible/modules/network/aci/aci_config_rollback.py deleted file mode 100644 index bf2adce5d4..0000000000 --- a/lib/ansible/modules/network/aci/aci_config_rollback.py +++ /dev/null @@ -1,321 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': '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. -version_added: '2.4' -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 - required: yes - 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: aci -seealso: -- module: 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 - aci_config_snapshot: - host: apic - username: admin - password: SomeSecretPassword - export_policy: config_backup - state: present - delegate_to: localhost - -- name: Query Existing Snapshots - aci_config_snapshot: - host: apic - username: admin - password: SomeSecretPassword - export_policy: config_backup - state: query - delegate_to: localhost - -- name: Compare Snapshot Files - 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 - 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 - 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_config_snapshot.py b/lib/ansible/modules/network/aci/aci_config_snapshot.py deleted file mode 100644 index a609eec481..0000000000 --- a/lib/ansible/modules/network/aci/aci_config_snapshot.py +++ /dev/null @@ -1,336 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': '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. -version_added: '2.4' -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: 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: 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 - 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 - 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 - 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 - 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_contract.py b/lib/ansible/modules/network/aci/aci_contract.py deleted file mode 100644 index 54ac21011d..0000000000 --- a/lib/ansible/modules/network/aci/aci_contract.py +++ /dev/null @@ -1,314 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': 'certified'} - -DOCUMENTATION = r''' ---- -module: aci_contract -short_description: Manage contract resources (vz:BrCP) -description: -- Manage Contract resources on Cisco ACI fabrics. -version_added: '2.4' -options: - contract: - description: - - The name of the contract. - type: str - required: yes - aliases: [ contract_name, name ] - description: - description: - - Description for the contract. - type: str - aliases: [ descr ] - tenant: - description: - - The name of the tenant. - type: str - required: yes - 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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: aci -notes: -- This module does not manage Contract Subjects, see M(aci_contract_subject) to do this. - Contract Subjects can still be removed using this module. -- The C(tenant) used must exist before using this module in your playbook. - The M(aci_tenant) module can be used for this. -seealso: -- module: aci_contract_subject -- module: 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 - 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 - aci_contract: - host: apic - username: admin - password: SomeSecretPassword - tenant: production - contract: web_to_db - state: absent - delegate_to: localhost - -- name: Query a specific contract - 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 - 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_contract_subject.py b/lib/ansible/modules/network/aci/aci_contract_subject.py deleted file mode 100644 index 59bc4b05c9..0000000000 --- a/lib/ansible/modules/network/aci/aci_contract_subject.py +++ /dev/null @@ -1,358 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': 'certified'} - -DOCUMENTATION = r''' ---- -module: aci_contract_subject -short_description: Manage initial Contract Subjects (vz:Subj) -description: -- Manage initial Contract Subjects on Cisco ACI fabrics. -version_added: '2.4' -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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: aci -notes: -- The C(tenant) and C(contract) used must exist before using this module in your playbook. - The M(aci_tenant) and M(aci_contract) modules can be used for this. -seealso: -- module: aci_contract -- module: 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 - 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 - 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 - 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 - 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_contract_subject_to_filter.py b/lib/ansible/modules/network/aci/aci_contract_subject_to_filter.py deleted file mode 100644 index e7d0dddce3..0000000000 --- a/lib/ansible/modules/network/aci/aci_contract_subject_to_filter.py +++ /dev/null @@ -1,319 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': '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. -version_added: '2.4' -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 - required: yes - aliases: [ tenant_name ] -extends_documentation_fragment: aci -notes: -- The C(tenant), C(contract), C(subject), and C(filter_name) must exist before using this module in your playbook. - The M(aci_tenant), M(aci_contract), M(aci_contract_subject), and M(aci_filter) modules can be used for these. -seealso: -- module: aci_contract_subject -- module: 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 - 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 - 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 - 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 - 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_domain.py b/lib/ansible/modules/network/aci/aci_domain.py deleted file mode 100644 index dc0bafe578..0000000000 --- a/lib/ansible/modules/network/aci/aci_domain.py +++ /dev/null @@ -1,394 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': '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. -version_added: '2.5' -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 - 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: - version_added: '2.10' - 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: aci -seealso: -- module: aci_aep_to_domain -- module: aci_domain_to_encap_pool -- module: 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 - aci_domain: - host: apic - username: admin - password: SomeSecretPassword - domain: phys_dom - domain_type: phys - state: present - -- name: Remove a physical domain - aci_domain: - host: apic - username: admin - password: SomeSecretPassword - domain: phys_dom - domain_type: phys - state: absent - -- name: Add a new VMM domain - 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 - 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 - 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 - 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_domain_to_encap_pool.py b/lib/ansible/modules/network/aci/aci_domain_to_encap_pool.py deleted file mode 100644 index eeddc842dc..0000000000 --- a/lib/ansible/modules/network/aci/aci_domain_to_encap_pool.py +++ /dev/null @@ -1,376 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Dag Wieers <dag@wieers.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function -__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(aci_domain) and M(aci_encap_pool) can be used for these. -version_added: '2.5' -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 - 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: aci -seealso: -- module: aci_domain -- module: 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 - 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 - 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 - 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 - 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.module_utils.network.aci.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 == 'l2ext': - domain_class = 'l2extDomP' - domain_mo = 'uni/l2dom-{0}'.format(domain) - domain_rn = 'l2dom-{0}'.format(domain) - elif domain_type == 'l3ext': - 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/lib/ansible/modules/network/aci/aci_domain_to_vlan_pool.py b/lib/ansible/modules/network/aci/aci_domain_to_vlan_pool.py deleted file mode 100644 index 006f734323..0000000000 --- a/lib/ansible/modules/network/aci/aci_domain_to_vlan_pool.py +++ /dev/null @@ -1,364 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Dag Wieers <dag@wieers.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function -__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. -version_added: '2.5' -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 - 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: aci -notes: -- The C(domain) and C(vlan_pool) parameters should exist before using this module. - The M(aci_domain) and M(aci_vlan_pool) can be used for these. -seealso: -- module: aci_domain -- module: 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 - 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 - 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 - 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 - 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 - 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 - 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_encap_pool.py b/lib/ansible/modules/network/aci/aci_encap_pool.py deleted file mode 100644 index 3f5ce5eec4..0000000000 --- a/lib/ansible/modules/network/aci/aci_encap_pool.py +++ /dev/null @@ -1,316 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': '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. -version_added: '2.5' -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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: aci -seealso: -- module: aci_encap_pool_range -- module: 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 - 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 - aci_encap_pool: - host: apic - username: admin - password: SomeSecretPassword - pool: production - pool_type: vlan - state: absent - delegate_to: localhost - -- name: Query a vlan pool - 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 - 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_encap_pool_range.py b/lib/ansible/modules/network/aci/aci_encap_pool_range.py deleted file mode 100644 index b2ab666748..0000000000 --- a/lib/ansible/modules/network/aci/aci_encap_pool_range.py +++ /dev/null @@ -1,449 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': '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. -version_added: '2.5' -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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: aci -notes: -- The C(pool) must exist in order to add or delete a range. -seealso: -- module: aci_encap_pool -- module: 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_epg.py b/lib/ansible/modules/network/aci/aci_epg.py deleted file mode 100644 index e28e559303..0000000000 --- a/lib/ansible/modules/network/aci/aci_epg.py +++ /dev/null @@ -1,393 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': '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. -version_added: '2.4' -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 - required: yes - aliases: [ app_profile, app_profile_name ] - epg: - description: - - Name of the end point group. - type: str - required: yes - 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 - version_added: '2.5' - 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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: aci -notes: -- The C(tenant) and C(app_profile) used must exist before using this module in your playbook. - The M(aci_tenant) and M(aci_ap) modules can be used for this. -seealso: -- module: aci_tenant -- module: 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) -''' - -EXAMPLES = r''' -- name: Add a new EPG - aci_epg: - host: apic - username: admin - password: SomeSecretPassword - tenant: production - ap: intranet - epg: web_epg - description: Web Intranet EPG - bd: prod_bd - 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 - aci_epg: - host: apic - username: admin - password: SomeSecretPassword - validate_certs: no - tenant: production - app_profile: intranet - epg: web_epg - state: absent - delegate_to: localhost - -- name: Query an EPG - 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 - aci_epg: - host: apic - username: admin - password: SomeSecretPassword - state: query - delegate_to: localhost - register: query_result - -- name: Query all EPGs with a Specific Name - 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 - 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.module_utils.network.aci.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'), - ) - - 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') - - 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'], - ) - - 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=[dict( - fvRsBd=dict( - attributes=dict( - tnFvBDName=bd, - ), - ), - )], - ) - - 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/lib/ansible/modules/network/aci/aci_epg_monitoring_policy.py b/lib/ansible/modules/network/aci/aci_epg_monitoring_policy.py deleted file mode 100644 index aa7e06c4b8..0000000000 --- a/lib/ansible/modules/network/aci/aci_epg_monitoring_policy.py +++ /dev/null @@ -1,248 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': 'certified'} - -DOCUMENTATION = r''' ---- -module: aci_epg_monitoring_policy -short_description: Manage monitoring policies (mon:EPGPol) -description: -- Manage monitoring policies on Cisco ACI fabrics. -version_added: '2.4' -options: - monitoring_policy: - description: - - The name of the monitoring policy. - type: str - required: yes - aliases: [ name ] - description: - description: - - Description for the monitoring policy. - type: str - aliases: [ descr ] - tenant: - description: - - The name of the tenant. - type: str - required: yes - 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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: aci -notes: -- The C(tenant) used must exist before using this module in your playbook. - The M(aci_tenant) module can be used for this. -seealso: -- module: 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''' -- 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_epg_to_contract.py b/lib/ansible/modules/network/aci/aci_epg_to_contract.py deleted file mode 100644 index cc1fe49608..0000000000 --- a/lib/ansible/modules/network/aci/aci_epg_to_contract.py +++ /dev/null @@ -1,350 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': '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(aci_tenant), M(aci_ap), M(aci_epg), and M(aci_contract) modules can be used for this. -version_added: '2.4' -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: aci -seealso: -- module: aci_ap -- module: aci_epg -- module: 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 - 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 - 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 - 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 - 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.module_utils.network.aci.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']), - 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/lib/ansible/modules/network/aci/aci_epg_to_domain.py b/lib/ansible/modules/network/aci/aci_epg_to_domain.py deleted file mode 100644 index 5c8c3d2f4c..0000000000 --- a/lib/ansible/modules/network/aci/aci_epg_to_domain.py +++ /dev/null @@ -1,423 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': '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. -version_added: '2.4' -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 - version_added: '2.9' - 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 ] - 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: aci -notes: -- The C(tenant), C(ap), C(epg), and C(domain) used must exist before using this module in your playbook. - The M(aci_tenant) M(aci_ap), M(aci_epg) M(aci_domain) modules can be used for this. -- OpenStack VMM domains must not be created using this module. The OpenStack VMM domain is created directly - by the Cisco APIC Neutron plugin as part of the installation and configuration. - This module can be used to query status of an OpenStack VMM domain. -seealso: -- module: aci_ap -- module: aci_epg -- module: 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) -''' - -EXAMPLES = r''' -- name: Add a new physical domain to EPG binding - 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 - 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 - 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 - 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.module_utils.network.aci.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']), - ) - - 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') - 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) - - # 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) - 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}, - ), - ) - - 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, - ), - ) - - 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/lib/ansible/modules/network/aci/aci_fabric_node.py b/lib/ansible/modules/network/aci/aci_fabric_node.py deleted file mode 100644 index 9dd1922506..0000000000 --- a/lib/ansible/modules/network/aci/aci_fabric_node.py +++ /dev/null @@ -1,288 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Bruno Calogero <brunocalogero@hotmail.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -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. -version_added: '2.5' -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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: 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 - 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 - aci_fabric_node: - host: apic - username: admin - password: SomeSecretPassword - serial: FDO2031124L - node_id: 1011 - state: absent - delegate_to: localhost - -- name: Query fabric nodes - 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_fabric_scheduler.py b/lib/ansible/modules/network/aci/aci_fabric_scheduler.py deleted file mode 100644 index d5be9c8c61..0000000000 --- a/lib/ansible/modules/network/aci/aci_fabric_scheduler.py +++ /dev/null @@ -1,333 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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 = ''' ---- -module: aci_fabric_scheduler - -short_description: This modules creates ACI schedulers. - -version_added: "2.8" - -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 - required: yes - aliases: [ name, 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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: aci - -author: - - Steven Gerhart (@sgerhart) -''' - -EXAMPLES = ''' - - name: Simple Scheduler (Empty) - aci_fabric_scheduler: - host: "{{ inventory_hostname }}" - username: "{{ user }}" - password: "{{ pass }}" - validate_certs: no - name: simpleScheduler - state: present - - name: Remove Simple Scheduler - aci_fabric_scheduler: - host: "{{ inventory_hostname }}" - username: "{{ user }}" - password: "{{ pass }}" - validate_certs: no - name: simpleScheduler - state: absent - - name: One Time Scheduler - 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 - 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 -''' - -import json -from ansible.module_utils.network.aci.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=['name', 'scheduler_name']), # Not required for querying all objects - description=dict(type='str', aliases=['descr']), - windowname=dict(type='str', aliases=['windowname']), - 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', aliases=['date']), # 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/lib/ansible/modules/network/aci/aci_filter.py b/lib/ansible/modules/network/aci/aci_filter.py deleted file mode 100644 index 5c1b7690f0..0000000000 --- a/lib/ansible/modules/network/aci/aci_filter.py +++ /dev/null @@ -1,281 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': '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(aci_filter_entry) for this functionality. -version_added: '2.4' -options: - filter: - description: - - The name of the filter. - type: str - required: yes - aliases: [ filter_name, name ] - description: - description: - - Description for the filter. - type: str - aliases: [ descr ] - tenant: - description: - - The name of the tenant. - type: str - required: yes - 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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: aci -notes: -- The C(tenant) used must exist before using this module in your playbook. - The M(aci_tenant) module can be used for this. -seealso: -- module: 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 - 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 - 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 - 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 - 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_filter_entry.py b/lib/ansible/modules/network/aci/aci_filter_entry.py deleted file mode 100644 index 90f1884eaa..0000000000 --- a/lib/ansible/modules/network/aci/aci_filter_entry.py +++ /dev/null @@ -1,375 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': '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. -version_added: '2.4' -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: - version_added: '2.10' - 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: aci -notes: -- The C(tenant) and C(filter) used must exist before using this module in your playbook. - The M(aci_tenant) and M(aci_filter) modules can be used for this. -seealso: -- module: aci_tenant -- module: 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) -''' - -EXAMPLES = r''' -- 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_firmware_group.py b/lib/ansible/modules/network/aci/aci_firmware_group.py deleted file mode 100644 index 8229eda8f8..0000000000 --- a/lib/ansible/modules/network/aci/aci_firmware_group.py +++ /dev/null @@ -1,240 +0,0 @@ -#!/usr/bin/python - -# 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 = ''' ---- -module: aci_firmware_group - -short_description: This module creates a firmware group - -version_added: "2.8" - -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 - required: true - 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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: - - aci -author: - - Steven Gerhart (@sgerhart) -''' - -EXAMPLES = ''' - - name: firmware group - 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 -''' - -import json -from ansible.module_utils.network.aci.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', aliases=['group']), # 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/lib/ansible/modules/network/aci/aci_firmware_group_node.py b/lib/ansible/modules/network/aci/aci_firmware_group_node.py deleted file mode 100644 index 7bf01a1700..0000000000 --- a/lib/ansible/modules/network/aci/aci_firmware_group_node.py +++ /dev/null @@ -1,252 +0,0 @@ -#!/usr/bin/python - -# 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 = ''' ---- -module: aci_firmware_group_node - -short_description: This modules adds and remove nodes from the firmware group - -version_added: "2.8" - -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 - required: true - node: - description: - - The node to be added to the firmware group - the value equals the NodeID - type: str - required: true - 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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: - - aci - -author: - - Steven Gerhart (@sgerhart) -''' - -EXAMPLES = ''' - - name: add firmware group node - 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 - 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 -''' - -import json -from ansible.module_utils.network.aci.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', aliases=['group']), # Not required for querying all objects - node=dict(type='str', aliases=['node']), - 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/lib/ansible/modules/network/aci/aci_firmware_policy.py b/lib/ansible/modules/network/aci/aci_firmware_policy.py deleted file mode 100644 index 041a616aa7..0000000000 --- a/lib/ansible/modules/network/aci/aci_firmware_policy.py +++ /dev/null @@ -1,255 +0,0 @@ -#!/usr/bin/python - - -# 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 = ''' ---- -module: aci_firmware_policy - -short_description: This creates a firmware policy - -version_added: "2.8" - -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 - required: true - 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 - required: true - 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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: - - aci - -author: - - Steven Gerhart (@sgerhart) -''' - -EXAMPLES = ''' - - name: firmware policy - 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.module_utils.network.aci.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=['name']), # Not required for querying all objects - version=dict(type='str', aliases=['version']), - 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/lib/ansible/modules/network/aci/aci_firmware_source.py b/lib/ansible/modules/network/aci/aci_firmware_source.py deleted file mode 100644 index 902cb51566..0000000000 --- a/lib/ansible/modules/network/aci/aci_firmware_source.py +++ /dev/null @@ -1,290 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2018, Dag Wieers (dagwieers) <dag@wieers.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -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. -version_added: '2.5' -options: - source: - description: - - The identifying name for the outside source of images, such as an HTTP or SCP server. - type: str - required: yes - 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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: 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 - 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 - 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 - 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 - 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.module_utils.network.aci.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='firmwareOSource', - aci_rn='fabric/fwrepop', - module_object=source, - target_filter={'name': source}, - ), - ) - aci.get_existing() - - if state == 'present': - aci.payload( - aci_class='firmwareOSource', - class_config=dict( - name=source, - url=url, - password=url_password, - pollingInterval=polling_interval, - proto=url_protocol, - user=url_username, - nameAlias=name_alias, - ), - ) - - aci.get_diff(aci_class='firmwareOSource') - - aci.post_config() - - elif state == 'absent': - aci.delete_config() - - aci.exit_json() - - -if __name__ == "__main__": - main() diff --git a/lib/ansible/modules/network/aci/aci_interface_policy_cdp.py b/lib/ansible/modules/network/aci/aci_interface_policy_cdp.py deleted file mode 100644 index fc723c9a74..0000000000 --- a/lib/ansible/modules/network/aci/aci_interface_policy_cdp.py +++ /dev/null @@ -1,257 +0,0 @@ -#!/usr/bin/python - -# Copyright: (c) 2019, Tim Knipper <tim.knipper@gmail.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function -__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. -version_added: '2.9' -options: - cdp_policy: - description: - - The CDP interface policy name. - type: str - required: yes - 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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: 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 Test Policy - aci_interface_policy_cdp: - name: Ansible_CDP_Test_Policy - host: apic.example.com - username: admin - password: adminpass - state: present - -- name: Remove CDP Test Policy - aci_interface_policy_cdp: - name: Ansible_CDP_Test_Policy - host: apic.example.com - username: admin - password: adminpass - output_level: debug - state: absent - -- name: Query CDP Policy - 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_interface_policy_fc.py b/lib/ansible/modules/network/aci/aci_interface_policy_fc.py deleted file mode 100644 index 969301cafe..0000000000 --- a/lib/ansible/modules/network/aci/aci_interface_policy_fc.py +++ /dev/null @@ -1,239 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': '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. -version_added: '2.4' -options: - fc_policy: - description: - - The name of the Fiber Channel interface policy. - type: str - required: yes - 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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: 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) -''' - -EXAMPLES = r''' -- 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_interface_policy_l2.py b/lib/ansible/modules/network/aci/aci_interface_policy_l2.py deleted file mode 100644 index 5dfd64b230..0000000000 --- a/lib/ansible/modules/network/aci/aci_interface_policy_l2.py +++ /dev/null @@ -1,264 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': '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. -version_added: '2.4' -options: - l2_policy: - description: - - The name of the Layer 2 interface policy. - type: str - required: yes - 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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: 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) -''' - -EXAMPLES = r''' -- 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_interface_policy_leaf_policy_group.py b/lib/ansible/modules/network/aci/aci_interface_policy_leaf_policy_group.py deleted file mode 100644 index 65e8abb90d..0000000000 --- a/lib/ansible/modules/network/aci/aci_interface_policy_leaf_policy_group.py +++ /dev/null @@ -1,570 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Bruno Calogero <brunocalogero@hotmail.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -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. -version_added: '2.5' -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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: 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 - 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 - fibre_channel_interface_policy: whateverfcpolicy - state: present - delegate_to: localhost - -- name: Create a Virtual Port Channel (VPC) Interface Policy Group (no description) - aci_interface_policy_leaf_policy_group: - host: apic - username: admin - password: SomeSecretPassword - lag_type: node - policy_group: policygroupname - link_level_policy: whateverlinklevelpolicy - fibre_channel_interface_policy: whateverfcpolicy - state: present - delegate_to: localhost - -- name: Create a Leaf Access Port Policy Group (no description) - aci_interface_policy_leaf_policy_group: - host: apic - username: admin - password: SomeSecretPassword - lag_type: leaf - policy_group: policygroupname - link_level_policy: whateverlinklevelpolicy - fibre_channel_interface_policy: whateverfcpolicy - state: present - delegate_to: localhost - -- name: Query all Leaf Access Port Policy Groups of type link - 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 - 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 - aci_interface_policy_leaf_policy_group: - host: apic - username: admin - password: SomeSecretPassword - lag_type: type_name - 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.module_utils.network.aci.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') - - if lag_type == 'leaf': - aci_class_name = 'infraAccPortGrp' - dn_name = 'accportgrp' - class_config_dict = dict( - name=policy_group, - descr=description, - nameAlias=name_alias, - ) - # Reset for target_filter - lag_type = None - elif lag_type in ('link', 'node'): - aci_class_name = 'infraAccBndlGrp' - dn_name = 'accbundle' - class_config_dict = dict( - name=policy_group, - descr=description, - lagT=lag_type, - nameAlias=name_alias, - ) - - child_configs = [ - dict( - infraRsCdpIfPol=dict( - attributes=dict( - tnCdpIfPolName=cdp_policy, - ), - ), - ), - dict( - infraRsFcIfPol=dict( - attributes=dict( - tnFcIfPolName=fibre_channel_interface_policy, - ), - ), - ), - dict( - infraRsHIfPol=dict( - attributes=dict( - tnFabricHIfPolName=link_level_policy, - ), - ), - ), - dict( - infraRsL2IfPol=dict( - attributes=dict( - tnL2IfPolName=l2_interface_policy, - ), - ), - ), - dict( - infraRsL2PortSecurityPol=dict( - attributes=dict( - tnL2PortSecurityPolName=port_security_policy, - ), - ), - ), - dict( - infraRsLacpPol=dict( - attributes=dict( - tnLacpLagPolName=port_channel_policy, - ), - ), - ), - dict( - infraRsLldpIfPol=dict( - attributes=dict( - tnLldpIfPolName=lldp_policy, - ), - ), - ), - dict( - infraRsMcpIfPol=dict( - attributes=dict( - tnMcpIfPolName=mcp_policy, - ), - ), - ), - dict( - infraRsMonIfInfraPol=dict( - attributes=dict( - tnMonInfraPolName=monitoring_policy, - ), - ), - ), - dict( - infraRsQosEgressDppIfPol=dict( - attributes=dict( - tnQosDppPolName=egress_data_plane_policing_policy, - ), - ), - ), - dict( - infraRsQosIngressDppIfPol=dict( - attributes=dict( - tnQosDppPolName=ingress_data_plane_policing_policy, - ), - ), - ), - dict( - infraRsQosPfcIfPol=dict( - attributes=dict( - tnQosPfcIfPolName=priority_flow_control_policy, - ), - ), - ), - dict( - infraRsQosSdIfPol=dict( - attributes=dict( - tnQosSdIfPolName=slow_drain_policy, - ), - ), - ), - dict( - infraRsStormctrlIfPol=dict( - attributes=dict( - tnStormctrlIfPolName=storm_control_interface_policy, - ), - ), - ), - dict( - infraRsStpIfPol=dict( - attributes=dict( - tnStpIfPolName=stp_interface_policy, - ), - ), - ), - ] - - # Add infraRsattEntP binding only when aep was defined - if aep is not None: - child_configs.append(dict( - infraRsAttEntP=dict( - attributes=dict( - tDn='uni/infra/attentp-{0}'.format(aep), - ), - ), - )) - - aci = ACIModule(module) - aci.construct_url( - root_class=dict( - aci_class=aci_class_name, - aci_rn='infra/funcprof/{0}-{1}'.format(dn_name, policy_group), - module_object=policy_group, - target_filter={'name': policy_group, 'lagT': lag_type}, - ), - child_classes=[ - 'infraRsAttEntP', - 'infraRsCdpIfPol', - 'infraRsFcIfPol', - 'infraRsHIfPol', - 'infraRsL2IfPol', - 'infraRsL2PortSecurityPol', - 'infraRsLacpPol', - 'infraRsLldpIfPol', - 'infraRsMcpIfPol', - 'infraRsMonIfInfraPol', - 'infraRsQosEgressDppIfPol', - 'infraRsQosIngressDppIfPol', - 'infraRsQosPfcIfPol', - 'infraRsQosSdIfPol', - 'infraRsStormctrlIfPol', - 'infraRsStpIfPol', - ], - ) - - aci.get_existing() - - if state == 'present': - aci.payload( - aci_class=aci_class_name, - class_config=class_config_dict, - child_configs=child_configs, - ) - - aci.get_diff(aci_class=aci_class_name) - - aci.post_config() - - elif state == 'absent': - aci.delete_config() - - aci.exit_json() - - -if __name__ == "__main__": - main() diff --git a/lib/ansible/modules/network/aci/aci_interface_policy_leaf_profile.py b/lib/ansible/modules/network/aci/aci_interface_policy_leaf_profile.py deleted file mode 100644 index 34bb9722b5..0000000000 --- a/lib/ansible/modules/network/aci/aci_interface_policy_leaf_profile.py +++ /dev/null @@ -1,257 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Bruno Calogero <brunocalogero@hotmail.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -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. -version_added: '2.5' -options: - leaf_interface_profile: - description: - - The name of the Fabric access policy leaf interface profile. - type: str - required: yes - aliases: [ name, leaf_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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: 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) -''' - -EXAMPLES = r''' -- name: Add a new leaf_interface_profile - aci_interface_policy_leaf_profile: - host: apic - username: admin - password: SomeSecretPassword - leaf_interface_profile: leafintprfname - description: leafintprfname description - state: present - delegate_to: localhost - -- name: Remove a leaf_interface_profile - aci_interface_policy_leaf_profile: - host: apic - username: admin - password: SomeSecretPassword - leaf_interface_profile: leafintprfname - state: absent - delegate_to: localhost - -- name: Remove all leaf_interface_profiles - aci_interface_policy_leaf_profile: - host: apic - username: admin - password: SomeSecretPassword - state: absent - delegate_to: localhost - -- name: Query a leaf_interface_profile - aci_interface_policy_leaf_profile: - host: apic - username: admin - password: SomeSecretPassword - leaf_interface_profile: leafintprfname - 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.module_utils.network.aci.aci import ACIModule, aci_argument_spec - - -def main(): - argument_spec = aci_argument_spec() - argument_spec.update( - leaf_interface_profile=dict(type='str', aliases=['name', 'leaf_interface_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_interface_profile']], - ['state', 'present', ['leaf_interface_profile']], - ], - ) - - leaf_interface_profile = module.params.get('leaf_interface_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='infraAccPortP', - aci_rn='infra/accportprof-{0}'.format(leaf_interface_profile), - module_object=leaf_interface_profile, - target_filter={'name': leaf_interface_profile}, - ), - ) - aci.get_existing() - - if state == 'present': - aci.payload( - aci_class='infraAccPortP', - class_config=dict( - name=leaf_interface_profile, - descr=description, - nameAlias=name_alias, - ), - ) - - aci.get_diff(aci_class='infraAccPortP') - - aci.post_config() - - elif state == 'absent': - aci.delete_config() - - aci.exit_json() - - -if __name__ == "__main__": - main() diff --git a/lib/ansible/modules/network/aci/aci_interface_policy_lldp.py b/lib/ansible/modules/network/aci/aci_interface_policy_lldp.py deleted file mode 100644 index 8632004af0..0000000000 --- a/lib/ansible/modules/network/aci/aci_interface_policy_lldp.py +++ /dev/null @@ -1,248 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': '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. -version_added: '2.4' -options: - lldp_policy: - description: - - The LLDP interface policy name. - type: str - required: yes - 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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: 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''' -- 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_interface_policy_mcp.py b/lib/ansible/modules/network/aci/aci_interface_policy_mcp.py deleted file mode 100644 index c7b52703b0..0000000000 --- a/lib/ansible/modules/network/aci/aci_interface_policy_mcp.py +++ /dev/null @@ -1,239 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': '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. -version_added: '2.4' -options: - mcp: - description: - - The name of the MCP interface. - type: str - required: yes - 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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: 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''' -- 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_interface_policy_ospf.py b/lib/ansible/modules/network/aci/aci_interface_policy_ospf.py deleted file mode 100644 index b2cef02c54..0000000000 --- a/lib/ansible/modules/network/aci/aci_interface_policy_ospf.py +++ /dev/null @@ -1,406 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2018, Dag Wieers (dagwieers) <dag@wieers.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -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. -version_added: '2.7' -options: - tenant: - description: - - The name of the Tenant the OSPF interface policy should belong to. - type: str - required: yes - 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 - required: yes - 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 - 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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: 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 - 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 - 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 - 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 - 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.module_utils.network.aci.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', 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/lib/ansible/modules/network/aci/aci_interface_policy_port_channel.py b/lib/ansible/modules/network/aci/aci_interface_policy_port_channel.py deleted file mode 100644 index 80b71a03b4..0000000000 --- a/lib/ansible/modules/network/aci/aci_interface_policy_port_channel.py +++ /dev/null @@ -1,321 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': '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. -version_added: '2.4' -options: - port_channel: - description: - - Name of the port channel. - type: str - required: yes - 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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: 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) -''' - -EXAMPLES = r''' -- 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_interface_policy_port_security.py b/lib/ansible/modules/network/aci/aci_interface_policy_port_security.py deleted file mode 100644 index 40da61ab4d..0000000000 --- a/lib/ansible/modules/network/aci/aci_interface_policy_port_security.py +++ /dev/null @@ -1,253 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': 'certified'} - -DOCUMENTATION = r''' ---- -module: aci_interface_policy_port_security -short_description: Manage port security (l2:PortSecurityPol) -description: -- Manage port security on Cisco ACI fabrics. -version_added: '2.4' -options: - port_security: - description: - - The name of the port security. - type: str - required: yes - 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: - version_added: '2.9' - 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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: 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''' -- 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.module_utils.network.aci.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, - ), - ) - - 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/lib/ansible/modules/network/aci/aci_interface_selector_to_switch_policy_leaf_profile.py b/lib/ansible/modules/network/aci/aci_interface_selector_to_switch_policy_leaf_profile.py deleted file mode 100644 index 8446afa97c..0000000000 --- a/lib/ansible/modules/network/aci/aci_interface_selector_to_switch_policy_leaf_profile.py +++ /dev/null @@ -1,253 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Bruno Calogero <brunocalogero@hotmail.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -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. -version_added: '2.5' -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: aci -notes: -- This module requires an existing leaf profile, the module M(aci_switch_policy_leaf_profile) can be used for this. -seealso: -- module: 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 - 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 - 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 - 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_l3out.py b/lib/ansible/modules/network/aci/aci_l3out.py deleted file mode 100644 index a1b7df3ea8..0000000000 --- a/lib/ansible/modules/network/aci/aci_l3out.py +++ /dev/null @@ -1,370 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': '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. -version_added: '2.6' -options: - tenant: - description: - - Name of an existing tenant. - type: str - required: yes - aliases: [ tenant_name ] - l3out: - description: - - Name of L3Out being created. - type: str - required: yes - aliases: [ l3out_name, name ] - vrf: - description: - - Name of the VRF being associated with the L3Out. - type: str - required: yes - aliases: [ vrf_name ] - domain: - description: - - Name of the external L3 domain being associated with the L3Out. - type: str - required: yes - 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 - choices: [ export, import ] - aliases: [ route_control_enforcement ] - l3protocol: - description: - - Routing protocol for the L3Out - type: list - 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 ] - version_added: '2.8' - 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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: aci -notes: -- The C(tenant) and C(domain) and C(vrf) used must exist before using this module in your playbook. - The M(aci_tenant) and M(aci_domain) and M(aci_vrf) modules can be used for this. -seealso: -- module: aci_tenant -- module: aci_domain -- module: 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 - 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 - aci_l3out: - host: apic - username: admin - password: SomeSecretPassword - tenant: production - name: prod_l3out - state: absent - delegate_to: localhost - -- name: Query L3Out information - 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.module_utils.network.aci.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', 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', 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/lib/ansible/modules/network/aci/aci_l3out_extepg.py b/lib/ansible/modules/network/aci/aci_l3out_extepg.py deleted file mode 100644 index 29d5b1bab5..0000000000 --- a/lib/ansible/modules/network/aci/aci_l3out_extepg.py +++ /dev/null @@ -1,312 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': '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) -version_added: '2.9' -options: - tenant: - description: - - Name of an existing tenant. - type: str - required: yes - aliases: [ tenant_name ] - l3out: - description: - - Name of an existing L3Out. - type: str - required: yes - aliases: [ l3out_name ] - extepg: - description: - - Name of ExtEpg being created. - type: str - required: yes - 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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: aci -notes: -- The C(tenant) and C(domain) and C(vrf) used must exist before using this module in your playbook. - The M(aci_tenant) and M(aci_domain) and M(aci_vrf) modules can be used for this. -seealso: -- module: aci_tenant -- module: aci_domain -- module: 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 - 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 - extepg: - host: apic - username: admin - password: SomeSecretPassword - tenant: production - l3out: prod_l3out - name: prod_extepg - state: absent - delegate_to: localhost - -- name: Query ExtEpg information - 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_l3out_extsubnet.py b/lib/ansible/modules/network/aci/aci_l3out_extsubnet.py deleted file mode 100644 index 63053501df..0000000000 --- a/lib/ansible/modules/network/aci/aci_l3out_extsubnet.py +++ /dev/null @@ -1,330 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': 'certified'} - -DOCUMENTATION = r''' ---- -module: aci_l3out_extsubnet -short_description: Manage External Subnet objects (l3extSubnet:extsubnet) -description: -- Manage External Subnet objects (l3extSubnet:extsubnet) -version_added: '2.9' -options: - tenant: - description: - - Name of an existing tenant. - type: str - required: yes - aliases: [ tenant_name ] - l3out: - description: - - Name of an existing L3Out. - type: str - required: yes - aliases: [ l3out_name ] - extepg: - description: - - Name of an existing ExtEpg. - type: str - required: yes - aliases: [ extepg_name ] - network: - description: - - The network address for the Subnet. - type: str - required: yes - 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. - type: list - 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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: aci -notes: -- The C(tenant) and C(domain) and C(vrf) used must exist before using this module in your playbook. - The M(aci_tenant) and M(aci_domain) and M(aci_vrf) modules can be used for this. -seealso: -- module: aci_tenant -- module: aci_domain -- module: 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 External Subnet - 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 - 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 information - 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.module_utils.network.aci.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 - network=dict(type='str', aliases=['address', 'ip']), - description=dict(type='str', aliases=['descr']), - subnet_name=dict(type='str', aliases=['name']), - scope=dict(type='list', 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/lib/ansible/modules/network/aci/aci_l3out_route_tag_policy.py b/lib/ansible/modules/network/aci/aci_l3out_route_tag_policy.py deleted file mode 100644 index ccc8ed5c14..0000000000 --- a/lib/ansible/modules/network/aci/aci_l3out_route_tag_policy.py +++ /dev/null @@ -1,257 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': '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. -version_added: '2.4' -options: - rtp: - description: - - The name of the route tag policy. - type: str - required: yes - 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 - required: yes - 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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: aci -notes: -- The C(tenant) used must exist before using this module in your playbook. - The M(aci_tenant) module can be used for this. -seealso: -- module: 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''' -- 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_maintenance_group.py b/lib/ansible/modules/network/aci/aci_maintenance_group.py deleted file mode 100644 index 74aacdc6be..0000000000 --- a/lib/ansible/modules/network/aci/aci_maintenance_group.py +++ /dev/null @@ -1,238 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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 = ''' -module: aci_maintenance_group -short_description: This creates an ACI maintenance group -version_added: "2.8" -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 - required: true - policy: - description: - - This is the name of the policy that was created using aci_maintenance_policy - type: str - required: true - 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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: - - aci -author: - - Steven Gerhart (@sgerhart) -''' - -EXAMPLES = ''' -- name: maintenance group - 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_maintenance_group_node.py b/lib/ansible/modules/network/aci/aci_maintenance_group_node.py deleted file mode 100644 index 4078ebfb7f..0000000000 --- a/lib/ansible/modules/network/aci/aci_maintenance_group_node.py +++ /dev/null @@ -1,245 +0,0 @@ -#!/usr/bin/python - -# 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_maintenance_group_node -short_description: Manage maintenance group nodes -version_added: '2.8' -description: -- Manage maintenance group nodes -options: - group: - description: - - The maintenance group name that you want to add the node to. - type: str - required: true - node: - description: - - The node to be added to the maintenance group. - - The value equals the nodeid. - type: str - required: true - 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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: -- aci -author: -- Steven Gerhart (@sgerhart) -''' - -EXAMPLES = r''' -- name: maintenance group - aci_maintenance_group_node: - host: "{{ inventory_hostname }}" - username: "{{ user }}" - password: "{{ pass }}" - validate_certs: no - group: maintenancegrp1 - node: 1001 - state: present - -- name: maintenance group - 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_maintenance_policy.py b/lib/ansible/modules/network/aci/aci_maintenance_policy.py deleted file mode 100644 index 886c4b4316..0000000000 --- a/lib/ansible/modules/network/aci/aci_maintenance_policy.py +++ /dev/null @@ -1,279 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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_maintenance_policy -short_description: Manage firmware maintenance policies -version_added: '2.8' -description: -- Manage maintenance policies that defines behavior during an ACI upgrade. -options: - name: - description: - - The name for the maintenance policy. - type: str - required: true - 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 - required: true - 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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: -- aci -notes: -- A scheduler is required for this module, which could have been created using the M(aci_fabric_scheduler) module or via the UI. -author: -- Steven Gerhart (@sgerhart) -''' - -EXAMPLES = r''' -- name: Ensure maintenance policy is present - 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_rest.py b/lib/ansible/modules/network/aci/aci_rest.py deleted file mode 100644 index e930403382..0000000000 --- a/lib/ansible/modules/network/aci/aci_rest.py +++ /dev/null @@ -1,442 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Dag Wieers (@dagwieers) <dag@wieers.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function -__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. -version_added: '2.4' -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: 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. -seealso: -- module: 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) -''' - -EXAMPLES = r''' -- name: Add a tenant using certificate authentication - 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/ - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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: - import lxml.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.module_utils.network.aci.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() - - # 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 - # FIXME: Converting from a dictionary to XML is unsupported at this time - # payload = etree.tostring(payload) - pass - elif payload and isinstance(payload, str): - try: - # Validate XML string - payload = lxml.etree.tostring(lxml.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 - - # Report success - aci.exit_json(**aci.result) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/network/aci/aci_static_binding_to_epg.py b/lib/ansible/modules/network/aci/aci_static_binding_to_epg.py deleted file mode 100644 index 7955b95c0a..0000000000 --- a/lib/ansible/modules/network/aci/aci_static_binding_to_epg.py +++ /dev/null @@ -1,440 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Bruno Calogero <brunocalogero@hotmail.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -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. -version_added: '2.5' -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 ] - version_added: '2.7' - 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 - 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: aci -notes: -- The C(tenant), C(ap), C(epg) used must exist before using this module in your playbook. - The M(aci_tenant), M(aci_ap), M(aci_epg) modules can be used for this. -seealso: -- module: aci_tenant -- module: aci_ap -- module: 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 - 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 - 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 - 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.module_utils.network.aci.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', 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/lib/ansible/modules/network/aci/aci_switch_leaf_selector.py b/lib/ansible/modules/network/aci/aci_switch_leaf_selector.py deleted file mode 100644 index ad0ca1d48c..0000000000 --- a/lib/ansible/modules/network/aci/aci_switch_leaf_selector.py +++ /dev/null @@ -1,349 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Bruno Calogero <brunocalogero@hotmail.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -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. -version_added: '2.5' -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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: aci -notes: -- This module is to be used with M(aci_switch_policy_leaf_profile). - One first creates a leaf profile (infra:NodeP) and then creates an associated selector (infra:LeafS), -seealso: -- module: 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) - 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) - 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 - 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 - 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_switch_policy_leaf_profile.py b/lib/ansible/modules/network/aci/aci_switch_policy_leaf_profile.py deleted file mode 100644 index 558eb6a9c3..0000000000 --- a/lib/ansible/modules/network/aci/aci_switch_policy_leaf_profile.py +++ /dev/null @@ -1,250 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Bruno Calogero <brunocalogero@hotmail.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -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. -version_added: '2.5' -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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: aci -seealso: -- module: 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 - 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 - 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 - 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_switch_policy_vpc_protection_group.py b/lib/ansible/modules/network/aci/aci_switch_policy_vpc_protection_group.py deleted file mode 100644 index c1525c2880..0000000000 --- a/lib/ansible/modules/network/aci/aci_switch_policy_vpc_protection_group.py +++ /dev/null @@ -1,308 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Bruno Calogero <brunocalogero@hotmail.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -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. -version_added: '2.5' -options: - protection_group: - description: - - The name of the Explicit vPC Protection Group. - type: str - required: yes - aliases: [ name, protection_group_name ] - protection_group_id: - description: - - The Explicit vPC Protection Group ID. - type: int - required: yes - 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 - required: yes - switch_2_id: - description: - - The ID of the Second Leaf Switch for the Explicit vPC Protection Group. - type: int - required: yes - 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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: aci -seealso: -- module: 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 - 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 - 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 - 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 - 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_taboo_contract.py b/lib/ansible/modules/network/aci/aci_taboo_contract.py deleted file mode 100644 index a64e9c8fac..0000000000 --- a/lib/ansible/modules/network/aci/aci_taboo_contract.py +++ /dev/null @@ -1,288 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2018, Dag Wieers (dagwieers) <dag@wieers.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -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. -version_added: '2.4' -options: - taboo_contract: - description: - - The name of the Taboo Contract. - type: str - required: yes - aliases: [ name ] - description: - description: - - The description for the Taboo Contract. - type: str - aliases: [ descr ] - tenant: - description: - - The name of the tenant. - type: str - required: yes - 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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: aci -notes: -- The C(tenant) used must exist before using this module in your playbook. - The M(aci_tenant) module can be used for this. -seealso: -- module: 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 - 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 - 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 - aci_taboo_contract: - host: apic - username: admin - password: SomeSecretPassword - state: query - delegate_to: localhost - register: query_result - -- name: Query a specific taboo contract - 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_tenant.py b/lib/ansible/modules/network/aci/aci_tenant.py deleted file mode 100644 index 1cb064d24c..0000000000 --- a/lib/ansible/modules/network/aci/aci_tenant.py +++ /dev/null @@ -1,262 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': 'certified'} - -DOCUMENTATION = r''' ---- -module: aci_tenant -short_description: Manage tenants (fv:Tenant) -description: -- Manage tenants on Cisco ACI fabrics. -version_added: '2.4' -options: - tenant: - description: - - The name of the tenant. - type: str - required: yes - 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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: aci -seealso: -- module: aci_ap -- module: aci_bd -- module: aci_contract -- module: aci_filter -- module: 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 - aci_tenant: - host: apic - username: admin - password: SomeSecretPassword - tenant: production - description: Production tenant - state: present - delegate_to: localhost - -- name: Remove a tenant - aci_tenant: - host: apic - username: admin - password: SomeSecretPassword - tenant: production - state: absent - delegate_to: localhost - -- name: Query a tenant - aci_tenant: - host: apic - username: admin - password: SomeSecretPassword - tenant: production - state: query - delegate_to: localhost - register: query_result - -- name: Query all tenants - 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_tenant_action_rule_profile.py b/lib/ansible/modules/network/aci/aci_tenant_action_rule_profile.py deleted file mode 100644 index 754c52b2ea..0000000000 --- a/lib/ansible/modules/network/aci/aci_tenant_action_rule_profile.py +++ /dev/null @@ -1,246 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': '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. -version_added: '2.4' -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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: aci -notes: -- The C(tenant) used must exist before using this module in your playbook. - The M(aci_tenant) module can be used for this. -seealso: -- module: 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''' -- 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_tenant_ep_retention_policy.py b/lib/ansible/modules/network/aci/aci_tenant_ep_retention_policy.py deleted file mode 100644 index 7ec66d4943..0000000000 --- a/lib/ansible/modules/network/aci/aci_tenant_ep_retention_policy.py +++ /dev/null @@ -1,361 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': '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. -version_added: '2.4' -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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: aci -notes: -- The C(tenant) used must exist before using this module in your playbook. - The M(aci_tenant) module can be used for this. -seealso: -- module: 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 - 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 - 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 - 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 - 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_tenant_span_dst_group.py b/lib/ansible/modules/network/aci/aci_tenant_span_dst_group.py deleted file mode 100644 index 50f8f2efb6..0000000000 --- a/lib/ansible/modules/network/aci/aci_tenant_span_dst_group.py +++ /dev/null @@ -1,248 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': '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. -version_added: '2.4' -options: - dst_group: - description: - - The name of the SPAN destination group. - type: str - required: yes - aliases: [ name ] - description: - description: - - The description of the SPAN destination group. - type: str - aliases: [ descr ] - tenant: - description: - - The name of the tenant. - type: str - required: yes - 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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: aci -notes: -- The C(tenant) used must exist before using this module in your playbook. - The M(aci_tenant) module can be used for this. -seealso: -- module: 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''' -- 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_tenant_span_src_group.py b/lib/ansible/modules/network/aci/aci_tenant_span_src_group.py deleted file mode 100644 index 535efcc564..0000000000 --- a/lib/ansible/modules/network/aci/aci_tenant_span_src_group.py +++ /dev/null @@ -1,264 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': '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. -version_added: '2.4' -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: - version_added: '2.10' - 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: aci -notes: -- The C(tenant) used must exist before using this module in your playbook. - The M(aci_tenant) module can be used for this. -seealso: -- module: 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) -''' - -EXAMPLES = r''' -- 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_tenant_span_src_group_to_dst_group.py b/lib/ansible/modules/network/aci/aci_tenant_span_src_group_to_dst_group.py deleted file mode 100644 index 3792eceb0f..0000000000 --- a/lib/ansible/modules/network/aci/aci_tenant_span_src_group_to_dst_group.py +++ /dev/null @@ -1,259 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': '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. -version_added: '2.4' -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: - version_added: '2.10' - 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: aci -notes: -- The C(tenant), C(src_group), and C(dst_group) must exist before using this module in your playbook. - The M(aci_tenant), M(aci_tenant_span_src_group), and M(aci_tenant_span_dst_group) modules can be used for this. -seealso: -- module: aci_tenant -- module: aci_tenant_span_src_group -- module: 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) -''' - -EXAMPLES = r''' -- 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_vlan_pool.py b/lib/ansible/modules/network/aci/aci_vlan_pool.py deleted file mode 100644 index a556d8993a..0000000000 --- a/lib/ansible/modules/network/aci/aci_vlan_pool.py +++ /dev/null @@ -1,283 +0,0 @@ -#!/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 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': 'certified'} - -DOCUMENTATION = r''' ---- -module: aci_vlan_pool -short_description: Manage VLAN pools (fvns:VlanInstP) -description: -- Manage VLAN pools on Cisco ACI fabrics. -version_added: '2.5' -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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: aci -seealso: -- module: aci_encap_pool -- module: 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 - 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 - 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 - 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 - 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_vlan_pool_encap_block.py b/lib/ansible/modules/network/aci/aci_vlan_pool_encap_block.py deleted file mode 100644 index 2aa8ed8e49..0000000000 --- a/lib/ansible/modules/network/aci/aci_vlan_pool_encap_block.py +++ /dev/null @@ -1,362 +0,0 @@ -#!/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 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': '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. -version_added: '2.5' -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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: aci -notes: -- The C(pool) must exist in order to add or delete a encap block. -seealso: -- module: aci_encap_pool_range -- module: 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 - 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 - 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 - 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 - 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 - 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.module_utils.network.aci.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/lib/ansible/modules/network/aci/aci_vmm_credential.py b/lib/ansible/modules/network/aci/aci_vmm_credential.py deleted file mode 100644 index f5e637a627..0000000000 --- a/lib/ansible/modules/network/aci/aci_vmm_credential.py +++ /dev/null @@ -1,316 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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_vmm_credential -short_description: Manage virtual domain credential profiles (vmm:UsrAccP) -description: -- Manage virtual domain credential profiles on Cisco ACI fabrics. -version_added: '2.9' -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: - version_added: '2.10' - 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: aci -seealso: -- module: 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 - 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 - 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 - 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 - 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.module_utils.network.aci.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=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/lib/ansible/modules/network/aci/aci_vrf.py b/lib/ansible/modules/network/aci/aci_vrf.py deleted file mode 100644 index de840a17b4..0000000000 --- a/lib/ansible/modules/network/aci/aci_vrf.py +++ /dev/null @@ -1,296 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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': '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. -version_added: '2.4' -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: - version_added: '2.10' - description: - - The alias for the current object. This relates to the nameAlias field in ACI. - type: str -extends_documentation_fragment: aci -notes: -- The C(tenant) used must exist before using this module in your playbook. - The M(aci_tenant) module can be used for this. -seealso: -- module: 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 - 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 - 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 - 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 - 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.module_utils.network.aci.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 - 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']), - 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') - - 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}, - ), - ) - - 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, - ), - ) - - aci.get_diff(aci_class='fvCtx') - - aci.post_config() - - elif state == 'absent': - aci.delete_config() - - aci.exit_json() - - -if __name__ == "__main__": - main() diff --git a/lib/ansible/plugins/doc_fragments/aci.py b/lib/ansible/plugins/doc_fragments/aci.py deleted file mode 100644 index 016a1bcff0..0000000000 --- a/lib/ansible/plugins/doc_fragments/aci.py +++ /dev/null @@ -1,88 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Dag Wieers (@dagwieers) <dag@wieers.com> -# Copyright: (c) 2017, Swetha Chunduri (@schunduri) -# 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 - - -class ModuleDocFragment(object): - # Standard files documentation fragment - DOCUMENTATION = r''' -options: - host: - description: - - IP Address or hostname of APIC resolvable by Ansible control host. - type: str - required: yes - aliases: [ hostname ] - port: - description: - - Port number to be used for REST connection. - - The default value depends on parameter C(use_ssl). - type: int - username: - description: - - The username to use for authentication. - type: str - default: admin - aliases: [ user ] - password: - description: - - The password to use for authentication. - - This option is mutual exclusive with C(private_key). If C(private_key) is provided too, it will be used instead. - type: str - required: yes - private_key: - description: - - Either a PEM-formatted private key file or the private key content used for signature-based authentication. - - This value also influences the default C(certificate_name) that is used. - - This option is mutual exclusive with C(password). If C(password) is provided too, it will be ignored. - type: str - required: yes - aliases: [ cert_key ] - certificate_name: - description: - - The X.509 certificate name attached to the APIC AAA user used for signature-based authentication. - - If a C(private_key) filename was provided, this defaults to the C(private_key) basename, without extension. - - If PEM-formatted content was provided for C(private_key), this defaults to the C(username) value. - type: str - aliases: [ cert_name ] - output_level: - description: - - Influence the output of this ACI module. - - C(normal) means the standard output, incl. C(current) dict - - C(info) adds informational output, incl. C(previous), C(proposed) and C(sent) dicts - - C(debug) adds debugging output, incl. C(filter_string), C(method), C(response), C(status) and C(url) information - type: str - choices: [ debug, info, normal ] - default: normal - timeout: - description: - - The socket level timeout in seconds. - type: int - default: 30 - use_proxy: - description: - - If C(no), it will not use a proxy, even if one is defined in an environment variable on the target hosts. - type: bool - default: yes - use_ssl: - description: - - If C(no), an HTTP connection will be used instead of the default HTTPS connection. - type: bool - default: yes - validate_certs: - description: - - If C(no), SSL certificates will not be validated. - - This should only set to C(no) when used on personally controlled sites using self-signed certificates. - type: bool - default: yes -seealso: -- ref: aci_guide - description: Detailed information on how to manage your ACI infrastructure using Ansible. -- ref: aci_dev_guide - description: Detailed guide on how to write your own Cisco ACI modules to contribute. -''' diff --git a/test/integration/targets/aci_aaa_user/aliases b/test/integration/targets/aci_aaa_user/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_aaa_user/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_aaa_user/tasks/main.yml b/test/integration/targets/aci_aaa_user/tasks/main.yml deleted file mode 100644 index 2202cb8b70..0000000000 --- a/test/integration/targets/aci_aaa_user/tasks/main.yml +++ /dev/null @@ -1,235 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Dag Wieers (dagwieers) <dag@wieers.com> -# -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - - -# CLEAN ENVIRONMENT -- name: Remove any pre-existing user - aci_aaa_user: &user_absent - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - aaa_user: ansible - state: absent - - -# ADD USER -- name: Add user (check_mode) - aci_aaa_user: &user_present - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - aaa_user: ansible - description: Ansible test user - email: ansible@ansible.lan - enabled: yes - expiration: never - expires: no - first_name: Test - last_name: User - phone: 1-234-555-678 - check_mode: yes - register: cm_add_user - -# NOTE: Setting password is not idempotent, see #35544 -- name: Add user (normal mode) - aci_aaa_user: - <<: *user_present - aaa_password: 12!Ab:cD!34 - register: nm_add_user - -- name: Add user again (check mode) - aci_aaa_user: *user_present - check_mode: yes - register: cm_add_user_again - -- name: Add user again (normal mode) - aci_aaa_user: *user_present - register: nm_add_user_again - -- name: Verify add user - assert: - that: - - cm_add_user is changed - - nm_add_user is changed - - nm_add_user.current.0.aaaUser.attributes.descr == 'Ansible test user' - - cm_add_user_again is not changed - - nm_add_user_again is not changed - - nm_add_user_again.current.0.aaaUser.attributes.descr == 'Ansible test user' - - -# MODIFY USER -- name: Modify user (check_mode) - aci_aaa_user: &user_changed - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - aaa_user: ansible - description: Ansible test user for integration tests - email: aci-ansible@ansible.lan - expiration: '2123-12-12' - expires: yes - phone: 2-345-555-678 - check_mode: yes - register: cm_modify_user - -- name: Modify user (normal mode) - aci_aaa_user: *user_changed - register: nm_modify_user - -- name: Modify user again (check mode) - aci_aaa_user: *user_changed - check_mode: yes - register: cm_modify_user_again - -- name: Modify user again (normal mode) - aci_aaa_user: *user_changed - register: nm_modify_user_again - -- name: Verify modify user - assert: - that: - - cm_modify_user is changed - - nm_modify_user is changed - - nm_modify_user.current.0.aaaUser.attributes.descr == 'Ansible test user for integration tests' - - cm_modify_user_again is not changed - - nm_modify_user_again is not changed - - nm_modify_user_again.current.0.aaaUser.attributes.descr == 'Ansible test user for integration tests' - - -# CLEAR PASSWORD HISTORY -- name: Clear password history (check_mode) - aci_aaa_user: &clear_password_history - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - aaa_user: ansible - clear_password_history: yes - check_mode: yes - register: cm_clear_password_history - -- name: Clear password history (normal mode) - aci_aaa_user: *clear_password_history - register: nm_clear_password_history - -- name: Clear password history (check mode) - aci_aaa_user: *clear_password_history - check_mode: yes - register: cm_clear_password_history_again - -- name: Clear password history (normal mode) - aci_aaa_user: *clear_password_history - register: nm_clear_password_history_again - -- name: Verify clear password history - assert: - that: - # NOTE: Clearing password history is a changing action, everytime - - cm_clear_password_history is changed - - nm_clear_password_history is changed - - cm_clear_password_history_again is changed - - nm_clear_password_history_again is changed - - -# QUERY ALL USERS -- name: Query all users (check_mode) - aci_aaa_user: &user_query - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - aaa_user: ansible - state: query - check_mode: yes - register: cm_query_all_users - -- name: Query all users (normal mode) - aci_aaa_user: *user_query - register: nm_query_all_users - -- name: Verify query_all_users - assert: - that: - - cm_query_all_users is not changed - - nm_query_all_users is not changed - # NOTE: Order of users is not stable between calls - #- cm_query_all_users == nm_query_all_users - - -# QUERY OUR USER -- name: Query our user (check_mode) - aci_aaa_user: - <<: *user_query - check_mode: yes - register: cm_query_user - -- name: Query our user (normal mode) - aci_aaa_user: - <<: *user_query - register: nm_query_user - -- name: Verify query_user - assert: - that: - - cm_query_user is not changed - - nm_query_user is not changed - - cm_query_user == nm_query_user - - nm_query_user.current.0.aaaUser.attributes.accountStatus == 'active' - - nm_query_user.current.0.aaaUser.attributes.descr == 'Ansible test user for integration tests' - - nm_query_user.current.0.aaaUser.attributes.email == 'aci-ansible@ansible.lan' - - nm_query_user.current.0.aaaUser.attributes.expiration == '2123-12-12T00:00:00.000+00:00' - - nm_query_user.current.0.aaaUser.attributes.expires == 'yes' - - nm_query_user.current.0.aaaUser.attributes.phone == '2-345-555-678' - - -# REMOVE USER -- name: Remove user (check_mode) - aci_aaa_user: *user_absent - check_mode: yes - register: cm_remove_user - -- name: Remove user (normal mode) - aci_aaa_user: *user_absent - register: nm_remove_user - -- name: Remove user again (check_mode) - aci_aaa_user: *user_absent - check_mode: yes - register: cm_remove_user_again - -- name: Remove user again (normal mode) - aci_aaa_user: *user_absent - register: nm_remove_user_again - -- name: Verify remove_user - assert: - that: - - cm_remove_user is changed - - nm_remove_user is changed - - cm_remove_user_again is not changed - - nm_remove_user_again is not changed diff --git a/test/integration/targets/aci_aaa_user_certificate/aliases b/test/integration/targets/aci_aaa_user_certificate/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_aaa_user_certificate/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_aaa_user_certificate/pki/admin.crt b/test/integration/targets/aci_aaa_user_certificate/pki/admin.crt deleted file mode 100644 index cfac5531e9..0000000000 --- a/test/integration/targets/aci_aaa_user_certificate/pki/admin.crt +++ /dev/null @@ -1,14 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICODCCAaGgAwIBAgIJAIt8XMntue0VMA0GCSqGSIb3DQEBCwUAMDQxDjAMBgNV -BAMMBUFkbWluMRUwEwYDVQQKDAxZb3VyIENvbXBhbnkxCzAJBgNVBAYTAlVTMCAX -DTE4MDEwOTAwNTk0NFoYDzIxMTcxMjE2MDA1OTQ0WjA0MQ4wDAYDVQQDDAVBZG1p -bjEVMBMGA1UECgwMWW91ciBDb21wYW55MQswCQYDVQQGEwJVUzCBnzANBgkqhkiG -9w0BAQEFAAOBjQAwgYkCgYEAohG/7axtt7CbSaMP7r+2mhTKbNgh0Ww36C7Ta14i -v+VmLyKkQHnXinKGhp6uy3Nug+15a+eIu7CrgpBVMQeCiWfsnwRocKcQJWIYDrWl -XHxGQn31yYKR6mylE7Dcj3rMFybnyhezr5D8GcP85YRPmwG9H2hO/0Y1FUnWu9Iw -AQkCAwEAAaNQME4wHQYDVR0OBBYEFD0jLXfpkrU/ChzRvfruRs/fy1VXMB8GA1Ud -IwQYMBaAFD0jLXfpkrU/ChzRvfruRs/fy1VXMAwGA1UdEwQFMAMBAf8wDQYJKoZI -hvcNAQELBQADgYEAOmvre+5tgZ0+F3DgsfxNQqLTrGiBgGCIymPkP/cBXXkNuJyl -3ac7tArHQc7WEA4U2R2rZbEq8FC3UJJm4nUVtCPvEh3G9OhN2xwYev79yt6pIn/l -KU0Td2OpVyo0eLqjoX5u2G90IBWzhyjFbo+CcKMrSVKj1YOdG0E3OuiJf00= ------END CERTIFICATE----- diff --git a/test/integration/targets/aci_aaa_user_certificate/pki/admin.key b/test/integration/targets/aci_aaa_user_certificate/pki/admin.key deleted file mode 100644 index 63bb00cc00..0000000000 --- a/test/integration/targets/aci_aaa_user_certificate/pki/admin.key +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKIRv+2sbbewm0mj -D+6/tpoUymzYIdFsN+gu02teIr/lZi8ipEB514pyhoaerstzboPteWvniLuwq4KQ -VTEHgoln7J8EaHCnECViGA61pVx8RkJ99cmCkepspROw3I96zBcm58oXs6+Q/BnD -/OWET5sBvR9oTv9GNRVJ1rvSMAEJAgMBAAECgYByu3QO0qF9h7X3JEu0Ld4cKBnB -giQ2uJC/et7KxIJ/LOvw9GopBthyt27KwG1ntBkJpkTuAaQHkyNns7vLkNB0S0IR -+owVFEcKYq9VCHTaiQU8TDp24gN+yPTrpRuH8YhDVq5SfVdVuTMgHVQdj4ya4VlF -Gj+a7+ipxtGiLsVGrQJBAM7p0Fm0xmzi+tBOASUAcVrPLcteFIaTBFwfq16dm/ON -00Khla8Et5kMBttTbqbukl8mxFjBEEBlhQqb6EdQQ0sCQQDIhHx1a9diG7y/4DQA -4KvR3FCYwP8PBORlSamegzCo+P1OzxiEo0amX7yQMA5UyiP/kUsZrme2JBZgna8S -p4R7AkEAr7rMhSOPUnMD6V4WgsJ5g1Jp5kqkzBaYoVUUSms5RASz4+cwJVCwTX91 -Y1jcpVIBZmaaY3a0wrx13ajEAa0dOQJBAIpjnb4wqpsEh7VpmJqOdSdGxb1XXfFQ -sA0T1OQYqQnFppWwqrxIL+d9pZdiA1ITnNqyvUFBNETqDSOrUHwwb2cCQGArE+vu -ffPUWQ0j+fiK+covFG8NL7H+26NSGB5+Xsn9uwOGLj7K/YT6CbBtr9hJiuWjM1Al -0V4ltlTuu2mTMaw= ------END PRIVATE KEY----- diff --git a/test/integration/targets/aci_aaa_user_certificate/tasks/main.yml b/test/integration/targets/aci_aaa_user_certificate/tasks/main.yml deleted file mode 100644 index 27ea5a1ebd..0000000000 --- a/test/integration/targets/aci_aaa_user_certificate/tasks/main.yml +++ /dev/null @@ -1,142 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Dag Wieers (dagwieers) <dag@wieers.com> -# -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - - -# CLEAN ENVIRONMENT -- name: Remove any pre-existing certificate - aci_aaa_user_certificate: &cert_absent - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - aaa_user: admin - certificate_name: admin - state: absent - - -# ADD USER CERTIFICATE -- name: Add user certificate (check_mode) - aci_aaa_user_certificate: &cert_present - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - aaa_user: admin - certificate_name: admin - certificate: "{{ lookup('file', 'pki/admin.crt') }}" - state: present - check_mode: yes - register: cm_add_cert - -- name: Add user certificate (normal mode) - aci_aaa_user_certificate: *cert_present - register: nm_add_cert - -- name: Add user certificate again (check mode) - aci_aaa_user_certificate: *cert_present - check_mode: yes - register: cm_add_cert_again - -- name: Add user certificate again (normal mode) - aci_aaa_user_certificate: *cert_present - register: nm_add_cert_again - -- name: Verify add_cert - assert: - that: - - cm_add_cert is changed - - nm_add_cert is change - - cm_add_cert_again is not changed - - nm_add_cert_again is not changed - - -# QUERY ALL USER CERTIFICATES -- name: Query all user certificates using signature-based authentication (check_mode) - aci_aaa_user_certificate: &cert_query - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - #password: '{{ aci_password }}' - private_key: '{{ role_path }}/pki/admin.key' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - aaa_user: admin - state: query - check_mode: yes - register: cm_query_all_certs - -- name: Query all user certificates using signature-based authentication (normal mode) - aci_aaa_user_certificate: *cert_query - register: nm_query_all_certs - -- name: Verify query_all_certs - assert: - that: - - cm_query_all_certs is not changed - - nm_query_all_certs is not changed - # NOTE: Order of certs is not stable between calls - #- cm_query_all_certs == nm_query_all_certs - - -# QUERY OUR USER CERTIFICATE -- name: Query our certificate using signature-based authentication (check_mode) - aci_aaa_user_certificate: - <<: *cert_query - certificate_name: admin - check_mode: yes - register: cm_query_cert - -- name: Query our certificate using signature-based authentication (normal mode) - aci_aaa_user_certificate: - <<: *cert_query - certificate_name: admin - register: nm_query_cert - -- name: Verify query_cert - assert: - that: - - cm_query_cert is not changed - - nm_query_cert is not changed - - cm_query_cert == nm_query_cert - - -# REMOVE CERTIFICATE -- name: Remove certificate (check_mode) - aci_aaa_user_certificate: *cert_absent - check_mode: yes - register: cm_remove_cert - -- name: Remove certificate (normal mode) - aci_aaa_user_certificate: *cert_absent - register: nm_remove_cert - -- name: Remove certificate again (check_mode) - aci_aaa_user_certificate: *cert_absent - check_mode: yes - register: cm_remove_cert_again - -- name: Remove certificate again (normal mode) - aci_aaa_user_certificate: *cert_absent - register: nm_remove_cert_again - -- name: Verify remove_cert - assert: - that: - - cm_remove_cert is changed - - nm_remove_cert is changed - - cm_remove_cert_again is not changed - - nm_remove_cert_again is not changed diff --git a/test/integration/targets/aci_access_port_block_to_access_port/aliases b/test/integration/targets/aci_access_port_block_to_access_port/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_access_port_block_to_access_port/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_access_port_block_to_access_port/tasks/main.yml b/test/integration/targets/aci_access_port_block_to_access_port/tasks/main.yml deleted file mode 100644 index 543e8e0ba3..0000000000 --- a/test/integration/targets/aci_access_port_block_to_access_port/tasks/main.yml +++ /dev/null @@ -1,135 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Bruno Calogero <brunocalogero@hotmail.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - -- name: Ensuring Interface Policy Leaf profile exists for kick off - aci_interface_policy_leaf_profile: &aci_interface_policy_leaf_profile_present - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - state: present - leaf_interface_profile: leafintprftest - register: leaf_profile_present - -- name: Ensure Interface Access Port Selector exists for kick of - aci_access_port_to_interface_policy_leaf_profile: &aci_access_port_to_interface_policy_leaf_profile_present - <<: *aci_interface_policy_leaf_profile_present - access_port_selector: anstest_accessportselector - -# TODO: Ensure that leaf Policy Group Exists (module missing) (infra:AccPortGrp) - -- name: Bind an Access Port Block to an Interface Access Port Selector - check mode works - aci_access_port_block_to_access_port: &aci_access_port_block_to_access_port_present - <<: *aci_access_port_to_interface_policy_leaf_profile_present - leaf_port_blk: anstest_leafportblkname - leaf_port_blk_description: anstest_leafportblkdesc - fromPort: 13 - toPort: 16 - check_mode: yes - register: accessportblock_to_accessport_check_mode_present - -- name: Bind an Access Port Block to an Interface Access Port Selector - creation works - aci_access_port_block_to_access_port: - <<: *aci_access_port_block_to_access_port_present - register: accessportblock_to_accessport_present - -- name: Bind an Access Port Block to an Interface Access Port Selector - idempotency works - aci_access_port_block_to_access_port: - <<: *aci_access_port_block_to_access_port_present - register: accessportblock_to_accessport_idempotent - -- name: Bind an Access Port Block to an Interface Access Port Selector - update works - aci_access_port_block_to_access_port: - <<: *aci_access_port_block_to_access_port_present - toPort: 15 - register: accessportblock_to_accessport_update - -# TODO: also test for errors -- name: present assertions - assert: - that: - - accessportblock_to_accessport_check_mode_present is changed - - accessportblock_to_accessport_present is changed - - accessportblock_to_accessport_present.previous == [] - - 'accessportblock_to_accessport_present.sent == {"infraPortBlk": {"attributes": {"descr": "anstest_leafportblkdesc", "name": "anstest_leafportblkname", "fromPort": "13", "toPort": "16"}}}' - - accessportblock_to_accessport_idempotent is not changed - - accessportblock_to_accessport_idempotent.sent == {} - - accessportblock_to_accessport_update is changed - - 'accessportblock_to_accessport_update.sent == {"infraPortBlk": {"attributes": {"toPort": "15"}}}' - - -- name: Query Specific port block and access_port_selector binding - aci_access_port_block_to_access_port: - <<: *aci_access_port_block_to_access_port_present - state: query - register: binding_query - -- name: present assertions - assert: - that: - - binding_query is not changed - - binding_query.current | length >= 1 - - '"api/mo/uni/infra/accportprof-leafintprftest/hports-anstest_accessportselector-typ-range/portblk-anstest_leafportblkname.json" in binding_query.url' - -- name: Remove binding of Access Port Block and Interface Access Port Selector - check mode - aci_access_port_block_to_access_port: &aci_access_port_block_to_access_port_absent - <<: *aci_access_port_block_to_access_port_present - state: absent - check_mode: yes - register: accessportblock_to_accessport_check_mode_absent - -- name: Remove binding of Access Port Block and Interface Access Port Selector - delete works - aci_access_port_block_to_access_port: - <<: *aci_access_port_block_to_access_port_absent - register: accessportblock_to_accessport_absent - -- name: Remove binding of Access Port Block and Interface Access Port Selector - idempotency works - aci_access_port_block_to_access_port: - <<: *aci_access_port_block_to_access_port_absent - register: accessportblock_to_accessport_absent_idempotent - -- name: Remove binding of Access Port Block and Interface Access Port Selector - check mode - aci_access_port_block_to_access_port: - <<: *aci_access_port_to_interface_policy_leaf_profile_present - #leaf_port_blk: anstest_leafportblkname - state: absent - ignore_errors: yes - register: accessportblock_to_accessport_absent_missing_param - -- name: absent assertions - assert: - that: - - accessportblock_to_accessport_check_mode_absent is changed - - accessportblock_to_accessport_check_mode_absent.previous != [] - - accessportblock_to_accessport_absent is changed - - accessportblock_to_accessport_absent.previous == accessportblock_to_accessport_check_mode_absent.previous - - accessportblock_to_accessport_absent_idempotent is not changed - - accessportblock_to_accessport_absent_idempotent.previous == [] - - accessportblock_to_accessport_absent_missing_param is failed - - 'accessportblock_to_accessport_absent_missing_param.msg == "state is absent but all of the following are missing: leaf_port_blk"' - - -- name: Remove binding of Access Port Block and Interface Access Port Selector - Clean up - aci_access_port_block_to_access_port: - <<: *aci_access_port_block_to_access_port_present - state: absent - -- name: Remove Interface Access Port Selector - Cleanup - aci_access_port_to_interface_policy_leaf_profile: - <<: *aci_access_port_to_interface_policy_leaf_profile_present - state: absent - -- name: Remove Interface policy leaf profile - Cleanup - aci_interface_policy_leaf_profile: - <<: *aci_interface_policy_leaf_profile_present - state: absent diff --git a/test/integration/targets/aci_access_port_to_interface_policy_leaf_profile/aliases b/test/integration/targets/aci_access_port_to_interface_policy_leaf_profile/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_access_port_to_interface_policy_leaf_profile/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_access_port_to_interface_policy_leaf_profile/tasks/main.yml b/test/integration/targets/aci_access_port_to_interface_policy_leaf_profile/tasks/main.yml deleted file mode 100644 index c21c71282b..0000000000 --- a/test/integration/targets/aci_access_port_to_interface_policy_leaf_profile/tasks/main.yml +++ /dev/null @@ -1,135 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Bruno Calogero <brunocalogero@hotmail.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - -- name: Ensuring bindings do not already exist - aci_access_port_to_interface_policy_leaf_profile: - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - leaf_interface_profile: leafintprftest - access_port_selector: anstest_accessportselector - state: absent - -- name: Ensuring Interface Policy Leaf profile exists for kick off - aci_interface_policy_leaf_profile: &aci_interface_policy_leaf_profile_present - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - state: present - leaf_interface_profile: leafintprftest - register: leaf_profile_present - -# TODO: Ensure that leaf Policy Group Exists (module missing) (infra:AccPortGrp) - -- name: Bind an Interface Access Port Selector to an Interface Policy Leaf Profile with a Policy Group - check mode works - aci_access_port_to_interface_policy_leaf_profile: &aci_access_port_to_interface_policy_leaf_profile_present - <<: *aci_interface_policy_leaf_profile_present - access_port_selector: anstest_accessportselector - check_mode: yes - register: accessport_to_intf_check_mode_present - -- name: Bind an Interface Access Port Selector to an Interface Policy Leaf Profile with a Policy Group - creation works - aci_access_port_to_interface_policy_leaf_profile: - <<: *aci_access_port_to_interface_policy_leaf_profile_present - register: accessport_to_intf_present - -- name: Bind an Interface Access Port Selector to an Interface Policy Leaf Profile with a Policy Group - idempotency works - aci_access_port_to_interface_policy_leaf_profile: - <<: *aci_access_port_to_interface_policy_leaf_profile_present - register: accessport_to_intf_idempotent - -- name: Bind an Interface Access Port Selector to an Interface Policy Leaf Profile with a Policy Group - update works - aci_access_port_to_interface_policy_leaf_profile: - <<: *aci_access_port_to_interface_policy_leaf_profile_present - policy_group: anstest_policygroupname - register: accessport_to_intf_update - -# TODO: also test for errors -- name: present assertions - assert: - that: - - accessport_to_intf_check_mode_present is changed - - accessport_to_intf_present is changed - - accessport_to_intf_present.previous == [] - - 'accessport_to_intf_present.sent == {"infraHPortS": {"attributes": {"name": "anstest_accessportselector"}}}' - - accessport_to_intf_idempotent is not changed - - accessport_to_intf_idempotent.sent == {} - - accessport_to_intf_update is changed - - 'accessport_to_intf_update.sent == {"infraHPortS": {"attributes": {},"children": [{"infraRsAccBaseGrp": {"attributes": {"tDn": "uni/infra/funcprof/accportgrp-anstest_policygroupname"}}}]}}' - -- name: Query Specific access_port_selector and leaf_interface_profile binding - aci_access_port_to_interface_policy_leaf_profile: - <<: *aci_interface_policy_leaf_profile_present - access_port_selector: anstest_accessportselector # "{{ fake_var | default(omit) }}" ? - state: query - register: binding_query - -- name: present assertions - assert: - that: - - binding_query is not changed - - binding_query.current | length >= 1 - - '"api/mo/uni/infra/accportprof-leafintprftest/hports-anstest_accessportselector-typ-range.json" in binding_query.url' - -- name: Remove binding of interface access port selector and Interface Policy Leaf Profile - check mode - aci_access_port_to_interface_policy_leaf_profile: &aci_access_port_to_interface_policy_leaf_profile_absent - <<: *aci_interface_policy_leaf_profile_present - access_port_selector: anstest_accessportselector - state: absent - check_mode: yes - register: accessport_to_intf_check_mode_absent - -- name: Remove binding of interface access port selector and Interface Policy Leaf Profile - delete works - aci_access_port_to_interface_policy_leaf_profile: - <<: *aci_access_port_to_interface_policy_leaf_profile_absent - register: accessport_to_intf_absent - -- name: Remove binding of interface access port selector and Interface Policy Leaf Profile - idempotency works - aci_access_port_to_interface_policy_leaf_profile: - <<: *aci_access_port_to_interface_policy_leaf_profile_absent - register: accessport_to_intf_absent_idempotent - -- name: Remove binding of interface access port selector and Interface Policy Leaf Profile - check mode - aci_access_port_to_interface_policy_leaf_profile: - <<: *aci_interface_policy_leaf_profile_present - #access_port_selector: anstest_accessportselector - state: absent - ignore_errors: yes - register: accessport_to_intf_absent_missing_param - -- name: absent assertions - assert: - that: - - accessport_to_intf_check_mode_absent is changed - - accessport_to_intf_check_mode_absent.previous != [] - - accessport_to_intf_absent is changed - - accessport_to_intf_absent.previous == accessport_to_intf_check_mode_absent.previous - - accessport_to_intf_absent_idempotent is not changed - - accessport_to_intf_absent_idempotent.previous == [] - - accessport_to_intf_absent_missing_param is failed - - 'accessport_to_intf_absent_missing_param.msg == "state is absent but all of the following are missing: access_port_selector"' - - -- name: Remove an interface access port selector associated with an Interface Policy Leaf Profile - Clean up - aci_access_port_to_interface_policy_leaf_profile: - <<: *aci_access_port_to_interface_policy_leaf_profile_absent - state: absent - -- name: Remove Interface policy leaf profile - Cleanup - aci_interface_policy_leaf_profile: - <<: *aci_interface_policy_leaf_profile_present - state: absent diff --git a/test/integration/targets/aci_access_sub_port_block_to_access_port/aliases b/test/integration/targets/aci_access_sub_port_block_to_access_port/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_access_sub_port_block_to_access_port/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_access_sub_port_block_to_access_port/tasks/main.yml b/test/integration/targets/aci_access_sub_port_block_to_access_port/tasks/main.yml deleted file mode 100644 index c8e20fb5fa..0000000000 --- a/test/integration/targets/aci_access_sub_port_block_to_access_port/tasks/main.yml +++ /dev/null @@ -1,137 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Bruno Calogero <brunocalogero@hotmail.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - -- name: Ensuring Interface Policy Leaf profile exists for kick off - aci_interface_policy_leaf_profile: &aci_interface_policy_leaf_profile_present - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - state: present - leaf_interface_profile: leafintprftest - register: leaf_profile_present - -- name: Ensure Interface Access Port Selector exists for kick of - aci_access_port_to_interface_policy_leaf_profile: &aci_access_port_to_interface_policy_leaf_profile_present - <<: *aci_interface_policy_leaf_profile_present - access_port_selector: anstest_accessportselector - -# TODO: Ensure that leaf Policy Group Exists (module missing) (infra:AccPortGrp) - -- name: Bind an Access Sub Port Block to an Interface Access Port Selector - check mode works - aci_access_sub_port_block_to_access_port: &aci_access_sub_port_block_to_access_port_present - <<: *aci_access_port_to_interface_policy_leaf_profile_present - leaf_port_blk: anstest_leafportblkname - leaf_port_blk_description: anstest_leafportblkdesc - fromPort: 13 - toPort: 13 - fromSubPort: 1 - toSubPort: 3 - check_mode: yes - register: accesssubportblock_to_accessport_check_mode_present - -- name: Bind an Access Sub Port Block to an Interface Access Port Selector - creation works - aci_access_sub_port_block_to_access_port: - <<: *aci_access_sub_port_block_to_access_port_present - register: accesssubportblock_to_accessport_present - -- name: Bind an Access Sub Port Block to an Interface Access Port Selector - idempotency works - aci_access_sub_port_block_to_access_port: - <<: *aci_access_sub_port_block_to_access_port_present - register: accesssubportblock_to_accessport_idempotent - -- name: Bind an Access Sub Port Block to an Interface Access Port Selector - update works - aci_access_sub_port_block_to_access_port: - <<: *aci_access_sub_port_block_to_access_port_present - toSubPort: 2 - register: accesssubportblock_to_accessport_update - -# TODO: also test for errors -- name: present assertions - assert: - that: - - accesssubportblock_to_accessport_check_mode_present is changed - - accesssubportblock_to_accessport_present is changed - - accesssubportblock_to_accessport_present.previous == [] - - 'accesssubportblock_to_accessport_present.sent == {"infraSubPortBlk": {"attributes": {"descr": "anstest_leafportblkdesc", "name": "anstest_leafportblkname", "fromPort": "13", "toPort": "13", "fromSubPort": "1", "toSubPort": "3"}}}' - - accesssubportblock_to_accessport_idempotent is not changed - - accesssubportblock_to_accessport_idempotent.sent == {} - - accesssubportblock_to_accessport_update is changed - - 'accesssubportblock_to_accessport_update.sent == {"infraSubPortBlk": {"attributes": {"toSubPort": "2"}}}' - - -- name: Query Specific sub port block and access_port_selector binding - aci_access_sub_port_block_to_access_port: - <<: *aci_access_sub_port_block_to_access_port_present - state: query - register: binding_query - -- name: present assertions - assert: - that: - - binding_query is not changed - - binding_query.current | length >= 1 - - '"api/mo/uni/infra/accportprof-leafintprftest/hports-anstest_accessportselector-typ-range/subportblk-anstest_leafportblkname.json" in binding_query.url' - -- name: Remove binding of Access Sub Port Block and Interface Access Port Selector - check mode - aci_access_sub_port_block_to_access_port: &aci_access_sub_port_block_to_access_port_absent - <<: *aci_access_sub_port_block_to_access_port_present - state: absent - check_mode: yes - register: accesssubportblock_to_accessport_check_mode_absent - -- name: Remove binding of Access Sub Port Block and Interface Access Port Selector - delete works - aci_access_sub_port_block_to_access_port: - <<: *aci_access_sub_port_block_to_access_port_absent - register: accesssubportblock_to_accessport_absent - -- name: Remove binding of Access Sub Port Block and Interface Access Port Selector - idempotency works - aci_access_sub_port_block_to_access_port: - <<: *aci_access_sub_port_block_to_access_port_absent - register: accesssubportblock_to_accessport_absent_idempotent - -- name: Remove binding of Access Sub Port Block and Interface Access Port Selector - check mode - aci_access_sub_port_block_to_access_port: - <<: *aci_access_port_to_interface_policy_leaf_profile_present - #leaf_port_blk: anstest_leafportblkname - state: absent - ignore_errors: yes - register: accesssubportblock_to_accessport_absent_missing_param - -- name: absent assertions - assert: - that: - - accesssubportblock_to_accessport_check_mode_absent is changed - - accesssubportblock_to_accessport_check_mode_absent.previous != [] - - accesssubportblock_to_accessport_absent is changed - - accesssubportblock_to_accessport_absent.previous == accesssubportblock_to_accessport_check_mode_absent.previous - - accesssubportblock_to_accessport_absent_idempotent is not changed - - accesssubportblock_to_accessport_absent_idempotent.previous == [] - - accesssubportblock_to_accessport_absent_missing_param is failed - - 'accesssubportblock_to_accessport_absent_missing_param.msg == "state is absent but all of the following are missing: leaf_port_blk"' - - -- name: Remove binding of Access Sub Port Block and Interface Access Port Selector - Clean up - aci_access_sub_port_block_to_access_port: - <<: *aci_access_sub_port_block_to_access_port_present - state: absent - -- name: Remove Interface Access Port Selector - Cleanup - aci_access_port_to_interface_policy_leaf_profile: - <<: *aci_access_port_to_interface_policy_leaf_profile_present - state: absent - -- name: Remove Interface policy leaf profile - Cleanup - aci_interface_policy_leaf_profile: - <<: *aci_interface_policy_leaf_profile_present - state: absent diff --git a/test/integration/targets/aci_aep/aliases b/test/integration/targets/aci_aep/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_aep/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_aep/tasks/main.yml b/test/integration/targets/aci_aep/tasks/main.yml deleted file mode 100644 index d80ea57541..0000000000 --- a/test/integration/targets/aci_aep/tasks/main.yml +++ /dev/null @@ -1,272 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - - -# CLEAN ENVIRONMENT -- name: Remove AEP - aci_aep: &aep_absent - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - aep: ansible_test - state: absent - - -# ADD AEP -- name: Add AEP (check_mode) - aci_aep: &aep_present - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - aep: ansible_test - state: present - check_mode: yes - register: cm_add_aep - -- name: Add AEP (normal mode) - aci_aep: *aep_present - register: nm_add_aep - -- name: Verify add_aep - assert: - that: - - cm_add_aep is changed - - nm_add_aep is changed - - nm_add_aep.previous == nm_add_aep.previous == cm_add_aep.current == [] - - 'nm_add_aep.current == [{"infraAttEntityP": {"attributes": {"descr": "", "dn": "uni/infra/attentp-ansible_test", "name": "ansible_test", "nameAlias": "", "ownerKey": "", "ownerTag": ""}}}]' - - 'cm_add_aep.proposed == nm_add_aep.proposed == cm_add_aep.sent == nm_add_aep.sent == {"infraAttEntityP": {"attributes": {"name": "ansible_test"}}}' - -- name: Add AEP again (check_mode) - aci_aep: *aep_present - check_mode: yes - register: cm_add_aep_again - -- name: Add AEP again (normal mode) - aci_aep: *aep_present - register: nm_add_aep_again - -- name: Verify add_aep_again - assert: - that: - - cm_add_aep_again is not changed - - nm_add_aep_again is not changed - - 'nm_add_aep_again.previous == nm_add_aep_again.previous == cm_add_aep_again.current == nm_add_aep_again.current == [{"infraAttEntityP": {"attributes": {"descr": "", "dn": "uni/infra/attentp-ansible_test", "name": "ansible_test", "nameAlias": "", "ownerKey": "", "ownerTag": ""}}}]' - - 'cm_add_aep_again.proposed == nm_add_aep_again.proposed == {"infraAttEntityP": {"attributes": {"name": "ansible_test"}}}' - - cm_add_aep_again.sent == nm_add_aep_again.sent == {} - - -# CHANGE AEP -- name: Change description of AEP (check_mode) - aci_aep: - <<: *aep_present - description: Ansible test AEP - check_mode: yes - register: cm_add_aep_descr - -- name: Change description of AEP (normal mode) - aci_aep: - <<: *aep_present - description: Ansible test AEP - register: nm_add_aep_descr - -- name: Verify add_aep_descr - assert: - that: - - cm_add_aep_descr is changed - - nm_add_aep_descr is changed - - 'cm_add_aep_descr.proposed == nm_add_aep_descr.proposed == {"infraAttEntityP": {"attributes": {"descr": "Ansible test AEP", "name": "ansible_test"}}}' - - 'cm_add_aep_descr.sent == nm_add_aep_descr.sent == {"infraAttEntityP": {"attributes": {"descr": "Ansible test AEP"}}}' - - 'cm_add_aep_descr.previous == nm_add_aep_descr.previous == cm_add_aep_descr.current == [{"infraAttEntityP": {"attributes": {"descr": "", "dn": "uni/infra/attentp-ansible_test", "name": "ansible_test", "nameAlias": "", "ownerKey": "", "ownerTag": ""}}}]' - - 'nm_add_aep_descr.current == [{"infraAttEntityP": {"attributes": {"descr": "Ansible test AEP", "dn": "uni/infra/attentp-ansible_test", "name": "ansible_test", "nameAlias": "", "ownerKey": "", "ownerTag": ""}}}]' - -- name: Change description of AEP again (check_mode) - aci_aep: - <<: *aep_present - description: Ansible test AEP - check_mode: yes - register: cm_add_aep_descr_again - -- name: Change description of AEP again (normal mode) - aci_aep: - <<: *aep_present - description: Ansible test AEP - register: nm_add_aep_descr_again - -- name: Verify add_aep_descr_again - assert: - that: - - cm_add_aep_descr_again is not changed - - nm_add_aep_descr_again is not changed - - 'cm_add_aep_descr_again.proposed == nm_add_aep_descr_again.proposed == {"infraAttEntityP": {"attributes": {"descr": "Ansible test AEP", "name": "ansible_test"}}}' - - 'cm_add_aep_descr_again.sent == nm_add_aep_descr_again.sent == {}' - - 'cm_add_aep_descr_again.previous == nm_add_aep_descr_again.previous == cm_add_aep_descr_again.current == nm_add_aep_descr_again.current == [{"infraAttEntityP": {"attributes": {"descr": "Ansible test AEP", "dn": "uni/infra/attentp-ansible_test", "name": "ansible_test", "nameAlias": "", "ownerKey": "", "ownerTag": ""}}}]' - - -# ADD AEP AGAIN -- name: Add AEP again with no description (check_mode) - aci_aep: *aep_present - check_mode: yes - register: cm_add_aep_again_no_descr - -- name: Add AEP again with no description (normal mode) - aci_aep: *aep_present - register: nm_add_aep_again_no_descr - -- name: Verify add_aep_again_no_descr - assert: - that: - - cm_add_aep_again_no_descr is not changed - - nm_add_aep_again_no_descr is not changed - - 'cm_add_aep_again_no_descr.proposed == nm_add_aep_again_no_descr.proposed == {"infraAttEntityP": {"attributes": {"name": "ansible_test"}}}' - - cm_add_aep_again_no_descr.sent == nm_add_aep_again_no_descr.sent == {} - - 'cm_add_aep_again_no_descr.previous == nm_add_aep_again_no_descr.previous == cm_add_aep_again_no_descr.current == nm_add_aep_again_no_descr.current == [{"infraAttEntityP": {"attributes": {"descr": "Ansible test AEP", "dn": "uni/infra/attentp-ansible_test", "name": "ansible_test", "nameAlias": "", "ownerKey": "", "ownerTag": ""}}}]' - - -# QUERY ALL AEPS -- name: Query all AEPs (check_mode) - aci_aep: &aep_query - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - state: query - check_mode: yes - register: cm_query_all_aeps - -- name: Query all AEPs (normal mode) - aci_aep: *aep_query - register: nm_query_all_aeps - -- name: Verify query_all_aeps - assert: - that: - - cm_query_all_aeps is not changed - - nm_query_all_aeps is not changed - - cm_query_all_aeps == nm_query_all_aeps - - nm_query_all_aeps.current|length >= 1 - - -# QUERY A AEP -- name: Query our AEP - aci_aep: - <<: *aep_query - aep: ansible_test - check_mode: yes - register: cm_query_aep - -- name: Query our AEP - aci_aep: - <<: *aep_query - aep: ansible_test - register: nm_query_aep - -- name: Verify query_aep - assert: - that: - - cm_query_aep is not changed - - nm_query_aep is not changed - - cm_query_aep == nm_query_aep - - nm_query_aep.current.0.infraAttEntityP.attributes.descr == "Ansible test AEP" - - nm_query_aep.current.0.infraAttEntityP.attributes.dn == "uni/infra/attentp-ansible_test" - - nm_query_aep.current.0.infraAttEntityP.attributes.name == "ansible_test" - - -# REMOVE AEP -- name: Remove AEP (check_mode) - aci_aep: *aep_absent - check_mode: yes - register: cm_remove_aep - -- name: Remove AEP (normal mode) - aci_aep: *aep_absent - register: nm_remove_aep - -- name: Verify remove_aep - assert: - that: - - cm_remove_aep is changed - - nm_remove_aep is changed - - cm_remove_aep.proposed == nm_remove_aep.proposed == {} - - cm_remove_aep.sent == nm_remove_aep.sent == {} - - 'cm_remove_aep.previous == nm_remove_aep.previous == cm_remove_aep.current == [{"infraAttEntityP": {"attributes": {"descr": "Ansible test AEP", "dn": "uni/infra/attentp-ansible_test", "name": "ansible_test", "nameAlias": "", "ownerKey": "", "ownerTag": ""}}}]' - - nm_remove_aep.current == [] - -- name: Remove AEP again (check_mode) - aci_aep: *aep_absent - check_mode: yes - register: cm_remove_aep_again - -- name: Remove AEP again (normal mode) - aci_aep: *aep_absent - register: nm_remove_aep_again - -- name: Verify remove_aep_again - assert: - that: - - cm_remove_aep_again is not changed - - nm_remove_aep_again is not changed - - cm_remove_aep_again.proposed == nm_remove_aep_again.proposed == {} - - cm_remove_aep_again.sent == nm_remove_aep_again.sent == {} - - cm_remove_aep_again.previous == nm_remove_aep_again.previous == cm_remove_aep_again.current == nm_remove_aep_again.current == [] - - -# QUERY NON-EXISTING AEP -- name: Query non-existing AEP (check_mode) - aci_aep: - <<: *aep_query - aep: ansible_test - check_mode: yes - register: cm_query_non_aep - -- name: Query non-existing AEP (normal mode) - aci_aep: - <<: *aep_query - aep: ansible_test - register: nm_query_non_aep - -- name: Verify query_non_aep - assert: - that: - - cm_query_non_aep is not changed - - nm_query_non_aep is not changed - - cm_query_non_aep == nm_query_non_aep - - cm_query_non_aep.current == nm_query_non_aep.current == [] - - -# PROVOKE ERRORS -- name: Error when required parameter is missing - aci_aep: - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - state: present - ignore_errors: yes - register: error_on_missing_required_param - -- name: Verify error_on_missing_required_param - assert: - that: - - error_on_missing_required_param is failed - - 'error_on_missing_required_param.msg == "state is present but all of the following are missing: aep"' diff --git a/test/integration/targets/aci_aep_to_domain/aliases b/test/integration/targets/aci_aep_to_domain/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_aep_to_domain/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_aep_to_domain/tasks/main.yml b/test/integration/targets/aci_aep_to_domain/tasks/main.yml deleted file mode 100644 index 5aafc367cf..0000000000 --- a/test/integration/targets/aci_aep_to_domain/tasks/main.yml +++ /dev/null @@ -1,210 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - - -# CLEAN ENVIRONMENT -- name: Remove AEP to domain binding - aci_aep_to_domain: &binding_absent - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - aep: test_aep - domain: phys_dom - domain_type: phys - state: absent - -- name: Create AEP - aci_aep: - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - aep: test_aep - description: Test AEP - state: present - -- name: Create physical domain - aci_domain: - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - domain: phys_dom - domain_type: phys - state: present - - -# ADD BINDING -- name: Add AEP to domain binding (check_mode) - aci_aep_to_domain: &binding_present - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - aep: test_aep - domain: phys_dom - domain_type: phys - state: present - check_mode: yes - register: cm_add_binding - -- name: Add AEP to domain binding (normal mode) - aci_aep_to_domain: *binding_present - register: nm_add_binding - -- name: Verify add_binding - assert: - that: - - cm_add_binding is changed - - nm_add_binding is changed - - 'cm_add_binding.sent == nm_add_binding.sent == {"infraRsDomP": {"attributes": {"tDn": "uni/phys-phys_dom"}}}' - - 'cm_add_binding.proposed == nm_add_binding.proposed == {"infraRsDomP": {"attributes": {"tDn": "uni/phys-phys_dom"}}}' - - cm_add_binding.current == cm_add_binding.previous == nm_add_binding.previous == [] - - 'nm_add_binding.current == [{"infraRsDomP": {"attributes": {"dn": "uni/infra/attentp-test_aep/rsdomP-[uni/phys-phys_dom]", "tDn": "uni/phys-phys_dom"}}}]' - -- name: Add AEP to domain binding again (check_mode) - aci_aep_to_domain: *binding_present - check_mode: yes - register: cm_add_binding_again - -- name: Add AEP to domain binding again (normal mode) - aci_aep_to_domain: *binding_present - register: nm_add_binding_again - -- name: Verify add_binding_again - assert: - that: - - cm_add_binding_again is not changed - - nm_add_binding_again is not changed - - -# QUERY ALL BINDINGS -- name: Query all AEP to domain bindings (check_mode) - aci_aep_to_domain: &binding_query - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - state: query - check_mode: yes - register: cm_query_all_bindings - -- name: Query all AEP to domain bindings (normal mode) - aci_aep_to_domain: *binding_query - register: nm_query_all_bindings - -- name: Verify query_all_bindings - assert: - that: - - cm_query_all_bindings is not changed - - nm_query_all_bindings is not changed - - cm_query_all_bindings == nm_query_all_bindings - - nm_query_all_bindings.current|length >= 1 - - -# QUERY A BINDING -- name: Query our AEP to domain binding (check_mode) - aci_aep_to_domain: - <<: *binding_query - aep: test_aep - domain: phys_dom - domain_type: phys - check_mode: yes - register: cm_query_binding - -- name: Query our AEP to domain binding (normal mode) - aci_aep_to_domain: - <<: *binding_query - aep: test_aep - domain: phys_dom - domain_type: phys - register: nm_query_binding - -- name: Verify query_binding - assert: - that: - - cm_query_binding is not changed - - nm_query_binding is not changed - - cm_query_binding == nm_query_binding - - nm_query_binding.current.0.infraRsDomP.attributes.dn == 'uni/infra/attentp-test_aep/rsdomP-[uni/phys-phys_dom]' - - nm_query_binding.current.0.infraRsDomP.attributes.tCl == 'physDomP' - - nm_query_binding.current.0.infraRsDomP.attributes.tDn == 'uni/phys-phys_dom' - - -# REMOVE BINDING -- name: Remove AEP to domain binding (check_mode) - aci_aep_to_domain: *binding_absent - check_mode: yes - register: cm_remove_binding - -- name: Remove AEP to domain binding (normal mode) - aci_aep_to_domain: *binding_absent - register: nm_remove_binding - -- name: Verify remove_binding - assert: - that: - - cm_remove_binding is changed - - nm_remove_binding is changed - - 'cm_remove_binding.current == cm_remove_binding.previous == nm_remove_binding.previous == [{"infraRsDomP": {"attributes": {"dn": "uni/infra/attentp-test_aep/rsdomP-[uni/phys-phys_dom]", "tDn": "uni/phys-phys_dom"}}}]' - - nm_remove_binding.current == [] - -- name: Remove AEP to domain binding again (check_mode) - aci_aep_to_domain: *binding_absent - check_mode: yes - register: cm_remove_binding_again - -- name: Remove AEP to domain binding again (normal mode) - aci_aep_to_domain: *binding_absent - register: nm_remove_binding_again - -- name: Verify remove_binding_again - assert: - that: - - cm_remove_binding_again is not changed - - nm_remove_binding_again is not changed - - -# QUERY NON-EXISTING BINDING -- name: Query non-existing AEP to domain binding (check_mode) - aci_aep_to_domain: - <<: *binding_query - aep: test_aep - domain: phys_dom - domain_type: phys - check_mode: yes - register: cm_query_non_binding - -- name: Query non-existing AEP to domain binding (normal mode) - aci_aep_to_domain: - <<: *binding_query - aep: test_aep - domain: phys_dom - domain_type: phys - register: nm_query_non_binding - -- name: Verify query_non_binding - assert: - that: - - cm_query_non_binding is not changed - - nm_query_non_binding is not changed - - cm_query_non_binding == nm_query_non_binding - - nm_query_non_binding.current == [] diff --git a/test/integration/targets/aci_ap/aliases b/test/integration/targets/aci_ap/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_ap/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_ap/tasks/main.yml b/test/integration/targets/aci_ap/tasks/main.yml deleted file mode 100644 index a31151c372..0000000000 --- a/test/integration/targets/aci_ap/tasks/main.yml +++ /dev/null @@ -1,173 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Jacob McGill (@jmcgill298) - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - -- name: ensure tenant exists for tests to kick off - aci_tenant: &aci_tenant_present - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - state: present - tenant: anstest - register: tenant_present - -- name: ensure ap does not exist initially - aci_ap: - <<: *aci_tenant_present - ap: anstest - state: absent - -- name: create ap - check mode works - aci_ap: &aci_ap_present - <<: *aci_tenant_present - ap: anstest - description: Ansible Test - check_mode: yes - register: ap_present_check_mode - -- name: create ap - creation works - aci_ap: - <<: *aci_ap_present - register: ap_present - -- name: create ap - extra for query - aci_ap: - <<: *aci_tenant_present - ap: anstest2 - -- name: create ap - idempotency works - aci_ap: - <<: *aci_ap_present - register: ap_present_idempotent - -- name: update ap - update works - aci_ap: - <<: *aci_ap_present - description: Ansible Test Update - register: ap_present_update - -- name: create ap - creation works - aci_ap: - <<: *aci_tenant_present - ignore_errors: yes - register: ap_present_missing_param - -- name: present asserts - assert: - that: - - ap_present_check_mode is changed - - ap_present is changed - - ap_present.previous == [] - - ap_present.sent == ap_present_check_mode.sent - - 'ap_present.sent == {"fvAp": {"attributes": {"descr": "Ansible Test", "name": "anstest"}}}' - - ap_present_idempotent is not changed - - ap_present_idempotent.previous != [] - - ap_present_idempotent.sent == {} - - ap_present_update is changed - - 'ap_present_update.sent.fvAp.attributes == {"descr": "Ansible Test Update"}' - - ap_present_missing_param is failed - - 'ap_present_missing_param.msg == "state is present but all of the following are missing: ap"' - -- name: get ap - query specific ap - aci_ap: &aci_ap_query - <<: *aci_ap_present - state: query - register: query_ap - -- name: get all ap for tenant - query tenant aps - aci_ap: - <<: *aci_ap_query - ap: "{{ fakevar | default(omit) }}" - register: query_ap_tenant - -- name: get all ap by name - query ap name - aci_ap: - <<: *aci_ap_query - tenant: "{{ fakevar | default(omit) }}" - register: query_ap_ap - -- name: get all aps - query general - aci_ap: - <<: *aci_ap_query - tenant: "{{ fakevar | default(omit) }}" - ap: "{{ fakevar | default(omit) }}" - register: query_all - -- name: query assertions - assert: - that: - - query_ap is not changed - - query_ap.current | length == 1 - - query_ap.current.0.fvAp.attributes.name == "anstest" - - '"tn-anstest/ap-anstest.json" in query_ap.url' - - query_ap_tenant is not changed - - query_ap_tenant.current | length == 1 - - query_ap_tenant.current.0.fvTenant.children | length == 2 - - '"rsp-subtree-class=fvAp" in query_ap_tenant.filter_string' - - '"tn-anstest.json" in query_ap_tenant.url' - - query_ap_ap is not changed - - query_ap_ap.current != [] - - query_ap_ap.current.0.fvAp is defined - - '"query-target-filter=eq(fvAp.name, \"anstest\")" in query_ap_ap.filter_string' - - '"class/fvAp.json" in query_ap_ap.url' - - query_all is not changed - - query_all.current | length > 1 - - '"class/fvAp.json" in query_all.url' - -- name: delete ap - check_mode works - aci_ap: &aci_ap_absent - <<: *aci_ap_present - state: absent - check_mode: yes - register: ap_delete_check_mode - -- name: delete ap - delete works - aci_ap: - <<: *aci_ap_absent - register: ap_delete - -- name: delete ap - delete idempotency works - aci_ap: - <<: *aci_ap_absent - register: ap_delete_idempotent - -- name: delete ap - missing param error - aci_ap: - <<: *aci_ap_absent - tenant: "{{ fakevar | default(omit) }}" - ignore_errors: yes - register: ap_delete_missing_param - -- name: delete ap remove ap used for query - aci_ap: - <<: *aci_ap_absent - ap: anstest2 - -- name: absent assertions - assert: - that: - - ap_delete_check_mode is changed - - ap_delete_check_mode.previous != [] - - '"tn-anstest/ap-anstest.json" in ap_delete_check_mode.url' - - ap_delete is changed - - ap_delete.previous == ap_delete_check_mode.previous - - ap_delete_idempotent is not changed - - ap_delete_idempotent.previous == [] - - ap_delete_missing_param is failed - - 'ap_delete_missing_param.msg == "state is absent but all of the following are missing: tenant"' - -- name: delete tenant - cleanup before ending tests - aci_tenant: - <<: *aci_tenant_present - state: absent - when: tenant_present is changed diff --git a/test/integration/targets/aci_bd/aliases b/test/integration/targets/aci_bd/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_bd/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_bd/tasks/main.yml b/test/integration/targets/aci_bd/tasks/main.yml deleted file mode 100644 index 3273fc1034..0000000000 --- a/test/integration/targets/aci_bd/tasks/main.yml +++ /dev/null @@ -1,205 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Jacob McGill (@jmcgill298) - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - -- name: ensure tenant exists for tests to kick off - aci_tenant: &aci_tenant_present - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - state: present - tenant: anstest - register: tenant_present - -- name: ensure vrf exists for tests to kick off - aci_vrf: &aci_vrf_present - <<: *aci_tenant_present - vrf: anstest - register: vrf_present - -- name: ensure bd anstest does not exist - aci_bd: - <<: *aci_tenant_present - bd: anstest - state: absent - -- name: ensure bd anstest2 does not exist - aci_bd: - <<: *aci_tenant_present - bd: anstest2 - state: absent - -- name: create bd - check mode works - aci_bd: &aci_bd_present - <<: *aci_tenant_present - bd: anstest - description: Ansible Test - check_mode: yes - register: bd_present_check_mode - -- name: create bd - creation works - aci_bd: - <<: *aci_bd_present - register: bd_present - -- name: create bd again - idempotency works - aci_bd: - <<: *aci_bd_present - register: bd_present_idempotent - -- name: update bd - update works - aci_bd: - <<: *aci_bd_present - vrf: anstest - description: Ansible Test Update - register: bd_update - -- name: create another bd - check more params - aci_bd: - <<: *aci_bd_present - bd: anstest2 - ip_learning: "no" - l2_unknown_unicast: flood - l3_unknown_multicast: opt-flood - multi_dest: drop - enable_routing: "no" - arp_flooding: "yes" - register: bd_present_2 - -- name: create bd without all necessary params - failure message works - aci_bd: - <<: *aci_bd_present - tenant: "{{ fake_var | default(omit) }}" - ignore_errors: yes - register: bd_present_missing_param - -- name: present asserts - assert: - that: - - bd_present_check_mode is changed - - 'bd_present_check_mode.sent == {"fvBD": {"attributes": {"descr": "Ansible Test", "name": "anstest"}}}' - - bd_present is changed - - bd_present.sent == bd_present_check_mode.sent - - bd_present.previous == [] - - bd_present_idempotent is not changed - - bd_present_idempotent.previous != [] - - bd_update is changed - - bd_update.previous != [] - - bd_update.sent != bd_update.proposed - - 'bd_update.sent == {"fvBD": {"attributes": {"descr": "Ansible Test Update"}, "children": [{"fvRsCtx": {"attributes": {"tnFvCtxName": "anstest"}}}]}}' - - 'bd_present_2.sent.fvBD.attributes == {"arpFlood": "yes", "descr": "Ansible Test", "ipLearning": "no", "multiDstPktAct": "drop", "name": "anstest2", - "unicastRoute": "no", "unkMacUcastAct": "flood", "unkMcastAct": "opt-flood"}' - - bd_present_missing_param is failed - - 'bd_present_missing_param.msg == "state is present but all of the following are missing: tenant"' - -- name: get all bd - aci_bd: &aci_query - <<: *aci_tenant_present - state: query - tenant: "{{ fake_var | default(omit) }}" - register: query_all - -- name: get all in tenant - aci_bd: - <<: *aci_query - tenant: anstest - register: query_tenant - -- name: get all with name - aci_bd: - <<: *aci_query - bd: anstest - register: query_bd_bd - -- name: get bd - aci_bd: - <<: *aci_bd_present - state: query - register: query_bd - -- name: query asserts - assert: - that: - - query_all is not changed - - query_all.current | length > 1 - - query_all.current.0.fvBD is defined - - '"rsp-subtree-class=fvRsBdToEpRet,fvRsCtx,fvRsIgmpsn,fvRsBDToNdP" in query_all.filter_string' - - '"class/fvBD.json" in query_all.url' - - query_tenant is not changed - - query_tenant.current | length == 1 - - query_tenant.current.0.fvTenant.children | length == 2 - - '"rsp-subtree-class=fvRsBdToEpRet,fvBD,fvRsCtx,fvRsIgmpsn,fvRsBDToNdP" in query_tenant.filter_string' - - '"tn-anstest.json" in query_tenant.url' - - query_bd_bd is not changed - - query_bd_bd.current != [] - - '"query-target-filter=eq(fvBD.name, \"anstest\")" in query_bd_bd.filter_string' - - '"rsp-subtree-class=fvRsBdToEpRet,fvRsCtx,fvRsIgmpsn,fvRsBDToNdP" in query_bd_bd.filter_string' - - '"class/fvBD.json" in query_bd_bd.url' - - query_bd is not changed - - query_bd.current | length == 1 - - query_bd.current.0.fvBD.attributes.name == "anstest" - - '"rsp-subtree-class=fvRsBdToEpRet,fvRsCtx,fvRsIgmpsn,fvRsBDToNdP" in query_bd.filter_string' - - '"tn-anstest/BD-anstest.json" in query_bd.url' - -- name: delete bd - check mode works - aci_bd: &aci_bd_absent - <<: *aci_bd_present - state: absent - check_mode: yes - register: bd_absent_check_mode - -- name: delete bd - delete works - aci_bd: - <<: *aci_bd_absent - register: bd_absent - -- name: delete bd again - idempotency works - aci_bd: - <<: *aci_bd_absent - register: bd_absent_idempotent - -- name: delete bd - cleanup - aci_bd: - <<: *aci_bd_absent - name: anstest2 - -- name: delete bd missing param - fails properly - aci_bd: - <<: *aci_bd_absent - bd: "{{ fakevar | default(omit) }}" - ignore_errors: yes - register: bd_absent_missing_param - -- name: asserts for deletion task - assert: - that: - - bd_absent_check_mode is changed - - bd_absent_check_mode.proposed == {} - - bd_absent is changed - - bd_absent.previous != [] - - bd_absent_idempotent is not changed - - bd_absent_idempotent.previous == [] - - bd_absent_missing_param is failed - - 'bd_absent_missing_param.msg == "state is absent but all of the following are missing: bd"' - -- name: delete vrf - cleanup before ending tests - aci_vrf: - <<: *aci_vrf_present - state: absent - when: vrf_present is changed - -- name: delete tenant - cleanup before ending tests - aci_tenant: - <<: *aci_tenant_present - state: absent - when: tenant_present is changed diff --git a/test/integration/targets/aci_bd_subnet/aliases b/test/integration/targets/aci_bd_subnet/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_bd_subnet/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_bd_subnet/tasks/main.yml b/test/integration/targets/aci_bd_subnet/tasks/main.yml deleted file mode 100644 index d6ac5f5336..0000000000 --- a/test/integration/targets/aci_bd_subnet/tasks/main.yml +++ /dev/null @@ -1,237 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Jacob McGill (@jmcgill298) - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - -- name: ensure tenant exists for tests to kick off - aci_tenant: &aci_tenant_present - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - state: present - tenant: anstest - register: tenant_present - -- name: ensure bd exists for tests to kick off - aci_bd: &aci_bd_present - <<: *aci_tenant_present - bd: anstest - register: bd_present - -- name: ensure subnet does not exist for tests to kick off - aci_bd_subnet: &aci_subnet_absent - <<: *aci_bd_present - state: absent - gateway: 10.100.100.1 - mask: 24 - -- name: ensure subnet does not exist for tests to kick off - aci_bd_subnet: &aci_subnet2_absent - <<: *aci_subnet_absent - gateway: 10.100.101.1 - mask: 25 - -- name: create subnet - check mode works - aci_bd_subnet: &aci_subnet_present - <<: *aci_subnet_absent - state: present - subnet_name: anstest - descr: Ansible Test - check_mode: yes - register: create_check_mode - -- name: create subnet - creation works - aci_bd_subnet: - <<: *aci_subnet_present - register: create_subnet - -- name: create new subnet - creation works - aci_bd_subnet: &aci_subnet2_present - <<: *aci_subnet2_absent - state: present - descr: Ansible Test - scope: [private, shared] - route_profile: default - route_profile_l3_out: default - register: create_subnet2 - -- name: create subnet again - idempotency works - aci_bd_subnet: - <<: *aci_subnet2_present - register: create_idempotency - -- name: modify subnet - update works - aci_bd_subnet: - <<: *aci_subnet_present - scope: [shared, public] - subnet_control: querier_ip - register: modify_subnet - -- name: create subnet with bad scope - failure message works - aci_bd_subnet: - <<: *aci_subnet_present - scope: [private, public] - register: create_bad_scope - ignore_errors: yes - -- name: create subnet without all necessary params - failure message works - aci_bd_subnet: - <<: *aci_subnet_present - bd: "{{ fake_var | default(omit) }}" - register: create_incomplete_data - ignore_errors: yes - -- name: asserts for subnet creation tasks - assert: - that: - - create_check_mode is changed - - 'create_check_mode.sent == {"fvSubnet": {"attributes": {"descr": "Ansible Test", "ip": "10.100.100.1/24", "name": "anstest"}}}' - - create_subnet is changed - - 'create_subnet.sent == {"fvSubnet": {"attributes": {"descr": "Ansible Test", "ip": "10.100.100.1/24", "name": "anstest"}}}' - - create_subnet.previous == [] - - create_subnet2 is changed - - create_subnet2.sent == create_subnet2.proposed - - create_subnet2.sent.fvSubnet.attributes.scope == "private,shared" - - 'create_subnet2.sent.fvSubnet.children.0.fvRsBDSubnetToProfile.attributes == {"tnL3extOutName": "default", "tnRtctrlProfileName": "default"}' - - create_idempotency is not changed - - create_idempotency.previous != [] - - modify_subnet is changed - - modify_subnet.previous != [] - - modify_subnet.sent != modify_subnet.proposed - - 'modify_subnet.sent == {"fvSubnet": {"attributes": {"ctrl": "querier", "scope": "public,shared"}}}' - - create_bad_scope is failed - - create_bad_scope.msg.startswith("Parameter 'scope' cannot be both 'private' and 'public'") - - create_incomplete_data is failed - - 'create_incomplete_data.msg == "state is present but all of the following are missing: bd"' - -- name: get all subnets - aci_bd_subnet: &aci_query - <<: *aci_tenant_present - state: query - tenant: "{{ fake_var | default(omit) }}" - register: get_all - -- name: get all in tenant - aci_bd_subnet: - <<: *aci_query - tenant: anstest - register: get_all_tenant - -- name: get all in bd - aci_bd_subnet: - <<: *aci_query - bd: anstest - register: get_all_bd - -- name: get all tenant and bd - aci_bd_subnet: - <<: *aci_bd_present - state: query - register: get_all_tenant_bd - -- name: get subnet in tenant - aci_bd_subnet: - <<: *aci_subnet_present - state: query - bd: "{{ fake_var | default(omit) }}" - register: get_subnet_tenant - -- name: get subnet in bd - aci_bd_subnet: - <<: *aci_subnet_present - state: query - tenant: "{{ fake_var | default(omit) }}" - register: get_subnet_bd - -- name: get specific subnet - aci_bd_subnet: - <<: *aci_subnet_present - state: query - register: get_subnet - -- name: get all subnets matching gateway - aci_bd_subnet: - <<: *aci_subnet_present - state: query - tenant: "{{ fake_var | default(omit) }}" - bd: "{{ fake_var | default(omit) }}" - register: get_subnets_gateway - -- name: asserts for query tasks - assert: - that: - - get_all is not changed - - get_all.current | length > 1 - - get_all_tenant is not changed - - '"tn-anstest.json" in get_all_tenant.url' - - get_all_bd is not changed - - '"query-target-filter=eq(fvBD.name, \"anstest\")" in get_all_bd.filter_string' - - '"class/fvBD.json" in get_all_bd.url' - - get_all_tenant_bd is not changed - - '"tn-anstest/BD-anstest.json" in get_all_tenant_bd.url' - - get_all_tenant_bd.current.0.fvBD.children | length > 1 - - get_subnet_tenant is not changed - - '"rsp-subtree-filter=eq(fvSubnet.ip, \"10.100.100.1/24\")" in get_subnet_tenant.filter_string' - - '"tn-anstest.json" in get_subnet_tenant.url' - - get_subnet_bd is not changed - - '"query-target-filter=eq(fvBD.name, \"anstest\")"' - - '"rsp-subtree-filter=eq(fvSubnet.ip, \"10.100.100.1/24\")" in get_subnet_bd.filter_string' - - '"class/fvBD.json" in get_subnet_bd.url' - - get_subnet is not changed - - get_subnet.current | length == 1 - - '"tn-anstest/BD-anstest/subnet-[10.100.100.1/24].json" in get_subnet.url' - - get_subnets_gateway is not changed - - '"query-target-filter=eq(fvSubnet.ip, \"10.100.100.1/24\")" in get_subnets_gateway.filter_string' - - '"class/fvSubnet.json" in get_subnets_gateway.url' - -- name: delete subnet - check mode works - aci_bd_subnet: - <<: *aci_subnet_absent - check_mode: yes - register: delete_check_mode - -- name: delete subnet - delete works - aci_bd_subnet: - <<: *aci_subnet_absent - register: delete_subnet - -- name: delete subnet - cleanup - aci_bd_subnet: - <<: *aci_subnet2_absent - -- name: delete subnet again - idempotency works - aci_bd_subnet: - <<: *aci_subnet2_absent - register: delete_idempotency - -- name: asserts for deletion task - assert: - that: - - delete_check_mode is changed - - delete_check_mode.proposed == {} - - delete_subnet is changed - - delete_subnet.previous != [] - - delete_subnet.method == "DELETE" - - delete_idempotency is not changed - - delete_idempotency.previous == [] - -- name: delete bd - cleanup before ending tests - aci_bd: - <<: *aci_bd_present - state: absent - when: bd_present is changed - -- name: delete tenant - cleanup before ending tests - aci_tenant: - <<: *aci_tenant_present - state: absent - when: tenant_present is changed diff --git a/test/integration/targets/aci_config_rollback/aliases b/test/integration/targets/aci_config_rollback/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_config_rollback/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_config_rollback/tasks/main.yml b/test/integration/targets/aci_config_rollback/tasks/main.yml deleted file mode 100644 index 47dc48431d..0000000000 --- a/test/integration/targets/aci_config_rollback/tasks/main.yml +++ /dev/null @@ -1,98 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Jacob McGill (@jmcgill298) - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - -- name: ensure tenant does not exist for tests to kick off - aci_tenant: &aci_tenant_absent - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - state: absent - tenant: anstest - -- name: create a snapshot - aci_config_snapshot: &create_snapshot - <<: *aci_tenant_absent - state: present - tenant: "{{ fakevar | default(omit) }}" - export_policy: anstest - -- name: create a tenant - use for rollback - aci_tenant: &aci_tenant - <<: *create_snapshot - export_policy: "{{ fakevar | default(omit) }}" - tenant: anstest - register: tenant_present - -- name: create a new snapshot - aci_config_snapshot: - <<: *create_snapshot - -- name: get snapshots - aci_config_snapshot: - <<: *create_snapshot - state: query - register: snapshots - -- name: compare snapshots - aci_config_rollback: &preview_rollback - <<: *create_snapshot - state: preview - compare_export_policy: anstest - compare_snapshot: "{{ snapshots.current.0.configSnapshotCont.children[-1].configSnapshot.attributes.name }}" - snapshot: "{{ snapshots.current.0.configSnapshotCont.children[-2].configSnapshot.attributes.name }}" - register: rollback_preview - -- name: rollback to snapshot - aci_config_rollback: &aci_rollback - <<: *create_snapshot - state: rollback - snapshot: "{{ snapshots.current.0.configSnapshotCont.children[-1].configSnapshot.attributes.name }}" - ignore_errors: yes - register: rollback_missing_param - -- name: rollback to snapshot - aci_config_rollback: - <<: *aci_rollback - import_policy: anstest - import_type: replace - import_mode: atomic - register: rollback_rollback - -- name: pause execution to let rollback take effect - pause: - seconds: 15 - -- name: ensure tenant doesn't exist after rollback - aci_tenant: - <<: *aci_tenant_absent - register: tenant_removed - -- name: rollback assertions - assert: - that: - - rollback_preview is not changed -# FIXME: diff output not longer works ? -# - '"<fvTenant name=\"anstest\" rn=\"tn-anstest\" status=\"deleted\">" in rollback_preview.diff' - - '"snapshots.diff.xml" in rollback_preview.url' - - rollback_missing_param is failed - - 'rollback_missing_param.msg == "state is rollback but all of the following are missing: import_policy"' - - rollback_rollback is changed -# FIXME: fileName key is missing from 'sent' dictionary, but exists in 'proposed' dictionary -# - '"ce2_" in rollback_rollback.sent.configImportP.attributes.fileName' -# - '".tar.gz" in rollback_rollback.sent.configImportP.attributes.fileName' - - '"ce2_" in rollback_rollback.proposed.configImportP.attributes.fileName' - - '".tar.gz" in rollback_rollback.proposed.configImportP.attributes.fileName' - - '"fabric/configimp-anstest.json" in rollback_rollback.url' - - tenant_removed is not changed - - tenant_removed.previous == [] diff --git a/test/integration/targets/aci_config_snapshot/aliases b/test/integration/targets/aci_config_snapshot/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_config_snapshot/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_config_snapshot/tasks/main.yml b/test/integration/targets/aci_config_snapshot/tasks/main.yml deleted file mode 100644 index 62c779aa00..0000000000 --- a/test/integration/targets/aci_config_snapshot/tasks/main.yml +++ /dev/null @@ -1,142 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Dag Wieers (@dagwieers) <dag@wieers.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - -- name: create a snapshot - creation works - aci_config_snapshot: &create_snapshot - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - export_policy: anstest - max_count: 10 - include_secure: no - format: json - description: ansible test - register: create - -- name: update snapshot to include secure and use xml - update works - aci_config_snapshot: - <<: *create_snapshot - include_secure: yes - format: xml - register: create_update - -- name: create a snapshot invalid max_count - error message - aci_config_snapshot: - <<: *create_snapshot - max_count: 11 - ignore_errors: yes - register: invalid_max_count - -- name: create a snapshot invalid max_count - error message - aci_config_snapshot: - <<: *create_snapshot - export_policy: "{{ fake_var | default(omit) }}" - ignore_errors: yes - register: missing_param - -- name: present assertion tests - assert: - that: - - create is not failed - - create is changed - - create.sent.configExportP.attributes.adminSt == "triggered" - - create_update is not failed - - create_update is changed - - 'create_update.sent == {"configExportP": {"attributes": {"adminSt": "triggered", "format": "xml", "includeSecureFields": "yes"}}}' - - invalid_max_count is failed - - invalid_max_count.msg == "Parameter 'max_count' must be a number between 1 and 10" - - missing_param is failed - - 'missing_param.msg == "state is present but all of the following are missing: export_policy"' - -- name: query with export_policy - aci_config_snapshot: &query_snapshot - <<: *create_snapshot - state: query - register: query_export - -- name: generate snapshot name - set_fact: - test_snapshot: "{{ query_export.current.0.configSnapshotCont.children.0.configSnapshot.attributes.rn.strip('snapshot-') }}" - -- name: query with export_policy and snapshot - aci_config_snapshot: &query_both - <<: *query_snapshot - snapshot: "{{ test_snapshot }}" - register: query_export_snapshot - -- name: query with snapshot - module add run- to snapshot - aci_config_snapshot: - <<: *query_snapshot - export_policy: "{{ fake_var | default(omit) }}" - snapshot: "{{ test_snapshot.strip('run-') }}" - register: query_snapshot - -- name: query no params - aci_config_snapshot: - <<: *query_snapshot - export_policy: "{{ fake_var | default(omit) }}" - register: query_all - -- name: query assertion tests - assert: - that: - - query_export is not failed - - query_export is not changed - - '"snapshots-[uni/fabric/configexp-anstest].json" in query_export.url' - - query_export.current.0.configSnapshotCont.attributes.name == "anstest" - - query_export.current.0.configSnapshotCont.children | length > 1 - - query_export_snapshot is not failed - - query_export_snapshot is not changed - - '"snapshots-[uni/fabric/configexp-anstest]/snapshot-{{ test_snapshot }}.json" in query_export_snapshot.url' - - query_export_snapshot.current | length == 1 - - query_snapshot is not failed - - query_snapshot is not changed - - '"class/configSnapshot.json" in query_snapshot.url' - - '"configSnapshot.name, \"{{ test_snapshot }}\"" in query_snapshot.filter_string' - - query_all is not failed - - query_all is not changed - - '"class/configSnapshot.json" in query_all.url' - - query_all.current | length > 1 - -- name: delete works - aci_config_snapshot: &delete - <<: *query_both - state: absent - register: delete_snapshot - -- name: delete works - idempotency - aci_config_snapshot: - <<: *delete - register: delete_idempotent - -- name: delete missing param - aci_config_snapshot: - <<: *delete - snapshot: "{{ fake_var | default(omit) }}" - ignore_errors: yes - register: delete_missing_param - -- name: absent assertion tests - assert: - that: - - delete_snapshot is not failed - - delete_snapshot is changed - - 'delete_snapshot.sent == {"configSnapshot": {"attributes": {"retire": "yes"}}}' - - delete_snapshot.previous != [] - - delete_snapshot.previous.0.configSnapshot.attributes.name == test_snapshot - - delete_idempotent is not failed - - delete_idempotent is not changed - - delete_idempotent.previous == [] - - delete_missing_param is failed - - 'delete_missing_param.msg == "state is absent but all of the following are missing: snapshot"' diff --git a/test/integration/targets/aci_contract/aliases b/test/integration/targets/aci_contract/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_contract/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_contract/tasks/main.yml b/test/integration/targets/aci_contract/tasks/main.yml deleted file mode 100644 index 24a054562a..0000000000 --- a/test/integration/targets/aci_contract/tasks/main.yml +++ /dev/null @@ -1,163 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Jacob McGill (@jmcgill298) - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - -- name: ensure tenant exists for tests to kick off - aci_tenant: &aci_tenant_present - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - tenant: anstest - state: present - register: tenant_present - -- name: create contract - check mode works - aci_contract: &aci_contract_present - <<: *aci_tenant_present - contract: anstest - description: Ansible Test - check_mode: yes - register: present_check_mode - -- name: create contract - creation works - aci_contract: - <<: *aci_contract_present - register: contract_present - -- name: create contract - idempotency works - aci_contract: - <<: *aci_contract_present - register: present_idempotent - -- name: update contract - update works - aci_contract: - <<: *aci_contract_present - scope: application-profile - register: present_update - -- name: create contract - used for query - aci_contract: - <<: *aci_contract_present - contract: anstest2 - -- name: missing param - failure message works - aci_contract: - <<: *aci_tenant_present - ignore_errors: yes - register: present_missing_param - -- name: present assertions - assert: - that: - - present_check_mode is changed - - present_check_mode.previous == [] - - 'present_check_mode.sent == {"vzBrCP": {"attributes": {"name": "anstest", "descr": "Ansible Test"}}}' - - contract_present is changed - - contract_present.sent == present_check_mode.sent - - present_idempotent is not changed - - present_update is changed - - present_update.sent != present_update.proposed - - present_update.sent.vzBrCP.attributes.scope == "application-profile" - - present_missing_param is failed - - 'present_missing_param.msg == "state is present but all of the following are missing: contract"' - -- name: query contract - aci_contract: &aci_contract_query - <<: *aci_contract_present - state: query - register: query_contract - -- name: query all in tenant - aci_contract: - <<: *aci_contract_query - contract: "{{ fakevar | default(omit) }}" - register: query_tenant - -- name: query all with name - aci_contract: - <<: *aci_contract_query - tenant: "{{ fakevar | default(omit) }}" - register: query_name - -- name: query all - aci_contract: - <<: *aci_contract_query - tenant: "{{ fakevar | default(omit) }}" - contract: "{{ fakevar | default(omit) }}" - register: query_all - -- name: query assertions - assert: - that: - - query_contract is not changed - - query_contract.current | length == 1 - - '"tn-anstest/brc-anstest.json" in query_contract.url' - - query_tenant is not changed - - query_tenant.current | length == 1 - - query_tenant.current.0.fvTenant.children | length > 1 - - '"rsp-subtree-class=vzBrCP" in query_tenant.filter_string' - - '"tn-anstest.json" in query_tenant.url' - - query_name is not changed - - query_name.current != [] - - '"query-target-filter=eq(vzBrCP.name, \"anstest\")" in query_name.filter_string' - - '"class/vzBrCP.json" in query_name.url' - - query_all is not changed - - query_all.current | length > 1 - - '"class/vzBrCP.json" in query_all.url' - -- name: delete contract - check mode works - aci_contract: &aci_contract_absent - <<: *aci_contract_present - state: absent - check_mode: yes - register: absent_check_mode - -- name: delete contract - deletion works - aci_contract: - <<: *aci_contract_absent - register: contract_absent - -- name: delete contract - idempotency works - aci_contract: - <<: *aci_contract_absent - register: absent_idempotent - -- name: delete contract - cleanup second contract - aci_contract: - <<: *aci_contract_absent - contract: anstest2 - -- name: missing param - fail message works - aci_contract: - <<: *aci_contract_absent - tenant: "{{ fakevar | default(omit) }}" - ignore_errors: yes - register: absent_missing_param - -- name: absent assertions - assert: - that: - - absent_check_mode is changed - - absent_check_mode.previous != [] - - contract_absent is changed - - contract_absent.previous == absent_check_mode.previous - - absent_idempotent is not changed - - absent_idempotent.previous == [] - - absent_missing_param is failed - - 'absent_missing_param.msg == "state is absent but all of the following are missing: tenant"' - -- name: cleanup tenant - aci_tenant: - <<: *aci_tenant_present - state: absent - when: tenant_present is changed diff --git a/test/integration/targets/aci_contract_subject/aliases b/test/integration/targets/aci_contract_subject/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_contract_subject/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_contract_subject/tasks/main.yml b/test/integration/targets/aci_contract_subject/tasks/main.yml deleted file mode 100644 index e10b2838cf..0000000000 --- a/test/integration/targets/aci_contract_subject/tasks/main.yml +++ /dev/null @@ -1,241 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Jacob McGill (@jmcgill298) - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - -- name: ensure tenant exists for tests to kick off - aci_tenant: &aci_tenant_present - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - state: present - tenant: anstest - register: tenant_present - -- name: ensure contract exists for tests to kick off - aci_contract: &aci_contract_present - <<: *aci_tenant_present - contract: anstest - register: contract_present - -- name: create subject - check mode works - aci_contract_subject: &aci_subject_present - <<: *aci_contract_present - subject: anstest - description: Ansible Test - check_mode: yes - register: subject_present_check_mode - -- name: create subject - creation works - aci_contract_subject: - <<: *aci_subject_present - register: subject_present - -- name: create subject - idempotency works - aci_contract_subject: - <<: *aci_subject_present - register: subject_present_idempotent - -- name: update subject - update works - aci_contract_subject: - <<: *aci_subject_present - description: Ansible Test - reverse_filter: "yes" - provider_match: at_most_one - priority: level2 - register: subject_update - -- name: create subject - try additional params - aci_contract_subject: &aci_subject_present_2 - <<: *aci_contract_present - subject: anstest2 - reverse_filter: "no" - consumer_match: all - priority: level3 - register: subject_present_2 - -- name: missing param - failure message works - aci_contract_subject: - <<: *aci_tenant_present - ignore_errors: yes - register: present_missing_param - -- name: present assertions - assert: - that: - - subject_present_check_mode is changed - - 'subject_present_check_mode.sent == {"vzSubj": {"attributes": {"descr": "Ansible Test", "name": "anstest"}}}' - - subject_present is changed - - subject_present.previous == [] - - subject_present.sent == subject_present_check_mode.sent - - subject_present_idempotent is not changed - - subject_present_idempotent.previous != [] - - subject_update is changed - - subject_update.sent != subject_update.proposed - - 'subject_update.sent.vzSubj.attributes == {"prio": "level2", "provMatchT": "AtmostOne"}' - - subject_present_2 is changed - - 'subject_present_2.sent.vzSubj.attributes == {"consMatchT": "All", "name": "anstest2", "prio": "level3", "revFltPorts": "no"}' - - present_missing_param is failed - - 'present_missing_param.msg == "state is present but all of the following are missing: contract, subject"' - -- name: query tenant contract subject - aci_contract_subject: &aci_query_subject - <<: *aci_subject_present - state: query - register: query_tenant_contract_subject - -- name: query tenant contract - aci_contract_subject: - <<: *aci_query_subject - subject: "{{ fakevar | default(omit) }}" - register: query_tenant_contract - -- name: query tenant subject - aci_contract_subject: - <<: *aci_query_subject - contract: "{{ fakevar | default(omit) }}" - register: query_tenant_subject - -- name: query contract subject - aci_contract_subject: - <<: *aci_query_subject - tenant: "{{ fakevar | default(omit) }}" - register: query_contract_subject - -- name: query tenant - aci_contract_subject: - <<: *aci_tenant_present - state: query - register: query_tenant - -- name: query contract - aci_contract_subject: - <<: *aci_contract_present - state: query - tenant: "{{ fakevar | default(omit) }}" - register: query_contract - -- name: query subject - aci_contract_subject: - <<: *aci_query_subject - tenant: "{{ fakevar | default(omit) }}" - contract: "{{ fakevar | default(omit) }}" - register: query_subject - -- name: query all - aci_contract_subject: - <<: *aci_tenant_present - state: query - tenant: "{{ fakevar | default(omit) }}" - register: query_all - -- name: query assertions - assert: - that: - - query_tenant_contract_subject is not changed - - query_tenant_contract_subject.current | length == 1 - - query_tenant_contract_subject.current.0.vzSubj.attributes.name == "anstest" - - '"tn-anstest/brc-anstest/subj-anstest.json" in query_tenant_contract_subject.url' - - query_tenant_contract is not changed - - query_tenant_contract.current | length == 1 - - query_tenant_contract.current.0.vzBrCP.attributes.name == "anstest" - - query_tenant_contract.current.0.vzBrCP.children | length == 2 - - '"rsp-subtree-class=vzSubj" in query_tenant_contract.filter_string' - - '"tn-anstest/brc-anstest.json" in query_tenant_contract.url' - - query_tenant_subject is not changed - - query_tenant_subject.current | length == 1 - - query_tenant_subject.current.0.fvTenant.attributes.name == "anstest" - - query_tenant_subject.current.0.fvTenant.children.0.vzBrCP.children | length == 1 - - query_tenant_subject.current.0.fvTenant.children.0.vzBrCP.children.0.vzSubj.attributes.name == "anstest" - - '"rsp-subtree-filter=eq(vzSubj.name, \"anstest\")" in query_tenant_subject.filter_string' - - '"rsp-subtree-class=vzSubj" in query_tenant_subject.filter_string' - - '"tn-anstest.json" in query_tenant_subject.url' - - query_contract_subject is not changed - - query_contract_subject.current.0.vzBrCP.attributes.name == "anstest" - - query_contract_subject.current.0.vzBrCP.children | length == 1 - - query_contract_subject.current.0.vzBrCP.children.0.vzSubj.attributes.name == "anstest" - - '"query-target-filter=eq(vzBrCP.name, \"anstest\")" in query_contract_subject.filter_string' - - '"rsp-subtree-filter=eq(vzSubj.name, \"anstest\")" in query_contract_subject.filter_string' - - '"rsp-subtree-class=vzSubj" in query_contract_subject.filter_string' - - '"class/vzBrCP.json" in query_contract_subject.url' - - query_tenant is not changed - - query_tenant.current | length == 1 - - query_tenant.current.0.fvTenant.attributes.name == "anstest" - - '"rsp-subtree-class=vzBrCP,vzSubj" in query_tenant.filter_string' - - '"tn-anstest.json" in query_tenant.url' - - query_contract is not changed - - query_contract.current.0.vzBrCP.attributes.name == "anstest" - - '"query-target-filter=eq(vzBrCP.name, \"anstest\")" in query_contract.filter_string' - - '"rsp-subtree-class=vzSubj" in query_contract.filter_string' - - '"class/vzBrCP.json" in query_contract.url' - - query_subject is not changed - - query_subject.current.0.vzSubj.attributes.name == "anstest" - - '"query-target-filter=eq(vzSubj.name, \"anstest\")" in query_subject.filter_string' - - '"class/vzSubj.json" in query_subject.url' - - query_all is not changed - - query_all.current > 1 - - query_all.current.0.vzSubj is defined - - '"class/vzSubj.json" in query_all.url' - -- name: delete subject - check mode works - aci_contract_subject: &aci_subject_absent - <<: *aci_subject_present - state: absent - check_mode: yes - register: subject_absent_check_mode - -- name: delete subject - deletion works - aci_contract_subject: - <<: *aci_subject_absent - register: subject_absent - -- name: delete subject - idempotency works - aci_contract_subject: - <<: *aci_subject_absent - register: subject_absent_idempotent - -- name: delete subject - cleanup - aci_contract_subject: - <<: *aci_subject_present_2 - state: absent - -- name: missing params - failure message works - aci_contract_subject: - <<: *aci_subject_absent - subject: "{{ fakevar | default(omit) }}" - ignore_errors: yes - register: absent_missing_param - -- name: absent assertions - assert: - that: - - subject_absent_check_mode is changed - - subject_absent_check_mode.previous != [] - - subject_absent_check_mode.proposed == {} - - subject_absent is changed - - subject_absent.previous == subject_absent_check_mode.previous - - subject_absent_idempotent is not changed - - subject_absent_idempotent.previous == [] - - absent_missing_param is failed - - 'absent_missing_param.msg == "state is absent but all of the following are missing: subject"' - -- name: cleanup contract - aci_contract: - <<: *aci_contract_present - state: absent - when: contract_present is changed - -- name: cleanup tenant - aci_tenant: - <<: *aci_tenant_present - state: absent - when: tenant_present is changed diff --git a/test/integration/targets/aci_contract_subject_to_filter/aliases b/test/integration/targets/aci_contract_subject_to_filter/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_contract_subject_to_filter/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_contract_subject_to_filter/tasks/main.yml b/test/integration/targets/aci_contract_subject_to_filter/tasks/main.yml deleted file mode 100644 index eeb92a956c..0000000000 --- a/test/integration/targets/aci_contract_subject_to_filter/tasks/main.yml +++ /dev/null @@ -1,193 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Jacob McGill (@jmcgill298) - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - -- name: ensure tenant exists for tests to kick off - aci_tenant: &aci_tenant_present - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - tenant: anstest - state: present - register: tenant_present - -- name: ensure filter exists for tests to kick off - aci_filter: &aci_filter_present - <<: *aci_tenant_present - filter: anstest - register: filter_present - -- name: ensure filter exists for tests to kick off - aci_filter: &aci_filter_present_2 - <<: *aci_tenant_present - filter: anstest2 - register: filter_present_2 - -- name: ensure contract exists for tests to kick off - aci_contract: &aci_contract_present - <<: *aci_tenant_present - contract: anstest - register: contract_present - -- name: ensure subject exists for tests to kick off - aci_contract_subject: &aci_subject_present - <<: *aci_contract_present - subject: anstest - register: subject_present - -- name: create subject filter binding - check mode works - aci_contract_subject_to_filter: &aci_subject_filter_present - <<: *aci_subject_present - filter: anstest - log: log - check_mode: yes - register: subject_filter_present_check_mode - -- name: create subject filter binding - creation works - aci_contract_subject_to_filter: - <<: *aci_subject_filter_present - register: subject_filter_present - -- name: create subject filter binding - additional testing - aci_contract_subject_to_filter: &aci_subject_filter_present_2 - <<: *aci_subject_filter_present - filter: anstest2 - register: subject_filter_present_2 - -- name: create subject filter binding - idempotency works - aci_contract_subject_to_filter: - <<: *aci_subject_filter_present - register: subject_filter_present_idempotent - -- name: update subject filter binding - update works - aci_contract_subject_to_filter: - <<: *aci_subject_filter_present - log: none - register: subject_filter_update - -- name: missing param - failure message works - aci_contract_subject_to_filter: - <<: *aci_tenant_present - ignore_errors: yes - register: present_missing_param - -- name: present assertions - assert: - that: - - subject_filter_present_check_mode is changed - - subject_filter_present_check_mode.previous == [] - - 'subject_filter_present_check_mode.sent == {"vzRsSubjFiltAtt": {"attributes": {"directives": "log", "tnVzFilterName": "anstest"}}}' - - subject_filter_present is changed - - subject_filter_present.previous == [] - - subject_filter_present.sent == subject_filter_present_check_mode.sent - - subject_filter_present_2 is changed - - subject_filter_present_idempotent is not changed - - subject_filter_present_idempotent.previous != [] - - subject_filter_update is changed - - 'subject_filter_update.sent.vzRsSubjFiltAtt.attributes == {"directives": ""}' - - present_missing_param is failed - - 'present_missing_param.msg == "state is present but all of the following are missing: contract, filter, subject"' - -- name: query all - aci_contract_subject_to_filter: - <<: *aci_tenant_present - state: query - tenant: "{{ fakevar | default(omit) }}" - register: query_all - -- name: query binding - aci_contract_subject_to_filter: - <<: *aci_subject_filter_present - state: query - register: query_binding - -- name: query assertions - assert: - that: - - query_all is not changed - - query_all.current | length > 1 - - query_all.current.0.vzRsSubjFiltAtt is defined - - query_binding is not changed - - query_binding.current != [] - -- name: delete subject filter binding - check mode works - aci_contract_subject_to_filter: &aci_subject_filter_absent - <<: *aci_subject_filter_present - state: absent - check_mode: yes - register: subject_filter_absent_check_mode - -- name: delete subject filter binding - deletion works - aci_contract_subject_to_filter: - <<: *aci_subject_filter_absent - register: subject_filter_absent - -- name: delete subject filter binding - idempotency works - aci_contract_subject_to_filter: - <<: *aci_subject_filter_absent - register: subject_filter_absent_idempotent - -- name: missing param - failure message works - aci_contract_subject_to_filter: - <<: *aci_subject_filter_absent - filter: "{{ fakevar | default(omit) }}" - ignore_errors: yes - register: absent_missing_param - -- name: cleanup subject filter binding - aci_contract_subject_to_filter: - <<: *aci_subject_filter_present_2 - state: absent - -- name: absent assertions - assert: - that: - - subject_filter_absent_check_mode is changed - - subject_filter_absent_check_mode.proposed == {} - - subject_filter_absent_check_mode.previous != [] - - subject_filter_absent is changed - - subject_filter_absent.previous != [] - - subject_filter_absent_idempotent is not changed - - subject_filter_absent_idempotent.previous == [] - - absent_missing_param is failed - - 'absent_missing_param.msg == "state is absent but all of the following are missing: filter"' - -- name: cleanup subject - aci_contract_subject: - <<: *aci_subject_present - state: absent - when: subject_present is changed - -- name: cleanup contract - aci_contract: - <<: *aci_contract_present - state: absent - when: contract_present is changed - -- name: cleanup filter - aci_filter: - <<: *aci_filter_present - state: absent - when: filter_present is changed - -- name: cleanup filter - aci_filter: - <<: *aci_filter_present_2 - state: absent - when: filter_present_2 is changed - -- name: cleanup tenant - aci_tenant: - <<: *aci_tenant_present - state: absent - when: tenant_present is changed diff --git a/test/integration/targets/aci_domain/aliases b/test/integration/targets/aci_domain/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_domain/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_domain/tasks/fc.yml b/test/integration/targets/aci_domain/tasks/fc.yml deleted file mode 100644 index 83dd61747b..0000000000 --- a/test/integration/targets/aci_domain/tasks/fc.yml +++ /dev/null @@ -1,174 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - - -# CLEAN ENVIRONMENT -- name: Remove FC domain - aci_domain: &domain_absent - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - domain: fc_dom - domain_type: fc - state: absent - - -# ADD DOMAIN -- name: Add FC domain (check_mode) - aci_domain: &domain_present - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - domain: fc_dom - domain_type: fc - state: present - check_mode: yes - register: cm_add_domain - -- name: Add FC domain (normal mode) - aci_domain: *domain_present - register: nm_add_domain - -- name: Verify add_domain - assert: - that: - - cm_add_domain is changed - - nm_add_domain is changed - - 'cm_add_domain.sent == nm_add_domain.sent == {"fcDomP": {"attributes": {"name": "fc_dom"}}}' - - 'cm_add_domain.proposed == nm_add_domain.proposed == {"fcDomP": {"attributes": {"name": "fc_dom"}}}' - - cm_add_domain.current == cm_add_domain.previous == nm_add_domain.previous == [] - - 'nm_add_domain.current == [{"fcDomP": {"attributes": {"dn": "uni/fc-fc_dom", "name": "fc_dom", "nameAlias": "", "ownerKey": "", "ownerTag": ""}}}]' - -- name: Add FC domain again (check_mode) - aci_domain: *domain_present - check_mode: yes - register: cm_add_domain_again - -- name: Add FC domain again (normal mode) - aci_domain: *domain_present - register: nm_add_domain_again - -- name: Verify add_domain_again - assert: - that: - - cm_add_domain_again is not changed - - nm_add_domain_again is not changed - - -# QUERY ALL DOMAINS -- name: Query all FC domains (check_mode) - aci_domain: &domain_query - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - domain_type: fc - state: query - check_mode: yes - register: cm_query_all_domains - -- name: Query all FC domains (normal mode) - aci_domain: *domain_query - register: nm_query_all_domains - -- name: Verify query_all_domains - assert: - that: - - cm_query_all_domains is not changed - - nm_query_all_domains is not changed - - cm_query_all_domains == nm_query_all_domains - - nm_query_all_domains.current|length >= 1 - - -# QUERY A DOMAIN -- name: Query our FC domain (check_mode) - aci_domain: - <<: *domain_query - domain: fc_dom - check_mode: yes - register: cm_query_domain - -- name: Query our FC domain (normal mode) - aci_domain: - <<: *domain_query - domain: fc_dom - register: nm_query_domain - -- name: Verify query_domain - assert: - that: - - cm_query_domain is not changed - - nm_query_domain is not changed - - cm_query_domain == nm_query_domain - - nm_query_domain.current.0.fcDomP.attributes.dn == 'uni/fc-fc_dom' - - nm_query_domain.current.0.fcDomP.attributes.name == 'fc_dom' - - -# REMOVE DOMAIN -- name: Remove FC domain (check_mode) - aci_domain: *domain_absent - check_mode: yes - register: cm_remove_domain - -- name: Remove FC domain (normal mode) - aci_domain: *domain_absent - register: nm_remove_domain - -- name: Verify remove_domain - assert: - that: - - cm_remove_domain is changed - - nm_remove_domain is changed - - 'cm_remove_domain.current == cm_remove_domain.previous == nm_remove_domain.previous == [{"fcDomP": {"attributes": {"dn": "uni/fc-fc_dom", "name": "fc_dom", "nameAlias": "", "ownerKey": "", "ownerTag": ""}}}]' - - nm_remove_domain.current == [] - -- name: Remove FC domain again (check_mode) - aci_domain: *domain_absent - check_mode: yes - register: cm_remove_domain_again - -- name: Remove FC domain again (normal mode) - aci_domain: *domain_absent - register: nm_remove_domain_again - -- name: Verify remove_domain_again - assert: - that: - - cm_remove_domain_again is not changed - - nm_remove_domain_again is not changed - - -# QUERY NON-EXISTING DOMAIN -- name: Query non-existing FC domain (check_mode) - aci_domain: - <<: *domain_query - domain: fc_dom - check_mode: yes - register: cm_query_non_domain - -- name: Query non-existing FC domain (normal mode) - aci_domain: - <<: *domain_query - domain: fc_dom - register: nm_query_non_domain - -- name: Verify query_non_domain - assert: - that: - - cm_query_non_domain is not changed - - nm_query_non_domain is not changed - - cm_query_non_domain == nm_query_non_domain - - nm_query_non_domain.current == [] diff --git a/test/integration/targets/aci_domain/tasks/l2dom.yml b/test/integration/targets/aci_domain/tasks/l2dom.yml deleted file mode 100644 index 0ec4f499fd..0000000000 --- a/test/integration/targets/aci_domain/tasks/l2dom.yml +++ /dev/null @@ -1,174 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - - -# CLEAN ENVIRONMENT -- name: Remove L2 domain - aci_domain: &domain_absent - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - domain: l2_dom - domain_type: l2dom - state: absent - - -# ADD DOMAIN -- name: Add L2 domain (check_mode) - aci_domain: &domain_present - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - domain: l2_dom - domain_type: l2dom - state: present - check_mode: yes - register: cm_add_domain - -- name: Add L2 domain (normal mode) - aci_domain: *domain_present - register: nm_add_domain - -- name: Verify add_domain - assert: - that: - - cm_add_domain is changed - - nm_add_domain is changed - - 'cm_add_domain.sent == nm_add_domain.sent == {"l2extDomP": {"attributes": {"name": "l2_dom"}}}' - - 'cm_add_domain.proposed == nm_add_domain.proposed == {"l2extDomP": {"attributes": {"name": "l2_dom"}}}' - - cm_add_domain.current == cm_add_domain.previous == nm_add_domain.previous == [] - - 'nm_add_domain.current == [{"l2extDomP": {"attributes": {"dn": "uni/l2dom-l2_dom", "name": "l2_dom", "nameAlias": "", "ownerKey": "", "ownerTag": ""}}}]' - -- name: Add L2 domain again (check_mode) - aci_domain: *domain_present - check_mode: yes - register: cm_add_domain_again - -- name: Add L2 domain again (normal mode) - aci_domain: *domain_present - register: nm_add_domain_again - -- name: Verify add_domain_again - assert: - that: - - cm_add_domain_again is not changed - - nm_add_domain_again is not changed - - -# QUERY ALL DOMAINS -- name: Query all L2 domains (check_mode) - aci_domain: &domain_query - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - domain_type: l2dom - state: query - check_mode: yes - register: cm_query_all_domains - -- name: Query all L2 domains (normal mode) - aci_domain: *domain_query - register: nm_query_all_domains - -- name: Verify query_all_domains - assert: - that: - - cm_query_all_domains is not changed - - nm_query_all_domains is not changed - - cm_query_all_domains == nm_query_all_domains - - nm_query_all_domains.current|length >= 1 - - -# QUERY A DOMAIN -- name: Query our L2 domain (check_mode) - aci_domain: - <<: *domain_query - domain: l2_dom - check_mode: yes - register: cm_query_domain - -- name: Query our L2 domain (normal mode) - aci_domain: - <<: *domain_query - domain: l2_dom - register: nm_query_domain - -- name: Verify query_domain - assert: - that: - - cm_query_domain is not changed - - nm_query_domain is not changed - - cm_query_domain == nm_query_domain - - nm_query_domain.current.0.l2extDomP.attributes.dn == 'uni/l2dom-l2_dom' - - nm_query_domain.current.0.l2extDomP.attributes.name == 'l2_dom' - - -# REMOVE DOMAIN -- name: Remove L2 domain (check_mode) - aci_domain: *domain_absent - check_mode: yes - register: cm_remove_domain - -- name: Remove L2 domain (normal mode) - aci_domain: *domain_absent - register: nm_remove_domain - -- name: Verify remove_domain - assert: - that: - - cm_remove_domain is changed - - nm_remove_domain is changed - - 'cm_remove_domain.current == cm_remove_domain.previous == nm_remove_domain.previous == [{"l2extDomP": {"attributes": {"dn": "uni/l2dom-l2_dom", "name": "l2_dom", "nameAlias": "", "ownerKey": "", "ownerTag": ""}}}]' - - nm_remove_domain.current == [] - -- name: Remove L2 domain again (check_mode) - aci_domain: *domain_absent - check_mode: yes - register: cm_remove_domain_again - -- name: Remove L2 domain again (normal mode) - aci_domain: *domain_absent - register: nm_remove_domain_again - -- name: Verify remove_domain_again - assert: - that: - - cm_remove_domain_again is not changed - - nm_remove_domain_again is not changed - - -# QUERY NON-EXISTING DOMAIN -- name: Query non-existing L2 domain (check_mode) - aci_domain: - <<: *domain_query - domain: l2_dom - check_mode: yes - register: cm_query_non_domain - -- name: Query non-existing L2 domain (normal mode) - aci_domain: - <<: *domain_query - domain: l2_dom - register: nm_query_non_domain - -- name: Verify query_non_domain - assert: - that: - - cm_query_non_domain is not changed - - nm_query_non_domain is not changed - - cm_query_non_domain == nm_query_non_domain - - nm_query_non_domain.current == [] diff --git a/test/integration/targets/aci_domain/tasks/l3dom.yml b/test/integration/targets/aci_domain/tasks/l3dom.yml deleted file mode 100644 index 9f101eb18b..0000000000 --- a/test/integration/targets/aci_domain/tasks/l3dom.yml +++ /dev/null @@ -1,174 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - - -# CLEAN ENVIRONMENT -- name: Remove L3 domain - aci_domain: &domain_absent - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - domain: l3_dom - domain_type: l3dom - state: absent - - -# ADD DOMAIN -- name: Add L3 domain (check_mode) - aci_domain: &domain_present - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - domain: l3_dom - domain_type: l3dom - state: present - check_mode: yes - register: cm_add_domain - -- name: Add L3 domain (normal mode) - aci_domain: *domain_present - register: nm_add_domain - -- name: Verify add_domain - assert: - that: - - cm_add_domain is changed - - nm_add_domain is changed - - 'cm_add_domain.sent == nm_add_domain.sent == {"l3extDomP": {"attributes": {"name": "l3_dom"}}}' - - 'cm_add_domain.proposed == nm_add_domain.proposed == {"l3extDomP": {"attributes": {"name": "l3_dom"}}}' - - cm_add_domain.current == cm_add_domain.previous == nm_add_domain.previous == [] - - 'nm_add_domain.current == [{"l3extDomP": {"attributes": {"dn": "uni/l3dom-l3_dom", "name": "l3_dom", "nameAlias": "", "ownerKey": "", "ownerTag": ""}}}]' - -- name: Add L3 domain again (check_mode) - aci_domain: *domain_present - check_mode: yes - register: cm_add_domain_again - -- name: Add L3 domain again (normal mode) - aci_domain: *domain_present - register: nm_add_domain_again - -- name: Verify add_domain_again - assert: - that: - - cm_add_domain_again is not changed - - nm_add_domain_again is not changed - - -# QUERY ALL DOMAINS -- name: Query all L3 domains (check_mode) - aci_domain: &domain_query - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - domain_type: l3dom - state: query - check_mode: yes - register: cm_query_all_domains - -- name: Query all L3 domains (normal mode) - aci_domain: *domain_query - register: nm_query_all_domains - -- name: Verify query_all_domains - assert: - that: - - cm_query_all_domains is not changed - - nm_query_all_domains is not changed - - cm_query_all_domains == nm_query_all_domains - - nm_query_all_domains.current|length >= 1 - - -# QUERY A DOMAIN -- name: Query our L3 domain (check_mode) - aci_domain: - <<: *domain_query - domain: l3_dom - check_mode: yes - register: cm_query_domain - -- name: Query our L3 domain (normal mode) - aci_domain: - <<: *domain_query - domain: l3_dom - register: nm_query_domain - -- name: Verify query_domain - assert: - that: - - cm_query_domain is not changed - - nm_query_domain is not changed - - cm_query_domain == nm_query_domain - - nm_query_domain.current.0.l3extDomP.attributes.dn == 'uni/l3dom-l3_dom' - - nm_query_domain.current.0.l3extDomP.attributes.name == 'l3_dom' - - -# REMOVE DOMAIN -- name: Remove L3 domain (check_mode) - aci_domain: *domain_absent - check_mode: yes - register: cm_remove_domain - -- name: Remove L3 domain (normal mode) - aci_domain: *domain_absent - register: nm_remove_domain - -- name: Verify remove_domain - assert: - that: - - cm_remove_domain is changed - - nm_remove_domain is changed - - 'cm_remove_domain.current == cm_remove_domain.previous == nm_remove_domain.previous == [{"l3extDomP": {"attributes": {"dn": "uni/l3dom-l3_dom", "name": "l3_dom", "nameAlias": "", "ownerKey": "", "ownerTag": ""}}}]' - - nm_remove_domain.current == [] - -- name: Remove L3 domain again (check_mode) - aci_domain: *domain_absent - check_mode: yes - register: cm_remove_domain_again - -- name: Remove L3 domain again (normal mode) - aci_domain: *domain_absent - register: nm_remove_domain_again - -- name: Verify remove_domain_again - assert: - that: - - cm_remove_domain_again is not changed - - nm_remove_domain_again is not changed - - -# QUERY NON-EXISTING DOMAIN -- name: Query non-existing L3 domain (check_mode) - aci_domain: - <<: *domain_query - domain: l3_dom - check_mode: yes - register: cm_query_non_domain - -- name: Query non-existing L3 domain (normal mode) - aci_domain: - <<: *domain_query - domain: l3_dom - register: nm_query_non_domain - -- name: Verify query_non_domain - assert: - that: - - cm_query_non_domain is not changed - - nm_query_non_domain is not changed - - cm_query_non_domain == nm_query_non_domain - - nm_query_non_domain.current == [] diff --git a/test/integration/targets/aci_domain/tasks/main.yml b/test/integration/targets/aci_domain/tasks/main.yml deleted file mode 100644 index 5a0585ef32..0000000000 --- a/test/integration/targets/aci_domain/tasks/main.yml +++ /dev/null @@ -1,24 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - -- include_tasks: phys.yml - when: phys is not defined or phys - -- include_tasks: l2dom.yml - when: l2dom is not defined or l2dom - -- include_tasks: l3dom.yml - when: l3dom is not defined or l3dom - -- include_tasks: fc.yml - when: fc is not defined or fc - -- include_tasks: vmm-vmware.yml - when: vmm_vmware is not defined or vmm_vmware diff --git a/test/integration/targets/aci_domain/tasks/phys.yml b/test/integration/targets/aci_domain/tasks/phys.yml deleted file mode 100644 index 66bb87595a..0000000000 --- a/test/integration/targets/aci_domain/tasks/phys.yml +++ /dev/null @@ -1,174 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - - -# CLEAN ENVIRONMENT -- name: Remove physical domain - aci_domain: &domain_absent - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - domain: phys_dom - domain_type: phys - state: absent - - -# ADD DOMAIN -- name: Add physical domain (check_mode) - aci_domain: &domain_present - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - domain: phys_dom - domain_type: phys - state: present - check_mode: yes - register: cm_add_domain - -- name: Add physical domain (normal mode) - aci_domain: *domain_present - register: nm_add_domain - -- name: Verify add_domain - assert: - that: - - cm_add_domain is changed - - nm_add_domain is changed - - 'cm_add_domain.sent == nm_add_domain.sent == {"physDomP": {"attributes": {"name": "phys_dom"}}}' - - 'cm_add_domain.proposed == nm_add_domain.proposed == {"physDomP": {"attributes": {"name": "phys_dom"}}}' - - cm_add_domain.current == cm_add_domain.previous == nm_add_domain.previous == [] - - 'nm_add_domain.current == [{"physDomP": {"attributes": {"dn": "uni/phys-phys_dom", "name": "phys_dom", "nameAlias": "", "ownerKey": "", "ownerTag": ""}}}]' - -- name: Add physical domain again (check_mode) - aci_domain: *domain_present - check_mode: yes - register: cm_add_domain_again - -- name: Add physical domain again (normal mode) - aci_domain: *domain_present - register: nm_add_domain_again - -- name: Verify add_domain_again - assert: - that: - - cm_add_domain_again is not changed - - nm_add_domain_again is not changed - - -# QUERY ALL DOMAINS -- name: Query all physical domains (check_mode) - aci_domain: &domain_query - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - domain_type: phys - state: query - check_mode: yes - register: cm_query_all_domains - -- name: Query all physical domains (normal mode) - aci_domain: *domain_query - register: nm_query_all_domains - -- name: Verify query_all_domains - assert: - that: - - cm_query_all_domains is not changed - - nm_query_all_domains is not changed - - cm_query_all_domains == nm_query_all_domains - - nm_query_all_domains.current|length >= 1 - - -# QUERY A DOMAIN -- name: Query our physical domain (check_mode) - aci_domain: - <<: *domain_query - domain: phys_dom - check_mode: yes - register: cm_query_domain - -- name: Query our physical domain (normal mode) - aci_domain: - <<: *domain_query - domain: phys_dom - register: nm_query_domain - -- name: Verify query_domain - assert: - that: - - cm_query_domain is not changed - - nm_query_domain is not changed - - cm_query_domain == nm_query_domain - - nm_query_domain.current.0.physDomP.attributes.dn == 'uni/phys-phys_dom' - - nm_query_domain.current.0.physDomP.attributes.name == 'phys_dom' - - -# REMOVE DOMAIN -- name: Remove physical domain (check_mode) - aci_domain: *domain_absent - check_mode: yes - register: cm_remove_domain - -- name: Remove physical domain (normal mode) - aci_domain: *domain_absent - register: nm_remove_domain - -- name: Verify remove_domain - assert: - that: - - cm_remove_domain is changed - - nm_remove_domain is changed - - 'cm_remove_domain.current == cm_remove_domain.previous == nm_remove_domain.previous == [{"physDomP": {"attributes": {"dn": "uni/phys-phys_dom", "name": "phys_dom", "nameAlias": "", "ownerKey": "", "ownerTag": ""}}}]' - - nm_remove_domain.current == [] - -- name: Remove physical domain again (check_mode) - aci_domain: *domain_absent - check_mode: yes - register: cm_remove_domain_again - -- name: Remove physical domain again (normal mode) - aci_domain: *domain_absent - register: nm_remove_domain_again - -- name: Verify remove_domain_again - assert: - that: - - cm_remove_domain_again is not changed - - nm_remove_domain_again is not changed - - -# QUERY NON-EXISTING DOMAIN -- name: Query non-existing physical domain (check_mode) - aci_domain: - <<: *domain_query - domain: phys_dom - check_mode: yes - register: cm_query_non_domain - -- name: Query non-existing physical domain (normal mode) - aci_domain: - <<: *domain_query - domain: phys_dom - register: nm_query_non_domain - -- name: Verify query_non_domain - assert: - that: - - cm_query_non_domain is not changed - - nm_query_non_domain is not changed - - cm_query_non_domain == nm_query_non_domain - - nm_query_non_domain.current == [] diff --git a/test/integration/targets/aci_domain/tasks/vmm-vmware.yml b/test/integration/targets/aci_domain/tasks/vmm-vmware.yml deleted file mode 100644 index 2d737e4451..0000000000 --- a/test/integration/targets/aci_domain/tasks/vmm-vmware.yml +++ /dev/null @@ -1,184 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - - -# CLEAN ENVIRONMENT -- name: Remove VMM domain - aci_domain: &domain_absent - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - domain: vmm_dom - domain_type: vmm - vm_provider: vmware - state: absent - - -# ADD DOMAIN -- name: Add VMM domain (check_mode) - aci_domain: &domain_present - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - domain: vmm_dom - domain_type: vmm - vm_provider: vmware - state: present - check_mode: yes - register: cm_add_domain - -- name: Add VMM domain (normal mode) - aci_domain: *domain_present - register: nm_add_domain - -- name: Verify add_domain - assert: - that: - - cm_add_domain is changed - - nm_add_domain is changed - - 'cm_add_domain.sent == nm_add_domain.sent == {"vmmDomP": {"attributes": {"name": "vmm_dom"}}}' - - 'cm_add_domain.proposed == nm_add_domain.proposed == {"vmmDomP": {"attributes": {"name": "vmm_dom"}}}' - - cm_add_domain.current == cm_add_domain.previous == nm_add_domain.previous == [] - - nm_add_domain.current.0.vmmDomP.attributes.dn == 'uni/vmmp-VMware/dom-vmm_dom' - - nm_add_domain.current.0.vmmDomP.attributes.name == 'vmm_dom' - -- name: Add VMM domain again (check_mode) - aci_domain: *domain_present - check_mode: yes - register: cm_add_domain_again - -- name: Add physical domain again (normal mode) - aci_domain: *domain_present - register: nm_add_domain_again - -- name: Verify add_domain_again - assert: - that: - - cm_add_domain_again is not changed - - nm_add_domain_again is not changed - - -# QUERY ALL DOMAINS -- name: Query all VMM domains (check_mode) - aci_domain: &domain_query - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - domain_type: vmm - vm_provider: vmware - state: query - check_mode: yes - register: cm_query_all_domains - -- name: Query all VMM domains (normal mode) - aci_domain: *domain_query - register: nm_query_all_domains - -- name: Verify query_all_domains - assert: - that: - - cm_query_all_domains is not changed - - nm_query_all_domains is not changed - - cm_query_all_domains == nm_query_all_domains - - nm_query_all_domains.current|length >= 1 - - -# QUERY A DOMAIN -- name: Query our VMM domain (check_mode) - aci_domain: - <<: *domain_query - domain: vmm_dom - vm_provider: vmware - check_mode: yes - register: cm_query_domain - -- name: Query our VMM domain (normal mode) - aci_domain: - <<: *domain_query - domain: vmm_dom - vm_provider: vmware - register: nm_query_domain - -- name: Verify query_domain - assert: - that: - - cm_query_domain is not changed - - nm_query_domain is not changed - - cm_query_domain == nm_query_domain - - nm_query_domain.current.0.vmmDomP.attributes.dn == 'uni/vmmp-VMware/dom-vmm_dom' - - nm_query_domain.current.0.vmmDomP.attributes.name == 'vmm_dom' - - -# REMOVE DOMAIN -- name: Remove VMM domain (check_mode) - aci_domain: *domain_absent - check_mode: yes - register: cm_remove_domain - -- name: Remove VMM domain (normal mode) - aci_domain: *domain_absent - register: nm_remove_domain - -- name: Verify remove_domain - assert: - that: - - cm_remove_domain is changed - - nm_remove_domain is changed - - cm_remove_domain.current == cm_remove_domain.previous == nm_remove_domain.previous - - nm_remove_domain.previous.0.vmmDomP.attributes.dn == 'uni/vmmp-VMware/dom-vmm_dom' - - nm_remove_domain.previous.0.vmmDomP.attributes.name == 'vmm_dom' - - nm_remove_domain.current == [] - -- name: Remove VMM domain again (check_mode) - aci_domain: *domain_absent - check_mode: yes - register: cm_remove_domain_again - -- name: Remove VMM domain again (normal mode) - aci_domain: *domain_absent - register: nm_remove_domain_again - -- name: Verify remove_domain_again - assert: - that: - - cm_remove_domain_again is not changed - - nm_remove_domain_again is not changed - - -# QUERY NON-EXISTING DOMAIN -- name: Query non-existing VMM domain (check_mode) - aci_domain: - <<: *domain_query - domain: vmm_dom - vm_provider: vmware - check_mode: yes - register: cm_query_non_domain - -- name: Query non-existing VMM domain (normal mode) - aci_domain: - <<: *domain_query - domain: vmm_dom - vm_provider: vmware - register: nm_query_non_domain - -- name: Verify query_non_domain - assert: - that: - - cm_query_non_domain is not changed - - nm_query_non_domain is not changed - - cm_query_non_domain == nm_query_non_domain - - nm_query_non_domain.current == [] diff --git a/test/integration/targets/aci_domain_to_vlan_pool/aliases b/test/integration/targets/aci_domain_to_vlan_pool/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_domain_to_vlan_pool/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_domain_to_vlan_pool/tasks/main.yml b/test/integration/targets/aci_domain_to_vlan_pool/tasks/main.yml deleted file mode 100644 index fcc8fea240..0000000000 --- a/test/integration/targets/aci_domain_to_vlan_pool/tasks/main.yml +++ /dev/null @@ -1,216 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - - -# CLEAN ENVIRONMENT -- name: Remove domain to VLAN pool binding - aci_domain_to_vlan_pool: &binding_absent - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - domain: phys_dom - domain_type: phys - pool: test_pool - pool_allocation_mode: dynamic - state: absent - -- name: Remove physical domain - aci_domain: - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - domain: phys_dom - domain_type: phys - state: absent - -- name: Create VLAN pool - aci_vlan_pool: - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - pool: test_pool - pool_allocation_mode: dynamic - description: Test VLAN pool - state: present - - -# ADD BINDING -- name: Add domain to VLAN pool binding (check_mode) - aci_domain_to_vlan_pool: &binding_present - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - domain: phys_dom - domain_type: phys - pool: test_pool - pool_allocation_mode: dynamic - state: present - check_mode: yes - register: cm_add_binding - -- name: Add domain to VLAN pool binding (normal mode) - aci_domain_to_vlan_pool: *binding_present - register: nm_add_binding - -- name: Verify add_binding - assert: - that: - - cm_add_binding is changed - - nm_add_binding is changed - - 'cm_add_binding.sent == nm_add_binding.sent == {"physDomP": {"attributes": {"name": "phys_dom"}, "children": [{"infraRsVlanNs": {"attributes": {"tDn": "uni/infra/vlanns-[test_pool]-dynamic"}}}]}}' - - 'cm_add_binding.proposed == nm_add_binding.proposed == {"physDomP": {"attributes": {"name": "phys_dom"}, "children": [{"infraRsVlanNs": {"attributes": {"tDn": "uni/infra/vlanns-[test_pool]-dynamic"}}}]}}' - - cm_add_binding.current == cm_add_binding.previous == nm_add_binding.previous == [] - - 'nm_add_binding.current == [{"physDomP": {"attributes": {"dn": "uni/phys-phys_dom", "name": "phys_dom", "nameAlias": "", "ownerKey": "", "ownerTag": ""}, "children": [{"infraRsVlanNs": {"attributes": {"tDn": "uni/infra/vlanns-[test_pool]-dynamic"}}}]}}]' - -- name: Add domain to VLAN pool binding again (check_mode) - aci_domain_to_vlan_pool: *binding_present - check_mode: yes - register: cm_add_binding_again - -- name: Add domain to VLAN pool binding again (normal mode) - aci_domain_to_vlan_pool: *binding_present - register: nm_add_binding_again - -- name: Verify add_binding_again - assert: - that: - - cm_add_binding_again is not changed - - nm_add_binding_again is not changed - - -# QUERY ALL BINDINGS -- name: Query all domain to VLAN pool bindings (check_mode) - aci_domain_to_vlan_pool: &binding_query - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - domain_type: phys - pool_allocation_mode: dynamic - state: query - check_mode: yes - register: cm_query_all_bindings - -- name: Query all domain to VLAN pool bindings (normal mode) - aci_domain_to_vlan_pool: *binding_query - register: nm_query_all_bindings - -- name: Verify query_all_bindings - assert: - that: - - cm_query_all_bindings is not changed - - nm_query_all_bindings is not changed - - cm_query_all_bindings == nm_query_all_bindings - - nm_query_all_bindings.current|length >= 1 - - -# QUERY A BINDING -- name: Query our domain to VLAN pool binding (check_mode) - aci_domain_to_vlan_pool: - <<: *binding_query - domain: phys_dom - pool: test_pool - pool_allocation_mode: dynamic - check_mode: yes - register: cm_query_binding - -- name: Query our domain to VLAN pool binding (normal mode) - aci_domain_to_vlan_pool: - <<: *binding_query - domain: phys_dom - pool: test_pool - pool_allocation_mode: dynamic - register: nm_query_binding - -- name: Verify query_binding - assert: - that: - - cm_query_binding is not changed - - nm_query_binding is not changed - - cm_query_binding == nm_query_binding - - nm_query_binding.current.0.physDomP.attributes.dn == 'uni/phys-phys_dom' - - nm_query_binding.current.0.physDomP.attributes.name == 'phys_dom' - - nm_query_binding.current.0.physDomP.children.0.infraRsVlanNs.attributes.tCl == 'fvnsVlanInstP' - - nm_query_binding.current.0.physDomP.children.0.infraRsVlanNs.attributes.tDn == 'uni/infra/vlanns-[test_pool]-dynamic' - - -# REMOVE BINDING -- name: Remove domain to VLAN pool binding (check_mode) - aci_domain_to_vlan_pool: *binding_absent - check_mode: yes - register: cm_remove_binding - -- name: Remove domain to VLAN pool binding (normal mode) - aci_domain_to_vlan_pool: *binding_absent - register: nm_remove_binding - -- name: Verify remove_binding - assert: - that: - - cm_remove_binding is changed - - nm_remove_binding is changed - - 'cm_remove_binding.current == cm_remove_binding.previous == nm_remove_binding.previous == [{"physDomP": {"attributes": {"dn": "uni/phys-phys_dom", "name": "phys_dom", "nameAlias": "", "ownerKey": "", "ownerTag": ""}, "children": [{"infraRsVlanNs": {"attributes": {"tDn": "uni/infra/vlanns-[test_pool]-dynamic"}}}]}}]' - - nm_remove_binding.current == [] - -- name: Remove domain to VLAN pool binding again (check_mode) - aci_domain_to_vlan_pool: *binding_absent - check_mode: yes - register: cm_remove_binding_again - -- name: Remove domain to VLAN pool binding again (normal mode) - aci_domain_to_vlan_pool: *binding_absent - register: nm_remove_binding_again - -- name: Verify remove_binding_again - assert: - that: - - cm_remove_binding_again is not changed - - nm_remove_binding_again is not changed - - -# QUERY NON-EXISTING BINDING -- name: Query non-existing domain to VLAN pool binding (check_mode) - aci_domain_to_vlan_pool: - <<: *binding_query - domain: phys_dom - pool: test_pool - pool_allocation_mode: dynamic - check_mode: yes - register: cm_query_non_binding - -- name: Query non-existing domain to VLAN pool binding (normal mode) - aci_domain_to_vlan_pool: - <<: *binding_query - domain: phys_dom - pool: test_pool - pool_allocation_mode: dynamic - register: nm_query_non_binding - -- name: Verify query_non_binding - assert: - that: - - cm_query_non_binding is not changed - - nm_query_non_binding is not changed - - cm_query_non_binding == nm_query_non_binding - - nm_query_non_binding.current == [] diff --git a/test/integration/targets/aci_encap_pool/aliases b/test/integration/targets/aci_encap_pool/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_encap_pool/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_encap_pool/tasks/main.yml b/test/integration/targets/aci_encap_pool/tasks/main.yml deleted file mode 100644 index 971b42bfeb..0000000000 --- a/test/integration/targets/aci_encap_pool/tasks/main.yml +++ /dev/null @@ -1,18 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Jacob McGill (@jmcgill298) - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: test that we have an aci apic host, aci username and aci password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - -- include_tasks: vlan.yml - when: vlan is not defined or vlan - -- include_tasks: vxlan.yml - when: vxlan is not defined or vxlan - -- include_tasks: vsan.yml - when: vsan is not defined or vsan diff --git a/test/integration/targets/aci_encap_pool/tasks/vlan.yml b/test/integration/targets/aci_encap_pool/tasks/vlan.yml deleted file mode 100644 index da2242b89f..0000000000 --- a/test/integration/targets/aci_encap_pool/tasks/vlan.yml +++ /dev/null @@ -1,264 +0,0 @@ ---- -- name: ensure vlan pool does not exist for tests to kick off - aci_encap_pool: &aci_pool_absent_static - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - state: absent - pool: anstest - pool_type: vlan - pool_allocation_mode: static - -- name: ensure vlan pool does not exist for tests to kick off - aci_encap_pool: &aci_pool_absent_dynamic - <<: *aci_pool_absent_static - pool_allocation_mode: dynamic - -- name: create static vlan pool - check mode works - aci_encap_pool: &aci_pool_present_static - <<: *aci_pool_absent_static - state: present - descr: Ansible Test - check_mode: yes - register: create_check_mode - -- name: assertion test - present - assert: - that: - - create_check_mode is changed - - 'create_check_mode.sent == {"fvnsVlanInstP": {"attributes": {"allocMode": "static", "descr": "Ansible Test", "name": "anstest"}}}' - -- name: create static vlan pool - creation works - aci_encap_pool: - <<: *aci_pool_present_static - register: create_static - -- name: assertion test - present - assert: - that: - - create_static is changed - - create_static.previous == [] - - create_static.sent == create_check_mode.sent - -- name: create dynamic vlan pool - creation works - aci_encap_pool: &aci_pool_present_dynamic - <<: *aci_pool_absent_dynamic - state: present - descr: Ansible Test - register: create_dynamic - -- name: assertion test - present - assert: - that: - - create_dynamic is changed - - create_dynamic.previous == [] - - 'create_dynamic.sent == {"fvnsVlanInstP": {"attributes": {"allocMode": "dynamic", "descr": "Ansible Test", "name": "anstest"}}}' - -- name: create static vlan pool again - idempotency works - aci_encap_pool: - <<: *aci_pool_present_static - register: idempotent_static - -- name: assertion test - present - assert: - that: - - idempotent_static is not changed - - 'idempotent_static.previous == [{"fvnsVlanInstP": {"attributes": {"allocMode": "static", "descr": "Ansible Test", "dn": "uni/infra/vlanns-[anstest]-static", "name": "anstest", "nameAlias": "", "ownerKey": "", "ownerTag": ""}}}]' - - idempotent_static.sent == {} - -- name: create dynamic vlan pool again - idempotency works - aci_encap_pool: - <<: *aci_pool_present_dynamic - register: idempotent_dynamic - -- name: assertion test - present - assert: - that: - - idempotent_dynamic is not changed - - 'idempotent_dynamic.previous == [{"fvnsVlanInstP": {"attributes": {"allocMode": "dynamic", "descr": "Ansible Test", "dn": "uni/infra/vlanns-[anstest]-dynamic", "name": "anstest", "nameAlias": "", "ownerKey": "", "ownerTag": ""}}}]' - - idempotent_dynamic.sent == {} - -- name: update static vlan pool - update works - aci_encap_pool: - <<: *aci_pool_present_static - descr: Ansible Test Change - register: update_static - -- name: assertion test - present - assert: - that: - - update_static is changed - - 'update_static.sent == {"fvnsVlanInstP": {"attributes": {"descr": "Ansible Test Change"}}}' - -- name: update dynamic vlan pool - update works - aci_encap_pool: - <<: *aci_pool_present_dynamic - descr: Ansible Test Change - register: update_dynamic - -- name: assertion test - present - assert: - that: - - update_dynamic is changed - - 'update_dynamic.sent == {"fvnsVlanInstP": {"attributes": {"descr": "Ansible Test Change"}}}' - -- name: missing param - failure message works - aci_encap_pool: - <<: *aci_pool_present_dynamic - pool_allocation_mode: "{{ fake_var | default(omit) }}" - ignore_errors: yes - register: vlan_alloc_fail - -- name: assertion test - present - assert: - that: - - vlan_alloc_fail is failed - - "vlan_alloc_fail.msg == 'ACI requires parameter \\'pool_allocation_mode\\' for \\'pool_type\\' of \\'vlan\\' and \\'vsan\\' when parameter \\'pool\\' is provided'" - -- name: missing param - failure message works - aci_encap_pool: - <<: *aci_pool_present_dynamic - pool: "{{ fake_var | default(omit) }}" - ignore_errors: yes - register: vlan_pool_fail - -- name: assertion test - present - assert: - that: - - vlan_pool_fail is failed - - 'vlan_pool_fail.msg == "state is present but all of the following are missing: pool"' - -- name: missing param - failure message works - aci_encap_pool: - <<: *aci_pool_present_dynamic - pool_type: "{{ fake_var | default(omit) }}" - ignore_errors: yes - register: vlan_pool_type_fail - -- name: assertion test - present - assert: - that: - - vlan_pool_type_fail is failed - - 'vlan_pool_type_fail.msg == "missing required arguments: pool_type"' - -- name: get all vlan pools - get class works - aci_encap_pool: - <<: *aci_pool_absent_static - state: query - pool: "{{ fake_var | default(omit) }}" - pool_allocation_mode: "{{ fake_var | default(omit) }}" - register: get_all_pools - -- name: assertion test - query - assert: - that: - - get_all_pools is not changed - - get_all_pools.method == "GET" - - get_all_pools.current | length > 1 - -- name: get created static vlan pool - get mo works - aci_encap_pool: - <<: *aci_pool_absent_static - state: query - register: get_static_pool - -- name: assertion test - query - assert: - that: - - get_static_pool is not changed - - get_static_pool.method == "GET" - - get_static_pool.current | length == 1 - - get_static_pool.current.0.fvnsVlanInstP.attributes.allocMode == "static" - - get_static_pool.current.0.fvnsVlanInstP.attributes.name == "anstest" - -- name: get created dynamic vlan pool - get mo works - aci_encap_pool: - <<: *aci_pool_absent_dynamic - state: query - register: get_dynamic_pool - -- name: assertion test - query - assert: - that: - - get_dynamic_pool is not changed - - get_dynamic_pool.method == "GET" - - get_dynamic_pool.current | length == 1 - - get_dynamic_pool.current.0.fvnsVlanInstP.attributes.allocMode == "dynamic" - - get_dynamic_pool.current.0.fvnsVlanInstP.attributes.name == "anstest" - -- name: get created dynamic vlan pool - get mo works - aci_encap_pool: - <<: *aci_pool_absent_dynamic - state: query - pool_type: "{{ fake_var | default(omit) }}" - ignore_errors: yes - register: vlan_query_pool_type_fail - -- name: assertion test - query - assert: - that: - - vlan_query_pool_type_fail is failed - - 'vlan_query_pool_type_fail.msg == "missing required arguments: pool_type"' - -- name: delete static vlan pool - deletion works - aci_encap_pool: - <<: *aci_pool_absent_static - register: delete_static - -- name: assertion test - absent - assert: - that: - - delete_static is changed - - delete_static.method == "DELETE" - - delete_static.previous.0.fvnsVlanInstP.attributes.allocMode == "static" - - delete_static.previous.0.fvnsVlanInstP.attributes.name == "anstest" - -- name: delete dynamic vlan pool - check mode works - aci_encap_pool: - <<: *aci_pool_absent_dynamic - check_mode: yes - register: delete_check_mode - -- name: assertion test - absent - assert: - that: - - delete_check_mode is changed - -- name: delete dynamic vlan pool - deletion works - aci_encap_pool: - <<: *aci_pool_absent_dynamic - register: delete_dynamic - -- name: assertion test - absent - assert: - that: - - delete_dynamic is changed - - delete_dynamic.method == "DELETE" - - delete_dynamic.previous.0.fvnsVlanInstP.attributes.allocMode == "dynamic" - - delete_dynamic.previous.0.fvnsVlanInstP.attributes.name == "anstest" - -- name: delete static vlan pool again - idempotency works - aci_encap_pool: - <<: *aci_pool_absent_static - register: idempotent_delete_static - -- name: assertion test - absent - assert: - that: - - idempotent_delete_static is not changed - - idempotent_delete_static.previous == [] - -- name: delete dynamic vlan pool again - idempotency works - aci_encap_pool: - <<: *aci_pool_absent_dynamic - register: idempotent_delete_dynamic - -- name: assertion test - absent - assert: - that: - - idempotent_delete_dynamic is not changed - - idempotent_delete_dynamic.previous == [] diff --git a/test/integration/targets/aci_encap_pool/tasks/vsan.yml b/test/integration/targets/aci_encap_pool/tasks/vsan.yml deleted file mode 100644 index daaf3c245e..0000000000 --- a/test/integration/targets/aci_encap_pool/tasks/vsan.yml +++ /dev/null @@ -1,14 +0,0 @@ ---- -- name: ensure vlan pool does not exist for tests to kick off - aci_encap_pool: &aci_pool_absent_static - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - pool: anstest - pool_type: vsan - pool_allocation_mode: static - state: absent diff --git a/test/integration/targets/aci_encap_pool/tasks/vxlan.yml b/test/integration/targets/aci_encap_pool/tasks/vxlan.yml deleted file mode 100644 index 2f45a98ea0..0000000000 --- a/test/integration/targets/aci_encap_pool/tasks/vxlan.yml +++ /dev/null @@ -1,177 +0,0 @@ ---- -- name: ensure vxlan pool anstest does not exist for tests to kick off - aci_encap_pool: &aci_vxlan_absent - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - state: absent - pool: anstest - pool_type: vxlan - -- name: ensure vxlan pool anstest_2 does not exist for tests to kick off - aci_encap_pool: - <<: *aci_vxlan_absent - pool: anstest_2 - -- name: ensure vxlan pool anstest_3 does not exist for tests to kick off - aci_encap_pool: - <<: *aci_vxlan_absent - pool: anstest_3 - -- name: create vxlan pool - check mode works - aci_encap_pool: &aci_vxlan_present - <<: *aci_vxlan_absent - state: present - descr: Ansible Test - check_mode: yes - register: create_vxlan_check_mode - -- name: assertion test - present - assert: - that: - - create_vxlan_check_mode is changed - - 'create_vxlan_check_mode.sent == {"fvnsVxlanInstP": {"attributes": {"descr": "Ansible Test", "name": "anstest"}}}' - -- name: create vxlan pool - creation works - aci_encap_pool: - <<: *aci_vxlan_present - register: create_vxlan - -- name: assertion test - present - assert: - that: - - create_vxlan is changed - - create_vxlan.previous == [] - - create_vxlan.sent == create_vxlan_check_mode.sent - -- name: create vxlan pool again - idempotency works - aci_encap_pool: - <<: *aci_vxlan_present - register: idempotent_vxlan - -- name: assertion test - present - assert: - that: - - idempotent_vxlan is not changed - - 'idempotent_vxlan.previous.0.fvnsVxlanInstP.attributes.name == "anstest"' - - idempotent_vxlan.sent == {} - -- name: update vxlan pool - update works - aci_encap_pool: - <<: *aci_vxlan_present - descr: Ansible Test Change - register: update_vxlan - -- name: assertion test - present - assert: - that: - - update_vxlan is changed - - 'update_vxlan.sent == {"fvnsVxlanInstP": {"attributes": {"descr": "Ansible Test Change"}}}' - -- name: create vxlan pool - used for query - aci_encap_pool: - <<: *aci_vxlan_present - name: anstest_2 - register: create_vxlan_2 - -- name: assertion test - present - assert: - that: - - create_vxlan_2 is changed - -- name: create vxlan pool with pool allocation mode - failure message works - aci_encap_pool: - <<: *aci_vxlan_present - name: anstest_3 - pool_allocation_mode: dynamic - ignore_errors: yes - register: create_vxlan_alloc_mode - -- name: assertion test - present - assert: - that: - - create_vxlan_alloc_mode is failed - - "create_vxlan_alloc_mode.msg == 'vxlan pools do not support setting the \\'pool_allocation_mode\\'; please remove this parameter from the task'" - -- name: get vxlan pool - get object works - aci_encap_pool: &aci_vxlan_query - <<: *aci_vxlan_present - state: query - register: query_vxlan - -- name: assertion test - query - assert: - that: - - query_vxlan is not changed - - query_vxlan.current | length == 1 - - '"infra/vxlanns-anstest.json" in query_vxlan.url' - -- name: get created static vlan pool - get class works - aci_encap_pool: - <<: *aci_vxlan_query - pool: "{{ fake_var | default(omit) }}" - register: query_vxlan_all - -- name: assertion test - query - assert: - that: - - query_vxlan_all is not changed - - query_vxlan_all.current | length > 1 - - '"class/fvnsVxlanInstP.json" in query_vxlan_all.url' - -- name: delete vxlan pool - check mode works - aci_encap_pool: - <<: *aci_vxlan_absent - check_mode: yes - register: delete_vxlan_check_mode - -- name: assertion test - absent - assert: - that: - - delete_vxlan_check_mode is changed - - delete_vxlan_check_mode.previous != [] - -- name: delete vxlan pool - deletion works - aci_encap_pool: - <<: *aci_vxlan_absent - register: delete_vxlan - -- name: assertion test - absent - assert: - that: - - delete_vxlan is changed - - delete_vxlan.previous == delete_vxlan_check_mode.previous - - delete_vxlan.previous.0.fvnsVxlanInstP.attributes.name == "anstest" - -- name: delete vxlan pool again - idempotency works - aci_encap_pool: - <<: *aci_vxlan_absent - register: delete_vxlan_idempotent - -- name: missing param - failure message works - aci_encap_pool: - <<: *aci_vxlan_absent - pool: "{{ fake_var | default(omit) }}" - ignore_errors: yes - register: delete_vxlan_pool_fail - -- name: assertion test - absent - assert: - that: - - delete_vxlan_idempotent is not changed - - delete_vxlan_idempotent.previous == [] - -- name: delete vxlan pool - cleanup - aci_encap_pool: - <<: *aci_vxlan_absent - pool: anstest_2 - -- name: assertion test - absent - assert: - that: - - delete_vxlan_pool_fail is failed - - 'delete_vxlan_pool_fail.msg == "state is absent but all of the following are missing: pool"' diff --git a/test/integration/targets/aci_encap_pool_range/aliases b/test/integration/targets/aci_encap_pool_range/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_encap_pool_range/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_encap_pool_range/tasks/main.yml b/test/integration/targets/aci_encap_pool_range/tasks/main.yml deleted file mode 100644 index 99ff04a24b..0000000000 --- a/test/integration/targets/aci_encap_pool_range/tasks/main.yml +++ /dev/null @@ -1,18 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Jacob McGill (@jmcgill298) - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: test that we have an aci apic host, aci username and aci password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - -- include_tasks: vlan.yml - when: "vlan is not defined or (vlan is defined and vlan == 'True')" - -- include_tasks: vxlan.yml - when: "vxlan is not defined or (vxlan is defined and vxlan == 'True')" - -- include_tasks: vsan.yml - when: "vsan is not defined or (vsan is defined and vsan == 'True')" diff --git a/test/integration/targets/aci_encap_pool_range/tasks/vlan.yml b/test/integration/targets/aci_encap_pool_range/tasks/vlan.yml deleted file mode 100644 index 5f8d26e60f..0000000000 --- a/test/integration/targets/aci_encap_pool_range/tasks/vlan.yml +++ /dev/null @@ -1,383 +0,0 @@ -- name: ensure vlan pool exists for tests to kick off - aci_encap_pool: - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - state: absent - pool: anstest - pool_type: vlan - allocation_mode: static - description: Ansible Test - -- name: ensure vlan pool exists for tests to kick off - aci_encap_pool: &aci_pool_present - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - state: present - pool: anstest - pool_type: vlan - allocation_mode: static - description: Ansible Test - register: pool_present - -- name: create vlan pool range - check mode works - aci_encap_pool_range: &aci_range_present - <<: *aci_pool_present - range_name: anstest - range_start: 20 - range_end: 40 - pool: anstest - pool_allocation_mode: static - allocation_mode: inherit - description: Ansible Test - check_mode: yes - register: range_present_check_mode - -- name: present assertions - assert: - that: - - range_present_check_mode is changed - - 'range_present_check_mode.sent == {"fvnsEncapBlk": {"attributes": {"allocMode": "inherit", "descr": "Ansible Test", "from": "vlan-20", "name": "anstest", "to": "vlan-40"}}}' - -- name: create vlan pool range - creation works - aci_encap_pool_range: - <<: *aci_range_present - register: range_present - -- name: present assertions - assert: - that: - - range_present is changed - - range_present.previous == [] - - range_present.sent == range_present_check_mode.sent - - range_present.sent == range_present.proposed - -- name: create vlan pool range - idempotency works - aci_encap_pool_range: - <<: *aci_range_present - register: range_present_idempotent - -- name: present assertions - assert: - that: - - range_present_idempotent is not changed - - range_present_idempotent.previous.0.fvnsEncapBlk.attributes.name == "anstest" - -- name: update vlan pool range - update works - aci_encap_pool_range: - <<: *aci_range_present - description: Ansible Test Update - allocation_mode: inherit - register: range_present_update - -- name: present assertions - assert: - that: - - range_present_update is changed - - range_present_update.previous != [] - - range_present_update.sent != range_present.sent - -- name: create vlan pool range - used for query - aci_encap_pool_range: &aci_range_present_2 - <<: *aci_range_present - range_name: anstest_2 - range_start: 50 - range_end: 55 - register: range_present_2 - -- name: present assertions - assert: - that: - - range_present_2 is changed - - range_present_2.previous == [] - -- name: invalid range_start - error message works - aci_encap_pool_range: - <<: *aci_range_present - range_start: 0 - ignore_errors: yes - register: range_start_low - -- name: present assertions - assert: - that: - - range_start_low is failed - - range_start_low.msg == 'vlan pools must have "range_start" and "range_end" values between 1 and 4094' - -- name: invalid range_start - error message works - aci_encap_pool_range: - <<: *aci_range_present - range_start: 4096 - ignore_errors: yes - register: range_start_high - -- name: present assertions - assert: - that: - - range_start_high is failed - - range_start_high.msg == 'vlan pools must have "range_start" and "range_end" values between 1 and 4094' - -- name: invalid range_end - error message works - aci_encap_pool_range: - <<: *aci_range_present - range_end: 0 - ignore_errors: yes - register: range_end_low - -- name: present assertions - assert: - that: - - range_end_low is failed - - range_end_low.msg == 'vlan pools must have "range_start" and "range_end" values between 1 and 4094' - -- name: invalid range_end - error message works - aci_encap_pool_range: - <<: *aci_range_present - range_end: 4096 - ignore_errors: yes - register: range_end_high - -- name: present assertions - assert: - that: - - range_end_high is failed - - range_end_high.msg == 'vlan pools must have "range_start" and "range_end" values between 1 and 4094' - -- name: range start higher than range end - error message works - aci_encap_pool_range: - <<: *aci_range_present - range_start: 1000 - ignore_errors: yes - register: range_start_end - -- name: present assertions - assert: - that: - - range_start_end is failed - - range_start_end.msg == 'The "range_start" must be less than or equal to the "range_end"' - -- name: missing required param - error message works - aci_encap_pool_range: - <<: *aci_range_present - pool_type: '{{ omit }}' - ignore_errors: yes - register: range_present_pool_type - -- name: present assertions - assert: - that: - - range_present_pool_type is failed - - "range_present_pool_type.msg == 'missing required arguments: pool_type'" - -- name: missing required param - error message works - aci_encap_pool_range: - <<: *aci_pool_present - ignore_errors: yes - register: range_present_missing_param - -- name: present assertions - assert: - that: - - range_present_missing_param is failed - - "range_present_missing_param.msg == 'state is present but all of the following are missing: range_end, range_name, range_start'" - -- name: missing required param - error message works - aci_encap_pool_range: - <<: *aci_range_present - pool_allocation_mode: '{{ omit }}' - ignore_errors: yes - register: range_present_allocation - -- name: present assertions - assert: - that: - - range_present_allocation is failed - - range_present_allocation.msg == 'ACI requires the "pool_allocation_mode" for "pool_type" of "vlan" and "vsan" when the "pool" is provided' - -- name: query specific vlan pool range - aci_encap_pool_range: &aci_range_query - <<: *aci_range_present - state: query - register: range_query - -- name: query assertions - assert: - that: - - range_query is not changed - - range_query.url.endswith("infra/vlanns-[anstest]-static/from-[vlan-20]-to-[vlan-40].json") - - range_query.current | length == 1 - - range_query.current.0.fvnsEncapBlk.attributes.name == "anstest" - -- name: query vlan pool range - from, to, and name are filtered - aci_encap_pool_range: &aci_range_query_filter - <<: *aci_range_query - pool: '{{ omit }}' - register: range_query_from_to_name - -- name: query assertions - assert: - that: - - range_query_from_to_name is not changed - - range_query_from_to_name.url.endswith("class/fvnsEncapBlk.json") - - '"eq(fvnsEncapBlk.from, \"vlan-20\")" in range_query_from_to_name.filter_string' - - '"eq(fvnsEncapBlk.name, \"anstest\")" in range_query_from_to_name.filter_string' - - '"eq(fvnsEncapBlk.to, \"vlan-40\")" in range_query_from_to_name.filter_string' - - range_query_from_to_name.current.0.fvnsEncapBlk.attributes.name == "anstest" - - range_query_from_to_name.current.0.fvnsEncapBlk.attributes.from == "vlan-20" - - range_query_from_to_name.current.0.fvnsEncapBlk.attributes.to == "vlan-40" - -- name: query vlan pool range - from and name are filtered - aci_encap_pool_range: - <<: *aci_range_query_filter - range_end: '{{ omit }}' - register: range_query_from_name - -- name: query assertions - assert: - that: - - range_query_from_name is not changed - - range_query_from_name.url.endswith("class/fvnsEncapBlk.json") - - '"eq(fvnsEncapBlk.from, \"vlan-20\")" in range_query_from_name.filter_string' - - '"eq(fvnsEncapBlk.name, \"anstest\")" in range_query_from_name.filter_string' - - range_query_from_name.current.0.fvnsEncapBlk.attributes.name == "anstest" - - range_query_from_name.current.0.fvnsEncapBlk.attributes.from == "vlan-20" - -- name: query vlan pool range - to and name are filtered - aci_encap_pool_range: - <<: *aci_range_query_filter - range_start: '{{ omit }}' - register: range_query_to_name - -- name: query assertions - assert: - that: - - range_query_to_name is not changed - - range_query_to_name.url.endswith('class/fvnsEncapBlk.json') - - '"eq(fvnsEncapBlk.name, \"anstest\")" in range_query_to_name.filter_string' - - '"eq(fvnsEncapBlk.to, \"vlan-40\")" in range_query_to_name.filter_string' - - range_query_to_name.current.0.fvnsEncapBlk.attributes.name == "anstest" - - range_query_to_name.current.0.fvnsEncapBlk.attributes.to == "vlan-40" - -- name: query vlan pool range - name is filtered - aci_encap_pool_range: - <<: *aci_range_query_filter - range_start: '{{ omit) }}' - range_end: '{{ omit }}' - register: range_query_name - -- name: query assertions - assert: - that: - - range_query_name is not changed - - range_query_name.url.endswith("class/fvnsEncapBlk.json") - - '"eq(fvnsEncapBlk.name, \"anstest\")" in range_query_name.filter_string' - - range_query_name.current.0.fvnsEncapBlk.attributes.name == "anstest" - -- name: query vlan pool range - from and to are filtered - aci_encap_pool_range: - <<: *aci_range_query_filter - range_name: '{{ omit }}' - register: range_query_from_to - -- name: query assertions - assert: - that: - - range_query_from_to is not changed - - range_query_from_to.url.endswith("class/fvnsEncapBlk.json") - - '"eq(fvnsEncapBlk.from, \"vlan-20\")" in range_query_from_to.filter_string' - - '"eq(fvnsEncapBlk.to, \"vlan-40\")" in range_query_from_to.filter_string' - - range_query_from_to.current.0.fvnsEncapBlk.attributes.from == "vlan-20" - - range_query_from_to.current.0.fvnsEncapBlk.attributes.to == "vlan-40" - -- name: query all ranges in a vlan pool - aci_encap_pool_range: - <<: *aci_pool_present - state: query - pool_allocation_mode: static - register: range_query_pool - -- name: query assertions - assert: - that: - - range_query_pool.current | length == 1 - - range_query_pool.current.0.fvnsVlanInstP.attributes.name == "anstest" - - range_query_pool.current.0.fvnsVlanInstP.children | length > 1 - - range_query_pool.url.endswith("infra/vlanns-[anstest]-static.json") - -- name: query all ranges - aci_encap_pool_range: - <<: *aci_pool_present - state: query - pool: '{{ omit }}' - register: range_query_all - -- name: query assertions - assert: - that: - - range_query_all is not changed - - range_query_all.current | length > 1 - - range_query_all.current.0.fvnsEncapBlk is defined - - range_query_all.url.endswith("class/fvnsEncapBlk.json") - -- name: delete vlan pool range - deletion works - aci_encap_pool_range: - <<: *aci_range_present - state: absent - register: delete_range - -- name: absent assertions - assert: - that: - - delete_range is changed - - delete_range.proposed == {} - - delete_range.previous.0.fvnsEncapBlk.attributes.name == "anstest" - -- name: delete vlan pool range - check mode works - aci_encap_pool_range: &aci_range_absent - <<: *aci_range_present_2 - state: absent - check_mode: yes - register: delete_check_mode - -- name: absent assertions - assert: - that: - - delete_check_mode is changed - - delete_check_mode.previous != [] - -- name: delete vlan pool range - deletion works - aci_encap_pool_range: - <<: *aci_range_absent - register: delete_range_2 - -- name: absent assertions - assert: - that: - - delete_range_2 is changed - - delete_range_2.previous == delete_check_mode.previous - -- name: delete vlan pool range again - idempotency works - aci_encap_pool_range: - <<: *aci_range_absent - register: delete_idempotent - -- name: absent assertions - assert: - that: - - delete_idempotent is not changed - - delete_idempotent.previous == [] - -- name: cleanup vlan pool - aci_encap_pool: - <<: *aci_pool_present - state: absent - when: pool_present is changed diff --git a/test/integration/targets/aci_encap_pool_range/tasks/vsan.yml b/test/integration/targets/aci_encap_pool_range/tasks/vsan.yml deleted file mode 100644 index 6e71b709a2..0000000000 --- a/test/integration/targets/aci_encap_pool_range/tasks/vsan.yml +++ /dev/null @@ -1,20 +0,0 @@ -- name: ensure vsan pool exists for tests to kick off - aci_encap_pool: &aci_pool_present - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - pool: anstest - pool_type: vsan - allocation_mode: static - description: Ansible Test - state: present - -- name: cleanup vsan pool - aci_encap_pool: - <<: *aci_pool_present - state: absent - when: pool_present is changed diff --git a/test/integration/targets/aci_encap_pool_range/tasks/vxlan.yml b/test/integration/targets/aci_encap_pool_range/tasks/vxlan.yml deleted file mode 100644 index abfc57a6ed..0000000000 --- a/test/integration/targets/aci_encap_pool_range/tasks/vxlan.yml +++ /dev/null @@ -1,19 +0,0 @@ -- name: ensure vxlan pool exists for tests to kick off - aci_encap_pool: &aci_pool_present - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - pool: anstest - pool_type: vxlan - description: Ansible Test - state: present - -- name: cleanup vxlan pool - aci_encap_pool: - <<: *aci_pool_present - state: absent - when: pool_present is changed diff --git a/test/integration/targets/aci_epg/aliases b/test/integration/targets/aci_epg/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_epg/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_epg/tasks/main.yml b/test/integration/targets/aci_epg/tasks/main.yml deleted file mode 100644 index 11a4f0dc46..0000000000 --- a/test/integration/targets/aci_epg/tasks/main.yml +++ /dev/null @@ -1,171 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Jacob McGill (@jmcgill298) - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - -- name: ensure tenant exists for tests to kick off - aci_tenant: &aci_tenant_present - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - state: present - tenant: anstest - register: tenant_present - -- name: ensure bd exists for tests to kick off - aci_bd: &aci_bd_present - <<: *aci_tenant_present - bd: anstest - register: bd_present - -- name: ensure ap exists for tests to kick off - aci_ap: &aci_ap_present - <<: *aci_tenant_present - ap: anstest - register: ap_present - -- name: create epg - check mode works - aci_epg: &aci_epg_present - <<: *aci_ap_present - epg: anstest - bd: anstest - description: Ansible Test - check_mode: yes - register: epg_present_check_mode - -- name: create epg - creation works - aci_epg: - <<: *aci_epg_present - register: epg_present - -- name: create epg - idempotency works - aci_epg: - <<: *aci_epg_present - register: epg_present_idempotent - -- name: update epg - update works - aci_epg: - <<: *aci_epg_present - description: Ansible Test Update - register: epg_present_update - -- name: create epg - missing param - aci_epg: - <<: *aci_epg_present - ap: "{{ fakevar | default(omit) }}" - ignore_errors: yes - register: epg_present_missing_param - -- name: create epg - used for query - aci_epg: - <<: *aci_epg_present - epg: anstest2 - -- name: present assertions - assert: - that: - - epg_present_check_mode is changed - - epg_present_check_mode.previous == [] - - epg_present_check_mode.sent.fvAEPg.attributes != {} - - epg_present_check_mode.sent.fvAEPg.children.0.fvRsBd.attributes.tnFvBDName == "anstest" - - epg_present is changed - - epg_present.sent == epg_present_check_mode.sent - - epg_present_idempotent is not changed - - epg_present_idempotent.sent == {} - - epg_present_update is changed - - 'epg_present_update.sent == {"fvAEPg": {"attributes": {"descr": "Ansible Test Update"}}}' - - epg_present_missing_param is failed - - 'epg_present_missing_param.msg == "state is present but all of the following are missing: ap"' - -- name: get specific epg - aci_epg: - <<: *aci_epg_present - state: query - register: epg_query - -- name: get all epgs - aci_epg: - <<: *aci_tenant_present - state: query - tenant: "{{ fakevar | default(omit) }}" - register: epg_query_all - -- name: query assertions - assert: - that: - - epg_query is not changed - - epg_query.current | length == 1 - - epg_query.current.0.fvAEPg.attributes.name == "anstest" - - '"tn-anstest/ap-anstest/epg-anstest.json" in epg_query.url' - - epg_query_all is not changed - - epg_query_all.current | length > 1 - - '"rsp-subtree-class=fvRsBd" in epg_query_all.filter_string' - - '"class/fvAEPg.json" in epg_query_all.url' - -- name: delete epg - check mode works - aci_epg: &aci_epg_absent - <<: *aci_epg_present - state: absent - check_mode: yes - register: delete_epg_check_mode - -- name: delete epg - delete works - aci_epg: - <<: *aci_epg_absent - register: delete_epg - -- name: delete epg - idempotency works - aci_epg: - <<: *aci_epg_absent - register: delete_epg_idempotent - -- name: delete epg - cleanup extra epg - aci_epg: - <<: *aci_epg_absent - epg: anstest2 - -- name: delete epg - missing param fails - aci_epg: - <<: *aci_epg_absent - tenant: "{{ fakevar | default(omit) }}" - ignore_errors: yes - register: delete_epg_missing_param - -- name: query assertions - assert: - that: - - delete_epg_check_mode is changed - - delete_epg_check_mode.previous != [] - - delete_epg is changed - - delete_epg.previous == delete_epg_check_mode.previous - - delete_epg_idempotent is not changed - - delete_epg_idempotent.previous == [] - - delete_epg_missing_param is failed - - 'delete_epg_missing_param.msg == "state is absent but all of the following are missing: tenant"' - -- name: cleanup bd - aci_bd: - <<: *aci_bd_present - state: absent - when: bd_present.previous == [] - -- name: cleanup ap - aci_ap: - <<: *aci_ap_present - state: absent - when: ap_present.previous == [] - -- name: cleanup tenant - aci_tenant: - <<: *aci_tenant_present - state: absent - when: tenant_present.previous == [] diff --git a/test/integration/targets/aci_epg_to_contract/aliases b/test/integration/targets/aci_epg_to_contract/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_epg_to_contract/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_epg_to_contract/tasks/main.yml b/test/integration/targets/aci_epg_to_contract/tasks/main.yml deleted file mode 100644 index c9b06fd691..0000000000 --- a/test/integration/targets/aci_epg_to_contract/tasks/main.yml +++ /dev/null @@ -1,254 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Jacob McGill (@jmcgill298) - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - -- name: Ensure contract binding does not exist prior to testing - aci_epg_to_contract: - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - tenant: anstest - ap: anstest - epg: anstest - contract_type: provider - contract: "anstest_http" - state: absent - -- name: ensure tenant exists for tests to kick off - aci_tenant: &aci_tenant_present - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - tenant: anstest - state: present - register: tenant_present - -- name: ensure contracts exist for tests to kick off - aci_contract: - <<: *aci_tenant_present - contract: "{{ item }}" - with_items: ["anstest_http", "anstest_https", "anstest_db"] - -- name: ensure ap exists - aci_ap: &aci_ap_present - <<: *aci_tenant_present - ap: anstest - register: ap_present - -- name: ensure epg exists - aci_epg: &aci_epg_present - <<: *aci_ap_present - epg: anstest - register: epg_present - -- name: bind contract to epg - check mode works - aci_epg_to_contract: &aci_epg_provide_present - <<: *aci_epg_present - contract_type: provider - contract: anstest_http - check_mode: yes - register: provide_present_check_mode - -- name: bind contract to epg - provide works - aci_epg_to_contract: - <<: *aci_epg_provide_present - register: provide_present - -- name: bind contract to epg - consume works - aci_epg_to_contract: &aci_epg_consume_present - <<: *aci_epg_provide_present - contract_type: consumer - contract: anstest_db - register: consume_present - -- name: bind contract to epg - add additional contract - aci_epg_to_contract: &aci_epg_provide_present2 - <<: *aci_epg_provide_present - contract: anstest_https - provider_match: at_most_one - register: provide_present2 - -- name: bind contract to epg - idempotency works - aci_epg_to_contract: - <<: *aci_epg_provide_present - register: idempotent_present - -- name: missing param - failure message works - aci_epg_to_contract: - <<: *aci_tenant_present - contract_type: provider - ignore_errors: yes - register: missing_param_present - -- name: missing required param - failure message works - aci_epg_to_contract: - <<: *aci_tenant_present - ignore_errors: yes - register: missing_required_present - -- name: incompatible param - failure message works - aci_epg_to_contract: - <<: *aci_epg_consume_present - provider_match: all - ignore_errors: yes - register: incompatible_present - -- name: present assertions - assert: - that: - - provide_present_check_mode is changed - - 'provide_present_check_mode.sent == {"fvRsProv": {"attributes": {"tnVzBrCPName": "anstest_http"}}}' - - provide_present is changed - - provide_present.sent == provide_present_check_mode.sent - - provide_present.previous == [] - - consume_present is changed - - consume_present.previous == [] - - 'consume_present.sent == {"fvRsCons": {"attributes": {"tnVzBrCPName": "anstest_db"}}}' - - provide_present2 is changed - - provide_present2.previous == [] - - missing_param_present is failed - - 'missing_param_present.msg == "state is present but all of the following are missing: ap, contract, epg"' - - missing_required_present is failed - - 'missing_required_present.msg == "missing required arguments: contract_type"' - - incompatible_present is failed - - incompatible_present.msg == "the 'provider_match' is only configurable for Provided Contracts" - -- name: get binding - aci_epg_to_contract: - <<: *aci_epg_provide_present2 - state: query - register: query_provide_contract - -- name: get binding - aci_epg_to_contract: - <<: *aci_epg_consume_present - state: query - register: query_consume_contract - -- name: get all bindings - aci_epg_to_contract: - <<: *aci_tenant_present - state: query - tenant: "{{ fakevar | default(omit) }}" - contract_type: provider - register: query_all - -- name: missing required param - failure message works - aci_epg_to_contract: - <<: *aci_tenant_present - state: query - ignore_errors: yes - register: missing_required_query - -- name: query assertions - assert: - that: - - query_provide_contract is not changed - - query_provide_contract.current != [] - - '"uni/tn-anstest/ap-anstest/epg-anstest/rsprov-anstest_https.json" in query_provide_contract.url' - - query_consume_contract is not changed - - query_consume_contract.current != [] - - '"uni/tn-anstest/ap-anstest/epg-anstest/rscons-anstest_db.json" in query_consume_contract.url' - - query_all is not changed - - '"class/fvRsProv.json" in query_all.url' - - missing_required_query is failed - - 'missing_required_query.msg == "missing required arguments: contract_type"' - -- name: delete consume binding - check mode works - aci_epg_to_contract: &aci_epg_consume_absent - <<: *aci_epg_consume_present - state: absent - check_mode: yes - register: consume_absent_check_mode - -- name: delete consume binding - deletion works - aci_epg_to_contract: - <<: *aci_epg_consume_absent - register: consume_absent - -- name: delete provide binding - deletion works - aci_epg_to_contract: - <<: *aci_epg_provide_present - state: absent - register: provide_absent - -- name: delete provide binding - deletion works - aci_epg_to_contract: - <<: *aci_epg_provide_present2 - state: absent - register: provide_absent2 - -- name: delete consume binding - idempotency works - aci_epg_to_contract: - <<: *aci_epg_consume_absent - register: consume_absent_idempotent - -- name: missing param - failure message works - aci_epg_to_contract: - <<: *aci_epg_consume_absent - contract: "{{ fakevar | default(omit) }}" - ignore_errors: yes - register: missing_param_absent - -- name: missing required param - failure message works - aci_epg_to_contract: - <<: *aci_epg_consume_absent - contract_type: "{{ fakevar | default(omit) }}" - ignore_errors: yes - register: missing_required_absent - -- name: absent assertions - assert: - that: - - consume_absent_check_mode is changed - - consume_absent_check_mode.previous.0.fvRsCons is defined - - consume_absent is changed - - consume_absent.previous == consume_absent_check_mode.previous - - provide_absent is changed - - provide_absent.previous.0.fvRsProv is defined - - provide_absent2 is changed - - consume_absent_idempotent is not changed - - consume_absent_idempotent.previous == [] - - missing_param_absent is failed - - 'missing_param_absent.msg == "state is absent but all of the following are missing: contract"' - - missing_required_absent is failed - - 'missing_required_absent.msg == "missing required arguments: contract_type"' - -- name: cleanup contracts - aci_contract: - <<: *aci_tenant_present - state: absent - contract: "{{ item }}" - with_items: ["anstest_http", "anstest_https", "anstest_db"] - -- name: cleanup epg - aci_epg: - <<: *aci_epg_present - state: absent - when: epg_present is changed - -- name: cleanup ap - aci_ap: - <<: *aci_ap_present - state: absent - when: ap_present is changed - -- name: cleanup tenant - aci_tenant: - <<: *aci_tenant_present - state: absent - when: tenant_present is changed diff --git a/test/integration/targets/aci_epg_to_domain/aliases b/test/integration/targets/aci_epg_to_domain/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_epg_to_domain/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_epg_to_domain/tasks/main.yml b/test/integration/targets/aci_epg_to_domain/tasks/main.yml deleted file mode 100644 index 5d95059a6e..0000000000 --- a/test/integration/targets/aci_epg_to_domain/tasks/main.yml +++ /dev/null @@ -1,217 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Dag Wieers (@dagwieers) <dag@wieers.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - -- name: ensure tenant exists for tests to kick off - aci_tenant: &aci_tenant_present - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - tenant: anstest - state: present - register: tenant_present - -- name: ensure ap exists for tests to kick off - aci_ap: &aci_ap_present - <<: *aci_tenant_present - ap: anstest - register: ap_present - -- name: ensure epg exists for tests to kick off - aci_epg: &aci_epg_present - <<: *aci_ap_present - epg: anstest - register: epg_present - -- name: ensure phys domain exists for tests to kick off - aci_rest: &aci_rest_phys_domain - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - method: post - path: api/mo/uni/phys-anstest.json - content: {"physDomP": {"attributes": {}}} - register: phys_domain_post - -- name: ensure vmm domain exists for tests to kick off - aci_rest: &aci_rest_vmm_domain - <<: *aci_rest_phys_domain - path: api/mo/uni/vmmp-VMware/dom-anstest.json - content: {"vmmDomP": {"attributes": {}}} - register: vmm_domain_post - -- name: bind phys domain to epg - check mode works - aci_epg_to_domain: &aci_epg_to_domain_present - <<: *aci_epg_present - domain: anstest - domain_type: phys - check_mode: yes - register: phys_check_mode_present - -- name: bind phys domain to epg - creation works - aci_epg_to_domain: - <<: *aci_epg_to_domain_present - register: phys_present - -- name: bind phys domain to epg - idempotency works - aci_epg_to_domain: - <<: *aci_epg_to_domain_present - register: phys_idempotent - -- name: bind phys domain to epg - update works - aci_epg_to_domain: - <<: *aci_epg_to_domain_present - deploy_immediacy: immediate - register: phys_update - -- name: bind vmm domain to epg - creation works - aci_epg_to_domain: &aci_epg_to_domain_vmm_present - <<: *aci_epg_to_domain_present - domain_type: vmm - vm_provider: vmware - resolution_immediacy: pre-provision - register: vmm_present - -- name: bind vmm domain to epg - missing params - aci_epg_to_domain: - <<: *aci_epg_to_domain_vmm_present - vm_provider: "{{ fake_var | default(omit) }}" - ignore_errors: yes - register: present_missing_params - -- name: bind vmm domain to epg - invalid vlan - aci_epg_to_domain: - <<: *aci_epg_to_domain_present - encap: 4097 - ignore_errors: yes - register: invalid_vlan - -- name: bind vmm domain to epg - incompatible params - aci_epg_to_domain: - <<: *aci_epg_to_domain_present - vm_provider: vmware - ignore_errors: yes - register: incompatible_params - -- name: present assertions - assert: - that: - - phys_check_mode_present is changed - - phys_present is changed - - phys_present.previous == [] - - 'phys_present.sent == {"fvRsDomAtt": {"attributes": {}}}' - - '"[uni/phys-anstest].json" in phys_present.url' - - phys_idempotent is not changed - - phys_idempotent.sent == {} - - phys_update is changed - - 'phys_update.sent == {"fvRsDomAtt": {"attributes": {"instrImedcy": "immediate"}}}' - - vmm_present is changed - - 'vmm_present.sent == {"fvRsDomAtt": {"attributes": {"resImedcy": "pre-provision"}}}' - - '"[uni/vmmp-VMware/dom-anstest].json" in vmm_present.url' - - present_missing_params is failed - - 'present_missing_params.msg == "domain_type is vmm but all of the following are missing: vm_provider"' - - invalid_vlan is failed - - invalid_vlan.msg == "Valid VLAN assigments are from 1 to 4096" - - incompatible_params is failed - - incompatible_params.msg == "Domain type 'phys' cannot have a 'vm_provider'" - -- name: get domain epg binding - aci_epg_to_domain: &aci_epg_domain_query - <<: *aci_tenant_present - state: query - tenant: "{{ fake_var | default(omit) }}" - register: binding_query - -- name: query assertions - assert: - that: - - binding_query is not changed - - binding_query.current | length > 1 - - '"class/fvRsDomAtt.json" in binding_query.url' - -- name: delete domain epg binding - check mode - aci_epg_to_domain: &aci_epg_to_domain_absent - <<: *aci_epg_to_domain_present - state: absent - check_mode: yes - register: epg_domain_check_mode_absent - -- name: delete phys domain epg binding - delete works - aci_epg_to_domain: - <<: *aci_epg_to_domain_absent - register: epg_domain_absent - -- name: delete vmm domain epg binding - delete works - aci_epg_to_domain: - <<: *aci_epg_to_domain_vmm_present - state: absent - register: epg_vmm_domain_absent - -- name: delete domain epg binding - idempotency works - aci_epg_to_domain: - <<: *aci_epg_to_domain_absent - register: idempotency_absent - -- name: delete domain epg binding - missing param - aci_epg_to_domain: - <<: *aci_tenant_present - state: absent - ignore_errors: true - register: absent_missing_param - -- name: absent assertions - assert: - that: - - epg_domain_check_mode_absent is changed - - epg_domain_check_mode_absent.previous != [] - - epg_domain_absent is changed - - epg_domain_absent.previous == epg_domain_check_mode_absent.previous - - epg_vmm_domain_absent is changed - - idempotency_absent is not changed - - idempotency_absent.previous == [] - - absent_missing_param is failed - - 'absent_missing_param.msg == "state is absent but all of the following are missing: ap, domain, domain_type, epg"' - -- name: remove vmm domain - cleanup - aci_rest: - <<: *aci_rest_vmm_domain - method: delete - when: vmm_domain_post is changed - -- name: remove phys domain - cleanup - aci_rest: - <<: *aci_rest_phys_domain - method: delete - when: phys_domain_post is changed - -- name: remove epg - cleanup - aci_epg: - <<: *aci_epg_present - state: absent - when: epg_present is changed - -- name: remove ap - cleanup - aci_ap: - <<: *aci_ap_present - state: absent - when: ap_present is changed - -- name: remove tenant - cleanup - aci_tenant: - <<: *aci_tenant_present - state: absent - when: tenant_present is changed diff --git a/test/integration/targets/aci_fabric_node/aliases b/test/integration/targets/aci_fabric_node/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_fabric_node/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_fabric_node/tasks/main.yml b/test/integration/targets/aci_fabric_node/tasks/main.yml deleted file mode 100644 index 4b280300bf..0000000000 --- a/test/integration/targets/aci_fabric_node/tasks/main.yml +++ /dev/null @@ -1,217 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Bruno Calogero <brunocalogero@hotmail.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - - -# CLEAN ENVIRONMENT -- name: Remove fabric node - aci_fabric_node: &aci_fabric_node_absent - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - serial: ansible_test - node_id: 105 - state: absent - - -# ADD FABRIC NODE -- name: Add fabric node (check_mode) - aci_fabric_node: &aci_fabric_node_present - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - serial: ansible_test - node_id: 105 - switch: test - state: present - check_mode: yes - register: cm_add_fabric_node - -- name: Add fabric node (normal mode) - aci_fabric_node: *aci_fabric_node_present - register: nm_add_fabric_node - -- name: Add fabric node again (check_mode) - aci_fabric_node: *aci_fabric_node_present - check_mode: yes - register: cm_add_fabric_node_again - -- name: Add fabric node again (normal mode) - aci_fabric_node: *aci_fabric_node_present - register: nm_add_fabric_node_again - -- name: Verify add_fabric_node - assert: - that: - - cm_add_fabric_node is changed - - nm_add_fabric_node is changed - # FIXME: Module is not idempotent - - cm_add_fabric_node_again is not changed - - nm_add_fabric_node_again is not changed - - -# CHANGE FABRIC NODE -- name: Change description of fabric node (check_mode) - aci_fabric_node: - <<: *aci_fabric_node_present - description: Ansible test fabric node - check_mode: yes - register: cm_add_fabric_node_descr - -- name: Change description of fabric node (normal mode) - aci_fabric_node: - <<: *aci_fabric_node_present - description: Ansible test fabric node - register: nm_add_fabric_node_descr - -- name: Change description of fabric nodeagain (check_mode) - aci_fabric_node: - <<: *aci_fabric_node_present - description: Ansible test fabric node - check_mode: yes - register: cm_add_fabric_node_descr_again - -- name: Change description of fabric node again (normal mode) - aci_fabric_node: - <<: *aci_fabric_node_present - description: Ansible test fabric node - register: nm_add_fabric_node_descr_again - -- name: Verify add_fabric_node_descr - assert: - that: - - cm_add_fabric_node_descr is changed - - nm_add_fabric_node_descr is changed - # FIXME: Module is not idempotent - - cm_add_fabric_node_descr_again is not changed - - nm_add_fabric_node_descr_again is not changed - - -# ADD FABRIC NODE AGAIN -- name: Add fabric node again with no description (check_mode) - aci_fabric_node: *aci_fabric_node_present - check_mode: yes - register: cm_add_fabric_node_again_no_descr - -- name: Add fabric node again with no description (normal mode) - aci_fabric_node: *aci_fabric_node_present - register: nm_add_fabric_node_again_no_descr - -- name: Verify add_fabric_node_again_no_descr - assert: - that: - # FIXME: Module is not idempotent - - cm_add_fabric_node_again_no_descr is not changed - - nm_add_fabric_node_again_no_descr is not changed - - -# QUERY ALL FABRIC NODES -- name: Query fabric nodes (check_mode) - aci_fabric_node: &aci_fabric_node_query - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - state: query - check_mode: yes - register: cm_query_all_fabric_nodes - -- name: Query all fabric nodes (normal mode) - aci_fabric_node: *aci_fabric_node_query - register: nm_query_all_fabric_nodes - -- name: Verify query_all_fabric_nodes - assert: - that: - - cm_query_all_fabric_nodes is not changed - - nm_query_all_fabric_nodes is not changed - - cm_query_all_fabric_nodes == nm_query_all_fabric_nodes - - -# QUERY A FABRIC NODE -- name: Query our fabric_node - aci_fabric_node: - <<: *aci_fabric_node_query - serial: ansible_test # might need node_id too - check_mode: yes - register: cm_query_fabric_node - -- name: Query our fabric_node - aci_fabric_node: - <<: *aci_fabric_node_query - serial: ansible_test - register: nm_query_fabric_node - -- name: Verify query_fabric_node - assert: - that: - - cm_query_fabric_node is not changed - - nm_query_fabric_node is not changed - - cm_query_fabric_node == nm_query_fabric_node - - -# REMOVE FABRIC NODE -- name: Remove fabric_node (check_mode) - aci_fabric_node: *aci_fabric_node_absent - check_mode: yes - register: cm_remove_fabric_node - -- name: Remove fabric_node (normal mode) - aci_fabric_node: *aci_fabric_node_absent - register: nm_remove_fabric_node - -- name: Remove fabric_node again (check_mode) - aci_fabric_node: *aci_fabric_node_absent - check_mode: yes - register: cm_remove_fabric_node_again - -- name: Remove fabric_node again (normal mode) - aci_fabric_node: *aci_fabric_node_absent - register: nm_remove_fabric_node_again - -- name: Verify remove_fabric_node - assert: - that: - - cm_remove_fabric_node is changed - - nm_remove_fabric_node is changed - - cm_remove_fabric_node_again is not changed - - nm_remove_fabric_node_again is not changed - - -# QUERY NON-EXISTING LEAF PROFILE -- name: Query non-existing fabric_node (check_mode) - aci_fabric_node: - <<: *aci_fabric_node_query - serial: ansible_test - check_mode: yes - register: cm_query_non_fabric_node - -- name: Query non-existing fabric_node (normal mode) - aci_fabric_node: - <<: *aci_fabric_node_query - serial: ansible_test - register: nm_query_non_fabric_node - -- name: Verify query_non_fabric_node - assert: - that: - - cm_query_non_fabric_node is not changed - - nm_query_non_fabric_node is not changed - - cm_query_non_fabric_node == nm_query_non_fabric_node diff --git a/test/integration/targets/aci_filter/aliases b/test/integration/targets/aci_filter/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_filter/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_filter/tasks/main.yml b/test/integration/targets/aci_filter/tasks/main.yml deleted file mode 100644 index 37513f9439..0000000000 --- a/test/integration/targets/aci_filter/tasks/main.yml +++ /dev/null @@ -1,223 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Dag Wieers (@dagwieers) <dag@wieers.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - -# CLEAN ENVIRONMENT -- name: Add tenant - aci_tenant: - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - tenant: ansible_test - state: present - -- name: Remove filter - aci_filter: &filter_absent - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - tenant: ansible_test - filter: filter_test - state: absent - -# ADD FILTER -- name: Add filter (check_mode) - aci_filter: &filter_present - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - tenant: ansible_test - filter: filter_test - state: present - check_mode: yes - register: cm_add_filter - -- name: Add filter again (check_mode) - aci_filter: *filter_present - check_mode: yes - register: cm_add_filter_again - -- name: Add filter (normal mode) - aci_filter: *filter_present - register: nm_add_filter - -- name: Add filter again (normal mode) - aci_filter: *filter_present - register: nm_add_filter_again - -- name: Verify add_filter - assert: - that: - - cm_add_filter is changed - - cm_add_filter_again is changed - - nm_add_filter is changed - - nm_add_filter_again is not changed - -# CHANGE FILTER -- name: Change description of filter (check_mode) - aci_filter: - <<: *filter_present - description: Ansible test filter - check_mode: yes - register: cm_add_filter_descr - -- name: Change description of filter again (check_mode) - aci_filter: - <<: *filter_present - description: Ansible test filter - check_mode: yes - register: cm_add_filter_descr_again - -- name: Change description of filter (normal mode) - aci_filter: - <<: *filter_present - description: Ansible test filter - register: nm_add_filter_descr - -- name: Change description of filter again (normal mode) - aci_filter: - <<: *filter_present - description: Ansible test filter - register: nm_add_filter_descr_again - -- name: Verify add_filter_descr - assert: - that: - - cm_add_filter_descr is changed - - cm_add_filter_descr_again is changed - - nm_add_filter_descr is changed - - nm_add_filter_descr_again is not changed - -# ADD FILTER AGAIN -- name: Add filter again with no description (check_mode) - aci_filter: *filter_present - check_mode: yes - register: cm_add_filter_again_no_descr - -- name: Add filter again with no description (normal mode) - aci_filter: *filter_present - register: nm_add_filter_again_no_descr - -- name: Verify add_filter_again_no_descr - assert: - that: - - cm_add_filter_again_no_descr is not changed - - nm_add_filter_again_no_descr is not changed - -# QUERY ALL FILTERS -- name: Query all filters (check_mode) - aci_filter: &filter_query - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - state: query - check_mode: yes - register: cm_query_all_filters - -- name: Query all filters (normal mode) - aci_filter: *filter_query - register: nm_query_all_filters - -- name: Verify query_all_filters - assert: - that: - - cm_query_all_filters is not changed - - nm_query_all_filters is not changed - # NOTE: Order of filters is not stable between calls - #- cm_query_all_filters == nm_query_all_filters - -# QUERY A FILTER -- name: Query our filter - aci_filter: - <<: *filter_query - tenant: ansible_test - filter: filter_test - check_mode: yes - register: cm_query_filter - -- name: Query our filter - aci_filter: - <<: *filter_query - tenant: ansible_test - filter: filter_test - register: nm_query_filter - -- name: Verify query_filter - assert: - that: - - cm_query_filter is not changed - - nm_query_filter is not changed - - cm_query_filter == nm_query_filter - -# REMOVE FILTER -- name: Remove filter (check_mode) - aci_filter: *filter_absent - check_mode: yes - register: cm_remove_filter - -- name: Remove filter again (check_mode) - aci_filter: *filter_absent - check_mode: yes - register: cm_remove_filter_again - -- name: Remove filter (normal mode) - aci_filter: *filter_absent - register: nm_remove_filter - -- name: Remove filter again (normal mode) - aci_filter: *filter_absent - register: nm_remove_filter_again - -- name: Verify remove_filter - assert: - that: - - cm_remove_filter is changed - - cm_remove_filter_again is changed - - nm_remove_filter is changed - - nm_remove_filter_again is not changed - -# QUERY NON-EXISTING FILTER -# FIXME: Should this fail or return empty values ? -- name: Query non-existing filter (check_mode) - aci_filter: - <<: *filter_query - tenant: ansible_test - filter: filter_test - check_mode: yes - register: cm_query_non_filter - -- name: Query non-existing filter (normal mode) - aci_filter: - <<: *filter_query - tenant: ansible_test - filter: filter_test - register: nm_query_non_filter - -- name: Verify query_non_filter - assert: - that: - - cm_query_non_filter is not changed - - nm_query_non_filter is not changed - - cm_query_non_filter == nm_query_non_filter diff --git a/test/integration/targets/aci_filter_entry/aliases b/test/integration/targets/aci_filter_entry/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_filter_entry/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_filter_entry/tasks/main.yml b/test/integration/targets/aci_filter_entry/tasks/main.yml deleted file mode 100644 index ca1bfa61bd..0000000000 --- a/test/integration/targets/aci_filter_entry/tasks/main.yml +++ /dev/null @@ -1,285 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Jacob McGill (@jmcgill298) - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - -- name: ensure tenant exists for tests to kick off - aci_tenant: - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - tenant: anstest - state: absent - -- name: ensure tenant exists for tests to kick off - aci_tenant: &aci_tenant_present - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - tenant: anstest - state: present - register: tenant_present - -- name: ensure filter exists for tests to kick off - aci_filter: &aci_filter_present - <<: *aci_tenant_present - filter: anstest - register: filter_present - -- name: create filter entry - check mode works - aci_filter_entry: &aci_entry_present - <<: *aci_filter_present - entry: anstest - description: Ansible Test - ether_type: ip - ip_protocol: tcp - dst_port_start: 80 - dst_port_end: 88 - check_mode: yes - register: entry_present_check_mode - -- name: create filter entry - creation works - aci_filter_entry: - <<: *aci_entry_present - register: entry_present - -- name: create filter entry - idempotency works - aci_filter_entry: - <<: *aci_entry_present - register: entry_present_idempotent - -- name: update filter entry - update works - aci_filter_entry: - <<: *aci_entry_present - description: Ansible Test Update - dst_port_start: 80 - dst_port_end: 90 - register: entry_present_update - -- name: create filter entry - test different types - aci_filter_entry: - <<: *aci_filter_present - entry: anstest2 - ether_type: arp - arp_flag: arp_reply - register: entry_present_2 - -- name: create filter entry - test different types - aci_filter_entry: - <<: *aci_filter_present - entry: anstest3 - ether_type: ip - ip_protocol: icmp - icmp_msg_type: echo - register: entry_present_3 - -- name: create filter entry - test different types - aci_filter_entry: - <<: *aci_filter_present - entry: anstest4 - ether_type: ip - ip_protocol: udp - dst_port: 1000 - register: entry_present_4 - -- name: missing param - failure message works - aci_filter_entry: - <<: *aci_filter_present - ignore_errors: yes - register: present_missing_param - -- name: incompatable params - failure message works - aci_filter_entry: - <<: *aci_entry_present - dst_port: 99 - ignore_errors: yes - register: present_incompatible_params - -- name: present assertions - assert: - that: - - entry_present_check_mode is changed - - entry_present_check_mode.previous == [] - - 'entry_present_check_mode.sent == {"vzEntry": {"attributes": {"dFromPort": "http","dToPort": "88","descr": "Ansible Test","etherT": "ip","name": "anstest","prot": "tcp"}}}' - - entry_present is changed - - entry_present.previous == [] - - entry_present.sent == entry_present_check_mode.sent - - entry_present_idempotent is not changed - - entry_present_idempotent.previous != [] - - entry_present_idempotent.sent == {} - - entry_present_update is changed - - entry_present_update.previous != [] - - entry_present_update.sent != entry_present_update.proposed - - entry_present_2 is changed - - 'entry_present_2.sent.vzEntry.attributes == {"arpOpc": "reply", "etherT": "arp", "name": "anstest2"}' - - entry_present_3 is changed - - 'entry_present_3.sent.vzEntry.attributes == {"etherT": "ip", "icmpv4T": "echo", "name": "anstest3", "prot": "icmp"}' - - entry_present_4 is changed - - 'entry_present_4.sent.vzEntry.attributes == {"dFromPort": "1000", "dToPort": "1000", "etherT": "ip", "name": "anstest4", "prot": "udp"}' - - present_missing_param is failed - - 'present_missing_param.msg == "state is present but all of the following are missing: entry"' - - present_incompatible_params is failed - - present_incompatible_params.msg.startswith("Parameter") - -- name: query tenant filter entry - aci_filter_entry: &aci_query_entry - <<: *aci_entry_present - state: query - register: query_tenant_filter_entry - -- name: query filter entry - aci_filter_entry: - <<: *aci_query_entry - tenant: "{{ fakevar | default(omit) }}" - register: query_filter_entry - -- name: query tenant entry - aci_filter_entry: - <<: *aci_query_entry - filter: "{{ fakevar | default(omit) }}" - register: query_tenant_entry - -- name: query tenant filter - aci_filter_entry: - <<: *aci_query_entry - entry: "{{ fakevar | default(omit) }}" - register: query_tenant_filter - -- name: query entry - aci_filter_entry: &aci_query_entry_2 - <<: *aci_query_entry - tenant: "{{ fakevar | default(omit) }}" - filter: "{{ fakevar | default(omit) }}" - register: query_entry - -- name: query filter - aci_filter_entry: - <<: *aci_query_entry - tenant: "{{ fakevar | default(omit) }}" - entry: "{{ fakevar | default(omit) }}" - register: query_filter - -- name: query tenant - aci_filter_entry: - <<: *aci_query_entry - filter: "{{ fakevar | default(omit) }}" - entry: "{{ fakevar | default(omit) }}" - register: query_tenant - -- name: query all - aci_filter_entry: - <<: *aci_query_entry_2 - entry: "{{ fakevar | default(omit) }}" - register: query_all - -- name: query assertions - assert: - that: - - query_tenant_filter_entry is not changed - - query_tenant_filter_entry.current | length == 1 - - query_tenant_filter_entry.current.0.vzEntry.attributes.name == "anstest" - - '"tn-anstest/flt-anstest/e-anstest.json" in query_tenant_filter_entry.url' - - query_filter_entry is not changed - - query_filter_entry.current.0.vzFilter.attributes.name == "anstest" - - query_filter_entry.current.0.vzFilter.children | length == 1 - - '"query-target-filter=eq(vzFilter.name, \"anstest\")" in query_filter_entry.filter_string' - - '"rsp-subtree-filter=eq(vzEntry.name, \"anstest\")" in query_filter_entry.filter_string' - - '"class/vzFilter.json" in query_filter_entry.url' - - query_tenant_entry is not changed - - query_tenant_entry.current | length == 1 - - query_tenant_entry.current.0.fvTenant.attributes.name == "anstest" - - '"rsp-subtree-filter=eq(vzEntry.name, \"anstest\")" in query_tenant_entry.filter_string' - - '"rsp-subtree-class=vzEntry" in query_tenant_entry.filter_string' - - '"tn-anstest.json" in query_tenant_entry.url' - - query_tenant_filter is not changed - - query_tenant_filter.current | length == 1 - - query_tenant_filter.current.0.vzFilter.attributes.name == "anstest" - - query_tenant_filter.current.0.vzFilter.children | length == 4 - - '"rsp-subtree-class=vzEntry" in query_tenant_filter.filter_string' - - '"tn-anstest/flt-anstest.json" in query_tenant_filter.url' - - query_entry is not changed - - query_entry.current.0.vzEntry.attributes.name == "anstest" - - '"query-target-filter=eq(vzEntry.name, \"anstest\")" in query_entry.filter_string' - - '"class/vzEntry.json" in query_entry.url' - - query_filter is not changed - - query_filter.current.0.vzFilter.attributes.name == "anstest" - - '"query-target-filter=eq(vzFilter.name, \"anstest\")" in query_filter.filter_string' - - '"rsp-subtree-class=vzEntry" in query_filter.filter_string' - - '"class/vzFilter.json" in query_filter.url' - - query_tenant is not changed - - query_tenant.current | length == 1 - - query_tenant.current.0.fvTenant.attributes.name == "anstest" - - '"rsp-subtree-class=vzEntry,vzFilter" in query_tenant.filter_string' - - '"tn-anstest.json" in query_tenant.url' - - query_all is not changed - - query_all.current | length > 1 - - query_all.current.0.vzEntry is defined - - '"class/vzEntry.json" in query_all.url' - -- name: delete entry - check mode works - aci_filter_entry: &aci_entry_absent - <<: *aci_entry_present - state: absent - check_mode: yes - register: entry_absent_check_mode - -- name: delete entry - deletion works - aci_filter_entry: - <<: *aci_entry_absent - register: entry_absent - -- name: delete entry - idempotency works - aci_filter_entry: - <<: *aci_entry_absent - register: entry_absent_idempotent - -- name: missing param - failure message works - aci_filter_entry: - <<: *aci_tenant_present - state: absent - ignore_errors: yes - register: absent_missing_param - -- name: cleanup remaining entries - aci_filter_entry: - <<: *aci_entry_absent - entry: "{{ item }}" - with_items: ["anstest2", "anstest3", "anstest4"] - -- name: absent assertions - assert: - that: - - entry_absent_check_mode is changed - - entry_absent_check_mode.previous != [] - - entry_absent is changed - - entry_absent.previous == entry_absent_check_mode.previous - - entry_absent.proposed == {} - - entry_absent_idempotent is not changed - - entry_absent_idempotent.previous == [] - - absent_missing_param is failed - - 'absent_missing_param.msg == "state is absent but all of the following are missing: entry, filter"' - -- name: cleanup filter - aci_filter: - <<: *aci_filter_present - state: absent - when: filter_present is changed - -- name: cleanup tenant - aci_tenant: - <<: *aci_tenant_present - state: absent - when: tenant_present is changed diff --git a/test/integration/targets/aci_firmware_source/aliases b/test/integration/targets/aci_firmware_source/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_firmware_source/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_firmware_source/tasks/main.yml b/test/integration/targets/aci_firmware_source/tasks/main.yml deleted file mode 100644 index 344a2ced80..0000000000 --- a/test/integration/targets/aci_firmware_source/tasks/main.yml +++ /dev/null @@ -1,197 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - - -# CLEAN ENVIRONMENT -- name: Remove firmware source - aci_firmware_source: &source_absent - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - source: aci-msft-pkg-3.1.1i.zip - state: absent - - -# ADD SOURCE -#- name: Add source (check_mode) -# aci_firmware_source: &source_present -# host: '{{ aci_hostname }}' -# username: '{{ aci_username }}' -# password: '{{ aci_password }}' -# validate_certs: '{{ aci_validate_certs | default(false) }}' -# use_ssl: '{{ aci_use_ssl | default(true) }}' -# use_proxy: '{{ aci_use_proxy | default(true) }}' -# output_level: '{{ aci_output_level | default("info") }}' -# source: aci-msft-pkg-3.1.1i.zip -# url: foobar.cisco.com/download/cisco/aci/aci-msft-pkg-3.1.1i.zip -# url_protocol: http -# state: present -# check_mode: yes -# register: cm_add_source -# -#- name: Add source (normal mode) -# aci_firmware_source: *source_present -# register: nm_add_source -# -#- name: Verify add_source -# assert: -# that: -# - cm_add_source is changed -# - nm_add_source is changed -# - 'cm_add_source.sent == nm_add_source.sent == {"firmwareOSource": {"attributes": {"name": "aci-msft-pkg-3.1.1i.zip", "proto": "http", "url": "foobar.cisco.com/download/cisco/aci/aci-msft-pkg-3.1.1i.zip"}}}' -# - 'cm_add_source.proposed == nm_add_source.proposed == {"firmwareOSource": {"attributes": {"name": "aci-msft-pkg-3.1.1i.zip", "proto": "http", "url": "foobar.cisco.com/download/cisco/aci/aci-msft-pkg-3.1.1i.zip"}}}' -# - cm_add_source.current == cm_add_source.previous == nm_add_source.previous == [] -# - nm_add_source.current.0.firmwareOSource.attributes.name == 'aci-msft-pkg-3.1.1i.zip' -# - nm_add_source.current.0.firmwareOSource.attributes.proto == 'http' -# - nm_add_source.current.0.firmwareOSource.attributes.url == 'foobar.cisco.com/download/cisco/aci/aci-msft-pkg-3.1.1i.zip' -# -#- name: Add source again (check_mode) -# aci_firmware_source: *source_present -# check_mode: yes -# register: cm_add_source_again -# -#- name: Add source again (normal mode) -# aci_firmware_source: *souce_present -# register: nm_add_source_again -# -#- name: Verify add_source_again -# assert: -# that: -# - cm_add_source_again is not changed -# - nm_add_source_again is not changed - - -# QUERY ALL SOURCES -- name: Query all sources (check_mode) - aci_firmware_source: &source_query - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - state: query - check_mode: yes - register: cm_query_all_sources - -- name: Query all sources (normal mode) - aci_firmware_source: *source_query - register: nm_query_all_sources - -- name: Verify query_all_sources - assert: - that: - - cm_query_all_sources is not changed - - nm_query_all_sources is not changed - - cm_query_all_sources == nm_query_all_sources -# - nm_query_all_sources.current|length >= 1 - - -# QUERY A SOURCE -#- name: Query our source (check_mode) -# aci_firmware_source: -# <<: *source_query -# source: aci-msft-pkg-3.1.1i.zip -# check_mode: yes -# register: cm_query_source -# -#- name: Query our source (normal mode) -# aci_firmware_source: -# <<: *source_query -# source: aci-msft-pkg-3.1.1i.zip -# register: nm_query_source -# -#- name: Verify query_source -# assert: -# that: -# - cm_query_source is not changed -# - nm_query_source is not changed -# - cm_query_source == nm_query_source -# - nm_query_source.current.0.infraRsDomP.attributes.dn == 'uni/infra/attentp-test_aep/rsdomP-[uni/phys-phys_dom]' -# - nm_query_source.current.0.infraRsDomP.attributes.tCl == 'physDomP' -# - nm_query_source.current.0.infraRsDomP.attributes.tDn == 'uni/phys-phys_dom' - - -# REMOVE SOURCE -#- name: Remove source (check_mode) -# aci_firmware_source: *source_absent -# check_mode: yes -# register: cm_remove_source - -#- name: Remove source (normal mode) -# aci_firmware_source: *source_absent -# register: nm_remove_source -# -#- name: Verify remove_source -# assert: -# that: -# - cm_remove_source is changed -# - nm_remove_source is changed -# - 'cm_remove_source.current == cm_remove_source.previous == nm_remove_source.previous == [{"infraRsDomP": {"attributes": {"dn": "uni/infra/attentp-test_aep/rsdomP-[uni/phys-phys_dom]", "tDn": "uni/phys-phys_dom"}}}]' -# - nm_remove_source.current == [] -# -#- name: Remove source again (check_mode) -# aci_firmware_source: *source_absent -# check_mode: yes -# register: cm_remove_source_again -# -#- name: Remove source again (normal mode) -# aci_firmware_source: *source_absent -# register: nm_remove_source_again -# -#- name: Verify remove_source_again -# assert: -# that: -# - cm_remove_source_again is not changed -# - nm_remove_source_again is not changed - - -# QUERY NON-EXISTING SOURCE -#- name: Query non-existing source (check_mode) -# aci_firmware_source: -# <<: *source_query -# source: aci-msft-pkg-3.1.1i.zip -# check_mode: yes -# register: cm_query_non_source -# -#- name: Query non-existing source (normal mode) -# aci_firmware_source: -# <<: *source_query -# source: aci-msft-pkg-3.1.1i.zip -# register: nm_query_non_source -# -#- name: Verify query_non_source -# assert: -# that: -# - cm_query_non_source is not changed -# - nm_query_non_source is not changed -# - cm_query_non_source == nm_query_non_source -# - nm_query_non_source.current == [] - - -# PROVOKE ERRORS -- name: Error when required parameter is missing - aci_firmware_source: - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - state: present - ignore_errors: yes - register: error_on_missing_required_param - -- name: Verify error_on_missing_required_param - assert: - that: - - error_on_missing_required_param is failed - - 'error_on_missing_required_param.msg == "state is present but all of the following are missing: source, url"' diff --git a/test/integration/targets/aci_interface_policy_cdp/aliases b/test/integration/targets/aci_interface_policy_cdp/aliases deleted file mode 100644 index ad7ccf7ada..0000000000 --- a/test/integration/targets/aci_interface_policy_cdp/aliases +++ /dev/null @@ -1 +0,0 @@ -unsupported diff --git a/test/integration/targets/aci_interface_policy_cdp/tasks/main.yml b/test/integration/targets/aci_interface_policy_cdp/tasks/main.yml deleted file mode 100644 index f82b3b78a0..0000000000 --- a/test/integration/targets/aci_interface_policy_cdp/tasks/main.yml +++ /dev/null @@ -1,106 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2019, Tim Knipper (tknipper11) <tim.knipper@gmail.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - -# CLEAN ENVIRONMENT -- name: Remove CDP Test Policy - aci_interface_policy_cdp: - name: Ansible_CDP_Test_Policy - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(false) }}' - output_level: debug - state: absent - register: cdp_delete - - - -- name: Create CDP Test Policy - aci_interface_policy_cdp: - name: Ansible_CDP_Test_Policy - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(false) }}' -# output_level: debug - state: present - register: cdp_create -- debug: - var: cdp_create - -- assert: - that: - - cdp_create is changed - - -- name: test for idempotency - aci_interface_policy_cdp: - name: Ansible_CDP_Test_Policy - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(false) }}' -# output_level: debug - state: present - register: cdp_idem - -- name: Assert that idempotency is not changed - assert: - that: - - cdp_idem is not changed - - - -- name: Create CDP Disable Test Policy - aci_interface_policy_cdp: - name: Ansible_CDP_Test_Policy - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(false) }}' -# output_level: debug - state: present - admin_state: no - register: cdp_disable -- debug: - var: cdp_disable - -- name: Assert that CDP is Disabled - assert: - that: - - 'cdp_disable.current.0.cdpIfPol.attributes.adminSt == "disabled"' - - -- name: Query CDP Policy - aci_interface_policy_cdp: - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(false) }}' -# output_level: debug - state: query - register: cdp_query -- debug: - var: cdp_query - -- name: CDP Query Assertion - assert: - that: - - cdp_query is not changed
\ No newline at end of file diff --git a/test/integration/targets/aci_interface_policy_leaf_policy_group/aliases b/test/integration/targets/aci_interface_policy_leaf_policy_group/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_interface_policy_leaf_policy_group/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_interface_policy_leaf_policy_group/tasks/main.yml b/test/integration/targets/aci_interface_policy_leaf_policy_group/tasks/main.yml deleted file mode 100644 index c9204101f0..0000000000 --- a/test/integration/targets/aci_interface_policy_leaf_policy_group/tasks/main.yml +++ /dev/null @@ -1,436 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Bruno Calogero <brunocalogero@hotmail.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - -- name: Making sure interface_policy_leaf_policy_group doesn't exist at beginning of test (PC) - aci_interface_policy_leaf_policy_group: &aci_interface_policy_leaf_policy_group_link_absent - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - policy_group: policygroupname_link - lag_type: link - state: absent - -- name: Making sure interface_policy_leaf_policy_group doesn't exist at beginning of test (VPC) - aci_interface_policy_leaf_policy_group: &aci_interface_policy_leaf_policy_group_node_absent - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - policy_group: policygroupname_node - lag_type: node - state: absent - -- name: Making sure interface_policy_leaf_policy_group doesn't exist at beginning of test (Leaf Access Port) - aci_interface_policy_leaf_policy_group: &aci_interface_policy_leaf_policy_group_leaf_absent - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - policy_group: policygroupname_leaf - lag_type: leaf - state: absent - - -# ==== TESTING Port Channel (PC), lag_type: link ==== - -- name: Adding a interface policy leaf policy group (PC) - check mode works - aci_interface_policy_leaf_policy_group: &aci_interface_policy_leaf_policy_group_link_present - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - policy_group: policygroupname_link - lag_type: link - link_level_policy: linklevelpolicy - fibre_channel_interface_policy: fiberchannelpolicy - state: present - check_mode: yes - register: intf_policy_leaf_polgrp_check_mode_present - -- name: Adding a interface policy leaf policy group (PC) - creation works - aci_interface_policy_leaf_policy_group: - <<: *aci_interface_policy_leaf_policy_group_link_present - register: intf_policy_leaf_polgrp_present - -- name: Adding a interface policy leaf policy group (PC) - idempotency works - aci_interface_policy_leaf_policy_group: - <<: *aci_interface_policy_leaf_policy_group_link_present - register: intf_policy_leaf_polgrp_idempotent - -- name: Adding a interface policy leaf policy group description (PC) - update works - aci_interface_policy_leaf_policy_group: - <<: *aci_interface_policy_leaf_policy_group_link_present - description: policygroup description - register: intf_policy_leaf_polgrp_update - -# TODO: also test for errors -- name: present assertions - assert: - that: - - intf_policy_leaf_polgrp_check_mode_present is changed - - intf_policy_leaf_polgrp_present is changed - - intf_policy_leaf_polgrp_present.previous == [] - - 'intf_policy_leaf_polgrp_present.sent == {"infraAccBndlGrp": {"attributes": {"lagT": "link","name": "policygroupname_link"},"children": [{"infraRsFcIfPol": {"attributes": {"tnFcIfPolName": "fiberchannelpolicy"}}},{"infraRsHIfPol": {"attributes": {"tnFabricHIfPolName": "linklevelpolicy"}}}]}}' - - intf_policy_leaf_polgrp_idempotent is not changed - - intf_policy_leaf_polgrp_idempotent.sent == {} - - intf_policy_leaf_polgrp_update is changed - - 'intf_policy_leaf_polgrp_update.sent == {"infraAccBndlGrp": {"attributes": {"descr": "policygroup description"}}}' - -- name: Query interface policy leaf policy group (PC) - aci_interface_policy_leaf_policy_group: - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - policy_group: policygroupname_link - lag_type: link - state: query - register: binding_query - -- name: present assertions - assert: - that: - - binding_query is not changed - - binding_query.current | length >= 1 - - '"/api/mo/uni/infra/funcprof/accbundle-policygroupname_link.json" in binding_query.url' - -- name: Remove interface policy leaf policy group (PC) - check mode - aci_interface_policy_leaf_policy_group: - <<: *aci_interface_policy_leaf_policy_group_link_absent - check_mode: yes - register: intf_policy_leaf_polgrp_check_mode_absent - -- name: Remove interface policy leaf policy group (PC) - delete works - aci_interface_policy_leaf_policy_group: - <<: *aci_interface_policy_leaf_policy_group_link_absent - register: intf_policy_leaf_polgrp_absent - -- name: Remove interface policy leaf policy group (PC) - idempotency works - aci_interface_policy_leaf_policy_group: - <<: *aci_interface_policy_leaf_policy_group_link_absent - register: intf_policy_leaf_polgrp_absent_idempotent - -- name: Remove interface policy leaf policy group (PC) - check mode - aci_interface_policy_leaf_policy_group: - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - policy_group: policygroupname_link - #lag_type: link - state: absent - ignore_errors: yes - register: intf_policy_leaf_polgrp_absent_missing_param - -- name: absent assertions - assert: - that: - - intf_policy_leaf_polgrp_check_mode_absent is changed - - intf_policy_leaf_polgrp_check_mode_absent.previous != [] - - intf_policy_leaf_polgrp_absent is changed - - intf_policy_leaf_polgrp_absent.previous == intf_policy_leaf_polgrp_absent.previous - - intf_policy_leaf_polgrp_absent_idempotent is not changed - - intf_policy_leaf_polgrp_absent_idempotent.previous == [] - - intf_policy_leaf_polgrp_absent_missing_param is failed - - 'intf_policy_leaf_polgrp_absent_missing_param.msg == "missing required arguments: lag_type"' - -# ==== END TESTING Port Channel (PC), lag_type: link ==== - - -# ==== START TESTING Virtual Port Channel (VPC), lag_type: node ==== - -- name: Making sure interface_policy_leaf_policy_group doesn't exist at beginning of test (VPC) - aci_interface_policy_leaf_policy_group: - <<: *aci_interface_policy_leaf_policy_group_node_absent - -- name: Adding a interface policy leaf policy group (VPC) - check mode works - aci_interface_policy_leaf_policy_group: &aci_interface_policy_leaf_policy_group_node_present - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - policy_group: policygroupname_node - lag_type: node - link_level_policy: linklevelpolicy - fibre_channel_interface_policy: fiberchannelpolicy - state: present - check_mode: yes - register: intf_policy_leaf_polgrp_check_mode_present - -- name: Adding a interface policy leaf policy group (VPC) - creation works - aci_interface_policy_leaf_policy_group: - <<: *aci_interface_policy_leaf_policy_group_node_present - register: intf_policy_leaf_polgrp_present - -- name: Adding a interface policy leaf policy group (VPC) - idempotency works - aci_interface_policy_leaf_policy_group: - <<: *aci_interface_policy_leaf_policy_group_node_present - register: intf_policy_leaf_polgrp_idempotent - -- name: Adding a interface policy leaf policy group description (VPC) - update works - aci_interface_policy_leaf_policy_group: - <<: *aci_interface_policy_leaf_policy_group_node_present - description: policygroup description - register: intf_policy_leaf_polgrp_update - -# TODO: also test for errors -- name: present assertions - assert: - that: - - intf_policy_leaf_polgrp_check_mode_present is changed - - intf_policy_leaf_polgrp_present is changed - - intf_policy_leaf_polgrp_present.previous == [] - - 'intf_policy_leaf_polgrp_present.sent == {"infraAccBndlGrp": {"attributes": {"lagT": "node","name": "policygroupname_node"},"children": [{"infraRsFcIfPol": {"attributes": {"tnFcIfPolName": "fiberchannelpolicy"}}},{"infraRsHIfPol": {"attributes": {"tnFabricHIfPolName": "linklevelpolicy"}}}]}}' - - intf_policy_leaf_polgrp_idempotent is not changed - - intf_policy_leaf_polgrp_idempotent.sent == {} - - intf_policy_leaf_polgrp_update is changed - - 'intf_policy_leaf_polgrp_update.sent == {"infraAccBndlGrp": {"attributes": {"descr": "policygroup description"}}}' - -- name: Query interface policy leaf policy group (VPC) - aci_interface_policy_leaf_policy_group: - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - policy_group: policygroupname_node - lag_type: node - state: query - register: binding_query - -- name: present assertions - assert: - that: - - binding_query is not changed - - binding_query.current | length >= 1 - - '"/api/mo/uni/infra/funcprof/accbundle-policygroupname_node.json" in binding_query.url' - -# Add lag_type link to see what we get back -- name: Adding a interface policy leaf policy group (PC) - creation works - aci_interface_policy_leaf_policy_group: - <<: *aci_interface_policy_leaf_policy_group_link_present - register: intf_policy_leaf_polgrp_present - -- name: Query interface policy leaf policy group (VPC) - aci_interface_policy_leaf_policy_group: - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - lag_type: node - state: query - register: binding_query_node_all - -- name: present assertions - assert: - that: - - binding_query_node_all is not changed - - binding_query_node_all.current | length >= 1 - - binding_query_node_all.current | selectattr("infraAccBndlGrp.attributes.lagT", "equalto", "link") | list == [] - - '"/api/class/infraAccBndlGrp.json" in binding_query_node_all.url' - -- name: Remove interface policy leaf policy group (VPC) - check mode - aci_interface_policy_leaf_policy_group: - <<: *aci_interface_policy_leaf_policy_group_node_absent - check_mode: yes - register: intf_policy_leaf_polgrp_check_mode_absent - -- name: Remove interface policy leaf policy group (VPC) - delete works - aci_interface_policy_leaf_policy_group: - <<: *aci_interface_policy_leaf_policy_group_node_absent - register: intf_policy_leaf_polgrp_absent - -- name: Remove interface policy leaf policy group (VPC) - idempotency works - aci_interface_policy_leaf_policy_group: - <<: *aci_interface_policy_leaf_policy_group_node_absent - register: intf_policy_leaf_polgrp_absent_idempotent - -- name: Remove interface policy leaf policy group (VPC) - check mode - aci_interface_policy_leaf_policy_group: - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - policy_group: policygroupname_node - #lag_type: node - state: absent - ignore_errors: yes - register: intf_policy_leaf_polgrp_absent_missing_param - -- name: absent assertions - assert: - that: - - intf_policy_leaf_polgrp_check_mode_absent is changed - - intf_policy_leaf_polgrp_check_mode_absent.previous != [] - - intf_policy_leaf_polgrp_absent is changed - - intf_policy_leaf_polgrp_absent.previous == intf_policy_leaf_polgrp_absent.previous - - intf_policy_leaf_polgrp_absent_idempotent is not changed - - intf_policy_leaf_polgrp_absent_idempotent.previous == [] - - intf_policy_leaf_polgrp_absent_missing_param is failed - - 'intf_policy_leaf_polgrp_absent_missing_param.msg == "missing required arguments: lag_type"' - -# ==== END TESTING Virtual Port Channel (VPC), lag_type: node ==== - - -# ==== START TESTING Virtual Port Channel (VPC), lag_type: leaf ==== - -- name: Making sure interface_policy_leaf_policy_group doesn't exist at beginning of test (Leaf Access Port) - aci_interface_policy_leaf_policy_group: - <<: *aci_interface_policy_leaf_policy_group_leaf_absent - -- name: Adding a interface policy leaf policy group (Leaf Access Port) - check mode works - aci_interface_policy_leaf_policy_group: &aci_interface_policy_leaf_policy_group_leaf_present - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - policy_group: policygroupname_leaf - lag_type: leaf - link_level_policy: linklevelpolicy - fibre_channel_interface_policy: fiberchannelpolicy - state: present - check_mode: yes - register: intf_policy_leaf_polgrp_check_mode_present - -- name: Adding a interface policy leaf policy group (Leaf Access Port) - creation works - aci_interface_policy_leaf_policy_group: - <<: *aci_interface_policy_leaf_policy_group_leaf_present - register: intf_policy_leaf_polgrp_present - -- name: Adding a interface policy leaf policy group (Leaf Access Port) - idempotency works - aci_interface_policy_leaf_policy_group: - <<: *aci_interface_policy_leaf_policy_group_leaf_present - register: intf_policy_leaf_polgrp_idempotent - -- name: Adding a interface policy leaf policy group description (Leaf Access Port) - update works - aci_interface_policy_leaf_policy_group: - <<: *aci_interface_policy_leaf_policy_group_leaf_present - description: policygroup description - register: intf_policy_leaf_polgrp_update - -- name: hello - debug: - msg: "{{ intf_policy_leaf_polgrp_present.sent }}" - -- name: hello - debug: - msg: "{{ intf_policy_leaf_polgrp_update.sent }}" - -# TODO: also test for errors -- name: present assertions - assert: - that: - - intf_policy_leaf_polgrp_check_mode_present is changed - - intf_policy_leaf_polgrp_present is changed - - intf_policy_leaf_polgrp_present.previous == [] - - 'intf_policy_leaf_polgrp_present.sent == {"infraAccPortGrp": {"attributes": {"name": "policygroupname_leaf"},"children": [{"infraRsFcIfPol": {"attributes": {"tnFcIfPolName": "fiberchannelpolicy"}}},{"infraRsHIfPol": {"attributes": {"tnFabricHIfPolName": "linklevelpolicy"}}}]}}' - - intf_policy_leaf_polgrp_idempotent is not changed - - intf_policy_leaf_polgrp_idempotent.sent == {} - - intf_policy_leaf_polgrp_update is changed - - 'intf_policy_leaf_polgrp_update.sent == {"infraAccPortGrp": {"attributes": {"descr": "policygroup description"}}}' - -- name: Query interface policy leaf policy group (Leaf Access Port) - aci_interface_policy_leaf_policy_group: - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - policy_group: policygroupname_leaf - lag_type: leaf - state: query - register: binding_query - -- name: present assertions - assert: - that: - - binding_query is not changed - - binding_query.current | length >= 1 - - '"/api/mo/uni/infra/funcprof/accportgrp-policygroupname_leaf.json" in binding_query.url' - -- name: Remove interface policy leaf policy group (Leaf Access Port) - check mode - aci_interface_policy_leaf_policy_group: - <<: *aci_interface_policy_leaf_policy_group_leaf_absent - check_mode: yes - register: intf_policy_leaf_polgrp_check_mode_absent - -- name: Remove interface policy leaf policy group (Leaf Access Port) - delete works - aci_interface_policy_leaf_policy_group: - <<: *aci_interface_policy_leaf_policy_group_leaf_absent - register: intf_policy_leaf_polgrp_absent - -- name: Remove interface policy leaf policy group (Leaf Access Port) - idempotency works - aci_interface_policy_leaf_policy_group: - <<: *aci_interface_policy_leaf_policy_group_leaf_absent - register: intf_policy_leaf_polgrp_absent_idempotent - -- name: Remove interface policy leaf policy group (Leaf Access Port) - check mode - aci_interface_policy_leaf_policy_group: - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - policy_group: policygroupname_leaf - #lag_type: leaf - state: absent - ignore_errors: yes - register: intf_policy_leaf_polgrp_absent_missing_param - -- name: absent assertions - assert: - that: - - intf_policy_leaf_polgrp_check_mode_absent is changed - - intf_policy_leaf_polgrp_check_mode_absent.previous != [] - - intf_policy_leaf_polgrp_absent is changed - - intf_policy_leaf_polgrp_absent.previous == intf_policy_leaf_polgrp_absent.previous - - intf_policy_leaf_polgrp_absent_idempotent is not changed - - intf_policy_leaf_polgrp_absent_idempotent.previous == [] - - intf_policy_leaf_polgrp_absent_missing_param is failed - - 'intf_policy_leaf_polgrp_absent_missing_param.msg == "missing required arguments: lag_type"' - -# ==== END TESTING Virtual Port Channel (VPC), lag_type: leaf ==== diff --git a/test/integration/targets/aci_interface_policy_leaf_profile/aliases b/test/integration/targets/aci_interface_policy_leaf_profile/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_interface_policy_leaf_profile/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_interface_policy_leaf_profile/tasks/main.yml b/test/integration/targets/aci_interface_policy_leaf_profile/tasks/main.yml deleted file mode 100644 index 70902a71e2..0000000000 --- a/test/integration/targets/aci_interface_policy_leaf_profile/tasks/main.yml +++ /dev/null @@ -1,213 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Bruno Calogero <brunocalogero@hotmail.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - - -# CLEAN ENVIRONMENT -- name: Remove leaf profile - aci_interface_policy_leaf_profile: &interface_policy_leaf_profile_absent - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - leaf_interface_profile: ansible_test - state: absent - - -# ADD LEAF INTERFACE PROFILE -- name: Add leaf interface profile (check_mode) - aci_interface_policy_leaf_profile: &interface_policy_leaf_profile_present - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - leaf_interface_profile: ansible_test - state: present - check_mode: yes - register: cm_add_leaf_interface_profile - -- name: Add leaf interface profile (normal mode) - aci_interface_policy_leaf_profile: *interface_policy_leaf_profile_present - register: nm_add_leaf_interface_profile - -- name: Add leaf interface profile again (check_mode) - aci_interface_policy_leaf_profile: *interface_policy_leaf_profile_present - check_mode: yes - register: cm_add_leaf_interface_profile_again - -- name: Add leaf interface profile again (normal mode) - aci_interface_policy_leaf_profile: *interface_policy_leaf_profile_present - register: nm_add_leaf_interface_profile_again - -- name: Verify add_leaf_interface_profile - assert: - that: - - cm_add_leaf_interface_profile is changed - - nm_add_leaf_interface_profile is changed - - cm_add_leaf_interface_profile_again is not changed - - nm_add_leaf_interface_profile_again is not changed - - -# CHANGE LEAF INTERFACE PROFILE -- name: Change description of leaf interface profile (check_mode) - aci_interface_policy_leaf_profile: - <<: *interface_policy_leaf_profile_present - description: Ansible test leaf interface profile - check_mode: yes - register: cm_add_leaf_interface_profile_descr - -- name: Change description of leaf interface profile (normal mode) - aci_interface_policy_leaf_profile: - <<: *interface_policy_leaf_profile_present - description: Ansible test leaf interface profile - register: nm_add_leaf_interface_profile_descr - -- name: Change description of leaf interface profile again (check_mode) - aci_interface_policy_leaf_profile: - <<: *interface_policy_leaf_profile_present - description: Ansible test leaf interface profile - check_mode: yes - register: cm_add_leaf_interface_profile_descr_again - -- name: Change description of leaf interface profile again (normal mode) - aci_interface_policy_leaf_profile: - <<: *interface_policy_leaf_profile_present - description: Ansible test leaf interface profile - register: nm_add_leaf_interface_profile_descr_again - -- name: Verify add_leaf_interface_profile_descr - assert: - that: - - cm_add_leaf_interface_profile_descr is changed - - nm_add_leaf_interface_profile_descr is changed - - cm_add_leaf_interface_profile_descr_again is not changed - - nm_add_leaf_interface_profile_descr_again is not changed - - -# ADD LEAF INTERFACE PROFILE AGAIN -- name: Add leaf interface profile again with no description (check_mode) - aci_interface_policy_leaf_profile: *interface_policy_leaf_profile_present - check_mode: yes - register: cm_add_leaf_interface_profile_again_no_descr - -- name: Add leaf interface profile again with no description (normal mode) - aci_interface_policy_leaf_profile: *interface_policy_leaf_profile_present - register: nm_add_leaf_interface_profile_again_no_descr - -- name: Verify add_leaf_interface_profile_again_no_descr - assert: - that: - - cm_add_leaf_interface_profile_again_no_descr is not changed - - nm_add_leaf_interface_profile_again_no_descr is not changed - - -# QUERY ALL LEAF INTERFACE PROFILES -- name: Query all interface profiles (check_mode) - aci_interface_policy_leaf_profile: &interface_policy_leaf_profile_query - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - state: query - check_mode: yes - register: cm_query_all_leaf_interface_profiles - -- name: Query all leaf_interface_profiles (normal mode) - aci_interface_policy_leaf_profile: *interface_policy_leaf_profile_query - register: nm_query_all_leaf_interface_profiles - -- name: Verify query_all_leaf_interface_profiles - assert: - that: - - cm_query_all_leaf_interface_profiles is not changed - - nm_query_all_leaf_interface_profiles is not changed - # NOTE: Order of leaf_interface_profiles is not stable between calls - #- cm_query_all_leaf_interface_profiles == nm_query_all_leaf_interface_profiles - - -# QUERY A LEAF INTERFACE PROFILE -- name: Query our leaf_interface_profile - aci_interface_policy_leaf_profile: - <<: *interface_policy_leaf_profile_query - leaf_interface_profile: ansible_test - check_mode: yes - register: cm_query_leaf_interface_profile - -- name: Query our leaf_interface_profile - aci_interface_policy_leaf_profile: - <<: *interface_policy_leaf_profile_query - leaf_interface_profile: ansible_test - register: nm_query_leaf_interface_profile - -- name: Verify query_leaf_interface_profile - assert: - that: - - cm_query_leaf_interface_profile is not changed - - nm_query_leaf_interface_profile is not changed - - cm_query_leaf_interface_profile == nm_query_leaf_interface_profile - - -# REMOVE LEAF INTERFACE PROFILE -- name: Remove leaf_interface_profile (check_mode) - aci_interface_policy_leaf_profile: *interface_policy_leaf_profile_absent - check_mode: yes - register: cm_remove_leaf_interface_profile - -- name: Remove leaf_interface_profile (normal mode) - aci_interface_policy_leaf_profile: *interface_policy_leaf_profile_absent - register: nm_remove_leaf_interface_profile - -- name: Remove leaf_interface_profile again (check_mode) - aci_interface_policy_leaf_profile: *interface_policy_leaf_profile_absent - check_mode: yes - register: cm_remove_leaf_interface_profile_again - -- name: Remove leaf_interface_profile again (normal mode) - aci_interface_policy_leaf_profile: *interface_policy_leaf_profile_absent - register: nm_remove_leaf_interface_profile_again - -- name: Verify remove_leaf_interface_profile - assert: - that: - - cm_remove_leaf_interface_profile is changed - - nm_remove_leaf_interface_profile is changed - - cm_remove_leaf_interface_profile_again is not changed - - nm_remove_leaf_interface_profile_again is not changed - - -# QUERY NON-EXISTING LEAF INTERFACE PROFILE -- name: Query non-existing leaf_interface_profile (check_mode) - aci_interface_policy_leaf_profile: - <<: *interface_policy_leaf_profile_query - leaf_interface_profile: ansible_test - check_mode: yes - register: cm_query_non_leaf_interface_profile - -- name: Query non-existing leaf_interface_profile (normal mode) - aci_interface_policy_leaf_profile: - <<: *interface_policy_leaf_profile_query - leaf_interface_profile: ansible_test - register: nm_query_non_leaf_interface_profile - -# TODO: Implement more tests -- name: Verify query_non_leaf_interface_profile - assert: - that: - - cm_query_non_leaf_interface_profile is not changed - - nm_query_non_leaf_interface_profile is not changed - - cm_query_non_leaf_interface_profile == nm_query_non_leaf_interface_profile diff --git a/test/integration/targets/aci_interface_policy_ospf/aliases b/test/integration/targets/aci_interface_policy_ospf/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_interface_policy_ospf/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_interface_policy_ospf/tasks/main.yml b/test/integration/targets/aci_interface_policy_ospf/tasks/main.yml deleted file mode 100644 index 2aa07a4e3b..0000000000 --- a/test/integration/targets/aci_interface_policy_ospf/tasks/main.yml +++ /dev/null @@ -1,231 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Dag Wieers (dagwieers) <dag@wieers.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - - -# CLEAN ENVIRONMENT -- name: Ensure tenant exists for tests to kick off - aci_tenant: &aci_tenant_present - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - tenant: anstest - state: present - register: tenant_present - -- name: Remove OSPF interface policy - aci_interface_policy_ospf: &interface_policy_ospf_absent - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - tenant: anstest - ospf: ansible_ospf - state: absent - - -# ADD OSPF INTERFACE POLICY -- name: Add ospf interface policy (check_mode) - aci_interface_policy_ospf: &interface_policy_ospf_present - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - tenant: anstest - ospf: ansible_ospf - state: present - check_mode: yes - register: cm_add_ospf_interface_policy - -- name: Add ospf interface policy (normal mode) - aci_interface_policy_ospf: *interface_policy_ospf_present - register: nm_add_ospf_interface_policy - -- name: Add ospf interface policy again (check_mode) - aci_interface_policy_ospf: *interface_policy_ospf_present - check_mode: yes - register: cm_add_ospf_interface_policy_again - -- name: Add ospf interface policy again (normal mode) - aci_interface_policy_ospf: *interface_policy_ospf_present - register: nm_add_ospf_interface_policy_again - -- name: Verify add_ospf_interface_policy - assert: - that: - - cm_add_ospf_interface_policy is changed - - nm_add_ospf_interface_policy is changed - - cm_add_ospf_interface_policy_again is not changed - - nm_add_ospf_interface_policy_again is not changed - - -# CHANGE OSPF INTERFACE POLICY -- name: Change description of ospf interface policy (check_mode) - aci_interface_policy_ospf: - <<: *interface_policy_ospf_present - description: Ansible test ospf interface policy - check_mode: yes - register: cm_add_ospf_descr - -- name: Change description of ospf interface policy (normal mode) - aci_interface_policy_ospf: - <<: *interface_policy_ospf_present - description: Ansible test ospf interface policy - register: nm_add_ospf_descr - -- name: Change description of ospf interface policy again (check_mode) - aci_interface_policy_ospf: - <<: *interface_policy_ospf_present - description: Ansible test ospf interface policy - check_mode: yes - register: cm_add_ospf_descr_again - -- name: Change description of ospf interface policy again (normal mode) - aci_interface_policy_ospf: - <<: *interface_policy_ospf_present - description: Ansible test ospf interface policy - register: nm_add_ospf_descr_again - -- name: Verify add_ospf_descr - assert: - that: - - cm_add_ospf_descr is changed - - nm_add_ospf_descr is changed - - cm_add_ospf_descr_again is not changed - - nm_add_ospf_descr_again is not changed - - -# ADD OSPF INTERFACE POLICY AGAIN -- name: Add ospf interface policy again with no description (check_mode) - aci_interface_policy_ospf: *interface_policy_ospf_present - check_mode: yes - register: cm_add_ospf_again_no_descr - -- name: Add ospf interface policy again with no description (normal mode) - aci_interface_policy_ospf: *interface_policy_ospf_present - register: nm_add_ospf_again_no_descr - -- name: Verify add_ospf_again_no_descr - assert: - that: - - cm_add_ospf_again_no_descr is not changed - - nm_add_ospf_again_no_descr is not changed - - -# QUERY ALL OSPF INTERFACE POLICIES -- name: Query all ospf interface policies (check_mode) - aci_interface_policy_ospf: &interface_policy_ospf_query - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - tenant: anstest - state: query - check_mode: yes - register: cm_query_all_ospfs - -- name: Query all ospfs (normal mode) - aci_interface_policy_ospf: *interface_policy_ospf_query - register: nm_query_all_ospfs - -- name: Verify query_all_ospfs - assert: - that: - - cm_query_all_ospfs is not changed - - nm_query_all_ospfs is not changed - # NOTE: Order of ospfs is not stable between calls - #- cm_query_all_ospfs == nm_query_all_ospfs - - -# QUERY A OSPF INTERFACE POLICY -- name: Query our ospf - aci_interface_policy_ospf: - <<: *interface_policy_ospf_query - tenant: anstest - ospf: ansible_ospf - check_mode: yes - register: cm_query_ospf - -- name: Query our ospf - aci_interface_policy_ospf: - <<: *interface_policy_ospf_query - tenant: anstest - ospf: ansible_ospf - register: nm_query_ospf - -- name: Verify query_ospf - assert: - that: - - cm_query_ospf is not changed - - nm_query_ospf is not changed - - cm_query_ospf == nm_query_ospf - - -# REMOVE OSPF INTERFACE POLICY -- name: Remove ospf (check_mode) - aci_interface_policy_ospf: *interface_policy_ospf_absent - check_mode: yes - register: cm_remove_ospf - -- name: Remove ospf (normal mode) - aci_interface_policy_ospf: *interface_policy_ospf_absent - register: nm_remove_ospf - -- name: Remove ospf again (check_mode) - aci_interface_policy_ospf: *interface_policy_ospf_absent - check_mode: yes - register: cm_remove_ospf_again - -- name: Remove ospf again (normal mode) - aci_interface_policy_ospf: *interface_policy_ospf_absent - register: nm_remove_ospf_again - -- name: Verify remove_ospf - assert: - that: - - cm_remove_ospf is changed - - nm_remove_ospf is changed - - cm_remove_ospf_again is not changed - - nm_remove_ospf_again is not changed - - -# QUERY NON-EXISTING OSPF INTERFACE POLICY -- name: Query non-existing ospf (check_mode) - aci_interface_policy_ospf: - <<: *interface_policy_ospf_query - ospf: ansible_ospf - check_mode: yes - register: cm_query_non_ospf - -- name: Query non-existing ospf (normal mode) - aci_interface_policy_ospf: - <<: *interface_policy_ospf_query - ospf: ansible_ospf - register: nm_query_non_ospf - -# TODO: Implement more tests -- name: Verify query_non_ospf - assert: - that: - - cm_query_non_ospf is not changed - - nm_query_non_ospf is not changed - - cm_query_non_ospf == nm_query_non_ospf diff --git a/test/integration/targets/aci_interface_selector_to_switch_policy_leaf_profile/aliases b/test/integration/targets/aci_interface_selector_to_switch_policy_leaf_profile/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_interface_selector_to_switch_policy_leaf_profile/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_interface_selector_to_switch_policy_leaf_profile/tasks/main.yml b/test/integration/targets/aci_interface_selector_to_switch_policy_leaf_profile/tasks/main.yml deleted file mode 100644 index 2f97034fec..0000000000 --- a/test/integration/targets/aci_interface_selector_to_switch_policy_leaf_profile/tasks/main.yml +++ /dev/null @@ -1,154 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Bruno Calogero <brunocalogero@hotmail.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - -- name: delete Switch Policy Leaf profile for kick off - aci_switch_policy_leaf_profile: - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - leaf_profile: swleafprftest - state: absent - -- name: delete Interface Policy Leaf profile for kick off - aci_interface_policy_leaf_profile: - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - leaf_interface_profile: leafintprftest - state: absent - -- name: Ensuring Switch Policy Leaf profile exists for kick off - aci_switch_policy_leaf_profile: &aci_switch_policy_leaf_profile_present - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - leaf_profile: swleafprftest - state: present - register: leaf_profile_present - -- name: Ensuring Interface Policy Leaf profile exists for kick off - aci_interface_policy_leaf_profile: &aci_interface_policy_leaf_profile_present - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - leaf_interface_profile: leafintprftest - state: present - register: leaf_profile_present - -- name: Bind an Interface Selector to a Switch Policy Leaf Profile - check mode works - aci_interface_selector_to_switch_policy_leaf_profile: &aci_interface_selector_to_switch_policy_leaf_profile_present - <<: *aci_switch_policy_leaf_profile_present - interface_selector: leafintprftest - check_mode: yes - register: intftoleaf_check_mode_present - -- name: Bind an Interface Selector to a Switch Policy Leaf Profile - creation works - aci_interface_selector_to_switch_policy_leaf_profile: - <<: *aci_interface_selector_to_switch_policy_leaf_profile_present - register: intftoleaf_present - -- name: Bind an Interface Selector to a Switch Policy Leaf Profile - idempotency works - aci_interface_selector_to_switch_policy_leaf_profile: - <<: *aci_interface_selector_to_switch_policy_leaf_profile_present - register: intftoleaf_idempotent - -# TODO: also test for errors -- name: present assertions - assert: - that: - - intftoleaf_check_mode_present is changed - - intftoleaf_present is changed - - intftoleaf_present.previous == [] - - 'intftoleaf_present.sent == {"infraRsAccPortP": {"attributes": {"tDn": "uni/infra/accportprof-leafintprftest"}}}' - - intftoleaf_idempotent is not changed - - intftoleaf_idempotent.sent == {} - -- name: Query an interface selector profile associated with a switch policy leaf profile - aci_interface_selector_to_switch_policy_leaf_profile: - <<: *aci_switch_policy_leaf_profile_present - interface_selector: leafintprftest - state: query - register: binding_query - -- name: query assertions - assert: - that: - - binding_query is not changed - - binding_query.current | length >= 1 - - '"api/mo/uni/infra/nprof-swleafprftest/rsaccPortP-[uni/infra/accportprof-leafintprftest].json" in binding_query.url' - -- name: Remove binding of interface access port selector and Interface Policy Leaf Profile - check mode - aci_interface_selector_to_switch_policy_leaf_profile: &aci_interface_selector_to_switch_policy_leaf_profile_absent - <<: *aci_switch_policy_leaf_profile_present - interface_selector: leafintprftest - state: absent - check_mode: yes - register: intftoleaf_check_mode_absent - -- name: Remove binding of interface access port selector and Interface Policy Leaf Profile - delete works - aci_interface_selector_to_switch_policy_leaf_profile: - <<: *aci_interface_selector_to_switch_policy_leaf_profile_absent - register: intftoleaf_absent - -- name: Remove binding of interface access port selector and Interface Policy Leaf Profile - idempotency works - aci_interface_selector_to_switch_policy_leaf_profile: - <<: *aci_interface_selector_to_switch_policy_leaf_profile_absent - register: intftoleaf_absent_idempotent - -- name: Remove binding of interface access port selector and Interface Policy Leaf Profile - check mode - aci_interface_selector_to_switch_policy_leaf_profile: - <<: *aci_switch_policy_leaf_profile_present - state: absent - ignore_errors: yes - register: intftoleaf_absent_missing_param - -- name: absent assertions - assert: - that: - - intftoleaf_check_mode_absent is changed - - intftoleaf_check_mode_absent.previous != [] - - intftoleaf_absent is changed - - intftoleaf_absent.previous == intftoleaf_check_mode_absent.previous - - intftoleaf_absent_idempotent is not changed - - intftoleaf_absent_idempotent.previous == [] - - intftoleaf_absent_missing_param is failed - - 'intftoleaf_absent_missing_param.msg == "state is absent but all of the following are missing: interface_selector"' - -- name: Remove an interface selector associated with a Switch Policy Leaf Profile - Clean up - aci_interface_selector_to_switch_policy_leaf_profile: - <<: *aci_interface_selector_to_switch_policy_leaf_profile_absent - state: absent - -- name: delete Switch Policy Leaf profile - Clean up - aci_switch_policy_leaf_profile: - <<: *aci_switch_policy_leaf_profile_present - state: absent - -- name: delete Interface Policy Leaf profile - Clean up - aci_interface_policy_leaf_profile: - <<: *aci_interface_policy_leaf_profile_present - leaf_interface_profile: leafintprftest - state: absent diff --git a/test/integration/targets/aci_rest/aliases b/test/integration/targets/aci_rest/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_rest/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_rest/tasks/error_handling.yml b/test/integration/targets/aci_rest/tasks/error_handling.yml deleted file mode 100644 index b438a1e43b..0000000000 --- a/test/integration/targets/aci_rest/tasks/error_handling.yml +++ /dev/null @@ -1,191 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - - -# PROVOKE ERRORS -- name: Error on name resolution - aci_rest: - host: foo.bar.cisco.com - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - path: /api/mo/uni.json - method: post - content: - fvTenant: - attributes: - name: ansible_test - ignore_errors: yes - register: error_on_name_resolution - -- name: Verify error_on_name_resolution - assert: - that: - - error_on_name_resolution is failed - - "error_on_name_resolution.msg == 'Connection failed for https://foo.bar.cisco.com/api/aaaLogin.json. Request failed: <urlopen error [Errno -2] Name or service not known>'" - - "'current' not in error_on_name_resolution" - - "'previous' not in error_on_name_resolution" - - "'sent' not in error_on_name_resolution" - - "'proposed' not in error_on_name_resolution" - - "'filter_string' not in error_on_name_resolution" - -- name: Error when required parameter is missing - aci_rest: - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - method: post - content: - fvTenant: - attributes: - name: ansible_test - ignore_errors: yes - register: error_on_missing_required_param - -- name: Verify error_on_missing_required_param - assert: - that: - - error_on_missing_required_param is failed - - 'error_on_missing_required_param.msg == "missing required arguments: path"' - - "'current' not in error_on_missing_required_param" - - "'previous' not in error_on_missing_required_param" - - "'sent' not in error_on_missing_required_param" - - "'proposed' not in error_on_missing_required_param" - - "'filter_string' not in error_on_missing_required_param" - -- name: Error when attributes are missing - aci_rest: - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - path: /api/mo/uni/tn-ansible_test.json - method: post - content: - fvTenant: - children: - ignore_errors: yes - register: error_on_missing_attributes - -- name: Verify error_on_missing_attributes - assert: - that: - - error_on_missing_attributes is failed - - error_on_missing_attributes.method == 'POST' - - "error_on_missing_attributes.msg == 'APIC Error 400: invalid data at line \\'1\\'. Attributes are missing, tag \\'attributes\\' must be specified first, before any other tag'" - - 'error_on_missing_attributes.response == "HTTP Error 400: Bad Request"' - - error_on_missing_attributes.status == 400 - - "'current' not in error_on_missing_attributes" - - "'previous' not in error_on_missing_attributes" - - "'sent' not in error_on_missing_attributes" - - "'proposed' not in error_on_missing_attributes" - - "'filter_string' not in error_on_missing_attributes" - -- name: Error when input does not validate - aci_rest: - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - path: /api/mo/uni.json - method: post - content: - fvTenant: - attributes: - name: ansible_test - descr: This is an [invalid] description - ignore_errors: yes - register: error_on_input_validation - -- name: Verify error_on_input_validation - assert: - that: - - error_on_input_validation is failed - - error_on_input_validation.method == 'POST' - - "error_on_input_validation.msg == 'APIC Error 801: property descr of tn-ansible_test failed validation for value \\'This is an [invalid] description\\''" - - 'error_on_input_validation.response == "HTTP Error 400: Bad Request"' - - error_on_input_validation.status == 400 - - "'current' not in error_on_input_validation" - - "'previous' not in error_on_input_validation" - - "'sent' not in error_on_input_validation" - - "'proposed' not in error_on_input_validation" - - "'filter_string' not in error_on_input_validation" - -- name: Error when invalid attributes are used - aci_rest: - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - path: /api/mo/uni.json - method: post - content: - fvTenant: - attributes: - name: ansible_test - description: This is an "invalid" description - ignore_errors: yes - register: error_on_invalid_attributes - -- name: Verify error_on_invalid_attributes - assert: - that: - - error_on_invalid_attributes is failed - - error_on_invalid_attributes.method == 'POST' - - "error_on_invalid_attributes.msg == 'APIC Error 400: unknown attribute \\'description\\' in element \\'fvTenant\\''" - - 'error_on_invalid_attributes.response == "HTTP Error 400: Bad Request"' - - error_on_invalid_attributes.status == 400 - - "'current' not in error_on_invalid_attributes" - - "'previous' not in error_on_invalid_attributes" - - "'sent' not in error_on_invalid_attributes" - - "'proposed' not in error_on_invalid_attributes" - - "'filter_string' not in error_on_invalid_attributes" - -- name: Error on invalid object - aci_rest: - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - path: /api/mo/uni.json - method: post - content: - fvFoobar: - attributes: - name: ansible_test - ignore_errors: yes - register: error_on_invalid_object - -- name: Verify error_on_invalid_object - assert: - that: - - error_on_invalid_object is failed - - error_on_invalid_object.method == 'POST' - - "error_on_invalid_object.msg == 'APIC Error 122: unknown managed object class fvFoobar'" - - 'error_on_invalid_object.response == "HTTP Error 400: Bad Request"' - - error_on_invalid_object.status == 400 - - "'current' not in error_on_invalid_object" - - "'previous' not in error_on_invalid_object" - - "'sent' not in error_on_invalid_object" - - "'proposed' not in error_on_invalid_object" diff --git a/test/integration/targets/aci_rest/tasks/json_inline.yml b/test/integration/targets/aci_rest/tasks/json_inline.yml deleted file mode 100644 index 110dd09e4f..0000000000 --- a/test/integration/targets/aci_rest/tasks/json_inline.yml +++ /dev/null @@ -1,166 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Dag Wieers (@dagwieers) <dag@wieers.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - - -# CLEAN ENVIRONMENT -- name: Remove tenant - aci_rest: &tenant_absent - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - path: /api/mo/uni/tn-[ansible_test].json - method: delete - -# ADD TENANT -- name: Add tenant (normal mode) - aci_rest: &tenant_present - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - path: /api/mo/uni.json - method: post - content: - { - "fvTenant": { - "attributes": { - "name": "ansible_test" - } - } - } - delegate_to: localhost - register: nm_add_tenant - -- name: Add tenant again (normal mode) - aci_rest: *tenant_present - delegate_to: localhost - register: nm_add_tenant_again - -- name: Verify add_tenant - assert: - that: - - nm_add_tenant is changed - - nm_add_tenant_again is not changed - -# CHANGE TENANT -- name: Change description of tenant (normal mode) - aci_rest: &tenant_changed - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - path: /api/mo/uni.json - method: post - content: - { - "fvTenant": { - "attributes": { - "descr": "Ansible test tenant", - "name": "ansible_test" - } - } - } - delegate_to: localhost - register: nm_add_tenant_descr - -- name: Change description of tenant again (normal mode) - aci_rest: *tenant_changed - delegate_to: localhost - register: nm_add_tenant_descr_again - -- name: Verify add_tenant_descr - assert: - that: - - nm_add_tenant_descr is changed - - nm_add_tenant_descr_again is not changed - -# ADD TENANT AGAIN -- name: Add tenant again with no description (normal mode) - aci_rest: *tenant_present - delegate_to: localhost - register: nm_add_tenant_again_no_descr - -- name: Verify add_tenant_again_no_descr - assert: - that: - - nm_add_tenant_again_no_descr is not changed - -# QUERY ALL TENANTS -- name: Query all tenants (normal mode) - aci_rest: &tenant_query_all - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - path: /api/mo/uni/tn-[ansible_test].json - method: get - delegate_to: localhost - register: nm_query_all_tenants - -- name: Verify query_all_tenants - assert: - that: - - nm_query_all_tenants is not changed - -# QUERY A TENANT -- name: Query our tenant - aci_rest: &tenant_query - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - path: /api/mo/uni/tn-[ansible_test].json - method: get - delegate_to: localhost - register: nm_query_tenant - -- name: Verify query_tenant - assert: - that: - - nm_query_tenant is not changed - -# REMOVE TENANT -- name: Remove tenant (normal mode) - aci_rest: *tenant_absent - delegate_to: localhost - register: nm_remove_tenant - -- name: Remove tenant again (normal mode) - aci_rest: *tenant_absent - delegate_to: localhost - register: nm_remove_tenant_again - -- name: Verify remove_tenant - assert: - that: - - nm_remove_tenant is changed - - nm_remove_tenant_again is not changed - -# QUERY NON-EXISTING TENANT -- name: Query non-existing tenant (normal mode) - aci_rest: *tenant_query - delegate_to: localhost - register: nm_query_non_tenant - -- name: Verify query_non_tenant - assert: - that: - - nm_query_non_tenant is not changed diff --git a/test/integration/targets/aci_rest/tasks/json_string.yml b/test/integration/targets/aci_rest/tasks/json_string.yml deleted file mode 100644 index 34d0ff4c98..0000000000 --- a/test/integration/targets/aci_rest/tasks/json_string.yml +++ /dev/null @@ -1,156 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Dag Wieers (@dagwieers) <dag@wieers.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - - -# CLEAN ENVIRONMENT -- name: Remove tenant - aci_rest: &tenant_absent - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - path: /api/mo/uni/tn-[ansible_test].json - method: delete - -# ADD TENANT -- name: Add tenant (normal mode) - aci_rest: &tenant_present - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - path: /api/mo/uni.json - method: post - content: | - { - "fvTenant": { - "attributes": { - "name": "ansible_test" - } - } - } - register: nm_add_tenant - -- name: Add tenant again (normal mode) - aci_rest: *tenant_present - register: nm_add_tenant_again - -- name: Verify add_tenant - assert: - that: - - nm_add_tenant is changed - - nm_add_tenant_again is not changed - -# CHANGE TENANT -- name: Change description of tenant (normal mode) - aci_rest: &tenant_changed - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - path: /api/mo/uni.json - method: post - content: | - { - "fvTenant": { - "attributes": { - "descr": "Ansible test tenant", - "name": "ansible_test" - } - } - } - register: nm_add_tenant_descr - -- name: Change description of tenant again (normal mode) - aci_rest: *tenant_changed - register: nm_add_tenant_descr_again - -- name: Verify add_tenant_descr - assert: - that: - - nm_add_tenant_descr is changed - - nm_add_tenant_descr_again is not changed - -# ADD TENANT AGAIN -- name: Add tenant again with no description (normal mode) - aci_rest: *tenant_present - register: nm_add_tenant_again_no_descr - -- name: Verify add_tenant_again_no_descr - assert: - that: - - nm_add_tenant_again_no_descr is not changed - -# QUERY ALL TENANTS -- name: Query all tenants (normal mode) - aci_rest: &tenant_query_all - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - path: /api/mo/uni/tn-[ansible_test].json - method: get - register: nm_query_all_tenants - -- name: Verify query_all_tenants - assert: - that: - - nm_query_all_tenants is not changed - -# QUERY A TENANT -- name: Query our tenant - aci_rest: &tenant_query - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - path: /api/mo/uni/tn-[ansible_test].json - method: get - register: nm_query_tenant - -- name: Verify query_tenant - assert: - that: - - nm_query_tenant is not changed - -# REMOVE TENANT -- name: Remove tenant (normal mode) - aci_rest: *tenant_absent - register: nm_remove_tenant - -- name: Remove tenant again (normal mode) - aci_rest: *tenant_absent - register: nm_remove_tenant_again - -- name: Verify remove_tenant - assert: - that: - - nm_remove_tenant is changed - - nm_remove_tenant_again is not changed - -# QUERY NON-EXISTING TENANT -- name: Query non-existing tenant (normal mode) - aci_rest: *tenant_query - register: nm_query_non_tenant - -- name: Verify query_non_tenant - assert: - that: - - nm_query_non_tenant is not changed diff --git a/test/integration/targets/aci_rest/tasks/main.yml b/test/integration/targets/aci_rest/tasks/main.yml deleted file mode 100644 index c7f7f20e9d..0000000000 --- a/test/integration/targets/aci_rest/tasks/main.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Dag Wieers (@dagwieers) <dag@wieers.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - -- include_tasks: yaml_inline.yml - tags: yaml_inline - -- include_tasks: yaml_string.yml - tags: yaml_string - -- include_tasks: json_inline.yml - tags: json_inline - -- include_tasks: json_string.yml - tags: json_string - -- include_tasks: xml_string.yml - tags: xml_string - -- include_tasks: error_handling.yml - tags: error_handling diff --git a/test/integration/targets/aci_rest/tasks/xml_string.yml b/test/integration/targets/aci_rest/tasks/xml_string.yml deleted file mode 100644 index c58aa488a9..0000000000 --- a/test/integration/targets/aci_rest/tasks/xml_string.yml +++ /dev/null @@ -1,143 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Dag Wieers (@dagwieers) <dag@wieers.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - - -# CLEAN ENVIRONMENT -- name: Remove tenant - aci_rest: &tenant_absent - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - path: /api/mo/uni/tn-[ansible_test].xml - method: delete - -# ADD TENANT -- name: Add tenant (normal mode) - aci_rest: &tenant_present - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - path: /api/mo/uni.xml - method: post - content: | - <fvTenant name="ansible_test"/> - register: nm_add_tenant - -- name: Add tenant again (normal mode) - aci_rest: *tenant_present - register: nm_add_tenant_again - -- name: Verify add_tenant - assert: - that: - - nm_add_tenant is changed - - nm_add_tenant_again is not changed - -# CHANGE TENANT -- name: Change description of tenant (normal mode) - aci_rest: &tenant_changed - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - path: /api/mo/uni.xml - method: post - content: | - <fvTenant name="ansible_test" descr="Ansible test tenant"/> - register: nm_add_tenant_descr - -- name: Change description of tenant again (normal mode) - aci_rest: *tenant_changed - register: nm_add_tenant_descr_again - -- name: Verify add_tenant_descr - assert: - that: - - nm_add_tenant_descr is changed - - nm_add_tenant_descr_again is not changed - -# ADD TENANT AGAIN -- name: Add tenant again with no description (normal mode) - aci_rest: *tenant_present - register: nm_add_tenant_again_no_descr - -- name: Verify add_tenant_again_no_descr - assert: - that: - - nm_add_tenant_again_no_descr is not changed - -# QUERY ALL TENANTS -- name: Query all tenants (normal mode) - aci_rest: &tenant_query_all - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - path: /api/mo/uni/tn-[ansible_test].xml - method: get - register: nm_query_all_tenants - -- name: Verify query_all_tenants - assert: - that: - - nm_query_all_tenants is not changed - -# QUERY A TENANT -- name: Query our tenant - aci_rest: &tenant_query - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - path: /api/mo/uni/tn-[ansible_test].xml - method: get - register: nm_query_tenant - -- name: Verify query_tenant - assert: - that: - - nm_query_tenant is not changed - -# REMOVE TENANT -- name: Remove tenant (normal mode) - aci_rest: *tenant_absent - register: nm_remove_tenant - -- name: Remove tenant again (normal mode) - aci_rest: *tenant_absent - register: nm_remove_tenant_again - -- name: Verify remove_tenant - assert: - that: - - nm_remove_tenant is changed - - nm_remove_tenant_again is not changed - -# QUERY NON-EXISTING TENANT -- name: Query non-existing tenant (normal mode) - aci_rest: *tenant_query - register: nm_query_non_tenant - -- name: Verify query_non_tenant - assert: - that: - - nm_query_non_tenant is not changed diff --git a/test/integration/targets/aci_rest/tasks/yaml_inline.yml b/test/integration/targets/aci_rest/tasks/yaml_inline.yml deleted file mode 100644 index 58b139d354..0000000000 --- a/test/integration/targets/aci_rest/tasks/yaml_inline.yml +++ /dev/null @@ -1,148 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Dag Wieers (@dagwieers) <dag@wieers.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - - -# CLEAN ENVIRONMENT -- name: Remove tenant - aci_rest: &tenant_absent - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - path: /api/mo/uni/tn-[ansible_test].json - method: delete - -# ADD TENANT -- name: Add tenant (normal mode) - aci_rest: &tenant_present - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - path: /api/mo/uni.json - method: post - content: - fvTenant: - attributes: - name: ansible_test - register: nm_add_tenant - -- name: Add tenant again (normal mode) - aci_rest: *tenant_present - register: nm_add_tenant_again - -- name: Verify add_tenant - assert: - that: - - nm_add_tenant is changed - - nm_add_tenant_again is not changed - -# CHANGE TENANT -- name: Change description of tenant (normal mode) - aci_rest: &tenant_changed - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - path: /api/mo/uni.json - method: post - content: - fvTenant: - attributes: - name: ansible_test - descr: Ansible test tenant - register: nm_add_tenant_descr - -- name: Change description of tenant again (normal mode) - aci_rest: *tenant_changed - register: nm_add_tenant_descr_again - -- name: Verify add_tenant_descr - assert: - that: - - nm_add_tenant_descr is changed - - nm_add_tenant_descr_again is not changed - -# ADD TENANT AGAIN -- name: Add tenant again with no description (normal mode) - aci_rest: *tenant_present - register: nm_add_tenant_again_no_descr - -- name: Verify add_tenant_again_no_descr - assert: - that: - - nm_add_tenant_again_no_descr is not changed - -# QUERY ALL TENANTS -- name: Query all tenants (normal mode) - aci_rest: &tenant_query_all - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - path: /api/mo/uni/tn-[ansible_test].json - method: get - register: nm_query_all_tenants - -- name: Verify query_all_tenants - assert: - that: - - nm_query_all_tenants is not changed - -# QUERY A TENANT -- name: Query our tenant - aci_rest: &tenant_query - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - path: /api/mo/uni/tn-[ansible_test].json - method: get - register: nm_query_tenant - -- name: Verify query_tenant - assert: - that: - - nm_query_tenant is not changed - -# REMOVE TENANT -- name: Remove tenant (normal mode) - aci_rest: *tenant_absent - register: nm_remove_tenant - -- name: Remove tenant again (normal mode) - aci_rest: *tenant_absent - register: nm_remove_tenant_again - -- name: Verify remove_tenant - assert: - that: - - nm_remove_tenant is changed - - nm_remove_tenant_again is not changed - -# QUERY NON-EXISTING TENANT -- name: Query non-existing tenant (normal mode) - aci_rest: *tenant_query - register: nm_query_non_tenant - -- name: Verify query_non_tenant - assert: - that: - - nm_query_non_tenant is not changed diff --git a/test/integration/targets/aci_rest/tasks/yaml_string.yml b/test/integration/targets/aci_rest/tasks/yaml_string.yml deleted file mode 100644 index d9b5e767bf..0000000000 --- a/test/integration/targets/aci_rest/tasks/yaml_string.yml +++ /dev/null @@ -1,148 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Dag Wieers (@dagwieers) <dag@wieers.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - - -# CLEAN ENVIRONMENT -- name: Remove tenant - aci_rest: &tenant_absent - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - path: /api/mo/uni/tn-[ansible_test].json - method: delete - -# ADD TENANT -- name: Add tenant (normal mode) - aci_rest: &tenant_present - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - path: /api/mo/uni.json - method: post - content: | - fvTenant: - attributes: - name: ansible_test - register: nm_add_tenant - -- name: Add tenant again (normal mode) - aci_rest: *tenant_present - register: nm_add_tenant_again - -- name: Verify add_tenant - assert: - that: - - nm_add_tenant is changed - - nm_add_tenant_again is not changed - -# CHANGE TENANT -- name: Change description of tenant (normal mode) - aci_rest: &tenant_changed - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - path: /api/mo/uni.json - method: post - content: | - fvTenant: - attributes: - name: ansible_test - descr: Ansible test tenant - register: nm_add_tenant_descr - -- name: Change description of tenant again (normal mode) - aci_rest: *tenant_changed - register: nm_add_tenant_descr_again - -- name: Verify add_tenant_descr - assert: - that: - - nm_add_tenant_descr is changed - - nm_add_tenant_descr_again is not changed - -# ADD TENANT AGAIN -- name: Add tenant again with no description (normal mode) - aci_rest: *tenant_present - register: nm_add_tenant_again_no_descr - -- name: Verify add_tenant_again_no_descr - assert: - that: - - nm_add_tenant_again_no_descr is not changed - -# QUERY ALL TENANTS -- name: Query all tenants (normal mode) - aci_rest: &tenant_query_all - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - path: /api/mo/uni/tn-[ansible_test].json - method: get - register: nm_query_all_tenants - -- name: Verify query_all_tenants - assert: - that: - - nm_query_all_tenants is not changed - -# QUERY A TENANT -- name: Query our tenant - aci_rest: &tenant_query - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - path: /api/mo/uni/tn-[ansible_test].json - method: get - register: nm_query_tenant - -- name: Verify query_tenant - assert: - that: - - nm_query_tenant is not changed - -# REMOVE TENANT -- name: Remove tenant (normal mode) - aci_rest: *tenant_absent - register: nm_remove_tenant - -- name: Remove tenant again (normal mode) - aci_rest: *tenant_absent - register: nm_remove_tenant_again - -- name: Verify remove_tenant - assert: - that: - - nm_remove_tenant is changed - - nm_remove_tenant_again is not changed - -# QUERY NON-EXISTING TENANT -- name: Query non-existing tenant (normal mode) - aci_rest: *tenant_query - register: nm_query_non_tenant - -- name: Verify query_non_tenant - assert: - that: - - nm_query_non_tenant is not changed diff --git a/test/integration/targets/aci_static_binding_to_epg/aliases b/test/integration/targets/aci_static_binding_to_epg/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_static_binding_to_epg/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_static_binding_to_epg/tasks/main.yml b/test/integration/targets/aci_static_binding_to_epg/tasks/main.yml deleted file mode 100644 index 7f3d3ce632..0000000000 --- a/test/integration/targets/aci_static_binding_to_epg/tasks/main.yml +++ /dev/null @@ -1,203 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Bruno Calogero <bcalogero@cisco.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - -- name: Ensure static path to epg is deleted for test kick off - aci_static_binding_to_epg: &aci_static_binding_to_epg_absent - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - tenant: anstest - ap: anstest - epg: anstest - interface_type: switch_port - pod: 1 - leafs: 101 - interface: '1/7' - state: absent - -- name: Ensure tenant exists for tests to kick off - aci_tenant: &aci_tenant_present - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - tenant: anstest - state: present - register: tenant_present - -- name: Ensure ap exists - aci_ap: &aci_ap_present - <<: *aci_tenant_present - ap: anstest - register: ap_present - -- name: Ensure epg exists - aci_epg: &aci_epg_present - <<: *aci_ap_present - epg: anstest - register: epg_present - -- name: Bind static-binding to epg - check mode works - aci_static_binding_to_epg: &aci_static_binding_to_epg_present - <<: *aci_epg_present - encap_id: 222 - deploy_immediacy: lazy - interface_mode: trunk - interface_type: switch_port - pod: 1 - leafs: 101 - interface: '1/7' - check_mode: yes - register: provide_present_check_mode - -- name: Bind static-binding to epg - provide works (creation w/o check-mode) - aci_static_binding_to_epg: - <<: *aci_static_binding_to_epg_present - ignore_errors: yes - register: provide_present - -- name: Bind static-binding to epg - primary_encap_id works - aci_static_binding_to_epg: &primary_encap_id_present - <<: *aci_static_binding_to_epg_present - primary_encap_id: 50 - register: primary_ecap_id_present - -- name: Bind contract to epg - idempotency works again - aci_static_binding_to_epg: - <<: *primary_encap_id_present - register: idempotent_present - -- name: Bind contract to epg - update description (check mode) - aci_static_binding_to_epg: - <<: *primary_encap_id_present - description: Binding description - check_mode: yes - register: description_cm - -- name: Bind contract to epg - update description (run mode) - aci_static_binding_to_epg: - <<: *primary_encap_id_present - description: Binding description - register: description - -- name: Bind contract to epg - update description (check mode) - aci_static_binding_to_epg: - <<: *primary_encap_id_present - description: Binding description - register: idempotent_description_cm - -- name: Bind contract to epg - update description (run mode) - aci_static_binding_to_epg: - <<: *primary_encap_id_present - description: Binding description - register: idempotent_description - -- name: Missing required param - failure message works - aci_static_binding_to_epg: - <<: *aci_tenant_present - ignore_errors: yes - register: missing_required_present - -- name: Present assertions - assert: - that: - - provide_present_check_mode is changed - - 'provide_present_check_mode.sent == {"fvRsPathAtt": {"attributes": { "encap": "vlan-222", "instrImedcy": "lazy", "mode": "regular", "tDn": "topology/pod-1/paths-101/pathep-[eth1/7]"}}}' - - provide_present is changed - - provide_present.sent == provide_present_check_mode.sent - - provide_present.previous == [] - - primary_ecap_id_present is changed - - 'primary_ecap_id_present.sent == {"fvRsPathAtt": {"attributes": {"primaryEncap": "vlan-50"}}}' - - description_cm is changed - - description is changed - - idempotent_description_cm is not changed - - idempotent_description is not changed - - missing_required_present is failed - - 'missing_required_present.msg == "state is present but all of the following are missing: ap, encap_id, epg, interface, leafs, pod_id"' - - missing_required_present is failed - - -- name: Query specific binding - aci_static_binding_to_epg: - <<: *primary_encap_id_present - state: query - register: query_static_binding - -- name: Query all bindings - aci_static_binding_to_epg: - <<: *aci_tenant_present - state: query - register: query_all - -- name: Query assertions - assert: - that: - - query_static_binding is not changed - - query_static_binding.current != [] - - '"uni/tn-anstest/ap-anstest/epg-anstest/rspathAtt-[topology/pod-1/paths-101/pathep-[eth1/7]]" in query_static_binding.url' - - query_all is not changed - - '"uni/tn-anstest.json" in query_all.url' - - -- name: Delete provide binding - deletion works - aci_static_binding_to_epg: - <<: *primary_encap_id_present - state: absent - register: provide_absent - -- name: Delete provide binding - idempotency works - aci_static_binding_to_epg: - <<: *primary_encap_id_present - state: absent - register: provide_absent_idempotent - -- name: Missing param - failure message works - aci_static_binding_to_epg: - <<: *aci_tenant_present - state: absent - ignore_errors: yes - register: missing_param_absent - -- name: Absent assertions - assert: - that: - - provide_absent is changed - - provide_absent.previous.0.fvRsPathAtt is defined - - provide_absent_idempotent is not changed - - provide_absent_idempotent.previous == [] - - missing_param_absent is failed - - missing_param_absent is failed - - 'missing_param_absent.msg == "state is absent but all of the following are missing: ap, epg, interface, leafs, pod_id"' - -- name: Cleanup binding - aci_static_binding_to_epg: - <<: *aci_static_binding_to_epg_absent - -- name: Cleanup epg - aci_epg: - <<: *aci_epg_present - state: absent - -- name: Cleanup ap - aci_ap: - <<: *aci_ap_present - state: absent - -- name: Cleanup tenant - aci_tenant: - <<: *aci_tenant_present - state: absent diff --git a/test/integration/targets/aci_switch_leaf_selector/aliases b/test/integration/targets/aci_switch_leaf_selector/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_switch_leaf_selector/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_switch_leaf_selector/tasks/main.yml b/test/integration/targets/aci_switch_leaf_selector/tasks/main.yml deleted file mode 100644 index fccc77c983..0000000000 --- a/test/integration/targets/aci_switch_leaf_selector/tasks/main.yml +++ /dev/null @@ -1,138 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Bruno Calogero <brunocalogero@hotmail.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - -- name: Deleting Switch Policy Leaf profile exists for kick off - aci_switch_policy_leaf_profile: - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - leaf_profile: sw_name_test - state: absent - -- name: Ensuring Switch Policy Leaf profile exists for kick off - aci_switch_policy_leaf_profile: &aci_switch_policy_leaf_profile_present - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - leaf_profile: sw_name_test - state: present - register: leaf_profile_present - -# TODO: Ensure that leaf Policy Group Exists (module missing) (infra:AccPortGrp) - -- name: Adding a switch policy leaf profile selector associated Node Block range (w/o policy group) - check mode works - aci_switch_leaf_selector: &aci_switch_leaf_selector_present - <<: *aci_switch_policy_leaf_profile_present - leaf: leaf_selector_name - leaf_node_blk: node_blk_name - from: 1011 - to: 1011 - check_mode: yes - register: sw_leaf_selec_check_mode_present - -- name: Adding a switch policy leaf profile selector associated Node Block range (w/o policy group) - creation works - aci_switch_leaf_selector: - <<: *aci_switch_leaf_selector_present - register: sw_leaf_selec_present - -- name: Adding a switch policy leaf profile selector associated Node Block range (w/o policy group) - idempotency works - aci_switch_leaf_selector: - <<: *aci_switch_leaf_selector_present - register: sw_leaf_selec_idempotent - -- name: Adding a switch policy leaf profile selector associated Node Block range (w/ policy group) - update works - aci_switch_leaf_selector: - <<: *aci_switch_leaf_selector_present - policy_group: anstest_policygroupname - register: sw_leaf_selec_update - -# TODO: also test for errors -- name: present assertions - assert: - that: - - sw_leaf_selec_check_mode_present is changed - - sw_leaf_selec_present is changed - - sw_leaf_selec_present.previous == [] - - 'sw_leaf_selec_present.sent == {"infraLeafS": {"attributes": {"name": "leaf_selector_name"}, "children": [{"infraNodeBlk": {"attributes": {"from_": "1011", "name": "node_blk_name", "to_": "1011"}}}]}}' - - sw_leaf_selec_idempotent is not changed - - sw_leaf_selec_idempotent.sent == {} - - sw_leaf_selec_update is changed - - 'sw_leaf_selec_update.sent == {"infraLeafS": {"attributes": {},"children": [{"infraRsAccNodePGrp": {"attributes": {"tDn": "uni/infra/funcprof/accnodepgrp-anstest_policygroupname"}}}]}}' - -- name: Query Specific switch policy leaf profile selector - aci_switch_leaf_selector: - <<: *aci_switch_policy_leaf_profile_present - leaf: leaf_selector_name # "{{ fake_var | default(omit) }}" ? - state: query - register: binding_query - -- name: present assertions - assert: - that: - - binding_query is not changed - - binding_query.current | length >= 1 - - '"api/mo/uni/infra/nprof-sw_name_test/leaves-leaf_selector_name-typ-range.json" in binding_query.url' - -- name: Remove binding of interface access port selector and Interface Policy Leaf Profile - check mode - aci_switch_leaf_selector: &aci_switch_leaf_selector_absent - <<: *aci_switch_policy_leaf_profile_present - leaf: leaf_selector_name - state: absent - check_mode: yes - register: sw_leaf_selec_check_mode_absent - -- name: Remove switch policy leaf profile selector - delete works - aci_switch_leaf_selector: - <<: *aci_switch_leaf_selector_absent - register: sw_leaf_selec_absent - -- name: Remove switch policy leaf profile selector - idempotency works - aci_switch_leaf_selector: - <<: *aci_switch_leaf_selector_absent - register: sw_leaf_selec_absent_idempotent - -- name: Remove switch policy leaf profile selector - check mode - aci_switch_leaf_selector: - <<: *aci_switch_policy_leaf_profile_present - #access_port_selector: anstest_accessportselector - state: absent - ignore_errors: yes - register: sw_leaf_selec_absent_missing_param - -- name: absent assertions - assert: - that: - - sw_leaf_selec_check_mode_absent is changed - - sw_leaf_selec_check_mode_absent.previous != [] - - sw_leaf_selec_absent is changed - - sw_leaf_selec_absent.previous == sw_leaf_selec_check_mode_absent.previous - - sw_leaf_selec_absent_idempotent is not changed - - sw_leaf_selec_absent_idempotent.previous == [] - - sw_leaf_selec_absent_missing_param is failed - - 'sw_leaf_selec_absent_missing_param.msg == "state is absent but all of the following are missing: leaf"' - - -- name: Remove switch policy leaf profile selector - Clean up - aci_switch_leaf_selector: - <<: *aci_switch_leaf_selector_absent - state: absent - -- name: Deleting Switch Policy Leaf profile exists for kick off - aci_switch_policy_leaf_profile: - <<: *aci_switch_policy_leaf_profile_present - state: absent diff --git a/test/integration/targets/aci_switch_policy_leaf_profile/aliases b/test/integration/targets/aci_switch_policy_leaf_profile/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_switch_policy_leaf_profile/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_switch_policy_leaf_profile/tasks/main.yml b/test/integration/targets/aci_switch_policy_leaf_profile/tasks/main.yml deleted file mode 100644 index cee1c26d3c..0000000000 --- a/test/integration/targets/aci_switch_policy_leaf_profile/tasks/main.yml +++ /dev/null @@ -1,213 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Bruno Calogero <brunocalogero@hotmail.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - - -# CLEAN ENVIRONMENT -- name: Remove leaf profile - aci_switch_policy_leaf_profile: &aci_switch_policy_leaf_profile_absent - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - leaf_profile: ansible_test - state: absent - - -# ADD LEAF PROFILE -- name: Add switch policy leaf profile (check_mode) - aci_switch_policy_leaf_profile: &aci_switch_policy_leaf_profile_present - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - leaf_profile: ansible_test - state: present - check_mode: yes - register: cm_add_switch_leaf_profile - -- name: Add leaf profile (normal mode) - aci_switch_policy_leaf_profile: *aci_switch_policy_leaf_profile_present - register: nm_add_switch_leaf_profile - -- name: Add leaf profile again (check_mode) - aci_switch_policy_leaf_profile: *aci_switch_policy_leaf_profile_present - check_mode: yes - register: cm_add_switch_leaf_profile_again - -- name: Add leaf profile again (normal mode) - aci_switch_policy_leaf_profile: *aci_switch_policy_leaf_profile_present - register: nm_add_switch_leaf_profile_again - -- name: Verify add_switch_leaf_profile - assert: - that: - - cm_add_switch_leaf_profile is changed - - nm_add_switch_leaf_profile is changed - - cm_add_switch_leaf_profile_again is not changed - - nm_add_switch_leaf_profile_again is not changed - - -# CHANGE SWITCH LEAF PROFILE -- name: Change description of leaf profile (check_mode) - aci_switch_policy_leaf_profile: - <<: *aci_switch_policy_leaf_profile_present - description: Ansible test leaf profile - check_mode: yes - register: cm_add_switch_leaf_profile_descr - -- name: Change description of leaf profile (normal mode) - aci_switch_policy_leaf_profile: - <<: *aci_switch_policy_leaf_profile_present - description: Ansible test leaf profile - register: nm_add_switch_leaf_profile_descr - -- name: Change description of leaf profile again (check_mode) - aci_switch_policy_leaf_profile: - <<: *aci_switch_policy_leaf_profile_present - description: Ansible test leaf profile - check_mode: yes - register: cm_add_switch_leaf_profile_descr_again - -- name: Change description of leaf profile again (normal mode) - aci_switch_policy_leaf_profile: - <<: *aci_switch_policy_leaf_profile_present - description: Ansible test leaf profile - register: nm_add_switch_leaf_profile_descr_again - -- name: Verify add_switch_leaf_profile_descr - assert: - that: - - cm_add_switch_leaf_profile_descr is changed - - nm_add_switch_leaf_profile_descr is changed - - cm_add_switch_leaf_profile_descr_again is not changed - - nm_add_switch_leaf_profile_descr_again is not changed - - -# ADD LEAF PROFILE AGAIN -- name: Add leaf profile again with no description (check_mode) - aci_switch_policy_leaf_profile: *aci_switch_policy_leaf_profile_present - check_mode: yes - register: cm_add_switch_leaf_profile_again_no_descr - -- name: Add leaf profile again with no description (normal mode) - aci_switch_policy_leaf_profile: *aci_switch_policy_leaf_profile_present - register: nm_add_switch_leaf_profile_again_no_descr - -- name: Verify add_switch_leaf_profile_again_no_descr - assert: - that: - - cm_add_switch_leaf_profile_again_no_descr is not changed - - nm_add_switch_leaf_profile_again_no_descr is not changed - - -# QUERY ALL LEAF PROFILES -- name: Query all profiles (check_mode) - aci_switch_policy_leaf_profile: &aci_switch_policy_leaf_profile_query - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - state: query - check_mode: yes - register: cm_query_all_switch_leaf_profiles - -- name: Query all switch_leaf_profiles (normal mode) - aci_switch_policy_leaf_profile: *aci_switch_policy_leaf_profile_query - register: nm_query_all_switch_leaf_profiles - -- name: Verify query_all_switch_leaf_profiles - assert: - that: - - cm_query_all_switch_leaf_profiles is not changed - - nm_query_all_switch_leaf_profiles is not changed - # NOTE: Order of switch_leaf_profiles is not stable between calls - #- cm_query_all_switch_leaf_profiles == nm_query_all_switch_leaf_profiles - - -# QUERY A LEAF PROFILE -- name: Query our switch_leaf_profile - aci_switch_policy_leaf_profile: - <<: *aci_switch_policy_leaf_profile_query - leaf_profile: ansible_test - check_mode: yes - register: cm_query_switch_leaf_profile - -- name: Query our switch_leaf_profile - aci_switch_policy_leaf_profile: - <<: *aci_switch_policy_leaf_profile_query - leaf_profile: ansible_test - register: nm_query_switch_leaf_profile - -- name: Verify query_switch_leaf_profile - assert: - that: - - cm_query_switch_leaf_profile is not changed - - nm_query_switch_leaf_profile is not changed - - cm_query_switch_leaf_profile == nm_query_switch_leaf_profile - - -# REMOVE LEAF PROFILE -- name: Remove switch_leaf_profile (check_mode) - aci_switch_policy_leaf_profile: *aci_switch_policy_leaf_profile_absent - check_mode: yes - register: cm_remove_switch_leaf_profile - -- name: Remove switch_leaf_profile (normal mode) - aci_switch_policy_leaf_profile: *aci_switch_policy_leaf_profile_absent - register: nm_remove_switch_leaf_profile - -- name: Remove switch_leaf_profile again (check_mode) - aci_switch_policy_leaf_profile: *aci_switch_policy_leaf_profile_absent - check_mode: yes - register: cm_remove_switch_leaf_profile_again - -- name: Remove switch_leaf_profile again (normal mode) - aci_switch_policy_leaf_profile: *aci_switch_policy_leaf_profile_absent - register: nm_remove_switch_leaf_profile_again - -- name: Verify remove_switch_leaf_profile - assert: - that: - - cm_remove_switch_leaf_profile is changed - - nm_remove_switch_leaf_profile is changed - - cm_remove_switch_leaf_profile_again is not changed - - nm_remove_switch_leaf_profile_again is not changed - - -# QUERY NON-EXISTING LEAF PROFILE -- name: Query non-existing switch_leaf_profile (check_mode) - aci_switch_policy_leaf_profile: - <<: *aci_switch_policy_leaf_profile_query - leaf_profile: ansible_test - check_mode: yes - register: cm_query_non_switch_leaf_profile - -- name: Query non-existing switch_leaf_profile (normal mode) - aci_switch_policy_leaf_profile: - <<: *aci_switch_policy_leaf_profile_query - leaf_profile: ansible_test - register: nm_query_non_switch_leaf_profile - -# TODO: Implement more tests -- name: Verify query_non_switch_leaf_profile - assert: - that: - - cm_query_non_switch_leaf_profile is not changed - - nm_query_non_switch_leaf_profile is not changed - - cm_query_non_switch_leaf_profile == nm_query_non_switch_leaf_profile diff --git a/test/integration/targets/aci_switch_policy_vpc_protection_group/aliases b/test/integration/targets/aci_switch_policy_vpc_protection_group/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_switch_policy_vpc_protection_group/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_switch_policy_vpc_protection_group/tasks/main.yml b/test/integration/targets/aci_switch_policy_vpc_protection_group/tasks/main.yml deleted file mode 100644 index 3924800d5d..0000000000 --- a/test/integration/targets/aci_switch_policy_vpc_protection_group/tasks/main.yml +++ /dev/null @@ -1,213 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Bruno Calogero <brunocalogero@hotmail.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - -# CLEAN ENVIRONMENT -- name: Remove vpc protection group - aci_switch_policy_vpc_protection_group: &aci_switch_policy_vpc_protection_group_absent - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - protection_group: ansible_test - state: absent - - -# ADD VPC PROTECTION GROUP -- name: Add vpc protection group (check_mode) - aci_switch_policy_vpc_protection_group: &aci_switch_policy_vpc_protection_group_present - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - protection_group: ansible_test - protection_group_id: 6 - switch_1_id: 3811 - switch_2_id: 3812 - state: present - check_mode: yes - register: cm_add_vpc_prot_grp - -- name: Add vpc protection group (normal mode) - aci_switch_policy_vpc_protection_group: *aci_switch_policy_vpc_protection_group_present - register: nm_add_vpc_prot_grp - -- name: Add vpc protection group again (check_mode) - aci_switch_policy_vpc_protection_group: *aci_switch_policy_vpc_protection_group_present - check_mode: yes - register: cm_add_vpc_prot_grp_again - -- name: Add vpc protection group again (normal mode) - aci_switch_policy_vpc_protection_group: *aci_switch_policy_vpc_protection_group_present - register: nm_add_vpc_prot_grp_again - -- name: Verify add_vpc_prot_grp_again - assert: - that: - - cm_add_vpc_prot_grp is changed - - nm_add_vpc_prot_grp is changed - - cm_add_vpc_prot_grp_again is not changed - - nm_add_vpc_prot_grp_again is not changed - - -# CHANGE VPC PROTECTION GROUP -- name: Change vpc domain policy of vpc protection group (check_mode) - aci_switch_policy_vpc_protection_group: - <<: *aci_switch_policy_vpc_protection_group_present - vpc_domain_policy: ansible_test_pol - check_mode: yes - register: cm_add_vpc_prot_grp_pol - -- name: Change vpc domain policy of vpc protection group (normal mode) - aci_switch_policy_vpc_protection_group: - <<: *aci_switch_policy_vpc_protection_group_present - vpc_domain_policy: ansible_test_pol - register: nm_add_vpc_prot_grp_pol - -- name: Change vpc domain policy of vpc protection group again (check_mode) - aci_switch_policy_vpc_protection_group: - <<: *aci_switch_policy_vpc_protection_group_present - vpc_domain_policy: ansible_test_pol - check_mode: yes - register: cm_add_vpc_prot_grp_pol_again - -- name: Change vpc domain policy of vpc protection group again (normal mode) - aci_switch_policy_vpc_protection_group: - <<: *aci_switch_policy_vpc_protection_group_present - vpc_domain_policy: ansible_test_pol - register: nm_add_vpc_prot_grp_pol_again - -- name: Verify add_vpc_prot_grp_pol - assert: - that: - - cm_add_vpc_prot_grp_pol is changed - - nm_add_vpc_prot_grp_pol is changed - - cm_add_vpc_prot_grp_pol_again is not changed - - nm_add_vpc_prot_grp_pol_again is not changed - - -# ADD FABRIC NODE AGAIN -- name: Add vpc protection group again with no domain policy (check_mode) - aci_switch_policy_vpc_protection_group: *aci_switch_policy_vpc_protection_group_present - check_mode: yes - register: cm_add_vpc_prot_grp_again_no_pol - -- name: Add vpc protection group again with no domain policy (normal mode) - aci_switch_policy_vpc_protection_group: *aci_switch_policy_vpc_protection_group_present - register: nm_add_vpc_prot_grp_again_no_pol - -- name: Verify add_vpc_prot_grp_again_no_pol - assert: - that: - - cm_add_vpc_prot_grp_again_no_pol is not changed - - nm_add_vpc_prot_grp_again_no_pol is not changed - - -# QUERY ALL VPC PROTECTION GROUPS -- name: Query vpc protection groups (check_mode) - aci_switch_policy_vpc_protection_group: &aci_switch_policy_vpc_protection_group_query - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - state: query - check_mode: yes - register: cm_query_all_vpc_prot_grps - -- name: Query all vpc protection groups (normal mode) - aci_switch_policy_vpc_protection_group: *aci_switch_policy_vpc_protection_group_query - register: nm_query_all_vpc_prot_grps - -- name: Verify query_all_vpc_prot_grps - assert: - that: - - cm_query_all_vpc_prot_grps is not changed - - nm_query_all_vpc_prot_grps is not changed - - cm_query_all_vpc_prot_grps == nm_query_all_vpc_prot_grps - - -# QUERY A VPC PROTECTION GROUP -- name: Query our vpc protection group - aci_switch_policy_vpc_protection_group: - <<: *aci_switch_policy_vpc_protection_group_query - protection_group: ansible_test # might need node_id too - check_mode: yes - register: cm_query_vpc_prot_grp - -- name: Query our vpc protection group - aci_switch_policy_vpc_protection_group: - <<: *aci_switch_policy_vpc_protection_group_query - protection_group: ansible_test - register: nm_query_vpc_prot_grp - -- name: Verify query_vpc_prot_grp - assert: - that: - - cm_query_vpc_prot_grp is not changed - - nm_query_vpc_prot_grp is not changed - - cm_query_vpc_prot_grp == nm_query_vpc_prot_grp - - -# REMOVE FABRIC NODE -- name: Remove vpc protection group (check_mode) - aci_switch_policy_vpc_protection_group: *aci_switch_policy_vpc_protection_group_absent - check_mode: yes - register: cm_remove_vpc_prot_grp - -- name: Remove vpc protection group (normal mode) - aci_switch_policy_vpc_protection_group: *aci_switch_policy_vpc_protection_group_absent - register: nm_remove_vpc_prot_grp - -- name: Remove vpc protection group again (check_mode) - aci_switch_policy_vpc_protection_group: *aci_switch_policy_vpc_protection_group_absent - check_mode: yes - register: cm_remove_vpc_prot_grp_again - -- name: Remove vpc protection group again (normal mode) - aci_switch_policy_vpc_protection_group: *aci_switch_policy_vpc_protection_group_absent - register: nm_remove_vpc_prot_grp_again - -- name: Verify remove_vpc_prot_grp - assert: - that: - - cm_remove_vpc_prot_grp is changed - - nm_remove_vpc_prot_grp is changed - - cm_remove_vpc_prot_grp_again is not changed - - nm_remove_vpc_prot_grp_again is not changed - - -# QUERY NON-EXISTING LEAF PROFILE -- name: Query non-existing vpc protection group (check_mode) - aci_switch_policy_vpc_protection_group: - <<: *aci_switch_policy_vpc_protection_group_query - protection_group: ansible_test - check_mode: yes - register: cm_query_non_vpc_prot_grp - -- name: Query non-existing vpc protection group (normal mode) - aci_switch_policy_vpc_protection_group: - <<: *aci_switch_policy_vpc_protection_group_query - protection_group: ansible_test - register: nm_query_non_vpc_prot_grp - -- name: Verify query_non_vpc_prot_grp - assert: - that: - - cm_query_non_vpc_prot_grp is not changed - - nm_query_non_vpc_prot_grp is not changed - - cm_query_non_vpc_prot_grp == nm_query_non_vpc_prot_grp diff --git a/test/integration/targets/aci_taboo_contract/aliases b/test/integration/targets/aci_taboo_contract/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_taboo_contract/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_taboo_contract/tasks/main.yml b/test/integration/targets/aci_taboo_contract/tasks/main.yml deleted file mode 100644 index a2099e7ff7..0000000000 --- a/test/integration/targets/aci_taboo_contract/tasks/main.yml +++ /dev/null @@ -1,286 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2018, Dag Wieers (dagwieers) <dag@wieers.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - - -# CLEAN ENVIRONMENT -- name: Remove taboo contract - aci_taboo_contract: &taboo_contract_absent - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - tenant: ansible_test - taboo_contract: taboo_contract_test - state: absent - -- name: Add tenant - aci_tenant: - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - tenant: ansible_test - state: present - - -# ADD TABOO CONTRACT -- name: Add taboo contract (check_mode) - aci_taboo_contract: &taboo_contract_present - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - tenant: ansible_test - taboo_contract: taboo_contract_test - state: present - check_mode: yes - register: cm_add_taboo_contract - -- name: Add taboo contract (normal mode) - aci_taboo_contract: *taboo_contract_present - register: nm_add_taboo_contract - -- name: Verify add_taboo_contract - assert: - that: - - cm_add_taboo_contract is changed - - nm_add_taboo_contract is changed - - 'cm_add_taboo_contract.sent == nm_add_taboo_contract.sent == {"vzTaboo": {"attributes": {"name": "taboo_contract_test"}}}' - - 'cm_add_taboo_contract.proposed == nm_add_taboo_contract.proposed == {"vzTaboo": {"attributes": {"name": "taboo_contract_test"}}}' - - cm_add_taboo_contract.previous == nm_add_taboo_contract.previous == [] - # NOTE: We cannot fix this easily - - cm_add_taboo_contract.current == [] - - nm_add_taboo_contract.current.0.vzTaboo.attributes.descr == '' - - nm_add_taboo_contract.current.0.vzTaboo.attributes.dn == 'uni/tn-ansible_test/taboo-taboo_contract_test' - - nm_add_taboo_contract.current.0.vzTaboo.attributes.name == 'taboo_contract_test' - -- name: Add taboo_contract again (check_mode) - aci_taboo_contract: *taboo_contract_present - check_mode: yes - register: cm_add_taboo_contract_again - -- name: Add taboo contract again (normal mode) - aci_taboo_contract: *taboo_contract_present - register: nm_add_taboo_contract_again - -- name: Verify add_taboo_contract_again - assert: - that: - - cm_add_taboo_contract_again is not changed - - nm_add_taboo_contract_again is not changed - - cm_add_taboo_contract_again.current == nm_add_taboo_contract_again.current == nm_add_taboo_contract.current - - -# CHANGE TABOO CONTRACT -- name: Change description of taboo contract (check_mode) - aci_taboo_contract: - <<: *taboo_contract_present - description: Ansible test taboo contract - check_mode: yes - register: cm_add_taboo_contract_descr - -- name: Change description of taboo contract (normal mode) - aci_taboo_contract: - <<: *taboo_contract_present - description: Ansible test taboo contract - register: nm_add_taboo_contract_descr - -- name: Verify add_taboo_contract_descr - assert: - that: - - cm_add_taboo_contract_descr is changed - - nm_add_taboo_contract_descr is changed - - 'cm_add_taboo_contract_descr.sent == nm_add_taboo_contract_descr.sent == {"vzTaboo": {"attributes": {"descr": "Ansible test taboo contract"}}}' - - 'cm_add_taboo_contract_descr.proposed == nm_add_taboo_contract_descr.proposed == {"vzTaboo": {"attributes": {"descr": "Ansible test taboo contract", "name": "taboo_contract_test"}}}' - - cm_add_taboo_contract_descr.previous == nm_add_taboo_contract_descr.previous == cm_add_taboo_contract_descr.current == nm_add_taboo_contract.current - - nm_add_taboo_contract_descr.current.0.vzTaboo.attributes.descr == 'Ansible test taboo contract' - - nm_add_taboo_contract_descr.current.0.vzTaboo.attributes.dn == 'uni/tn-ansible_test/taboo-taboo_contract_test' - - nm_add_taboo_contract_descr.current.0.vzTaboo.attributes.name == 'taboo_contract_test' - -- name: Change description of taboo contract again (check_mode) - aci_taboo_contract: - <<: *taboo_contract_present - description: Ansible test taboo contract - check_mode: yes - register: cm_add_taboo_contract_descr_again - -- name: Change description of taboo contract again (normal mode) - aci_taboo_contract: - <<: *taboo_contract_present - description: Ansible test taboo contract - register: nm_add_taboo_contract_descr_again - -- name: Verify add_taboo_contract_descr_again - assert: - that: - - cm_add_taboo_contract_descr_again is not changed - - nm_add_taboo_contract_descr_again is not changed - - cm_add_taboo_contract_descr_again.current == nm_add_taboo_contract_descr_again.current == nm_add_taboo_contract_descr.current - - -# ADD TABOO CONTRACT AGAIN -- name: Add taboo contract again with no description (check_mode) - aci_taboo_contract: *taboo_contract_present - check_mode: yes - register: cm_add_taboo_contract_again_no_descr - -- name: Add taboo contract again with no description (normal mode) - aci_taboo_contract: *taboo_contract_present - register: nm_add_taboo_contract_again_no_descr - -- name: Verify add_taboo_contract_again_no_descr - assert: - that: - - cm_add_taboo_contract_again_no_descr is not changed - - nm_add_taboo_contract_again_no_descr is not changed - - cm_add_taboo_contract_again_no_descr.current == nm_add_taboo_contract_again_no_descr.current == nm_add_taboo_contract_descr.current - - -# QUERY ALL TABOO CONTRACTS -- name: Query all taboo contracts (check_mode) - aci_taboo_contract: &taboo_contract_query - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - state: query - check_mode: yes - register: cm_query_all_taboo_contracts - -- name: Query all taboo contracts (normal mode) - aci_taboo_contract: *taboo_contract_query - register: nm_query_all_taboo_contracts - -- name: Verify query_all_taboo_contracts - assert: - that: - - cm_query_all_taboo_contracts is not changed - - nm_query_all_taboo_contracts is not changed - - cm_query_all_taboo_contracts == nm_query_all_taboo_contracts - - cm_query_all_taboo_contracts.current|length >= 1 - - -# QUERY A TABOO CONTRACT -- name: Query our taboo contract - aci_taboo_contract: - <<: *taboo_contract_query - tenant: ansible_test - taboo_contract: taboo_contract_test - check_mode: yes - register: cm_query_taboo_contract - -- name: Query our taboo contract - aci_taboo_contract: - <<: *taboo_contract_query - tenant: ansible_test - taboo_contract: taboo_contract_test - register: nm_query_taboo_contract - -- name: Verify query_taboo_contract - assert: - that: - - cm_query_taboo_contract is not changed - - nm_query_taboo_contract is not changed - - cm_query_taboo_contract == nm_query_taboo_contract - - nm_query_taboo_contract.current.0.vzTaboo.attributes.descr == 'Ansible test taboo contract' - - nm_query_taboo_contract.current.0.vzTaboo.attributes.dn == 'uni/tn-ansible_test/taboo-taboo_contract_test' - - nm_query_taboo_contract.current.0.vzTaboo.attributes.name == 'taboo_contract_test' - - -# REMOVE TABOO CONTRACT -- name: Remove taboo contract (check_mode) - aci_taboo_contract: *taboo_contract_absent - check_mode: yes - register: cm_remove_taboo_contract - -- name: Remove taboo contract (normal mode) - aci_taboo_contract: *taboo_contract_absent - register: nm_remove_taboo_contract - -- name: Verify remove_taboo_contract - assert: - that: - - cm_remove_taboo_contract is changed - - nm_remove_taboo_contract is changed - - 'cm_remove_taboo_contract.current == cm_remove_taboo_contract.previous == nm_remove_taboo_contract.previous == [{"vzTaboo": {"attributes": {"descr": "Ansible test taboo contract", "dn": "uni/tn-ansible_test/taboo-taboo_contract_test", "name": "taboo_contract_test", "nameAlias": "", "ownerKey": "", "ownerTag": ""}}}]' - - nm_remove_taboo_contract.current == [] - -- name: Remove taboo contract again (check_mode) - aci_taboo_contract: *taboo_contract_absent - check_mode: yes - register: cm_remove_taboo_contract_again - -- name: Remove taboo contract again (normal mode) - aci_taboo_contract: *taboo_contract_absent - register: nm_remove_taboo_contract_again - -- name: Verify remove_taboo_contract_again - assert: - that: - - cm_remove_taboo_contract_again is not changed - - nm_remove_taboo_contract_again is not changed - - cm_remove_taboo_contract_again.proposed == nm_remove_taboo_contract_again.proposed == {} - - cm_remove_taboo_contract_again.sent == nm_remove_taboo_contract_again.sent == {} - - cm_remove_taboo_contract_again.previous == nm_remove_taboo_contract_again.previous == [] - - cm_remove_taboo_contract_again.current == nm_remove_taboo_contract_again.current == [] - - -# QUERY NON-EXISTING TABOO CONTRACT -- name: Query non-existing taboo contract (check_mode) - aci_taboo_contract: - <<: *taboo_contract_query - tenant: ansible_test - taboo_contract: taboo_contract_test - check_mode: yes - register: cm_query_non_taboo_contract - -- name: Query non-existing taboo contract (normal mode) - aci_taboo_contract: - <<: *taboo_contract_query - tenant: ansible_test - taboo_contract: taboo_contract_test - register: nm_query_non_taboo_contract - -# TODO: Implement more tests -- name: Verify query_non_taboo_contract - assert: - that: - - cm_query_non_taboo_contract is not changed - - nm_query_non_taboo_contract is not changed - - cm_remove_taboo_contract_again.previous == nm_remove_taboo_contract_again.previous == [] - - cm_remove_taboo_contract_again.current == nm_remove_taboo_contract_again.current == [] - - -# PROVOKE ERRORS -- name: Error when required parameter is missing - aci_taboo_contract: - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - state: present - ignore_errors: yes - register: error_on_missing_required_param - -- name: Verify error_on_missing_required_param - assert: - that: - - error_on_missing_required_param is failed - - 'error_on_missing_required_param.msg == "state is present but all of the following are missing: tenant, taboo_contract"' diff --git a/test/integration/targets/aci_tenant/aliases b/test/integration/targets/aci_tenant/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_tenant/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_tenant/tasks/main.yml b/test/integration/targets/aci_tenant/tasks/main.yml deleted file mode 100644 index 0098fce7c0..0000000000 --- a/test/integration/targets/aci_tenant/tasks/main.yml +++ /dev/null @@ -1,213 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Dag Wieers (@dagwieers) <dag@wieers.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - - -# CLEAN ENVIRONMENT -- name: Remove tenant - aci_tenant: &tenant_absent - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - tenant: ansible_test - state: absent - - -# ADD TENANT -- name: Add tenant (check_mode) - aci_tenant: &tenant_present - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - tenant: ansible_test - state: present - check_mode: yes - register: cm_add_tenant - -- name: Add tenant (normal mode) - aci_tenant: *tenant_present - register: nm_add_tenant - -- name: Add tenant again (check_mode) - aci_tenant: *tenant_present - check_mode: yes - register: cm_add_tenant_again - -- name: Add tenant again (normal mode) - aci_tenant: *tenant_present - register: nm_add_tenant_again - -- name: Verify add_tenant - assert: - that: - - cm_add_tenant is changed - - nm_add_tenant is changed - - cm_add_tenant_again is not changed - - nm_add_tenant_again is not changed - - -# CHANGE TENANT -- name: Change description of tenant (check_mode) - aci_tenant: - <<: *tenant_present - description: Ansible test tenant - check_mode: yes - register: cm_add_tenant_descr - -- name: Change description of tenant (normal mode) - aci_tenant: - <<: *tenant_present - description: Ansible test tenant - register: nm_add_tenant_descr - -- name: Change description of tenant again (check_mode) - aci_tenant: - <<: *tenant_present - description: Ansible test tenant - check_mode: yes - register: cm_add_tenant_descr_again - -- name: Change description of tenant again (normal mode) - aci_tenant: - <<: *tenant_present - description: Ansible test tenant - register: nm_add_tenant_descr_again - -- name: Verify add_tenant_descr - assert: - that: - - cm_add_tenant_descr is changed - - nm_add_tenant_descr is changed - - cm_add_tenant_descr_again is not changed - - nm_add_tenant_descr_again is not changed - - -# ADD TENANT AGAIN -- name: Add tenant again with no description (check_mode) - aci_tenant: *tenant_present - check_mode: yes - register: cm_add_tenant_again_no_descr - -- name: Add tenant again with no description (normal mode) - aci_tenant: *tenant_present - register: nm_add_tenant_again_no_descr - -- name: Verify add_tenant_again_no_descr - assert: - that: - - cm_add_tenant_again_no_descr is not changed - - nm_add_tenant_again_no_descr is not changed - - -# QUERY ALL TENANTS -- name: Query all tenants (check_mode) - aci_tenant: &tenant_query - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - state: query - check_mode: yes - register: cm_query_all_tenants - -- name: Query all tenants (normal mode) - aci_tenant: *tenant_query - register: nm_query_all_tenants - -- name: Verify query_all_tenants - assert: - that: - - cm_query_all_tenants is not changed - - nm_query_all_tenants is not changed - # NOTE: Order of tenants is not stable between calls - #- cm_query_all_tenants == nm_query_all_tenants - - -# QUERY A TENANT -- name: Query our tenant - aci_tenant: - <<: *tenant_query - tenant: ansible_test - check_mode: yes - register: cm_query_tenant - -- name: Query our tenant - aci_tenant: - <<: *tenant_query - tenant: ansible_test - register: nm_query_tenant - -- name: Verify query_tenant - assert: - that: - - cm_query_tenant is not changed - - nm_query_tenant is not changed - - cm_query_tenant == nm_query_tenant - - -# REMOVE TENANT -- name: Remove tenant (check_mode) - aci_tenant: *tenant_absent - check_mode: yes - register: cm_remove_tenant - -- name: Remove tenant (normal mode) - aci_tenant: *tenant_absent - register: nm_remove_tenant - -- name: Remove tenant again (check_mode) - aci_tenant: *tenant_absent - check_mode: yes - register: cm_remove_tenant_again - -- name: Remove tenant again (normal mode) - aci_tenant: *tenant_absent - register: nm_remove_tenant_again - -- name: Verify remove_tenant - assert: - that: - - cm_remove_tenant is changed - - nm_remove_tenant is changed - - cm_remove_tenant_again is not changed - - nm_remove_tenant_again is not changed - - -# QUERY NON-EXISTING TENANT -- name: Query non-existing tenant (check_mode) - aci_tenant: - <<: *tenant_query - tenant: ansible_test - check_mode: yes - register: cm_query_non_tenant - -- name: Query non-existing tenant (normal mode) - aci_tenant: - <<: *tenant_query - tenant: ansible_test - register: nm_query_non_tenant - -# TODO: Implement more tests -- name: Verify query_non_tenant - assert: - that: - - cm_query_non_tenant is not changed - - nm_query_non_tenant is not changed - - cm_query_non_tenant == nm_query_non_tenant diff --git a/test/integration/targets/aci_vlan_pool/aliases b/test/integration/targets/aci_vlan_pool/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_vlan_pool/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_vlan_pool/tasks/dynamic.yml b/test/integration/targets/aci_vlan_pool/tasks/dynamic.yml deleted file mode 100644 index 7b9257332a..0000000000 --- a/test/integration/targets/aci_vlan_pool/tasks/dynamic.yml +++ /dev/null @@ -1,296 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2018, Dag Wieers (dagwieers) <dag@wieers.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# CLEAN ENVIRONMENT -- name: Remove dynamic vlan pool - aci_vlan_pool: &dynamic_vlan_pool_absent - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - pool: anstest - pool_allocation_mode: dynamic - state: absent - - -# ADD VLAN POOL -- name: Add dynamic vlan pool (check_mode) - aci_vlan_pool: &dynamic_vlan_pool_present - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - pool: anstest - pool_allocation_mode: dynamic - state: present - check_mode: yes - register: cm_add_dynamic_vlan_pool - -- name: Add dynamic vlan pool (normal mode) - aci_vlan_pool: *dynamic_vlan_pool_present - register: nm_add_dynamic_vlan_pool - -- name: Verify add_dynamic_vlan_pool - assert: - that: - - cm_add_dynamic_vlan_pool is changed - - nm_add_dynamic_vlan_pool is changed - - 'cm_add_dynamic_vlan_pool.sent == nm_add_dynamic_vlan_pool.sent == {"fvnsVlanInstP": {"attributes": {"allocMode": "dynamic", "name": "anstest"}}}' - - 'cm_add_dynamic_vlan_pool.proposed == nm_add_dynamic_vlan_pool.proposed == {"fvnsVlanInstP": {"attributes": {"allocMode": "dynamic", "name": "anstest"}}}' - - cm_add_dynamic_vlan_pool.previous == nm_add_dynamic_vlan_pool.previous == [] - # NOTE: We cannot fix this easily - - cm_add_dynamic_vlan_pool.current == [] - - nm_add_dynamic_vlan_pool.current.0.fvnsVlanInstP.attributes.allocMode == 'dynamic' - - nm_add_dynamic_vlan_pool.current.0.fvnsVlanInstP.attributes.descr == '' - - nm_add_dynamic_vlan_pool.current.0.fvnsVlanInstP.attributes.dn == 'uni/infra/vlanns-[anstest]-dynamic' - - nm_add_dynamic_vlan_pool.current.0.fvnsVlanInstP.attributes.name == 'anstest' - -- name: Add dynamic_vlan_pool again (check_mode) - aci_vlan_pool: *dynamic_vlan_pool_present - check_mode: yes - register: cm_add_dynamic_vlan_pool_again - -- name: Add dynamic vlan pool again (normal mode) - aci_vlan_pool: *dynamic_vlan_pool_present - register: nm_add_dynamic_vlan_pool_again - -- name: Verify add_dynamic_vlan_pool_again - assert: - that: - - cm_add_dynamic_vlan_pool_again is not changed - - nm_add_dynamic_vlan_pool_again is not changed - - cm_add_dynamic_vlan_pool_again.current == nm_add_dynamic_vlan_pool_again.current == nm_add_dynamic_vlan_pool.current - - -# CHANGE VLAN POOL -- name: Change description of dynamic vlan pool (check_mode) - aci_vlan_pool: - <<: *dynamic_vlan_pool_present - description: Ansible test dynamic vlan pool - check_mode: yes - register: cm_add_dynamic_vlan_pool_descr - -- name: Change description of dynamic vlan pool (normal mode) - aci_vlan_pool: - <<: *dynamic_vlan_pool_present - description: Ansible test dynamic vlan pool - register: nm_add_dynamic_vlan_pool_descr - -- name: Verify add_dynamic_vlan_pool_descr - assert: - that: - - cm_add_dynamic_vlan_pool_descr is changed - - nm_add_dynamic_vlan_pool_descr is changed - - 'cm_add_dynamic_vlan_pool_descr.sent == nm_add_dynamic_vlan_pool_descr.sent == {"fvnsVlanInstP": {"attributes": {"descr": "Ansible test dynamic vlan pool"}}}' - - 'cm_add_dynamic_vlan_pool_descr.proposed == nm_add_dynamic_vlan_pool_descr.proposed == {"fvnsVlanInstP": {"attributes": {"allocMode": "dynamic", "descr": "Ansible test dynamic vlan pool", "name": "anstest"}}}' - - cm_add_dynamic_vlan_pool_descr.previous == nm_add_dynamic_vlan_pool_descr.previous == cm_add_dynamic_vlan_pool_descr.current == nm_add_dynamic_vlan_pool.current - - nm_add_dynamic_vlan_pool_descr.current.0.fvnsVlanInstP.attributes.allocMode == 'dynamic' - - nm_add_dynamic_vlan_pool_descr.current.0.fvnsVlanInstP.attributes.descr == 'Ansible test dynamic vlan pool' - - nm_add_dynamic_vlan_pool_descr.current.0.fvnsVlanInstP.attributes.dn == 'uni/infra/vlanns-[anstest]-dynamic' - - nm_add_dynamic_vlan_pool_descr.current.0.fvnsVlanInstP.attributes.name == 'anstest' - -- name: Change description of dynamic vlan pool again (check_mode) - aci_vlan_pool: - <<: *dynamic_vlan_pool_present - description: Ansible test dynamic vlan pool - check_mode: yes - register: cm_add_dynamic_vlan_pool_descr_again - -- name: Change description of dynamic vlan pool again (normal mode) - aci_vlan_pool: - <<: *dynamic_vlan_pool_present - description: Ansible test dynamic vlan pool - register: nm_add_dynamic_vlan_pool_descr_again - -- name: Verify add_dynamic_vlan_pool_descr_again - assert: - that: - - cm_add_dynamic_vlan_pool_descr_again is not changed - - nm_add_dynamic_vlan_pool_descr_again is not changed - - cm_add_dynamic_vlan_pool_descr_again.current == nm_add_dynamic_vlan_pool_descr_again.current == nm_add_dynamic_vlan_pool_descr.current - - -# ADD VLAN POOL AGAIN -- name: Add dynamic vlan pool again with no description (check_mode) - aci_vlan_pool: *dynamic_vlan_pool_present - check_mode: yes - register: cm_add_dynamic_vlan_pool_again_no_descr - -- name: Add dynamic vlan pool again with no description (normal mode) - aci_vlan_pool: *dynamic_vlan_pool_present - register: nm_add_dynamic_vlan_pool_again_no_descr - -- name: Verify add_dynamic_vlan_pool_again_no_descr - assert: - that: - - cm_add_dynamic_vlan_pool_again_no_descr is not changed - - nm_add_dynamic_vlan_pool_again_no_descr is not changed - - cm_add_dynamic_vlan_pool_again_no_descr.current == nm_add_dynamic_vlan_pool_again_no_descr.current == nm_add_dynamic_vlan_pool_descr.current - - -# QUERY ALL VLAN POOLS -- name: Query all dynamic vlan pools (check_mode) - aci_vlan_pool: &dynamic_vlan_pool_query - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - state: query - check_mode: yes - register: cm_query_all_dynamic_vlan_pools - -- name: Query all dynamic vlan pools (normal mode) - aci_vlan_pool: *dynamic_vlan_pool_query - register: nm_query_all_dynamic_vlan_pools - -- name: Verify query_all_dynamic_vlan_pools - assert: - that: - - cm_query_all_dynamic_vlan_pools is not changed - - nm_query_all_dynamic_vlan_pools is not changed - - cm_query_all_dynamic_vlan_pools == nm_query_all_dynamic_vlan_pools - - cm_query_all_dynamic_vlan_pools.current|length >= 1 - - -# QUERY A VLAN POOL -- name: Query our dynamic vlan pool - aci_vlan_pool: - <<: *dynamic_vlan_pool_query - pool: anstest - pool_allocation_mode: dynamic - check_mode: yes - register: cm_query_dynamic_vlan_pool - -- name: Query our dynamic vlan pool - aci_vlan_pool: - <<: *dynamic_vlan_pool_query - pool: anstest - pool_allocation_mode: dynamic - register: nm_query_dynamic_vlan_pool - -- name: Verify query_dynamic_vlan_pool - assert: - that: - - cm_query_dynamic_vlan_pool is not changed - - nm_query_dynamic_vlan_pool is not changed - - cm_query_dynamic_vlan_pool == nm_query_dynamic_vlan_pool - - nm_query_dynamic_vlan_pool.current.0.fvnsVlanInstP.attributes.allocMode == 'dynamic' - - nm_query_dynamic_vlan_pool.current.0.fvnsVlanInstP.attributes.descr == 'Ansible test dynamic vlan pool' - - nm_query_dynamic_vlan_pool.current.0.fvnsVlanInstP.attributes.dn == 'uni/infra/vlanns-[anstest]-dynamic' - - nm_query_dynamic_vlan_pool.current.0.fvnsVlanInstP.attributes.name == 'anstest' - - -# REMOVE VLAN POOL -- name: Remove dynamic vlan pool (check_mode) - aci_vlan_pool: *dynamic_vlan_pool_absent - check_mode: yes - register: cm_remove_dynamic_vlan_pool - -- name: Remove dynamic vlan pool (normal mode) - aci_vlan_pool: *dynamic_vlan_pool_absent - register: nm_remove_dynamic_vlan_pool - -- name: Verify remove_dynamic_vlan_pool - assert: - that: - - cm_remove_dynamic_vlan_pool is changed - - nm_remove_dynamic_vlan_pool is changed - - 'cm_remove_dynamic_vlan_pool.current == cm_remove_dynamic_vlan_pool.previous == nm_remove_dynamic_vlan_pool.previous == [{"fvnsVlanInstP": {"attributes": {"allocMode": "dynamic", "descr": "Ansible test dynamic vlan pool", "dn": "uni/infra/vlanns-[anstest]-dynamic", "name": "anstest", "nameAlias": "", "ownerKey": "", "ownerTag": ""}}}]' - - nm_remove_dynamic_vlan_pool.current == [] - -- name: Remove dynamic vlan pool again (check_mode) - aci_vlan_pool: *dynamic_vlan_pool_absent - check_mode: yes - register: cm_remove_dynamic_vlan_pool_again - -- name: Remove dynamic vlan pool again (normal mode) - aci_vlan_pool: *dynamic_vlan_pool_absent - register: nm_remove_dynamic_vlan_pool_again - -- name: Verify remove_dynamic_vlan_pool_again - assert: - that: - - cm_remove_dynamic_vlan_pool_again is not changed - - nm_remove_dynamic_vlan_pool_again is not changed - - cm_remove_dynamic_vlan_pool_again.proposed == nm_remove_dynamic_vlan_pool_again.proposed == {} - - cm_remove_dynamic_vlan_pool_again.sent == nm_remove_dynamic_vlan_pool_again.sent == {} - - cm_remove_dynamic_vlan_pool_again.previous == nm_remove_dynamic_vlan_pool_again.previous == [] - - cm_remove_dynamic_vlan_pool_again.current == nm_remove_dynamic_vlan_pool_again.current == [] - - -# QUERY NON-EXISTING VLAN POOL -- name: Query non-existing dynamic vlan pool (check_mode) - aci_vlan_pool: - <<: *dynamic_vlan_pool_query - pool: anstest - pool_allocation_mode: dynamic - check_mode: yes - register: cm_query_non_dynamic_vlan_pool - -- name: Query non-existing dynamic vlan pool (normal mode) - aci_vlan_pool: - <<: *dynamic_vlan_pool_query - pool: anstest - pool_allocation_mode: dynamic - register: nm_query_non_dynamic_vlan_pool - -# TODO: Implement more tests -- name: Verify query_non_dynamic_vlan_pool - assert: - that: - - cm_query_non_dynamic_vlan_pool is not changed - - nm_query_non_dynamic_vlan_pool is not changed - - cm_remove_dynamic_vlan_pool_again.previous == nm_remove_dynamic_vlan_pool_again.previous == [] - - cm_remove_dynamic_vlan_pool_again.current == nm_remove_dynamic_vlan_pool_again.current == [] - - -# PROVOKE ERRORS -- name: Error when required parameter is missing - aci_vlan_pool: - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - state: present - ignore_errors: yes - register: error_on_missing_required_param - -- name: Verify error_on_missing_required_param - assert: - that: - - error_on_missing_required_param is failed - - 'error_on_missing_required_param.msg == "state is present but all of the following are missing: pool"' - -- name: Error when together parameter is missing - aci_vlan_pool: - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - pool: anstest - state: present - ignore_errors: yes - register: error_on_missing_together_param - -- name: Verify error_on_missing_together_param - assert: - that: - - error_on_missing_together_param is failed - - error_on_missing_together_param.msg == "ACI requires the 'pool_allocation_mode' when 'pool' is provided" diff --git a/test/integration/targets/aci_vlan_pool/tasks/main.yml b/test/integration/targets/aci_vlan_pool/tasks/main.yml deleted file mode 100644 index 7838dc8c45..0000000000 --- a/test/integration/targets/aci_vlan_pool/tasks/main.yml +++ /dev/null @@ -1,15 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2018, Dag Wieers (dagwieers) <dag@wieers.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - -- include_tasks: static.yml - when: static is not defined or static - -- include_tasks: dynamic.yml - when: dynamic is not defined or dynamic diff --git a/test/integration/targets/aci_vlan_pool/tasks/static.yml b/test/integration/targets/aci_vlan_pool/tasks/static.yml deleted file mode 100644 index 9d3cebec58..0000000000 --- a/test/integration/targets/aci_vlan_pool/tasks/static.yml +++ /dev/null @@ -1,296 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2018, Dag Wieers (dagwieers) <dag@wieers.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# CLEAN ENVIRONMENT -- name: Remove static vlan pool - aci_vlan_pool: &static_vlan_pool_absent - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - pool: anstest - pool_allocation_mode: static - state: absent - - -# ADD VLAN POOL -- name: Add static vlan pool (check_mode) - aci_vlan_pool: &static_vlan_pool_present - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - pool: anstest - pool_allocation_mode: static - state: present - check_mode: yes - register: cm_add_static_vlan_pool - -- name: Add static vlan pool (normal mode) - aci_vlan_pool: *static_vlan_pool_present - register: nm_add_static_vlan_pool - -- name: Verify add_static_vlan_pool - assert: - that: - - cm_add_static_vlan_pool is changed - - nm_add_static_vlan_pool is changed - - 'cm_add_static_vlan_pool.sent == nm_add_static_vlan_pool.sent == {"fvnsVlanInstP": {"attributes": {"allocMode": "static", "name": "anstest"}}}' - - 'cm_add_static_vlan_pool.proposed == nm_add_static_vlan_pool.proposed == {"fvnsVlanInstP": {"attributes": {"allocMode": "static", "name": "anstest"}}}' - - cm_add_static_vlan_pool.previous == nm_add_static_vlan_pool.previous == [] - # NOTE: We cannot fix this easily - - cm_add_static_vlan_pool.current == [] - - nm_add_static_vlan_pool.current.0.fvnsVlanInstP.attributes.allocMode == 'static' - - nm_add_static_vlan_pool.current.0.fvnsVlanInstP.attributes.descr == '' - - nm_add_static_vlan_pool.current.0.fvnsVlanInstP.attributes.dn == 'uni/infra/vlanns-[anstest]-static' - - nm_add_static_vlan_pool.current.0.fvnsVlanInstP.attributes.name == 'anstest' - -- name: Add static_vlan_pool again (check_mode) - aci_vlan_pool: *static_vlan_pool_present - check_mode: yes - register: cm_add_static_vlan_pool_again - -- name: Add static vlan pool again (normal mode) - aci_vlan_pool: *static_vlan_pool_present - register: nm_add_static_vlan_pool_again - -- name: Verify add_static_vlan_pool_again - assert: - that: - - cm_add_static_vlan_pool_again is not changed - - nm_add_static_vlan_pool_again is not changed - - cm_add_static_vlan_pool_again.current == nm_add_static_vlan_pool_again.current == nm_add_static_vlan_pool.current - - -# CHANGE VLAN POOL -- name: Change description of static vlan pool (check_mode) - aci_vlan_pool: - <<: *static_vlan_pool_present - description: Ansible test static vlan pool - check_mode: yes - register: cm_add_static_vlan_pool_descr - -- name: Change description of static vlan pool (normal mode) - aci_vlan_pool: - <<: *static_vlan_pool_present - description: Ansible test static vlan pool - register: nm_add_static_vlan_pool_descr - -- name: Verify add_static_vlan_pool_descr - assert: - that: - - cm_add_static_vlan_pool_descr is changed - - nm_add_static_vlan_pool_descr is changed - - 'cm_add_static_vlan_pool_descr.sent == nm_add_static_vlan_pool_descr.sent == {"fvnsVlanInstP": {"attributes": {"descr": "Ansible test static vlan pool"}}}' - - 'cm_add_static_vlan_pool_descr.proposed == nm_add_static_vlan_pool_descr.proposed == {"fvnsVlanInstP": {"attributes": {"allocMode": "static", "descr": "Ansible test static vlan pool", "name": "anstest"}}}' - - cm_add_static_vlan_pool_descr.previous == nm_add_static_vlan_pool_descr.previous == cm_add_static_vlan_pool_descr.current == nm_add_static_vlan_pool.current - - nm_add_static_vlan_pool_descr.current.0.fvnsVlanInstP.attributes.allocMode == 'static' - - nm_add_static_vlan_pool_descr.current.0.fvnsVlanInstP.attributes.descr == 'Ansible test static vlan pool' - - nm_add_static_vlan_pool_descr.current.0.fvnsVlanInstP.attributes.dn == 'uni/infra/vlanns-[anstest]-static' - - nm_add_static_vlan_pool_descr.current.0.fvnsVlanInstP.attributes.name == 'anstest' - -- name: Change description of static vlan pool again (check_mode) - aci_vlan_pool: - <<: *static_vlan_pool_present - description: Ansible test static vlan pool - check_mode: yes - register: cm_add_static_vlan_pool_descr_again - -- name: Change description of static vlan pool again (normal mode) - aci_vlan_pool: - <<: *static_vlan_pool_present - description: Ansible test static vlan pool - register: nm_add_static_vlan_pool_descr_again - -- name: Verify add_static_vlan_pool_descr_again - assert: - that: - - cm_add_static_vlan_pool_descr_again is not changed - - nm_add_static_vlan_pool_descr_again is not changed - - cm_add_static_vlan_pool_descr_again.current == nm_add_static_vlan_pool_descr_again.current == nm_add_static_vlan_pool_descr.current - - -# ADD VLAN POOL AGAIN -- name: Add static vlan pool again with no description (check_mode) - aci_vlan_pool: *static_vlan_pool_present - check_mode: yes - register: cm_add_static_vlan_pool_again_no_descr - -- name: Add static vlan pool again with no description (normal mode) - aci_vlan_pool: *static_vlan_pool_present - register: nm_add_static_vlan_pool_again_no_descr - -- name: Verify add_static_vlan_pool_again_no_descr - assert: - that: - - cm_add_static_vlan_pool_again_no_descr is not changed - - nm_add_static_vlan_pool_again_no_descr is not changed - - cm_add_static_vlan_pool_again_no_descr.current == nm_add_static_vlan_pool_again_no_descr.current == nm_add_static_vlan_pool_descr.current - - -# QUERY ALL VLAN POOLS -- name: Query all static vlan pools (check_mode) - aci_vlan_pool: &static_vlan_pool_query - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - state: query - check_mode: yes - register: cm_query_all_static_vlan_pools - -- name: Query all static vlan pools (normal mode) - aci_vlan_pool: *static_vlan_pool_query - register: nm_query_all_static_vlan_pools - -- name: Verify query_all_static_vlan_pools - assert: - that: - - cm_query_all_static_vlan_pools is not changed - - nm_query_all_static_vlan_pools is not changed - - cm_query_all_static_vlan_pools == nm_query_all_static_vlan_pools - - cm_query_all_static_vlan_pools.current|length >= 1 - - -# QUERY A VLAN POOL -- name: Query our static vlan pool - aci_vlan_pool: - <<: *static_vlan_pool_query - pool: anstest - pool_allocation_mode: static - check_mode: yes - register: cm_query_static_vlan_pool - -- name: Query our static vlan pool - aci_vlan_pool: - <<: *static_vlan_pool_query - pool: anstest - pool_allocation_mode: static - register: nm_query_static_vlan_pool - -- name: Verify query_static_vlan_pool - assert: - that: - - cm_query_static_vlan_pool is not changed - - nm_query_static_vlan_pool is not changed - - cm_query_static_vlan_pool == nm_query_static_vlan_pool - - nm_query_static_vlan_pool.current.0.fvnsVlanInstP.attributes.allocMode == 'static' - - nm_query_static_vlan_pool.current.0.fvnsVlanInstP.attributes.descr == 'Ansible test static vlan pool' - - nm_query_static_vlan_pool.current.0.fvnsVlanInstP.attributes.dn == 'uni/infra/vlanns-[anstest]-static' - - nm_query_static_vlan_pool.current.0.fvnsVlanInstP.attributes.name == 'anstest' - - -# REMOVE VLAN POOL -- name: Remove static vlan pool (check_mode) - aci_vlan_pool: *static_vlan_pool_absent - check_mode: yes - register: cm_remove_static_vlan_pool - -- name: Remove static vlan pool (normal mode) - aci_vlan_pool: *static_vlan_pool_absent - register: nm_remove_static_vlan_pool - -- name: Verify remove_static_vlan_pool - assert: - that: - - cm_remove_static_vlan_pool is changed - - nm_remove_static_vlan_pool is changed - - 'cm_remove_static_vlan_pool.current == cm_remove_static_vlan_pool.previous == nm_remove_static_vlan_pool.previous == [{"fvnsVlanInstP": {"attributes": {"allocMode": "static", "descr": "Ansible test static vlan pool", "dn": "uni/infra/vlanns-[anstest]-static", "name": "anstest", "nameAlias": "", "ownerKey": "", "ownerTag": ""}}}]' - - nm_remove_static_vlan_pool.current == [] - -- name: Remove static vlan pool again (check_mode) - aci_vlan_pool: *static_vlan_pool_absent - check_mode: yes - register: cm_remove_static_vlan_pool_again - -- name: Remove static vlan pool again (normal mode) - aci_vlan_pool: *static_vlan_pool_absent - register: nm_remove_static_vlan_pool_again - -- name: Verify remove_static_vlan_pool_again - assert: - that: - - cm_remove_static_vlan_pool_again is not changed - - nm_remove_static_vlan_pool_again is not changed - - cm_remove_static_vlan_pool_again.proposed == nm_remove_static_vlan_pool_again.proposed == {} - - cm_remove_static_vlan_pool_again.sent == nm_remove_static_vlan_pool_again.sent == {} - - cm_remove_static_vlan_pool_again.previous == nm_remove_static_vlan_pool_again.previous == [] - - cm_remove_static_vlan_pool_again.current == nm_remove_static_vlan_pool_again.current == [] - - -# QUERY NON-EXISTING VLAN POOL -- name: Query non-existing static vlan pool (check_mode) - aci_vlan_pool: - <<: *static_vlan_pool_query - pool: anstest - pool_allocation_mode: static - check_mode: yes - register: cm_query_non_static_vlan_pool - -- name: Query non-existing static vlan pool (normal mode) - aci_vlan_pool: - <<: *static_vlan_pool_query - pool: anstest - pool_allocation_mode: static - register: nm_query_non_static_vlan_pool - -# TODO: Implement more tests -- name: Verify query_non_static_vlan_pool - assert: - that: - - cm_query_non_static_vlan_pool is not changed - - nm_query_non_static_vlan_pool is not changed - - cm_remove_static_vlan_pool_again.previous == nm_remove_static_vlan_pool_again.previous == [] - - cm_remove_static_vlan_pool_again.current == nm_remove_static_vlan_pool_again.current == [] - - -# PROVOKE ERRORS -- name: Error when required parameter is missing - aci_vlan_pool: - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - state: present - ignore_errors: yes - register: error_on_missing_required_param - -- name: Verify error_on_missing_required_param - assert: - that: - - error_on_missing_required_param is failed - - 'error_on_missing_required_param.msg == "state is present but all of the following are missing: pool"' - -- name: Error when together parameter is missing - aci_vlan_pool: - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - pool: anstest - state: present - ignore_errors: yes - register: error_on_missing_together_param - -- name: Verify error_on_missing_together_param - assert: - that: - - error_on_missing_together_param is failed - - error_on_missing_together_param.msg == "ACI requires the 'pool_allocation_mode' when 'pool' is provided" diff --git a/test/integration/targets/aci_vlan_pool_encap_block/aliases b/test/integration/targets/aci_vlan_pool_encap_block/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_vlan_pool_encap_block/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_vlan_pool_encap_block/tasks/main.yml b/test/integration/targets/aci_vlan_pool_encap_block/tasks/main.yml deleted file mode 100644 index 95259fb936..0000000000 --- a/test/integration/targets/aci_vlan_pool_encap_block/tasks/main.yml +++ /dev/null @@ -1,380 +0,0 @@ -# Test code for the ACI modules - -# Copyright: (c) 2017, Jacob McGill (jmcgill298) -# Copyright: (c) 2018, Dag Wieers (dagwieers) <dag@wieers.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an aci apic host, aci username and aci password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - -- name: Ensure vlan pool exists for tests to kick off - aci_vlan_pool: - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - state: absent - pool: anstest - allocation_mode: static - description: Ansible Test - -- name: Ensure vlan pool exists for tests to kick off - aci_vlan_pool: &aci_pool_present - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - state: present - pool: anstest - allocation_mode: static - description: Ansible Test - register: pool_present - -- name: Create vlan pool encap block - check mode works - aci_vlan_pool_encap_block: &aci_encap_block_present - <<: *aci_pool_present - block_name: anstest - block_start: 20 - block_end: 40 - pool: anstest - pool_allocation_mode: static - allocation_mode: inherit - description: Ansible Test - check_mode: yes - register: encap_block_present_check_mode - -- name: Present assertions - assert: - that: - - encap_block_present_check_mode is changed - - 'encap_block_present_check_mode.sent == {"fvnsEncapBlk": {"attributes": {"allocMode": "inherit", "descr": "Ansible Test", "from": "vlan-20", "name": "anstest", "to": "vlan-40"}}}' - -- name: Create vlan pool encap_block - creation works - aci_vlan_pool_encap_block: - <<: *aci_encap_block_present - register: encap_block_present - -- name: Present assertions - assert: - that: - - encap_block_present is changed - - encap_block_present.previous == [] - - encap_block_present.sent == encap_block_present_check_mode.sent - - encap_block_present.sent == encap_block_present.proposed - -- name: Create vlan pool range - idempotency works - aci_vlan_pool_encap_block: - <<: *aci_encap_block_present - register: encap_block_present_idempotent - -- name: Present assertions - assert: - that: - - encap_block_present_idempotent is not changed - - encap_block_present_idempotent.previous.0.fvnsEncapBlk.attributes.name == "anstest" - -- name: Update vlan pool range - update works - aci_vlan_pool_encap_block: - <<: *aci_encap_block_present - description: Ansible Test Update - allocation_mode: inherit - register: encap_block_present_update - -- name: Present assertions - assert: - that: - - encap_block_present_update is changed - - encap_block_present_update.previous != [] - - encap_block_present_update.sent != encap_block_present.sent - -- name: Create vlan pool range - used for query - aci_vlan_pool_encap_block: &aci_encap_block_present_2 - <<: *aci_encap_block_present - block_name: anstest_2 - block_start: 50 - block_end: 55 - register: encap_block_present_2 - -- name: Present assertions - assert: - that: - - encap_block_present_2 is changed - - encap_block_present_2.previous == [] - -- name: Invalid encap_block_start - error message works - aci_vlan_pool_encap_block: - <<: *aci_encap_block_present - block_start: 0 - ignore_errors: yes - register: encap_block_start_low - -- name: Present assertions - assert: - that: - - encap_block_start_low is failed - - encap_block_start_low.msg == "vlan pools must have 'block_start' and 'block_end' values between 1 and 4094" - -- name: Invalid encap_block_start - error message works - aci_vlan_pool_encap_block: - <<: *aci_encap_block_present - block_start: 4096 - ignore_errors: yes - register: encap_block_start_high - -- name: Present assertions - assert: - that: - - encap_block_start_high is failed - - encap_block_start_high.msg == "vlan pools must have 'block_start' and 'block_end' values between 1 and 4094" - -- name: Invalid encap_block_end - error message works - aci_vlan_pool_encap_block: - <<: *aci_encap_block_present - block_end: 0 - ignore_errors: yes - register: encap_block_end_low - -- name: Present assertions - assert: - that: - - encap_block_end_low is failed - - encap_block_end_low.msg == "vlan pools must have 'block_start' and 'block_end' values between 1 and 4094" - -- name: Invalid encap_block_end - error message works - aci_vlan_pool_encap_block: - <<: *aci_encap_block_present - block_end: 4096 - ignore_errors: yes - register: encap_block_end_high - -- name: Present assertions - assert: - that: - - encap_block_end_high is failed - - encap_block_end_high.msg == "vlan pools must have 'block_start' and 'block_end' values between 1 and 4094" - -- name: Range start higher than range end - error message works - aci_vlan_pool_encap_block: - <<: *aci_encap_block_present - block_start: 1000 - ignore_errors: yes - register: encap_block_start_end - -- name: Present assertions - assert: - that: - - encap_block_start_end is failed - - encap_block_start_end.msg == "The 'block_start' must be less than or equal to the 'block_end'" - -- name: Missing required param - error message works - aci_vlan_pool_encap_block: - <<: *aci_pool_present - ignore_errors: yes - register: encap_block_present_missing_param - -- name: Present assertions - assert: - that: - - encap_block_present_missing_param is failed - - 'encap_block_present_missing_param.msg == "state is present but all of the following are missing: block_end, block_name, block_start"' - -- name: Missing required param - error message works - aci_vlan_pool_encap_block: - <<: *aci_encap_block_present - pool_allocation_mode: "{{ fake_var | default(omit) }}" - ignore_errors: yes - register: encap_block_present_allocation - -- name: Present assertions - assert: - that: - - encap_block_present_allocation is failed - - encap_block_present_allocation.msg == "ACI requires the 'pool_allocation_mode' when 'pool' is provided" - -- name: Query specific vlan pool range - aci_vlan_pool_encap_block: &aci_encap_block_query - <<: *aci_encap_block_present - state: query - register: encap_block_query - -- name: Query assertions - assert: - that: - - encap_block_query is not changed - - encap_block_query.url.endswith("infra/vlanns-[anstest]-static/from-[vlan-20]-to-[vlan-40].json") - - encap_block_query.current | length == 1 - - encap_block_query.current.0.fvnsEncapBlk.attributes.name == "anstest" - -- name: Query vlan pool range - from, to, and name are filtered - aci_vlan_pool_encap_block: &aci_encap_block_query_filter - <<: *aci_encap_block_query - pool: "{{ fake_var | default(omit) }}" - register: encap_block_query_from_to_name - -- name: Query assertions - assert: - that: - - encap_block_query_from_to_name is not changed - - encap_block_query_from_to_name.url.endswith("class/fvnsEncapBlk.json") - - '"eq(fvnsEncapBlk.from, \"vlan-20\")" in encap_block_query_from_to_name.filter_string' - - '"eq(fvnsEncapBlk.name, \"anstest\")" in encap_block_query_from_to_name.filter_string' - - '"eq(fvnsEncapBlk.to, \"vlan-40\")" in encap_block_query_from_to_name.filter_string' - - encap_block_query_from_to_name.current.0.fvnsEncapBlk.attributes.name == "anstest" - - encap_block_query_from_to_name.current.0.fvnsEncapBlk.attributes.from == "vlan-20" - - encap_block_query_from_to_name.current.0.fvnsEncapBlk.attributes.to == "vlan-40" - -- name: Query vlan pool range - from and name are filtered - aci_vlan_pool_encap_block: - <<: *aci_encap_block_query_filter - block_end: "{{ fake_var | default(omit) }}" - register: encap_block_query_from_name - -- name: Query assertions - assert: - that: - - encap_block_query_from_name is not changed - - encap_block_query_from_name.url.endswith("class/fvnsEncapBlk.json") - - '"eq(fvnsEncapBlk.from, \"vlan-20\")" in encap_block_query_from_name.filter_string' - - '"eq(fvnsEncapBlk.name, \"anstest\")" in encap_block_query_from_name.filter_string' - - encap_block_query_from_name.current.0.fvnsEncapBlk.attributes.name == "anstest" - - encap_block_query_from_name.current.0.fvnsEncapBlk.attributes.from == "vlan-20" - -- name: Query vlan pool range - to and name are filtered - aci_vlan_pool_encap_block: - <<: *aci_encap_block_query_filter - block_start: "{{ fake_var | default(omit) }}" - register: encap_block_query_to_name - -- name: Query assertions - assert: - that: - - encap_block_query_to_name is not changed - - encap_block_query_to_name.url.endswith("class/fvnsEncapBlk.json") - - '"eq(fvnsEncapBlk.name, \"anstest\")" in encap_block_query_to_name.filter_string' - - '"eq(fvnsEncapBlk.to, \"vlan-40\")" in encap_block_query_to_name.filter_string' - - encap_block_query_to_name.current.0.fvnsEncapBlk.attributes.name == "anstest" - - encap_block_query_to_name.current.0.fvnsEncapBlk.attributes.to == "vlan-40" - -- name: Query vlan pool range - name is filtered - aci_vlan_pool_encap_block: - <<: *aci_encap_block_query_filter - block_start: "{{ fake_var | default(omit) }}" - block_end: "{{ fake_var | default(omit) }}" - register: encap_block_query_name - -- name: Query assertions - assert: - that: - - encap_block_query_name is not changed - - encap_block_query_name.url.endswith("class/fvnsEncapBlk.json") - - '"eq(fvnsEncapBlk.name, \"anstest\")" in encap_block_query_name.filter_string' - - encap_block_query_name.current.0.fvnsEncapBlk.attributes.name == "anstest" - -- name: Query vlan pool range - from and to are filtered - aci_vlan_pool_encap_block: - <<: *aci_encap_block_query_filter - block_name: "{{ fake_var | default(omit) }}" - register: encap_block_query_from_to - -- name: Query assertions - assert: - that: - - encap_block_query_from_to is not changed - - encap_block_query_from_to.url.endswith("class/fvnsEncapBlk.json") - - '"eq(fvnsEncapBlk.from, \"vlan-20\")" in encap_block_query_from_to.filter_string' - - '"eq(fvnsEncapBlk.to, \"vlan-40\")" in encap_block_query_from_to.filter_string' - - encap_block_query_from_to.current.0.fvnsEncapBlk.attributes.from == "vlan-20" - - encap_block_query_from_to.current.0.fvnsEncapBlk.attributes.to == "vlan-40" - -- name: Query all ranges in a vlan pool - aci_vlan_pool_encap_block: - <<: *aci_pool_present - state: query - pool_allocation_mode: static - register: encap_block_query_pool - -- name: Query assertions - assert: - that: - - encap_block_query_pool is not changed - - encap_block_query_pool.current | length == 1 - - encap_block_query_pool.current.0.fvnsVlanInstP.attributes.name == "anstest" - - encap_block_query_pool.current.0.fvnsVlanInstP.children | length > 1 - - encap_block_query_pool.url.endswith("infra/vlanns-[anstest]-static.json") - -- name: Query all ranges - aci_vlan_pool_encap_block: - <<: *aci_pool_present - state: query - pool: "{{ fake_var | default(omit) }}" - register: encap_block_query_all - -- name: Query assertions - assert: - that: - - encap_block_query_all is not changed - - encap_block_query_all.current | length > 1 - - encap_block_query_all.current.0.fvnsEncapBlk is defined - - encap_block_query_all.url.endswith("class/fvnsEncapBlk.json") - -- name: Delete vlan pool range - deletion works - aci_vlan_pool_encap_block: - <<: *aci_encap_block_present - state: absent - register: delete_range - -- name: Absent assertions - assert: - that: - - delete_range is changed - - delete_range.proposed == {} - - delete_range.previous.0.fvnsEncapBlk.attributes.name == "anstest" - -- name: Delete vlan pool range - check mode works - aci_vlan_pool_encap_block: &aci_encap_block_absent - <<: *aci_encap_block_present_2 - state: absent - check_mode: yes - register: delete_check_mode - -- name: Absent assertions - assert: - that: - - delete_check_mode is changed - - delete_check_mode.previous != [] - -- name: Delete vlan pool range - deletion works - aci_vlan_pool_encap_block: - <<: *aci_encap_block_absent - register: delete_encap_block_2 - -- name: Absent assertions - assert: - that: - - delete_encap_block_2 is changed - - delete_encap_block_2.previous == delete_check_mode.previous - -- name: Delete vlan pool range again - idempotency works - aci_vlan_pool_encap_block: - <<: *aci_encap_block_absent - register: delete_idempotent - -- name: Absent assertions - assert: - that: - - delete_idempotent is not changed - - delete_idempotent.previous == [] - -- name: Cleanup vlan pool - aci_vlan_pool: - <<: *aci_pool_present - state: absent - when: pool_present is changed diff --git a/test/integration/targets/aci_vmm_credential/aliases b/test/integration/targets/aci_vmm_credential/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_vmm_credential/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_vmm_credential/tasks/main.yml b/test/integration/targets/aci_vmm_credential/tasks/main.yml deleted file mode 100644 index 3095ed5027..0000000000 --- a/test/integration/targets/aci_vmm_credential/tasks/main.yml +++ /dev/null @@ -1,12 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - -- include_tasks: vmware.yml - when: vmware is not defined or vmware
\ No newline at end of file diff --git a/test/integration/targets/aci_vmm_credential/tasks/vmware.yml b/test/integration/targets/aci_vmm_credential/tasks/vmware.yml deleted file mode 100644 index be386718d9..0000000000 --- a/test/integration/targets/aci_vmm_credential/tasks/vmware.yml +++ /dev/null @@ -1,239 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Dag Wieers (@dagwieers) <dag@wieers.com> - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# Remove VMM domain -- name: Remove VMM domain (normal mode) - aci_domain: &domain_absent - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - domain: vmm_dom - domain_type: vmm - vm_provider: vmware - state: absent - register: nm_remove_domain - -# ADD VMM domain for testing -- name: Add VMM domain (normal mode) - aci_domain: &domain_present - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - domain: vmm_dom - domain_type: vmm - vm_provider: vmware - state: present - register: nm_add_domain - -- name: Verify add_domain - assert: - that: - - nm_add_domain is changed - -# REMOVE credential -- name: Remove credential (check mode) - aci_vmm_credential: &credential_absent - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - name: vmm_cred - description: my_new_cred - domain: vmm_dom - credential_username: myUsername - credential_password: mySecretPassword - vm_provider: vmware - state: absent - check_mode: yes - register: cm_remove_credential - -- name: Remove vmware VMM credential (normal mode) - aci_vmm_credential: *credential_absent - register: nm_remove_credential - -- name: Verify remove_credential - assert: - that: - - cm_remove_credential is not changed - - nm_remove_credential is not changed - -# ADD credential -- name: Add vmware VMM credential (check mode) - aci_vmm_credential: &credential_present - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - name: vmm_cred - description: my_new_cred - domain: vmm_dom - credential_username: myUsername - credential_password: mySecretPassword - vm_provider: vmware - state: present - check_mode: yes - register: cm_add_credential - -# NOTE: Setting password is not idempotent -- name: Add vmware VMM credential (normal mode) - aci_vmm_credential: *credential_present - register: nm_add_credential - -# NOTE: Setting password is not idempotent -- name: Add vmware VMM credential again (check mode) - aci_vmm_credential: *credential_present - check_mode: yes - register: cm_add_credential_again - -- name: Verify add_credential - assert: - that: - - cm_add_credential is changed - - nm_add_credential is changed - - 'cm_add_credential.sent == nm_add_credential.sent == {"vmmUsrAccP": {"attributes": {"descr": "my_new_cred", "name": "vmm_cred", "pwd": "mySecretPassword", "usr": "myUsername"}}}' - - 'cm_add_credential.proposed == nm_add_credential.proposed == {"vmmUsrAccP": {"attributes": {"descr": "my_new_cred", "name": "vmm_cred", "pwd": "mySecretPassword", "usr": "myUsername"}}}' - - cm_add_credential.current == cm_add_credential.previous == nm_add_credential.previous == [] - - nm_add_credential.current.0.vmmUsrAccP.attributes.dn == 'uni/vmmp-VMware/dom-vmm_dom/usracc-vmm_cred' - - nm_add_credential.current.0.vmmUsrAccP.attributes.name == 'vmm_cred' - -# MODIFY credential -- name: Modify vmware VMM credential (check mode) - aci_vmm_credential: &credential_mod - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - name: vmm_cred - description: my_updated_descr - domain: vmm_dom - credential_username: myNewUsername - credential_password: myNewSecretPassword - vm_provider: vmware - state: present - check_mode: yes - register: cm_mod_credential - -- name: Modify vmware VMM credential (normal mode) - aci_vmm_credential: *credential_mod - register: nm_mod_credential - -- name: Verify mod_credential - assert: - that: - - cm_mod_credential is changed - - nm_mod_credential is changed - - 'cm_mod_credential.sent == nm_mod_credential.sent == {"vmmUsrAccP": {"attributes": {"descr": "my_updated_descr", "pwd": "myNewSecretPassword", "usr": "myNewUsername"}}}' - - 'cm_mod_credential.proposed == nm_mod_credential.proposed == {"vmmUsrAccP": {"attributes": {"descr": "my_updated_descr", "name": "vmm_cred", "pwd": "myNewSecretPassword", "usr": "myNewUsername"}}}' - - nm_mod_credential.current.0.vmmUsrAccP.attributes.dn == 'uni/vmmp-VMware/dom-vmm_dom/usracc-vmm_cred' - - nm_mod_credential.current.0.vmmUsrAccP.attributes.name == 'vmm_cred' - -- name: Query existing vmware VMM credential (check mode) - aci_vmm_credential: &query_existing_cred - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - name: vmm_cred - domain: vmm_dom - vm_provider: vmware - state: query - check_mode: yes - register: cm_query_credential - -- name: Query existing vmware VMM credential (normal mode) - aci_vmm_credential: *query_existing_cred - register: nm_query_credential - -- name: Query non-existent vmware VMM credential - aci_vmm_credential: - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - name: vmm_fake_cred - domain: vmm_dom - vm_provider: vmware - state: query - register: nm_query_fake_credential - -- name: Query all vmware VMM credentials (check mode) - aci_vmm_credential: &query_all_creds - host: '{{ aci_hostname }}' - username: '{{ aci_username }}' - password: '{{ aci_password }}' - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: '{{ aci_output_level | default("info") }}' - vm_provider: vmware - state: query - check_mode: yes - register: cm_query_all_credential - -- name: Query all vmware VMM credentials (normal mode) - aci_vmm_credential: *query_all_creds - register: nm_query_all_credential - -- name: Verify query_credential - assert: - that: - - cm_query_credential is not changed - - nm_query_credential is not changed - - nm_query_fake_credential is not changed - - cm_query_all_credential is not changed - - nm_query_all_credential is not changed - - cm_query_credential.current.0.vmmUsrAccP.attributes.name == 'vmm_cred' - - nm_query_credential.current.0.vmmUsrAccP.attributes.name == 'vmm_cred' - - nm_query_fake_credential.current == [] - - cm_query_all_credential.current.0.vmmUsrAccP.attributes.name == 'vmm_cred' - - nm_query_all_credential.current.0.vmmUsrAccP.attributes.name == 'vmm_cred' - -- name: Remove credential (check_mode) - aci_vmm_credential: *credential_absent - check_mode: yes - register: cm_remove_credential_again - -- name: Remove credential (normal_mode) - aci_vmm_credential: *credential_absent - register: nm_remove_credential_again - -- name: Remove credential (normal_mode) - aci_vmm_credential: *credential_absent - register: nm_remove_credential_final - -- name: Verify remove_credential - assert: - that: - - cm_remove_credential_again is changed - - nm_remove_credential_again is changed - - nm_remove_credential_final is not changed - -# Remove VMM domain after testing -- name: Remove VMM domain (normal_mode) - aci_domain: *domain_absent - register: nm_remove_domain_again
\ No newline at end of file diff --git a/test/integration/targets/aci_vrf/aliases b/test/integration/targets/aci_vrf/aliases deleted file mode 100644 index f16b250929..0000000000 --- a/test/integration/targets/aci_vrf/aliases +++ /dev/null @@ -1,2 +0,0 @@ -# No ACI simulator yet, so not enabled -unsupported diff --git a/test/integration/targets/aci_vrf/tasks/main.yml b/test/integration/targets/aci_vrf/tasks/main.yml deleted file mode 100644 index ca8b89d611..0000000000 --- a/test/integration/targets/aci_vrf/tasks/main.yml +++ /dev/null @@ -1,174 +0,0 @@ -# Test code for the ACI modules -# Copyright: (c) 2017, Jacob McGill (@jmcgill298) - -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -- name: Test that we have an ACI APIC host, ACI username and ACI password - fail: - msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' - when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - -- name: ensure tenant exists for tests to kick off - aci_tenant: &aci_tenant_present - host: "{{ aci_hostname }}" - username: "{{ aci_username }}" - password: "{{ aci_password }}" - validate_certs: '{{ aci_validate_certs | default(false) }}' - use_ssl: '{{ aci_use_ssl | default(true) }}' - use_proxy: '{{ aci_use_proxy | default(true) }}' - output_level: debug - state: present - tenant: anstest - register: tenant_present - -- name: create vrf - check mode works - aci_vrf: &aci_vrf_present - <<: *aci_tenant_present - vrf: anstest - description: Ansible Test - check_mode: yes - register: vrf_present_check_mode - -- name: create vrf - creation works - aci_vrf: - <<: *aci_vrf_present - register: vrf_present - -- name: create vrf again - idempotency works - aci_vrf: - <<: *aci_vrf_present - register: vrf_present_idempotent - -- name: update vrf - update works - aci_vrf: - <<: *aci_vrf_present - description: Ansible Test Update - policy_control_preference: unenforced - register: vrf_update - -- name: create another vrf - check more params - aci_vrf: - <<: *aci_vrf_present - vrf: anstest2 - policy_control_direction: egress - register: vrf_present_2 - -- name: create vrf without all necessary params - failure message works - aci_vrf: - <<: *aci_vrf_present - tenant: "{{ fake_var | default(omit) }}" - ignore_errors: yes - register: vrf_present_missing_param - -- name: present asserts - assert: - that: - - vrf_present_check_mode is changed - - 'vrf_present_check_mode.sent == {"fvCtx": {"attributes": {"descr": "Ansible Test", "name": "anstest"}}}' - - vrf_present is changed - - vrf_present.sent == vrf_present_check_mode.sent - - vrf_present.previous == [] - - vrf_present_idempotent is not changed - - vrf_present_idempotent.previous != [] - - vrf_update is changed - - vrf_update.previous != [] - - vrf_update.sent != vrf_update.proposed - - 'vrf_update.sent == {"fvCtx": {"attributes": {"descr": "Ansible Test Update", "pcEnfPref": "unenforced"}}}' - - 'vrf_present_2.sent.fvCtx.attributes == {"name": "anstest2", "pcEnfDir": "egress", "descr": "Ansible Test"}' - - vrf_present_missing_param is failed - - 'vrf_present_missing_param.msg == "state is present but all of the following are missing: tenant"' - -- name: get all vrf - aci_vrf: &aci_query - <<: *aci_tenant_present - state: query - tenant: "{{ fake_var | default(omit) }}" - register: query_all - -- name: get all in tenant - aci_vrf: - <<: *aci_query - tenant: anstest - register: query_tenant - -- name: get all with name - aci_vrf: - <<: *aci_query - vrf: anstest - register: query_vrf_vrf - -- name: get vrf - aci_vrf: - <<: *aci_vrf_present - state: query - register: query_vrf - -- name: query asserts - assert: - that: - - query_all is not changed - - query_all.current | length > 1 - - query_all.current.0.fvCtx is defined - - '"class/fvCtx.json" in query_all.url' - - query_tenant is not changed - - query_tenant.current | length == 1 - - query_tenant.current.0.fvTenant.children | length == 2 - - query_tenant.current.0.fvTenant.attributes.name == "anstest" - - '"rsp-subtree-class=fvCtx" in query_tenant.filter_string' - - '"tn-anstest.json" in query_tenant.url' - - query_vrf_vrf is not changed - - query_vrf_vrf.current != [] - - query_vrf_vrf.current.0.fvCtx.attributes.name == "anstest" - - '"query-target-filter=eq(fvCtx.name, \"anstest\")" in query_vrf_vrf.filter_string' - - '"class/fvCtx.json" in query_vrf_vrf.url' - - query_vrf is not changed - - query_vrf.current | length == 1 - - '"tn-anstest/ctx-anstest.json" in query_vrf.url' - -- name: delete vrf - check mode works - aci_vrf: &aci_vrf_absent - <<: *aci_vrf_present - state: absent - check_mode: yes - register: vrf_absent_check_mode - -- name: delete vrf - delete works - aci_vrf: - <<: *aci_vrf_absent - register: vrf_absent - -- name: delete vrf again - idempotency works - aci_vrf: - <<: *aci_vrf_absent - register: vrf_absent_idempotent - -- name: delete vrf - cleanup - aci_vrf: - <<: *aci_vrf_absent - name: anstest2 - -- name: delete vrf missing param - fails properly - aci_vrf: - <<: *aci_vrf_absent - vrf: "{{ fakevar | default(omit) }}" - ignore_errors: yes - register: vrf_absent_missing_param - -- name: asserts for deletion task - assert: - that: - - vrf_absent_check_mode is changed - - vrf_absent_check_mode.previous != [] - - vrf_absent_check_mode.proposed == {} - - vrf_absent is changed - - vrf_absent.previous == vrf_absent_check_mode.previous - - vrf_absent_idempotent is not changed - - vrf_absent_idempotent.previous == [] - - vrf_absent_missing_param is failed - - 'vrf_absent_missing_param.msg == "state is absent but all of the following are missing: vrf"' - -- name: delete tenant - cleanup before ending tests - aci_tenant: - <<: *aci_tenant_present - state: absent - when: tenant_present is changed diff --git a/test/sanity/ignore.txt b/test/sanity/ignore.txt index 948c760854..ff1e5d18d3 100644 --- a/test/sanity/ignore.txt +++ b/test/sanity/ignore.txt @@ -1488,84 +1488,6 @@ lib/ansible/modules/net_tools/basics/uri.py pylint:blacklisted-name lib/ansible/modules/net_tools/basics/uri.py validate-modules:doc-required-mismatch lib/ansible/modules/net_tools/basics/uri.py validate-modules:parameter-list-no-elements lib/ansible/modules/net_tools/basics/uri.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/network/aci/aci_aaa_user.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_aaa_user_certificate.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_access_port_block_to_access_port.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_access_port_to_interface_policy_leaf_profile.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_access_sub_port_block_to_access_port.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_aep.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_aep_to_domain.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_ap.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_bd.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_bd_subnet.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_bd_subnet.py validate-modules:parameter-list-no-elements -lib/ansible/modules/network/aci/aci_bd_to_l3out.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_bd_to_l3out.py validate-modules:required_together-unknown -lib/ansible/modules/network/aci/aci_config_rollback.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_config_snapshot.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_contract.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_contract_subject.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_contract_subject_to_filter.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_domain.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_domain_to_encap_pool.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_domain_to_vlan_pool.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_encap_pool.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_encap_pool_range.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_epg.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_epg_monitoring_policy.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_epg_to_contract.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_epg_to_domain.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_fabric_node.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_fabric_scheduler.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_fabric_scheduler.py validate-modules:parameter-alias-self -lib/ansible/modules/network/aci/aci_filter.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_filter_entry.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_firmware_group.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_firmware_group.py validate-modules:parameter-alias-self -lib/ansible/modules/network/aci/aci_firmware_group_node.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_firmware_group_node.py validate-modules:parameter-alias-self -lib/ansible/modules/network/aci/aci_firmware_policy.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_firmware_policy.py validate-modules:parameter-alias-self -lib/ansible/modules/network/aci/aci_firmware_source.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_interface_policy_cdp.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_interface_policy_fc.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_interface_policy_l2.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_interface_policy_leaf_policy_group.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_interface_policy_leaf_profile.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_interface_policy_lldp.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_interface_policy_mcp.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_interface_policy_ospf.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_interface_policy_ospf.py validate-modules:parameter-list-no-elements -lib/ansible/modules/network/aci/aci_interface_policy_port_channel.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_interface_policy_port_security.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_interface_selector_to_switch_policy_leaf_profile.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_l3out.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_l3out.py validate-modules:parameter-list-no-elements -lib/ansible/modules/network/aci/aci_l3out_extepg.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_l3out_extsubnet.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_l3out_extsubnet.py validate-modules:parameter-list-no-elements -lib/ansible/modules/network/aci/aci_l3out_route_tag_policy.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_maintenance_group.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_maintenance_group_node.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_maintenance_policy.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_rest.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_static_binding_to_epg.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_static_binding_to_epg.py validate-modules:parameter-list-no-elements -lib/ansible/modules/network/aci/aci_switch_leaf_selector.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_switch_policy_leaf_profile.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_switch_policy_vpc_protection_group.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_taboo_contract.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_tenant.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_tenant_action_rule_profile.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_tenant_ep_retention_policy.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_tenant_span_dst_group.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_tenant_span_src_group.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_tenant_span_src_group_to_dst_group.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_vlan_pool.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_vlan_pool_encap_block.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_vmm_credential.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/aci/aci_vmm_credential.py validate-modules:invalid-ansiblemodule-schema -lib/ansible/modules/network/aci/aci_vrf.py validate-modules:doc-required-mismatch lib/ansible/modules/network/aci/mso_label.py validate-modules:doc-required-mismatch lib/ansible/modules/network/aci/mso_role.py validate-modules:doc-required-mismatch lib/ansible/modules/network/aci/mso_role.py validate-modules:parameter-list-no-elements diff --git a/test/units/module_utils/network/aci/test_aci.py b/test/units/module_utils/network/aci/test_aci.py deleted file mode 100644 index 0d53b29c3d..0000000000 --- a/test/units/module_utils/network/aci/test_aci.py +++ /dev/null @@ -1,328 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Dag Wieers (@dagwieers) <dag@wieers.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -import sys - -from units.compat import unittest -from ansible.module_utils.network.aci.aci import ACIModule -from ansible.module_utils.six import PY2 -from ansible.module_utils._text import to_native - -import pytest - - -class AltModule(): - params = dict( - hostname='dummy', - port=123, - protocol='https', - state='present', - ) - - -class AltACIModule(ACIModule): - def __init__(self): - self.result = dict(changed=False) - self.module = AltModule - self.params = self.module.params - - -aci = AltACIModule() - - -try: - from lxml import etree - if sys.version_info >= (2, 7): - from xmljson import cobra -except ImportError: - pytestmark = pytest.mark.skip("ACI Ansible modules require the lxml and xmljson Python libraries") - - -class AciRest(unittest.TestCase): - - def test_invalid_aci_login(self): - self.maxDiff = None - - error = dict( - code='401', - text='Username or password is incorrect - FAILED local authentication', - ) - - imdata = [{ - 'error': { - 'attributes': { - 'code': '401', - 'text': 'Username or password is incorrect - FAILED local authentication', - }, - }, - }] - - totalCount = 1 - - json_response = '{"totalCount":"1","imdata":[{"error":{"attributes":{"code":"401","text":"Username or password is incorrect - FAILED local authentication"}}}]}' # NOQA - json_result = dict() - aci.response_json(json_response) - self.assertEqual(aci.error, error) - self.assertEqual(aci.imdata, imdata) - self.assertEqual(aci.totalCount, totalCount) - - # Python 2.7+ is needed for xmljson - if sys.version_info < (2, 7): - return - - xml_response = '''<?xml version="1.0" encoding="UTF-8"?><imdata totalCount="1"> - <error code="401" text="Username or password is incorrect - FAILED local authentication"/> - </imdata> - ''' - xml_result = dict() - aci.response_xml(xml_response) - self.assertEqual(aci.error, error) - self.assertEqual(aci.imdata, imdata) - self.assertEqual(aci.totalCount, totalCount) - - def test_valid_aci_login(self): - self.maxDiff = None - - imdata = [{ - 'aaaLogin': { - 'attributes': { - 'token': 'ZldYAsoO9d0FfAQM8xaEVWvQPSOYwpnqzhwpIC1r4MaToknJjlIuAt9+TvXqrZ8lWYIGPj6VnZkWiS8nJfaiaX/AyrdD35jsSxiP3zydh+849xym7ALCw/fFNsc7b5ik1HaMuSUtdrN8fmCEUy7Pq/QNpGEqkE8m7HaxAuHpmvXgtdW1bA+KKJu2zY1c/tem', # NOQA - 'siteFingerprint': 'NdxD72K/uXaUK0wn', - 'refreshTimeoutSeconds': '600', - 'maximumLifetimeSeconds': '86400', - 'guiIdleTimeoutSeconds': '1200', - 'restTimeoutSeconds': '90', - 'creationTime': '1500134817', - 'firstLoginTime': '1500134817', - 'userName': 'admin', - 'remoteUser': 'false', - 'unixUserId': '15374', - 'sessionId': 'o7hObsqNTfCmDGcZI5c4ng==', - 'lastName': '', - 'firstName': '', - 'version': '2.0(2f)', - 'buildTime': 'Sat Aug 20 23:07:07 PDT 2016', - 'node': 'topology/pod-1/node-1', - }, - 'children': [{ - 'aaaUserDomain': { - 'attributes': { - 'name': 'all', - 'rolesR': 'admin', - 'rolesW': 'admin', - }, - 'children': [{ - 'aaaReadRoles': { - 'attributes': {}, - }, - }, { - 'aaaWriteRoles': { - 'attributes': {}, - 'children': [{ - 'role': { - 'attributes': { - 'name': 'admin', - }, - }, - }], - }, - }], - }, - }, { - 'DnDomainMapEntry': { - 'attributes': { - 'dn': 'uni/tn-common', - 'readPrivileges': 'admin', - 'writePrivileges': 'admin', - }, - }, - }, { - 'DnDomainMapEntry': { - 'attributes': { - 'dn': 'uni/tn-infra', - 'readPrivileges': 'admin', - 'writePrivileges': 'admin', - }, - }, - }, { - 'DnDomainMapEntry': { - 'attributes': { - 'dn': 'uni/tn-mgmt', - 'readPrivileges': 'admin', - 'writePrivileges': 'admin', - }, - }, - }], - }, - }] - - totalCount = 1 - - json_response = '{"totalCount":"1","imdata":[{"aaaLogin":{"attributes":{"token":"ZldYAsoO9d0FfAQM8xaEVWvQPSOYwpnqzhwpIC1r4MaToknJjlIuAt9+TvXqrZ8lWYIGPj6VnZkWiS8nJfaiaX/AyrdD35jsSxiP3zydh+849xym7ALCw/fFNsc7b5ik1HaMuSUtdrN8fmCEUy7Pq/QNpGEqkE8m7HaxAuHpmvXgtdW1bA+KKJu2zY1c/tem","siteFingerprint":"NdxD72K/uXaUK0wn","refreshTimeoutSeconds":"600","maximumLifetimeSeconds":"86400","guiIdleTimeoutSeconds":"1200","restTimeoutSeconds":"90","creationTime":"1500134817","firstLoginTime":"1500134817","userName":"admin","remoteUser":"false","unixUserId":"15374","sessionId":"o7hObsqNTfCmDGcZI5c4ng==","lastName":"","firstName":"","version":"2.0(2f)","buildTime":"Sat Aug 20 23:07:07 PDT 2016","node":"topology/pod-1/node-1"},"children":[{"aaaUserDomain":{"attributes":{"name":"all","rolesR":"admin","rolesW":"admin"},"children":[{"aaaReadRoles":{"attributes":{}}},{"aaaWriteRoles":{"attributes":{},"children":[{"role":{"attributes":{"name":"admin"}}}]}}]}},{"DnDomainMapEntry":{"attributes":{"dn":"uni/tn-common","readPrivileges":"admin","writePrivileges":"admin"}}},{"DnDomainMapEntry":{"attributes":{"dn":"uni/tn-infra","readPrivileges":"admin","writePrivileges":"admin"}}},{"DnDomainMapEntry":{"attributes":{"dn":"uni/tn-mgmt","readPrivileges":"admin","writePrivileges":"admin"}}}]}}]}' # NOQA - json_result = dict() - aci.response_json(json_response) - self.assertEqual(aci.imdata, imdata) - self.assertEqual(aci.totalCount, totalCount) - - # Python 2.7+ is needed for xmljson - if sys.version_info < (2, 7): - return - - xml_response = '<?xml version="1.0" encoding="UTF-8"?><imdata totalCount="1">\n<aaaLogin token="ZldYAsoO9d0FfAQM8xaEVWvQPSOYwpnqzhwpIC1r4MaToknJjlIuAt9+TvXqrZ8lWYIGPj6VnZkWiS8nJfaiaX/AyrdD35jsSxiP3zydh+849xym7ALCw/fFNsc7b5ik1HaMuSUtdrN8fmCEUy7Pq/QNpGEqkE8m7HaxAuHpmvXgtdW1bA+KKJu2zY1c/tem" siteFingerprint="NdxD72K/uXaUK0wn" refreshTimeoutSeconds="600" maximumLifetimeSeconds="86400" guiIdleTimeoutSeconds="1200" restTimeoutSeconds="90" creationTime="1500134817" firstLoginTime="1500134817" userName="admin" remoteUser="false" unixUserId="15374" sessionId="o7hObsqNTfCmDGcZI5c4ng==" lastName="" firstName="" version="2.0(2f)" buildTime="Sat Aug 20 23:07:07 PDT 2016" node="topology/pod-1/node-1">\n<aaaUserDomain name="all" rolesR="admin" rolesW="admin">\n<aaaReadRoles/>\n<aaaWriteRoles>\n<role name="admin"/>\n</aaaWriteRoles>\n</aaaUserDomain>\n<DnDomainMapEntry dn="uni/tn-common" readPrivileges="admin" writePrivileges="admin"/>\n<DnDomainMapEntry dn="uni/tn-infra" readPrivileges="admin" writePrivileges="admin"/>\n<DnDomainMapEntry dn="uni/tn-mgmt" readPrivileges="admin" writePrivileges="admin"/>\n</aaaLogin></imdata>\n''' # NOQA - xml_result = dict() - aci.response_xml(xml_response) - self.assertEqual(aci.imdata, imdata) - self.assertEqual(aci.totalCount, totalCount) - - def test_invalid_input(self): - self.maxDiff = None - - error = dict( - code='401', - text='Username or password is incorrect - FAILED local authentication', - ) - - imdata = [{ - 'error': { - 'attributes': { - 'code': '401', - 'text': 'Username or password is incorrect - FAILED local authentication', - }, - }, - }] - - totalCount = 1 - - json_response = '{"totalCount":"1","imdata":[{"error":{"attributes":{"code":"401","text":"Username or password is incorrect - FAILED local authentication"}}}]}' # NOQA - json_result = dict() - aci.response_json(json_response) - self.assertEqual(aci.error, error) - self.assertEqual(aci.imdata, imdata) - self.assertEqual(aci.totalCount, totalCount) - - # Python 2.7+ is needed for xmljson - if sys.version_info < (2, 7): - return - - xml_response = '''<?xml version="1.0" encoding="UTF-8"?><imdata totalCount="1"> - <error code="401" text="Username or password is incorrect - FAILED local authentication"/> - </imdata> - ''' - xml_result = dict() - aci.response_xml(xml_response) - self.assertEqual(aci.error, error) - self.assertEqual(aci.imdata, imdata) - self.assertEqual(aci.totalCount, totalCount) - - def test_empty_response(self): - self.maxDiffi = None - - if PY2: - error_text = "Unable to parse output as JSON, see 'raw' output. No JSON object could be decoded" - else: - error_text = "Unable to parse output as JSON, see 'raw' output. Expecting value: line 1 column 1 (char 0)" - - error = dict( - code=-1, - text=error_text, - ) - raw = '' - - json_response = '' - json_result = dict() - aci.response_json(json_response) - self.assertEqual(aci.error, error) - self.assertEqual(aci.result['raw'], raw) - - # Python 2.7+ is needed for xmljson - if sys.version_info < (2, 7): - return - - elif etree.LXML_VERSION < (3, 3, 0, 0): - error_text = "Unable to parse output as XML, see 'raw' output. None", - elif etree.LXML_VERSION < (4, 0, 0, 0): - error_text = to_native(u"Unable to parse output as XML, see 'raw' output. None (line 0)", errors='surrogate_or_strict') - elif PY2: - error_text = "Unable to parse output as XML, see 'raw' output. Document is empty, line 1, column 1 (line 1)" - else: - error_text = None - - xml_response = '' - aci.response_xml(xml_response) - - if error_text is None: - # errors vary on Python 3.8+ for unknown reasons - # accept any of the following error messages - errors = ( - "Unable to parse output as XML, see 'raw' output. None (line 0)", - "Unable to parse output as XML, see 'raw' output. Document is empty, line 1, column 1 (<string>, line 1)", - ) - - for error in errors: - if error in aci.error['text']: - error_text = error - break - - error = dict( - code=-1, - text=error_text, - ) - - raw = '' - - self.assertEqual(aci.error, error) - self.assertEqual(aci.result['raw'], raw) - - def test_invalid_response(self): - self.maxDiff = None - - if sys.version_info < (2, 7): - error_text = "Unable to parse output as JSON, see 'raw' output. Expecting object: line 1 column 8 (char 8)" - elif PY2: - error_text = "Unable to parse output as JSON, see 'raw' output. No JSON object could be decoded" - else: - error_text = "Unable to parse output as JSON, see 'raw' output. Expecting value: line 1 column 9 (char 8)" - - error = dict( - code=-1, - text=error_text, - ) - - raw = '{ "aaa":' - - json_response = '{ "aaa":' - json_result = dict() - aci.response_json(json_response) - self.assertEqual(aci.error, error) - self.assertEqual(aci.result['raw'], raw) - - # Python 2.7+ is needed for xmljson - if sys.version_info < (2, 7): - return - - elif etree.LXML_VERSION < (3, 3, 0, 0): - error_text = "Unable to parse output as XML, see 'raw' output. Couldn't find end of Start Tag aaa line 1, line 1, column 5" # NOQA - - elif PY2: - error_text = "Unable to parse output as XML, see 'raw' output. Couldn't find end of Start Tag aaa line 1, line 1, column 6 (line 1)" # NOQA - - else: - error_text = "Unable to parse output as XML, see 'raw' output. Couldn't find end of Start Tag aaa line 1, line 1, column 6 (<string>, line 1)" # NOQA - - error = dict( - code=-1, - text=error_text, - ) - - raw = '<aaa ' - - xml_response = '<aaa ' - xml_result = dict() - aci.response_xml(xml_response) - self.assertEqual(aci.error, error) - self.assertEqual(aci.result['raw'], raw) |